assert_recognizes example throws syntax error

I am trying to test some restful routes and the example from the API docs (suitably munged) is failing. What am I not seeing?

Example from API docs on api.rubyonrails.com

# Check the default route (i.e., the index action)
  assert_recognizes {:controller => 'items', :action => 'index'}, 'items'

My test file test/functionals/birds_controller_test.rb

require ‘test_helper’

class BirdsControllerTest < ActionController::TestCase test “should have some restful routes” do assert_recognizes {:controller => ‘birds’, :action => “index”}, “birds”

end end

Test errors

$ ruby -Itest test/functional/birds_controller_test.rb test/functional/birds_controller_test.rb:47: syntax error, unexpected tASSOC, expecting ‘}’ assert_recognizes {:controller => ‘birds’, :action => “index”}, “birds”

                                 ^

test/functional/birds_controller_test.rb:47: syntax error, unexpected ‘,’, expecting ‘}’ assert_recognizes {:controller => ‘birds’, :action => “index”}, “birds”

                                          ^

test/functional/birds_controller_test.rb:47: syntax error, unexpected ‘,’, expecting kEND assert_recognizes {:controller => ‘birds’, :action => “index”}, “birds”

                                                               ^

Hi   This will work

assert_recognizes({:controller => 'birds', :action => "index"},"birds")

Sijo

Thanks. Adding parentheses fixed that test, and more importantly, fixed restful routes tests like:

  test "should have some restful routes" do     assert_recognizes({:controller => 'birds', :action => "index"}, "birds")     assert_recognizes({:controller => 'birds', :action => 'create'}, {:path => 'birds', :method => :post})     assert_routing({:path => 'birds', :method => :post}, {:controller => 'birds', :action => 'create'})   end

Thanks Sijo.

As Sijo pointed out, calls to assert_recognizes should have parentheses around the method parameters when the first parameter is a hash. The error you're seeing is a syntax error in Ruby. The code never gets executed because the Ruby parser barfs. The API docs are a misleading in this case; assert_recognizes won't work with parentheses omitted and a hash as the first parameter. Actually, as I poke around through the routing_assertions.rb file, I see several examples of omitted parentheses in the docs that may not work exactly as written.

The conventional Ruby wisdom, as far as I can tell is to omit parentheses for single method calls that are command-like, such as puts. also.omit.parentheses.when.method.chaining. :slight_smile:

Ruby allows parentheses to be omitted whenever possible, but has some internal parsing rules that check for ambiguity. I haven't run across a really clear and detailed explanation of these rules, but here's an example:

def my_method(arg)   puts 'hello' # => non-ambiguous, no parentheses needed end

my_method {:a => 'foo', :b => 'bar'} # => ambiguous. Is this a block or a hash?

HTH.

-TJ