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

Remove instance variables in generated specs #2599

Merged
merged 1 commit into from May 2, 2022

Conversation

nekketsuuu
Copy link
Contributor

@nekketsuuu nekketsuuu commented May 1, 2022

Problem

I noticed some generated scaffold specs contain explicit instance variable gets and sets. But rubocop-rspec gem, at least v2.10.0, prefers no instance variable usages in specs by default (RSpec/InstanceVariable cop, introduced in 2014 rubocop/rubocop-rspec#3).

In fact, I confirmed that some specs such as spec/views/posts/edit.html.erb_spec.rb generated by bin/rails g scaffold post are offended by rubocop.

What I Changed

Therefore, I removed usage of instance variables from generated specs.

For historians, commits in 2010 (f06aa50 and 0d244a1) introduce the use of instance variables, maybe without strong reasons.

Changes to Specs

The following table is a summary of changes to generated edit_spec.rb. I generated these results on my local environment with Rails 7.0.2.4 and rspec-{core,expectations,mocks,support} 3.12.0.pre. Specs in "After" column do not contain @post.

Context Before After
Without attributes
require 'rails_helper'

RSpec.describe "posts/edit", type: :view do
  before(:each) do
    @post = assign(:post, Post.create!())
  end

  it "renders the edit post form" do
    render

    assert_select "form[action=?][method=?]", post_path(@post), "post" do
    end
  end
end
require 'rails_helper'

RSpec.describe "posts/edit", type: :view do
  let(:post) {
    Post.create!()
  }

  before(:each) do
    assign(:post, post)
  end

  it "renders the edit post form" do
    render

    assert_select "form[action=?][method=?]", post_path(post), "post" do
    end
  end
end
With an attribute
require 'rails_helper'

RSpec.describe "posts/edit", type: :view do
  before(:each) do
    @post = assign(:post, Post.create!(
      content: "MyText"
    ))
  end

  it "renders the edit post form" do
    render

    assert_select "form[action=?][method=?]", post_path(@post), "post" do

      assert_select "textarea[name=?]", "post[content]"
    end
  end
end
require 'rails_helper'

RSpec.describe "posts/edit", type: :view do
  let(:post) {
    Post.create!(
      content: "MyText"
    )
  }

  before(:each) do
    assign(:post, post)
  end

  it "renders the edit post form" do
    render

    assert_select "form[action=?][method=?]", post_path(post), "post" do

      assert_select "textarea[name=?]", "post[content]"
    end
  end
end
With two attributes
require 'rails_helper'

RSpec.describe "posts/edit", type: :view do
  before(:each) do
    @post = assign(:post, Post.create!(
      content: "MyText",
      priority: 1
    ))
  end

  it "renders the edit post form" do
    render

    assert_select "form[action=?][method=?]", post_path(@post), "post" do

      assert_select "textarea[name=?]", "post[content]"

      assert_select "input[name=?]", "post[priority]"
    end
  end
end
require 'rails_helper'

RSpec.describe "posts/edit", type: :view do
  let(:post) {
    Post.create!(
      content: "MyText",
      priority: 1
    )
  }

  before(:each) do
    assign(:post, post)
  end

  it "renders the edit post form" do
    render

    assert_select "form[action=?][method=?]", post_path(post), "post" do

      assert_select "textarea[name=?]", "post[content]"

      assert_select "input[name=?]", "post[priority]"
    end
  end
end

RSpec/InstanceVariable rule of rubocop-rspec gem prefers
no instance variable usages in specs by default, at least v2.10.0
@pirj
Copy link
Member

pirj commented May 2, 2022

Is it the only change needed for generated specs to pass the RuboCop check?
I can think of e.g. RSpec/HookArgument cop that might be triggered by before(:each), as its default enforced style is "implicit", and it is enabled by default.

@nekketsuuu
Copy link
Contributor Author

nekketsuuu commented May 2, 2022

Is it the only change needed for generated specs to pass the RuboCop check?

Nice point. No, other cops such as Style/StringLiterals by rubocop gem are triggered. Almost all triggered cops are, however, able to auto-corrected by rubocop. The only exceptions I found are RSpec/InstanceVariable cop and Metrics/BlockLength cop.

So I want to change generated codes beforehand for RSpec/InstanceVariable. Also I don't touch for Metrics/BlockLength because many generated specs can be offended by that cop when attributes are too many (and I personally prefer to ignore Metrics/BlockLength for specs).

This is why I only changed usage of instance variables in this pull request. Thank you for pointing it out.

@pirj pirj requested review from benoittgt and JonRowe May 2, 2022 01:41
@JonRowe JonRowe merged commit 40427a0 into rspec:main May 2, 2022
JonRowe added a commit that referenced this pull request May 2, 2022
Remove instance variables in generated specs
@nekketsuuu nekketsuuu deleted the nekketsuuu-instance-variable branch May 2, 2022 09:45
@pirj
Copy link
Member

pirj commented May 2, 2022

Thank you!

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

Successfully merging this pull request may close these issues.

None yet

3 participants