Forum: RSpec assert_select - to do negative tests - need help with syntax please :)

Posted by Gordon (Guest)
on 2011-10-12 08:01
(Received via mailing list)
Hi all,

  I am trying to figure out how to use assert_select properly.

 When I created a new resource in rails 3 called Brands, the view
specs for brands had a test which read:

    # Run the generator again with the --webrat flag if you want to
use webrat matchers
    assert_select "form", :action => brands_path, :method => "post" do
      assert_select "input#brand_name", :name => "brand[name]"
      assert_select "input#brand_description", :name =>
"brand[description]"
      assert_select "input#brand_created_by", :name =>
"brand[created_by]"
    end


With my project, I do not want the "created by" attribute
to be set from the new.html.erb entry form.


I read http://content.labnotes.org/assert_select/assert_select.html
and figured I need to use the 'false' equality operator.

It also says the following:


---------- extract starts --------------
assert_select(selector, *values, equality?, message?) { |elems| ... }
assert_select(element, selector, *values, equality?, message?) { |
elems| ... }
---------- extract ends --------------

Alas, my attempts at using it failed.

For  a spec/statement such as 'assert_select
input#brand_created_by", :name => "brand[created_by]',
 I would think that input#brand_created_by would be the 'element' and
the 'selector' combined.

Since I need to use the 'false' equality operator,
1) how do i give null to *values? I have tried the following to no
success and kept getting syntax errors:

a) assert_select "input#brand_created_by", :name =>
"brand[created_by]", '', false   --> spec/views/brands/
new.html.erb_spec.rb:53: syntax error, unexpected ',', expecting
tASSOC (SyntaxError) me => "brand[created_by]", '', false
b)  assert_select "input#brand_created_by", :name =>
"brand[created_by]", nil, false -->
spec/views/brands/new.html.erb_spec.rb:53: syntax error, unexpected
',', expecting tASSOC (SyntaxError)  ...me => "brand[created_by]",
nil, false
c)  assert_select "input#brand_created_by", :name =>
"brand[created_by]", , false --> spec/views/brands/
new.html.erb_spec.rb:53: syntax error, unexpected ',', expecting
keyword_end (SyntaxError) ...:name => "brand[created_by]", , false


 It looks as if any attempts I make to denote that I have no 'values'
to give to it is not working.

Can someone please tell me what the right syntax is for saying, "i
expect not to see the brand[created_by]" input attribute at all in the
rendered form for adding new entries?

Thank you :)
Gordon
Posted by David Chelimsky (Guest)
on 2011-10-12 13:47
(Received via mailing list)
On Oct 12, 2011, at 12:58 AM, Gordon wrote:

>      assert_select "input#brand_description", :name =>
> "brand[description]"
>      assert_select "input#brand_created_by", :name =>
> "brand[created_by]"
>    end
>
>
> With my project, I do not want the "created by" attribute to be set from the 
new.html.erb entry form.
>
> I read http://content.labnotes.org/assert_select/assert_select.html and figured 
I need to use the 'false' equality operator.

That's old. Check out 
http://api.rubyonrails.org/classes/ActionDispatch/... 
for the latest.

<snip/>

> Alas, my attempts at using it failed.
>
> For  a spec/statement such as 'assert_select
> input#brand_created_by", :name => "brand[created_by]',
> I would think that input#brand_created_by would be the 'element' and
> the 'selector' combined.

Correct.

> a) assert_select "input#brand_created_by", :name =>
> "brand[created_by]", '', false   --> spec/views/brands/
> new.html.erb_spec.rb:53: syntax error, unexpected ',', expecting
> tASSOC (SyntaxError) me => "brand[created_by]", '', false

This is a problem with Ruby argument ordering working against the 
expressiveness you're looking for. Keyword arguments have to come last. 
So you can say:

  do_something 1, 2, :a, thing, :b => 3

but you can't say

  do_something 1, :a, thing, :b => 3, 2

What _will_ work is this:

  assert_select "input#brand_created_by", false

This leaves out the :name argument, but you don't need it IMO. If you 
really want it, you'd have to do this:


  assert_select "input#brand_created_by", false, :name => 
"brand[created_by]"

But that feels really awkward to me, since the negative assertion is 
expressed in the middle of the argument list

> Can someone please tell me what the right syntax is for saying, "i
> expect not to see the brand[created_by]" input attribute at all in the
> rendered form for adding new entries?

  rendered.should_not have_selector("input#brand_created_by") # ;)

You need Capybara for that, of course, but I think it's easier to grok 
than:

  assert_select "input#brand_created_by", false

HTH,
David
Posted by Gordon Yeong (Guest)
on 2011-10-12 15:48
(Received via mailing list)
>
> What _will_ work is this:
>
>  assert_select "input#brand_created_by", false
>
>
Hmmm. Sadly it does not work :( See below:

---------------- extract start -------------------------

     Failure/Error: assert_select "input#brand_created_by", false, :name 
=>
"brand[created_by]"
     ArgumentError:
       assertion message must be String or Proc, but Hash was given.
     # (eval):2:in `assert'
     # ./spec/views/brands/new.html.erb_spec.rb:37:in `block (3 levels) 
in
<top (required)>'
     # ./spec/views/brands/new.html.erb_spec.rb:34:in `block (2 levels) 
in
<top (required)

---------------- extract end  -------------------------
Posted by David Chelimsky (Guest)
on 2011-10-12 16:38
(Received via mailing list)
On Oct 12, 2011, at 6:53 AM, Gordon Yeong wrote:

> What _will_ work is this:
>
>  assert_select "input#brand_created_by", false

This ^^ does not include :name => "..."

>
>
> Hmmm. Sadly it does not work :( See below:
>
> ---------------- extract start -------------------------
>
>      Failure/Error: assert_select "input#brand_created_by", false, :name => 
"brand[created_by]"

This ^^ does include :name => "....".

What happens when you just run

  assert_select "input#brand_created_by", false
Posted by Gordon Yeong (Guest)
on 2011-10-13 13:01
(Received via mailing list)
>
>
> This ^^ does include :name => "....".
>
> What happens when you just run
>
>   assert_select "input#brand_created_by", false
>
> this runs successfully but how do I do it with the :name? :( I just want to
be complete and explicit :)
Posted by David Chelimsky (Guest)
on 2011-10-13 13:52
(Received via mailing list)
On Oct 13, 2011, at 4:40 AM, Gordon Yeong wrote:

>
> This ^^ does include :name => "....".
>
> What happens when you just run
>
>   assert_select "input#brand_created_by", false
>
> this runs successfully but how do I do it with the :name? :( I just want to be 
complete and explicit :)

I don't know if you can. Maybe somebody on the Rails list knows.

http://groups.google.com/group/rubyonrails-talk
Posted by Gordon (Guest)
on 2011-10-14 04:50
(Received via mailing list)
>
> I don't know if you can. Maybe somebody on the Rails list knows.


If it can't, it means that people can't use assert_select to expect
NOT to find a given element with extra attributes (such as :name)
being defined. If that's the case, i think assert_select was either
poorly written OR not completed yet. It's like saying that "if"
conditional works but "if not" only works to a simple extend only :( I
am sure it can be done.
Can someone please show us how?
Posted by Evgeni Dzhelyov (Guest)
on 2011-10-14 11:34
(Received via mailing list)
See this
https://github.com/rails/rails/blob/master/actionp...

seems the syntax is "[name=...]"
Posted by David Chelimsky (Guest)
on 2011-10-14 14:30
(Received via mailing list)
On Oct 13, 2011, at 8:56 PM, Gordon wrote:

>> I don't know if you can. Maybe somebody on the Rails list knows.
>
> If it can't, it means that people can't use assert_select to expect
> NOT to find a given element with extra attributes (such as :name)
> being defined. If that's the case, i think assert_select was either
> poorly written OR not completed yet. It's like saying that "if"
> conditional works but "if not" only works to a simple extend only :( I
> am sure it can be done.
> Can someone please show us how?

This is the main benefit of should and should_not vs assertions. 
Virtually every matcher works in with both should and should_not (unless 
it's author explicitly makes it not work that way).

Again, assert_select is part of the Rails library, not RSpec. Please 
post this question to http://groups.google.com/group/rubyonrails-talk 
and I'm sure you'll find someone who uses assert_select and can either 
help you figure out how to do this, or help you work towards making it 
work better.

Cheers,
David
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.