3

I'm getting some strange results from view specs

Failure/Error: assert_select "div.fileinput-new.thumbnail"
ArgumentError:
  wrong number of arguments (3 for 1)

Ok, so this seems self explanatory (though I'm not sure what are the 3 arguments referenced).

However, if I run the suite again, I might get 0 errors. And the next, 5 errors, of the same type as above but referencing different DOM elements.

There is nothing fancy in any of these specs

describe do 
  build :object / create :object 
  @object = assign(:object, object )
  it 'displays the DOM elements' do 
    render
    asset_select #DOM_elements
  end
end

What could cause this kind of inconsistent coverage of view specs?

An example stack trace

Failure/Error: assert_select "div.fileinput-new.thumbnail"

     ArgumentError:
       wrong number of arguments (3 for 1)
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/actionview-4.2.6/lib/action_view/helpers/text_helper.rb:52:in `concat'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/searchable.rb:165:in `evaluate'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/searchable.rb:165:in `block in xpath'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/searchable.rb:156:in `map'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/searchable.rb:156:in `xpath'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/searchable.rb:193:in `css_internal'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/node_set.rb:76:in `block in css'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/node_set.rb:187:in `block in each'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/node_set.rb:186:in `upto'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/node_set.rb:186:in `each'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/node_set.rb:75:in `inject'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/nokogiri-1.6.7.2/lib/nokogiri/xml/node_set.rb:75:in `css'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rails-dom-testing-1.0.7/lib/rails/dom/testing/assertions/selector_assertions/html_selector.rb:20:in `select'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rails-dom-testing-1.0.7/lib/rails/dom/testing/assertions/selector_assertions.rb:174:in `assert_select'
     # ./spec/views/users/settings/profile.html.erb_spec.rb:24:in `block (4 levels) in <top (required)>'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rails-dom-testing-1.0.7/lib/rails/dom/testing/assertions/selector_assertions.rb:295:in `nest_selection'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rails-dom-testing-1.0.7/lib/rails/dom/testing/assertions/selector_assertions.rb:177:in `block in assert_select'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rails-dom-testing-1.0.7/lib/rails/dom/testing/assertions/selector_assertions.rb:174:in `tap'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rails-dom-testing-1.0.7/lib/rails/dom/testing/assertions/selector_assertions.rb:174:in `assert_select'
     # ./spec/views/users/settings/profile.html.erb_spec.rb:22:in `block (3 levels) in <top (required)>'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:236:in `instance_exec'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:236:in `block in run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:478:in `block in with_around_and_singleton_context_hooks'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:435:in `block in with_around_example_hooks'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:478:in `block in run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:618:in `block in run_around_example_hooks_for'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:320:in `call'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:320:in `call'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-rails-3.4.2/lib/rspec/rails/adapters.rb:127:in `block (2 levels) in <module:MinitestLifecycleAdapter>'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:425:in `instance_exec'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:425:in `instance_exec'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:389:in `execute_with'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:620:in `block (2 levels) in run_around_example_hooks_for'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:320:in `call'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:320:in `call'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:621:in `run_around_example_hooks_for'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/hooks.rb:478:in `run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:435:in `with_around_example_hooks'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:478:in `with_around_and_singleton_context_hooks'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example.rb:233:in `run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:581:in `block in run_examples'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:577:in `map'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:577:in `run_examples'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:543:in `run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:544:in `block in run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:544:in `map'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/example_group.rb:544:in `run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:119:in `block (3 levels) in run_specs'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:119:in `map'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:119:in `block (2 levels) in run_specs'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/configuration.rb:1680:in `with_suite_hooks'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:118:in `block in run_specs'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/reporter.rb:77:in `report'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:117:in `run_specs'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:93:in `run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:78:in `run'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/lib/rspec/core/runner.rb:45:in `invoke'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/gems/rspec-core-3.4.4/exe/rspec:4:in `<top (required)>'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/bin/rspec:23:in `load'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/bin/rspec:23:in `<main>'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/bin/ruby_executable_hooks:15:in `eval'
     # /Users/me/.rvm/gems/ruby-2.2.3@myapp/bin/ruby_executable_hooks:15:in `<main>'
Andy Harvey
  • 12,333
  • 17
  • 93
  • 185

1 Answers1

2

This is not a definitive answer: it appears that, for some weird reason, the evaluate method in the Nokogiri's Searchable module considers the concat() function as a custom XPath function instead of the internal XPath function.

External XPath functions are called as normal ruby methods in the context of the handler attribute of evaluate. Normally the handler is the SubstitutionContext class but in your case it seems that sometimes this gets the context of the TextHelper module where the concat method is defined, accepting just 1 parameter (whereas the XPath's concat() function accepts any number of parameters). I think that this can lead to the errors you observe.

Could you open the searchable.rb file (see the stack trace for its location) on this line and add before it some debug messages to inspect the contents of the following variables?

puts "ctx #{ctx.inspect}"
puts "path #{path.inspect}"
puts "handler #{handler.inspect}"
if handler.respond_to?(:concat)
  puts "concat #{handler.method(:concat).inspect}"
else
  puts "not responding to :concat"
end

Then, can you provide the output printed for one of the failing tests?

Update: the output showed that indeed the tests context was being polluted by the ActionView::TextHelpers module and in the end it turned out that there was a ActionView::Helpers module included in a model used in the tests.

Community
  • 1
  • 1
Matouš Borák
  • 15,606
  • 1
  • 42
  • 53
  • thanks @BoraMa, I've added the full output to a gist: https://gist.github.com/ahharvey/ff87016bfaf48e0799cc0ef49a589db9. As the suite fails on a different test each time it is run, it's not clear to me which line is most relevant to this issue, hence I'm pasting all. This particular test run failed with: `Failure/Error: assert_select "input.btn.btn-primary.btn-lg[name=?][type=?]", "commit", "submit" ArgumentError: wrong number of arguments (3 for 1) ` – Andy Harvey Apr 28 '16 at 14:25
  • the last line in the gist may be the key, but appreciate your thoughts. – Andy Harvey Apr 28 '16 at 14:32
  • Hmm, I'm glad the output proved that my guess was right! The ruby `concat` method is defined in [this](https://gist.github.com/ahharvey/ff87016bfaf48e0799cc0ef49a589db9#file-nokogiri_trace-L1039) test run and all further tests, because the `handler` gets set to nil and the current context gets polluted with the `TextHelper` module for some reason. However it's still a mystery to me why... – Matouš Borák Apr 28 '16 at 14:32
  • Can you search all your tests for lines where there is an argument, that is not of the `Hash`, `String` or `Symbol` class, passed to the `assert_select` method? It might even be `nil` or anything else but hash, string, or symbol. I'm asking because it seems that arguments of other classes may be interpreted as the `handler`. – Matouš Borák Apr 28 '16 at 15:10
  • bearing in mind this is an inherited test suite, the only non Hash, String or Symbol asset_select cases appear to be Integers (e.g., `assert_select "td", :text => 1.to_s, :count => 2`), empty strings (e.g., `assert_select "td", :text => "".to_s, :count => 2`) and path_helpers (e.g., `assert_select "form", :action => objects_path`). Thanks for your thoughts – Andy Harvey Apr 28 '16 at 16:05
  • No, these are all hashes and now I think this was a false idea, sorry. Nevertheless, I found out something: I get very similar errors if I try to `include ActionView::Helpers` in my view test. Can you check your tests for such includes? If you find some, can you comment them out to see it something changes? – Matouš Borák Apr 29 '16 at 06:05
  • No specs `include ActionView::Helpers`, however this line was included in a model for some reason. After removing the include, the view tests appear to now be working. You are a genius! Thanks for spending time on this and for your help! – Andy Harvey Apr 29 '16 at 06:15
  • Oh, this is so great to hear, I was beginning to be running out of ideas! :) Most probably this model has been used in one of the view tests and this `include` polluted the test's context. I updated the answer with this probable explanation. – Matouš Borák Apr 29 '16 at 11:05