-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FEATURE: Add a cop that checks for potential fabricator shorthand use (…
…#40) In discourse/discourse#24314, @danielwaterworth introduced the ability to use #fab! with a shorthand when simply fabricating a vanilla record with the same name as the assigned let. This PR introduces a cop that highlights places where this shorthand can be used.
- Loading branch information
Showing
3 changed files
with
91 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# frozen_string_literal: true | ||
|
||
module RuboCop | ||
module Cop | ||
module Discourse | ||
# When fabricating a record without custom attributes, we can use the | ||
# fabricator shorthand as long as the identifier matches the fabricator | ||
# name. | ||
# | ||
# @example | ||
# | ||
# # bad | ||
# fab!(:user) { Fabricate(:user) } | ||
# | ||
# # good | ||
# fab!(:user) | ||
# | ||
# When using custom attributes or the identifier doesn't match, the | ||
# shorthand can't be used. | ||
# | ||
# @example | ||
# | ||
# # good | ||
# fab!(:user) { Fabricate(:user, trust_level: TrustLevel[0]) } | ||
# | ||
# # good | ||
# fab!(:another_user) { Fabricate(:user) } | ||
class FabricatorShorthand < Base | ||
def_node_matcher :offending_fabricator?, <<-MATCHER | ||
(block | ||
(send nil? :fab! | ||
(sym $_identifier)) | ||
(args) | ||
(send nil? :Fabricate | ||
(sym $_identifier))) | ||
MATCHER | ||
|
||
def on_block(node) | ||
offending_fabricator?(node) do |identifier| | ||
add_offense(node, message: message(identifier)) | ||
end | ||
end | ||
|
||
private | ||
|
||
def message(identifier) | ||
"Use the fabricator shorthand: `fab!(:#{identifier})`" | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# frozen_string_literal: true | ||
|
||
require "spec_helper" | ||
|
||
describe RuboCop::Cop::Discourse::FabricatorShorthand, :config do | ||
subject(:cop) { described_class.new(config) } | ||
|
||
let(:config) { RuboCop::Config.new } | ||
|
||
it "registers an offense when not using the fabricator shorthand" do | ||
expect_offense(<<~RUBY) | ||
RSpec.describe "Foo" do | ||
fab!(:foo) { Fabricate(:foo) } | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Discourse/FabricatorShorthand: Use the fabricator shorthand: `fab!(:foo)` | ||
end | ||
RUBY | ||
end | ||
|
||
it "does not register an offense when the fabricator has attributes" do | ||
expect_no_offenses(<<~RUBY) | ||
RSpec.describe "Foo" do | ||
fab!(:foo) { Fabricate(:foo, bar: 1) } | ||
end | ||
RUBY | ||
end | ||
|
||
it "does not register an offense when the identifier doesn't match" do | ||
expect_no_offenses(<<~RUBY) | ||
RSpec.describe "Foo" do | ||
fab!(:bar) { Fabricate(:foo) } | ||
end | ||
RUBY | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,8 @@ AllCops: | |
|
||
Discourse: | ||
Enabled: true | ||
|
||
Discourse/FabricatorShorthand: | ||
Enabled: true | ||
Include: | ||
- 'spec/**/*_spec.rb' |