rubocop-airbnb 3.0.2 → 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 (51) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +19 -1
  3. data/config/default.yml +18 -8
  4. data/config/rubocop-layout.yml +18 -13
  5. data/config/rubocop-lint.yml +8 -9
  6. data/config/rubocop-metrics.yml +0 -4
  7. data/config/rubocop-naming.yml +3 -3
  8. data/config/rubocop-performance.yml +3 -0
  9. data/config/rubocop-rails.yml +7 -0
  10. data/config/rubocop-rspec.yml +4 -9
  11. data/config/rubocop-style.yml +17 -14
  12. data/lib/rubocop/airbnb/version.rb +1 -1
  13. data/lib/rubocop/cop/airbnb/class_or_module_declared_in_wrong_file.rb +1 -1
  14. data/lib/rubocop/cop/airbnb/const_assigned_in_wrong_file.rb +1 -1
  15. data/lib/rubocop/cop/airbnb/continuation_slash.rb +2 -2
  16. data/lib/rubocop/cop/airbnb/default_scope.rb +1 -1
  17. data/lib/rubocop/cop/airbnb/factory_attr_references_class.rb +1 -1
  18. data/lib/rubocop/cop/airbnb/factory_class_use_string.rb +1 -1
  19. data/lib/rubocop/cop/airbnb/mass_assignment_accessible_modifier.rb +1 -1
  20. data/lib/rubocop/cop/airbnb/module_method_in_wrong_file.rb +1 -1
  21. data/lib/rubocop/cop/airbnb/no_timeout.rb +1 -1
  22. data/lib/rubocop/cop/airbnb/opt_arg_parameters.rb +1 -1
  23. data/lib/rubocop/cop/airbnb/phrase_bundle_keys.rb +1 -1
  24. data/lib/rubocop/cop/airbnb/risky_activerecord_invocation.rb +1 -1
  25. data/lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb +1 -1
  26. data/lib/rubocop/cop/airbnb/rspec_environment_modification.rb +1 -1
  27. data/lib/rubocop/cop/airbnb/simple_modifier_conditional.rb +1 -1
  28. data/lib/rubocop/cop/airbnb/simple_unless.rb +1 -1
  29. data/lib/rubocop/cop/airbnb/spec_constant_assignment.rb +3 -4
  30. data/lib/rubocop/cop/airbnb/unsafe_yaml_marshal.rb +1 -1
  31. data/rubocop-airbnb.gemspec +5 -5
  32. data/spec/rubocop/cop/airbnb/class_or_module_declared_in_wrong_file_spec.rb +69 -102
  33. data/spec/rubocop/cop/airbnb/const_assigned_in_wrong_file_spec.rb +58 -101
  34. data/spec/rubocop/cop/airbnb/continuation_slash_spec.rb +77 -112
  35. data/spec/rubocop/cop/airbnb/default_scope_spec.rb +24 -31
  36. data/spec/rubocop/cop/airbnb/factory_attr_references_class_spec.rb +81 -121
  37. data/spec/rubocop/cop/airbnb/factory_class_use_string_spec.rb +12 -20
  38. data/spec/rubocop/cop/airbnb/mass_assignment_accessible_modifier_spec.rb +17 -22
  39. data/spec/rubocop/cop/airbnb/module_method_in_wrong_file_spec.rb +75 -114
  40. data/spec/rubocop/cop/airbnb/no_timeout_spec.rb +16 -22
  41. data/spec/rubocop/cop/airbnb/opt_arg_parameter_spec.rb +46 -73
  42. data/spec/rubocop/cop/airbnb/phrase_bundle_keys_spec.rb +5 -20
  43. data/spec/rubocop/cop/airbnb/risky_activerecord_invocation_spec.rb +19 -33
  44. data/spec/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace_spec.rb +109 -187
  45. data/spec/rubocop/cop/airbnb/rspec_environment_modification_spec.rb +31 -41
  46. data/spec/rubocop/cop/airbnb/simple_modifier_conditional_spec.rb +64 -88
  47. data/spec/rubocop/cop/airbnb/simple_unless_spec.rb +17 -27
  48. data/spec/rubocop/cop/airbnb/spec_constant_assignment_spec.rb +42 -60
  49. data/spec/rubocop/cop/airbnb/unsafe_yaml_marshal_spec.rb +24 -36
  50. data/spec/spec_helper.rb +2 -0
  51. metadata +12 -13
@@ -1,6 +1,4 @@
1
- describe RuboCop::Cop::Airbnb::ClassOrModuleDeclaredInWrongFile do
2
- subject(:cop) { described_class.new(config) }
3
-
1
+ describe RuboCop::Cop::Airbnb::ClassOrModuleDeclaredInWrongFile, :config do
4
2
  let(:config) do
5
3
  RuboCop::Config.new(
6
4
  {
@@ -25,150 +23,119 @@ describe RuboCop::Cop::Airbnb::ClassOrModuleDeclaredInWrongFile do
25
23
  end
26
24
 
27
25
  it 'rejects if class declaration is in a file with non-matching name' do
28
- source = [
29
- 'module Foo',
30
- ' module Bar',
31
- ' class Baz',
32
- ' end',
33
- ' end',
34
- 'end',
35
- ].join("\n")
36
-
37
26
  File.open "#{models_dir}/qux.rb", "w" do |file|
38
- inspect_source(source, file)
27
+ expect_offense(<<~RUBY, file)
28
+ module Foo
29
+ ^^^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this class/module, move its definition to a file that matches its name. Module Foo should be defined in foo.rb.
30
+ module Bar
31
+ ^^^^^^^^^^ In order for Rails autoloading [...]
32
+ class Baz
33
+ ^^^^^^^^^ In order for Rails autoloading [...]
34
+ end
35
+ end
36
+ end
37
+ RUBY
39
38
  end
40
-
41
- expect(cop.offenses.size).to eq(3)
42
- expect(cop.offenses.map(&:line).sort).to eq([1, 2, 3])
43
- expect(cop.offenses.first.message).to include('Module Foo should be defined in foo.rb.')
44
39
  end
45
40
 
46
41
  it 'rejects if class declaration is in a file with matching name but wrong parent dir' do
47
- source = [
48
- 'module Foo',
49
- ' module Bar',
50
- ' class Baz',
51
- ' end',
52
- ' end',
53
- 'end',
54
- ].join("\n")
55
-
56
42
  File.open "#{models_dir}/baz.rb", "w" do |file|
57
- inspect_source(source, file)
43
+ expect_offense(<<~RUBY, file)
44
+ module Foo
45
+ ^^^^^^^^^^ In order for Rails autoloading [...]
46
+ module Bar
47
+ ^^^^^^^^^^ In order for Rails autoloading [...]
48
+ class Baz
49
+ ^^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this class/module, move its definition to a file that matches its name. Class Baz should be defined in foo/bar/baz.rb.
50
+ end
51
+ end
52
+ end
53
+ RUBY
58
54
  end
59
-
60
- expect(cop.offenses.size).to eq(3)
61
- expect(cop.offenses.map(&:line).sort).to eq([1, 2, 3])
62
- expect(cop.offenses.last.message).to include('Class Baz should be defined in foo/bar/baz.rb.')
63
55
  end
64
56
 
65
57
  it 'accepts if class declaration is in a file with matching name and right parent dir' do
66
- source = [
67
- 'module Foo',
68
- ' module Bar',
69
- ' class Baz',
70
- ' end',
71
- ' end',
72
- 'end',
73
- ].join("\n")
74
-
75
58
  FileUtils.mkdir_p "#{models_dir}/foo/bar"
76
59
  File.open "#{models_dir}/foo/bar/baz.rb", "w" do |file|
77
- inspect_source(source, file)
60
+ expect_no_offenses(<<~RUBY, file)
61
+ module Foo
62
+ module Bar
63
+ class Baz
64
+ end
65
+ end
66
+ end
67
+ RUBY
78
68
  end
79
-
80
- expect(cop.offenses).to be_empty
81
69
  end
82
70
 
83
71
  it 'rejects if class declaration is in wrong dir and parent module uses ::' do
84
- source = [
85
- 'module Foo::Bar',
86
- ' class Baz',
87
- ' end',
88
- 'end',
89
- ].join("\n")
90
-
91
72
  FileUtils.mkdir_p "#{models_dir}/bar"
92
73
  File.open "#{models_dir}/bar/baz.rb", "w" do |file|
93
- inspect_source(source, file)
74
+ expect_offense(<<~RUBY, file)
75
+ module Foo::Bar
76
+ ^^^^^^^^^^^^^^^ In order for Rails autoloading [...]
77
+ class Baz
78
+ ^^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this class/module, move its definition to a file that matches its name. Class Baz should be defined in foo/bar/baz.rb.
79
+ end
80
+ end
81
+ RUBY
94
82
  end
95
-
96
- expect(cop.offenses.map(&:line).sort).to eq([1, 2])
97
- expect(cop.offenses.last.message).to include('Class Baz should be defined in foo/bar/baz.rb.')
98
83
  end
99
84
 
100
85
  it 'accepts if class declaration is in a file with matching name and parent module uses ::' do
101
- source = [
102
- 'module Foo::Bar',
103
- ' class Baz',
104
- ' end',
105
- 'end',
106
- ].join("\n")
107
-
108
86
  FileUtils.mkdir_p "#{models_dir}/foo/bar"
109
87
  File.open "#{models_dir}/foo/bar/baz.rb", "w" do |file|
110
- inspect_source(source, file)
88
+ expect_no_offenses(<<~RUBY, file)
89
+ module Foo::Bar
90
+ class Baz
91
+ end
92
+ end
93
+ RUBY
111
94
  end
112
-
113
- expect(cop.offenses).to be_empty
114
95
  end
115
96
 
116
97
  it 'accepts class declaration where the containing class uses an acronym' do
117
- source = [
118
- 'module CSVFoo',
119
- ' class Baz',
120
- ' end',
121
- 'end',
122
- ].join("\n")
123
-
124
98
  FileUtils.mkdir_p "#{models_dir}/csv_foo"
125
99
  File.open "#{models_dir}/csv_foo/baz.rb", "w" do |file|
126
- inspect_source(source, file)
100
+ expect_no_offenses(<<~RUBY)
101
+ module CSVFoo
102
+ class Baz
103
+ end
104
+ end
105
+ RUBY
127
106
  end
128
-
129
- expect(cop.offenses).to be_empty
130
107
  end
131
108
 
132
109
  it 'ignores class/module declaration in a rake task' do
133
- source = [
134
- 'class Baz',
135
- 'end',
136
- ].join("\n")
137
-
138
110
  File.open "#{models_dir}/foo.rake", "w" do |file|
139
- inspect_source(source, file)
111
+ expect_no_offenses(<<~RUBY, file)
112
+ class Baz
113
+ end
114
+ RUBY
140
115
  end
141
-
142
- expect(cop.offenses).to be_empty
143
116
  end
144
117
 
145
118
  it 'suggests moving error classes into the file that defines the owning scope' do
146
- source = [
147
- 'module Foo',
148
- ' class BarError < StandardError; end',
149
- 'end',
150
- ].join("\n")
151
-
152
119
  File.open "#{models_dir}/bar.rb", "w" do |file|
153
- inspect_source(source, file)
120
+ expect_offense(<<~RUBY, file)
121
+ module Foo
122
+ ^^^^^^^^^^ In order for Rails autoloading [...]
123
+ class BarError < StandardError; end
124
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this class, move its definition to a file that defines the owning module. Class BarError should be defined in foo.rb.
125
+ end
126
+ RUBY
154
127
  end
155
-
156
- expect(cop.offenses.map(&:line)).to include(2)
157
- expect(cop.offenses.map(&:message)).to include(%r{Class BarError should be defined in foo\.rb.})
158
128
  end
159
129
 
160
130
  it 'recognizes error class based on the superclass name' do
161
- source = [
162
- 'module Foo',
163
- ' class Bar < StandardError; end',
164
- 'end',
165
- ].join("\n")
166
-
167
131
  File.open "#{models_dir}/bar.rb", "w" do |file|
168
- inspect_source(source, file)
132
+ expect_offense(<<~RUBY, file)
133
+ module Foo
134
+ ^^^^^^^^^^ In order for Rails autoloading [...]
135
+ class Bar < StandardError; end
136
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone references this class, move its definition to a file that defines the owning module. Class Bar should be defined in foo.rb.
137
+ end
138
+ RUBY
169
139
  end
170
-
171
- expect(cop.offenses.map(&:line)).to include(2)
172
- expect(cop.offenses.map(&:message)).to include(%r{Class Bar should be defined in foo\.rb.})
173
140
  end
174
141
  end
@@ -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