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

no easy way to set locals in view specs #2676

Closed
mreinsch opened this issue May 10, 2023 · 3 comments
Closed

no easy way to set locals in view specs #2676

mreinsch opened this issue May 10, 2023 · 3 comments

Comments

@mreinsch
Copy link

mreinsch commented May 10, 2023

What Ruby, Rails and RSpec versions are you using?

Ruby version: ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x86_64-darwin21]
Rails version: Rails 7.0.4.3
RSpec version: RSpec 3.12

  • rspec-core 3.12.2
  • rspec-expectations 3.12.3
  • rspec-mocks 3.12.5
  • rspec-rails 6.0.2
  • rspec-support 3.12.0

Observed behaviour

This is about a view spec. While writing a test for a partial which uses a local variable I couldn't find a documented way on how to approach it. I tried:

render {}, { variable_name: some_object }

but that resulted in local_assigns in the template to be an empty hash and thus the rendering failed.

Expected behaviour

Provide an easy way to pass local variables to a partial.

Investigation / Suggested fix

The render method (defined as https://github.com/rspec/rspec-rails/blob/main/lib/rspec/rails/example/view_example_group.rb#LL66C8-L66C61): render(options = {}, local_assigns = {}, &block) only seems to pass local_assigns through in case options is not as Hash (i.e. a String). Otherwise the code will refer to options[:locals].

Thus I'd suggest the following code for the render method to allow passing locals:

def render(options = {}, local_assigns = {}, &block)
  options = _default_render_options.merge(options) if options.is_a?(Hash) && !(options[:partial] || options[:template])
  super(options, local_assigns, &block)
end

Then it's possible to use

render locals: { variable_name: some_object }

which looks nicer.

If that's acceptable, I can prepare a PR.

@mreinsch mreinsch changed the title local_assigns no easy way to set locals in view specs May 10, 2023
@JonRowe
Copy link
Member

JonRowe commented Jun 26, 2023

Apologies for the delay in looking into this, there are two ways we support for rendering partials with locals, see:
https://rspec.info/features/6-0/rspec-rails/view-specs/view-spec/

First, explicit partials:

render :partial => "widgets/widget", :locals => {:widget => widget}

Second, implicit partials:

render "widgets/widget", :widget => widget

@JonRowe
Copy link
Member

JonRowe commented Jun 26, 2023

Theres actually a whole bunch of keys you can pass to Rails to render here, and you actually have to provide something, so but we can use the defaults which check the implicit template, and merge in the locals, which is what I've done in #2686

@JonRowe
Copy link
Member

JonRowe commented Jun 28, 2023

#2686 will allow render locals: { ... } by defaulting to the template behaviour.

@JonRowe JonRowe closed this as completed Jun 28, 2023
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