Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails 6 error thrown in render - wrong number of arguments (given 2, expected 1) #204

Closed
ishields opened this issue Sep 23, 2019 · 3 comments

Comments

@ishields
Copy link

ishields commented Sep 23, 2019

Hello! I just updated to Rails 6 and have the latest version of the gem (2.12.0).

I'm experiencing an error in one of my rspec tests in which it looks the controller render method is passing the wrong number of arguments.

The test is very simple

describe HomeController do
  describe '#index' do
    it 'is successful and calls seo data' do
      expect(controller).to receive(:set_meta_tags)
      get :index
      expect(response).to be_successful
    end
  end
end
ActionView::Template::Error: wrong number of arguments (given 2, expected 1)

  0) HomeController #index is successful
     Failure/Error:[0mget[33m:index[0m

     ActionView::Template::Error:
       wrong number of arguments (given 2, expected 1)
     # /Users/myuser/.rvm/gems/ruby-2.6.3/gems/meta-tags-2.12.0/lib/meta_tags/controller_helper.rb:22:in `render'

I believe the offending method is in ControllerHelper in the render method

def render(*args, &block)
      meta_tags[:title]       = @page_title       if @page_title
      meta_tags[:keywords]    = @page_keywords    if @page_keywords
      meta_tags[:description] = @page_description if @page_description

      super 
end

I believe super is passing both args and block to the render method but the super render method is only expecting one argument. As a proof of concept I modified the call to be super(args) and that seemed to work. Not really sure if this is the solution though.

@kpumuk
Copy link
Owner

kpumuk commented Sep 23, 2019

Hi! I checked the issue, and it seems like the problem is not in meta-tags, but in RSpec.

First of all, in Ruby you can pass a block to any method without consequences:

def a
  puts "Hello"
end

a { raise "Really?" }
# → Hello

Now, for your issue, if you turn on a backtrace in RSpec (--backtrace argument), last two lines will be:

     # /Users/kpumuk/.rvm/gems/ruby-2.6.3/gems/rspec-rails-3.8.2/lib/rspec/rails/view_rendering.rb:105:in `call'
     # /Users/kpumuk/.rvm/gems/ruby-2.6.3/gems/actionview-6.0.0/lib/action_view/template.rb:315:in `compile'

So, ActionView calls a handler with two arguments (link):

      def compile(mod)
        source = encode!
        code = @handler.call(self, source)

While RSpec overrides it with one argument (link):

      class EmptyTemplateHandler
        def self.call(_template)
          ::Rails.logger.info("  Template rendering was prevented by rspec-rails. Use `render_views` to verify rendered view contents if necessary.")

          %("")
        end
      end

This was already reported and fixed in RSpec 4.dev:

@kpumuk kpumuk closed this as completed Sep 23, 2019
@ishields
Copy link
Author

ishields commented Sep 23, 2019

You're totally right. Switching to that branch worked. Really appreciate your quick reply on this.
Thanks a lot!

@kpumuk
Copy link
Owner

kpumuk commented Sep 23, 2019

You're welcome :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants