rubocop-airbnb 3.0.2 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
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