rubocop-airbnb 4.0.0 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/config/default.yml +9 -8
  4. data/config/rubocop-performance.yml +3 -0
  5. data/config/rubocop-rails.yml +3 -0
  6. data/config/rubocop-rspec.yml +4 -9
  7. data/lib/rubocop/airbnb/version.rb +1 -1
  8. data/lib/rubocop/cop/airbnb/class_or_module_declared_in_wrong_file.rb +1 -1
  9. data/lib/rubocop/cop/airbnb/const_assigned_in_wrong_file.rb +1 -1
  10. data/lib/rubocop/cop/airbnb/continuation_slash.rb +1 -1
  11. data/lib/rubocop/cop/airbnb/default_scope.rb +1 -1
  12. data/lib/rubocop/cop/airbnb/factory_attr_references_class.rb +1 -1
  13. data/lib/rubocop/cop/airbnb/factory_class_use_string.rb +1 -1
  14. data/lib/rubocop/cop/airbnb/mass_assignment_accessible_modifier.rb +1 -1
  15. data/lib/rubocop/cop/airbnb/module_method_in_wrong_file.rb +1 -1
  16. data/lib/rubocop/cop/airbnb/no_timeout.rb +1 -1
  17. data/lib/rubocop/cop/airbnb/opt_arg_parameters.rb +1 -1
  18. data/lib/rubocop/cop/airbnb/phrase_bundle_keys.rb +1 -1
  19. data/lib/rubocop/cop/airbnb/risky_activerecord_invocation.rb +1 -1
  20. data/lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb +1 -1
  21. data/lib/rubocop/cop/airbnb/rspec_environment_modification.rb +1 -1
  22. data/lib/rubocop/cop/airbnb/simple_modifier_conditional.rb +1 -1
  23. data/lib/rubocop/cop/airbnb/simple_unless.rb +1 -1
  24. data/lib/rubocop/cop/airbnb/spec_constant_assignment.rb +3 -4
  25. data/lib/rubocop/cop/airbnb/unsafe_yaml_marshal.rb +1 -1
  26. data/rubocop-airbnb.gemspec +3 -3
  27. data/spec/rubocop/cop/airbnb/class_or_module_declared_in_wrong_file_spec.rb +69 -102
  28. data/spec/rubocop/cop/airbnb/const_assigned_in_wrong_file_spec.rb +58 -101
  29. data/spec/rubocop/cop/airbnb/continuation_slash_spec.rb +77 -112
  30. data/spec/rubocop/cop/airbnb/default_scope_spec.rb +24 -31
  31. data/spec/rubocop/cop/airbnb/factory_attr_references_class_spec.rb +81 -121
  32. data/spec/rubocop/cop/airbnb/factory_class_use_string_spec.rb +12 -20
  33. data/spec/rubocop/cop/airbnb/mass_assignment_accessible_modifier_spec.rb +17 -22
  34. data/spec/rubocop/cop/airbnb/module_method_in_wrong_file_spec.rb +75 -114
  35. data/spec/rubocop/cop/airbnb/no_timeout_spec.rb +16 -22
  36. data/spec/rubocop/cop/airbnb/opt_arg_parameter_spec.rb +46 -73
  37. data/spec/rubocop/cop/airbnb/phrase_bundle_keys_spec.rb +5 -20
  38. data/spec/rubocop/cop/airbnb/risky_activerecord_invocation_spec.rb +19 -33
  39. data/spec/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace_spec.rb +109 -187
  40. data/spec/rubocop/cop/airbnb/rspec_environment_modification_spec.rb +31 -41
  41. data/spec/rubocop/cop/airbnb/simple_modifier_conditional_spec.rb +64 -88
  42. data/spec/rubocop/cop/airbnb/simple_unless_spec.rb +17 -27
  43. data/spec/rubocop/cop/airbnb/spec_constant_assignment_spec.rb +42 -60
  44. data/spec/rubocop/cop/airbnb/unsafe_yaml_marshal_spec.rb +24 -36
  45. data/spec/spec_helper.rb +2 -0
  46. metadata +8 -8
@@ -1,6 +1,4 @@
1
- describe RuboCop::Cop::Airbnb::ConstAssignedInWrongFile do
2
- subject(:cop) { described_class.new(config) }
3
-
1
+ describe RuboCop::Cop::Airbnb::ConstAssignedInWrongFile, :config do
4
2
  let(:config) do
5
3
  RuboCop::Config.new(
6
4
  {
@@ -25,154 +23,113 @@ describe RuboCop::Cop::Airbnb::ConstAssignedInWrongFile do
25
23
  end
26
24
 
27
25
  it 'rejects if const assignment is in a file with non-matching name' do
28
- source = [
29
- 'module Foo',
30
- ' module Bar',
31
- ' BAZ = 42',
32
- ' end',
33
- 'end',
34
- ].join("\n")
35
-
36
26
  File.open "#{models_dir}/qux.rb", "w" do |file|
37
- inspect_source(source, file)
27
+ expect_offense(<<~RUBY, file)
28
+ module Foo
29
+ module Bar
30
+ BAZ = 42
31
+ ^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this const, move the const assignment to a file that defines the owning module. Const BAZ should be defined in foo/bar.rb.
32
+ end
33
+ end
34
+ RUBY
38
35
  end
39
-
40
- expect(cop.offenses.map(&:line)).to include(3)
41
- expect(cop.offenses.map(&:message)).to include(%r{Const BAZ should be defined in foo/bar\.rb.})
42
36
  end
43
37
 
44
38
  it 'rejects if const assignment is in a file with matching name but wrong parent dir' do
45
- source = [
46
- 'module Foo',
47
- ' module Bar',
48
- ' BAZ = 42',
49
- ' end',
50
- 'end',
51
- ].join("\n")
52
-
53
39
  File.open "#{models_dir}/bar.rb", "w" do |file|
54
- inspect_source(source, file)
40
+ expect_offense(<<~RUBY, file)
41
+ module Foo
42
+ module Bar
43
+ BAZ = 42
44
+ ^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this const, move the const assignment to a file that defines the owning module. Const BAZ should be defined in foo/bar.rb.
45
+ end
46
+ end
47
+ RUBY
55
48
  end
56
-
57
- expect(cop.offenses.map(&:line)).to include(3)
58
- expect(cop.offenses.map(&:message)).to include(%r{Const BAZ should be defined in foo/bar\.rb.})
59
49
  end
60
50
 
61
51
  it 'accepts if const assignment is in a file with matching name and right parent dir' do
62
- source = [
63
- 'module Foo',
64
- ' module Bar',
65
- ' BAZ = 42',
66
- ' end',
67
- 'end',
68
- ].join("\n")
69
-
70
52
  FileUtils.mkdir "#{models_dir}/foo"
71
53
  File.open "#{models_dir}/foo/bar.rb", "w" do |file|
72
- inspect_source(source, file)
54
+ expect_no_offenses(<<~RUBY, file)
55
+ module Foo
56
+ module Bar
57
+ BAZ = 42
58
+ end
59
+ end
60
+ RUBY
73
61
  end
74
-
75
- expect(cop.offenses).to be_empty
76
62
  end
77
63
 
78
64
  it 'accepts if const assignment is in a file with matching name and right parent dir' \
79
65
  'and parent modules were defined on a single line' do
80
- source = [
81
- 'module Foo::Bar',
82
- ' BAZ = 42',
83
- 'end',
84
- ].join("\n")
85
-
86
66
  FileUtils.mkdir "#{models_dir}/foo"
87
67
  File.open "#{models_dir}/foo/bar.rb", "w" do |file|
88
- inspect_source(source, file)
68
+ expect_no_offenses(<<~RUBY, file)
69
+ module Foo::Bar
70
+ BAZ = 42
71
+ end
72
+ RUBY
89
73
  end
90
-
91
- expect(cop.offenses).to be_empty
92
74
  end
93
75
 
94
76
  it 'accepts if const assignment is in a file whose name matches the const and right parent dir' do
95
- source = [
96
- 'module Foo',
97
- ' module Bar',
98
- ' BAZ = 42',
99
- ' end',
100
- 'end',
101
- ].join("\n")
102
-
103
77
  FileUtils.mkdir_p "#{models_dir}/foo/bar"
104
78
  File.open "#{models_dir}/foo/bar/baz.rb", "w" do |file|
105
- inspect_source(source, file)
79
+ expect_no_offenses(<<~RUBY, file)
80
+ module Foo
81
+ module Bar
82
+ BAZ = 42
83
+ end
84
+ end
85
+ RUBY
106
86
  end
107
-
108
- expect(cop.offenses).to be_empty
109
87
  end
110
88
 
111
89
  it 'ignores if const assignment is assigning something in another scope' do
112
- source = [
113
- 'module Foo',
114
- ' Bar::BAZ = 42',
115
- 'end',
116
- ].join("\n")
117
-
118
90
  File.open "#{models_dir}/foo.rb", "w" do |file|
119
- inspect_source(source, file)
91
+ expect_no_offenses(<<~RUBY, file)
92
+ module Foo
93
+ Bar::BAZ = 42
94
+ end
95
+ RUBY
120
96
  end
121
-
122
- expect(cop.offenses).to be_empty
123
97
  end
124
98
 
125
99
  it 'accepts const assignment where the containing class uses an acronym' do
126
- source = [
127
- 'module CSVFoo',
128
- ' BAZ = 42',
129
- 'end',
130
- ].join("\n")
131
-
132
100
  File.open "#{models_dir}/csv_foo.rb", "w" do |file|
133
- inspect_source(source, file)
101
+ expect_no_offenses(<<~RUBY, file)
102
+ module CSVFoo
103
+ BAZ = 42
104
+ end
105
+ RUBY
134
106
  end
135
-
136
- expect(cop.offenses).to be_empty
137
107
  end
138
108
 
139
109
  it 'suggests moving a global const into a namespace' do
140
- source = [
141
- 'FOO = 42',
142
- ].join("\n")
143
-
144
110
  File.open "#{models_dir}/bar.rb", "w" do |file|
145
- inspect_source(source, file)
111
+ expect_offense(<<~RUBY, file)
112
+ FOO = 42
113
+ ^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this const, move the const assignment to a file that defines the owning module. Const FOO should be moved into a namespace or defined in foo.rb.
114
+ RUBY
146
115
  end
147
-
148
- expect(cop.offenses.map(&:line)).to eq([1])
149
- expect(cop.offenses.first.message).
150
- to include('Const FOO should be moved into a namespace or defined in foo.rb.')
151
116
  end
152
117
 
153
118
  it 'ignores const assignment in global namespace in a rake task' do
154
- source = [
155
- 'FOO = 42',
156
- ].join("\n")
157
-
158
119
  File.open "#{models_dir}/foo.rake", "w" do |file|
159
- inspect_source(source, file)
120
+ expect_no_offenses(<<~RUBY, file)
121
+ FOO = 42
122
+ RUBY
160
123
  end
161
-
162
- expect(cop.offenses).to be_empty
163
124
  end
164
125
 
165
126
  it 'ignores const assignment in a class in a rake task' do
166
- source = [
167
- 'class Baz',
168
- ' FOO = 42',
169
- 'end',
170
- ].join("\n")
171
-
172
127
  File.open "#{models_dir}/foo.rake", "w" do |file|
173
- inspect_source(source, file)
128
+ expect_no_offenses(<<~RUBY, file)
129
+ class Baz
130
+ FOO = 42
131
+ end
132
+ RUBY
174
133
  end
175
-
176
- expect(cop.offenses).to be_empty
177
134
  end
178
135
  end
@@ -1,162 +1,127 @@
1
- describe RuboCop::Cop::Airbnb::ContinuationSlash do
2
- subject(:cop) { described_class.new }
3
-
1
+ describe RuboCop::Cop::Airbnb::ContinuationSlash, :config do
4
2
  it 'rejects continuations used to continue a method call with trailing dot' do
5
- source = [
6
- 'User. \\',
7
- ' first_name',
8
- ].join("\n")
9
- inspect_source(source)
10
-
11
- expect(cop.offenses.size).to eq(1)
12
- expect(cop.offenses.map(&:line).sort).to eq([1])
3
+ expect_offense(<<~RUBY)
4
+ User. \\
5
+ ^^^^^^^ Slash continuation should be reserved [...]
6
+ first_name
7
+ RUBY
13
8
  end
14
9
 
15
10
  context 'on assignment' do
16
11
  it 'rejects on constant assignment' do
17
- source = [
18
- 'CONSTANT = "I am a string that \\',
19
- ' spans multiple lines"',
20
- ].join("\n")
21
- inspect_source(source)
22
-
23
- expect(cop.offenses.size).to eq(1)
12
+ expect_offense(<<~RUBY)
13
+ CONSTANT = "I am a string that \\
14
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Slash continuation should be reserved [...]
15
+ spans multiple lines"
16
+ RUBY
24
17
  end
25
18
 
26
19
  it 'rejects on local variable assignment' do
27
- source = [
28
- 'variable = "I am a string that \\',
29
- ' spans multiple lines"',
30
- ].join("\n")
31
- inspect_source(source)
32
-
33
- expect(cop.offenses.size).to eq(1)
20
+ expect_offense(<<~RUBY)
21
+ variable = "I am a string that \\
22
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Slash continuation should be reserved [...]
23
+ spans multiple lines"
24
+ RUBY
34
25
  end
35
26
 
36
27
  it 'rejects on @var assignment' do
37
- source = [
38
- 'class SomeClass',
39
- ' @class_var = "I am a string that \\',
40
- ' spans multiple lines"',
41
- 'end',
42
- ].join("\n")
43
- inspect_source(source)
44
-
45
- expect(cop.offenses.size).to eq(1)
28
+ expect_offense(<<~RUBY)
29
+ class SomeClass
30
+ @class_var = "I am a string that \\
31
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Slash continuation should be reserved [...]
32
+ spans multiple lines"
33
+ end
34
+ RUBY
46
35
  end
47
36
 
48
37
  it 'rejects on @@var assignment' do
49
- source = [
50
- 'class SomeClass',
51
- ' @@class_var = "I am a string that \\',
52
- ' spans multiple lines"',
53
- 'end',
54
- ].join("\n")
55
- inspect_source(source)
56
-
57
- expect(cop.offenses.size).to eq(1)
38
+ expect_offense(<<~RUBY)
39
+ class SomeClass
40
+ @@class_var = "I am a string that \\
41
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Slash continuation should be reserved [...]
42
+ spans multiple lines"
43
+ end
44
+ RUBY
58
45
  end
59
46
  end
60
47
 
61
48
  context 'in conditional continuation' do
62
49
  it 'rejects if with continuation \\ before operator' do
63
- source = [
64
- 'if true \\',
65
- ' && false',
66
- ' return false',
67
- 'end',
68
- ].join("\n")
69
- inspect_source(source)
70
-
71
- expect(cop.offenses.size).to eq(1)
50
+ expect_offense(<<~RUBY)
51
+ if true \\
52
+ ^^^^^^^^^ Slash continuation should be reserved [...]
53
+ && false
54
+ return false
55
+ end
56
+ RUBY
72
57
  end
73
58
 
74
59
  it 'rejects unless with continuation \\' do
75
- source = [
76
- 'unless true \\',
77
- ' && false',
78
- ' return false',
79
- 'end',
80
- ].join("\n")
81
- inspect_source(source)
82
-
83
- expect(cop.offenses.size).to eq(1)
60
+ expect_offense(<<~RUBY)
61
+ unless true \\
62
+ ^^^^^^^^^^^^^ Slash continuation should be reserved [...]
63
+ && false
64
+ return false
65
+ end
66
+ RUBY
84
67
  end
85
68
 
86
69
  it 'rejects if with continuation \\ after operator' do
87
- source = [
88
- 'if true || \\',
89
- ' false',
90
- ' return false',
91
- 'end',
92
- ].join("\n")
93
- inspect_source(source)
94
-
95
- expect(cop.offenses.size).to eq(1)
70
+ expect_offense(<<~RUBY)
71
+ if true || \\
72
+ ^^^^^^^^^^^^ Slash continuation should be reserved [...]
73
+ false
74
+ return false
75
+ end
76
+ RUBY
96
77
  end
97
78
  end
98
79
 
99
80
  context 'open string continuation' do
100
81
  it 'rejects contination with space before \\' do
101
- source = [
102
- 'I18n.t("I am a string that \\',
103
- ' spans multiple lines")',
104
- ].join("\n")
105
- inspect_source(source)
106
-
107
- expect(cop.offenses.size).to eq(1)
82
+ expect_offense(<<~RUBY)
83
+ I18n.t("I am a string that \\
84
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Slash continuation should be reserved [...]
85
+ spans multiple lines")
86
+ RUBY
108
87
  end
109
88
 
110
89
  it 'rejects contination with no space before \\' do
111
- source = [
112
- 'I18n.t(\'I am a string that \\',
113
- ' spans multiple lines\')',
114
- ].join("\n")
115
- inspect_source(source)
116
-
117
- expect(cop.offenses.size).to eq(1)
90
+ expect_offense(<<~RUBY)
91
+ I18n.t(\'I am a string that \\
92
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Slash continuation should be reserved [...]
93
+ spans multiple lines\')
94
+ RUBY
118
95
  end
119
96
  end
120
97
 
121
98
  context 'closed string continuation' do
122
99
  it 'allows double quote string with no space before \\' do
123
- source = [
124
- 'I18n.t("I am a string that "\\',
125
- ' "spans multiple lines")',
126
- ].join("\n")
127
- inspect_source(source)
128
-
129
- expect(cop.offenses).to be_empty
100
+ expect_no_offenses(<<~RUBY)
101
+ I18n.t("I am a string that "\\
102
+ "spans multiple lines")
103
+ RUBY
130
104
  end
131
105
 
132
106
  it 'allows double quote string with space before \\' do
133
- source = [
134
- 'I18n.t("I am a string that " \\',
135
- ' "spans multiple lines")',
136
- ].join("\n")
137
- inspect_source(source)
138
-
139
- expect(cop.offenses).to be_empty
107
+ expect_no_offenses(<<~RUBY)
108
+ I18n.t("I am a string that " \\
109
+ "spans multiple lines")
110
+ RUBY
140
111
  end
141
112
 
142
113
  it 'allows single quote string with no space before \\' do
143
- source = [
144
- 'I18n.t(\'I am a string that \'\\',
145
- ' \'spans multiple lines\')',
146
- ].join("\n")
147
- inspect_source(source)
148
-
149
- expect(cop.offenses).to be_empty
114
+ expect_no_offenses(<<~RUBY)
115
+ I18n.t(\'I am a string that \'\\
116
+ \'spans multiple lines\')
117
+ RUBY
150
118
  end
151
119
 
152
120
  it 'allows single quote string with space before \\' do
153
- source = [
154
- 'I18n.t(\'I am a string that \' \\',
155
- ' \'spans multiple lines\')',
156
- ].join("\n")
157
- inspect_source(source)
158
-
159
- expect(cop.offenses).to be_empty
121
+ expect_no_offenses(<<~RUBY)
122
+ I18n.t(\'I am a string that \' \\
123
+ \'spans multiple lines\')
124
+ RUBY
160
125
  end
161
126
  end
162
127
  end
@@ -1,38 +1,31 @@
1
- describe RuboCop::Cop::Airbnb::DefaultScope do
2
- subject(:cop) { described_class.new }
3
-
1
+ describe RuboCop::Cop::Airbnb::DefaultScope, :config do
4
2
  it 'rejects with default_scopes' do
5
- source = [
6
- '# encoding: UTF-8',
7
- 'module SurveyQuestion',
8
- ' class Host < PhraseBundle',
9
- ' db_magic :connection => AIRMISC_MASTER,',
10
- ' :slaves => AIRMISC_DB_SLAVES,',
11
- ' :force_slave_reads => FORCE_SLAVE_READS',
12
- '',
13
- ' default_scope where(active: true)',
14
- '',
15
- ' end',
16
- 'end',
17
- ].join("\n")
18
- inspect_source(source)
3
+ expect_offense(<<~RUBY)
4
+ # encoding: UTF-8
5
+ module SurveyQuestion
6
+ class Host < PhraseBundle
7
+ db_magic :connection => AIRMISC_MASTER,
8
+ :slaves => AIRMISC_DB_SLAVES,
9
+ :force_slave_reads => FORCE_SLAVE_READS
10
+
11
+ default_scope where(active: true)
12
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Avoid `default_scope`. [...]
19
13
 
20
- expect(cop.offenses.size).to eq(1)
21
- expect(cop.offenses.map(&:line).sort).to eq([8])
14
+ end
15
+ end
16
+ RUBY
22
17
  end
23
18
 
24
19
  it 'passes when there is no default_scope' do
25
- source = [
26
- '# encoding: UTF-8',
27
- 'module SurveyQuestion',
28
- ' class Host < PhraseBundle',
29
- ' db_magic :connection => AIRMISC_MASTER,',
30
- ' :slaves => AIRMISC_DB_SLAVES,',
31
- ' :force_slave_reads => FORCE_SLAVE_READS',
32
- ' end',
33
- 'end',
34
- ].join("\n")
35
- inspect_source(source)
36
- expect(cop.offenses).to be_empty
20
+ expect_no_offenses(<<~RUBY)
21
+ # encoding: UTF-8
22
+ module SurveyQuestion
23
+ class Host < PhraseBundle
24
+ db_magic :connection => AIRMISC_MASTER,
25
+ :slaves => AIRMISC_DB_SLAVES,
26
+ :force_slave_reads => FORCE_SLAVE_READS
27
+ end
28
+ end
29
+ RUBY
37
30
  end
38
31
  end