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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +19 -1
- data/config/default.yml +18 -8
- data/config/rubocop-layout.yml +18 -13
- data/config/rubocop-lint.yml +8 -9
- data/config/rubocop-metrics.yml +0 -4
- data/config/rubocop-naming.yml +3 -3
- data/config/rubocop-performance.yml +3 -0
- data/config/rubocop-rails.yml +7 -0
- data/config/rubocop-rspec.yml +4 -9
- data/config/rubocop-style.yml +17 -14
- data/lib/rubocop/airbnb/version.rb +1 -1
- data/lib/rubocop/cop/airbnb/class_or_module_declared_in_wrong_file.rb +1 -1
- data/lib/rubocop/cop/airbnb/const_assigned_in_wrong_file.rb +1 -1
- data/lib/rubocop/cop/airbnb/continuation_slash.rb +2 -2
- data/lib/rubocop/cop/airbnb/default_scope.rb +1 -1
- data/lib/rubocop/cop/airbnb/factory_attr_references_class.rb +1 -1
- data/lib/rubocop/cop/airbnb/factory_class_use_string.rb +1 -1
- data/lib/rubocop/cop/airbnb/mass_assignment_accessible_modifier.rb +1 -1
- data/lib/rubocop/cop/airbnb/module_method_in_wrong_file.rb +1 -1
- data/lib/rubocop/cop/airbnb/no_timeout.rb +1 -1
- data/lib/rubocop/cop/airbnb/opt_arg_parameters.rb +1 -1
- data/lib/rubocop/cop/airbnb/phrase_bundle_keys.rb +1 -1
- data/lib/rubocop/cop/airbnb/risky_activerecord_invocation.rb +1 -1
- data/lib/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace.rb +1 -1
- data/lib/rubocop/cop/airbnb/rspec_environment_modification.rb +1 -1
- data/lib/rubocop/cop/airbnb/simple_modifier_conditional.rb +1 -1
- data/lib/rubocop/cop/airbnb/simple_unless.rb +1 -1
- data/lib/rubocop/cop/airbnb/spec_constant_assignment.rb +3 -4
- data/lib/rubocop/cop/airbnb/unsafe_yaml_marshal.rb +1 -1
- data/rubocop-airbnb.gemspec +5 -5
- data/spec/rubocop/cop/airbnb/class_or_module_declared_in_wrong_file_spec.rb +69 -102
- data/spec/rubocop/cop/airbnb/const_assigned_in_wrong_file_spec.rb +58 -101
- data/spec/rubocop/cop/airbnb/continuation_slash_spec.rb +77 -112
- data/spec/rubocop/cop/airbnb/default_scope_spec.rb +24 -31
- data/spec/rubocop/cop/airbnb/factory_attr_references_class_spec.rb +81 -121
- data/spec/rubocop/cop/airbnb/factory_class_use_string_spec.rb +12 -20
- data/spec/rubocop/cop/airbnb/mass_assignment_accessible_modifier_spec.rb +17 -22
- data/spec/rubocop/cop/airbnb/module_method_in_wrong_file_spec.rb +75 -114
- data/spec/rubocop/cop/airbnb/no_timeout_spec.rb +16 -22
- data/spec/rubocop/cop/airbnb/opt_arg_parameter_spec.rb +46 -73
- data/spec/rubocop/cop/airbnb/phrase_bundle_keys_spec.rb +5 -20
- data/spec/rubocop/cop/airbnb/risky_activerecord_invocation_spec.rb +19 -33
- data/spec/rubocop/cop/airbnb/rspec_describe_or_context_under_namespace_spec.rb +109 -187
- data/spec/rubocop/cop/airbnb/rspec_environment_modification_spec.rb +31 -41
- data/spec/rubocop/cop/airbnb/simple_modifier_conditional_spec.rb +64 -88
- data/spec/rubocop/cop/airbnb/simple_unless_spec.rb +17 -27
- data/spec/rubocop/cop/airbnb/spec_constant_assignment_spec.rb +42 -60
- data/spec/rubocop/cop/airbnb/unsafe_yaml_marshal_spec.rb +24 -36
- data/spec/spec_helper.rb +2 -0
- metadata +12 -13
@@ -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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
21
|
-
|
14
|
+
end
|
15
|
+
end
|
16
|
+
RUBY
|
22
17
|
end
|
23
18
|
|
24
19
|
it 'passes when there is no default_scope' do
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
@@ -1,160 +1,120 @@
|
|
1
|
-
describe RuboCop::Cop::Airbnb::FactoryAttrReferencesClass do
|
2
|
-
subject(:cop) { described_class.new }
|
3
|
-
|
1
|
+
describe RuboCop::Cop::Airbnb::FactoryAttrReferencesClass, :config do
|
4
2
|
it 'rejects with `attr_name CONST_NAME` in a factory' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
expect(cop.offenses.size).to eq(1)
|
13
|
-
expect(cop.offenses.map(&:line)).to eq([2])
|
3
|
+
expect_offense(<<~RUBY)
|
4
|
+
factory :reservation2 do
|
5
|
+
status Reservation2::STATUS_NEW
|
6
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
7
|
+
end
|
8
|
+
RUBY
|
14
9
|
end
|
15
10
|
|
16
11
|
it 'passes with `attr_name { CONST_NAME }` in a factory' do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
inspect_source(source)
|
23
|
-
|
24
|
-
expect(cop.offenses).to be_empty
|
12
|
+
expect_no_offenses(<<~RUBY)
|
13
|
+
factory :reservation2 do
|
14
|
+
status { Reservation2::STATUS_NEW }
|
15
|
+
end
|
16
|
+
RUBY
|
25
17
|
end
|
26
18
|
|
27
19
|
it 'rejects with `attr_name [CONST_NAME]`' do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
expect(cop.offenses.size).to eq(1)
|
36
|
-
expect(cop.offenses.map(&:line)).to eq([2])
|
20
|
+
expect_offense(<<~RUBY)
|
21
|
+
factory :reservation2 do
|
22
|
+
statuses [Reservation2::STATUS_NEW]
|
23
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
24
|
+
end
|
25
|
+
RUBY
|
37
26
|
end
|
38
27
|
|
39
28
|
it 'passes with `attr_name { [CONST_NAME] }`' do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
inspect_source(source)
|
46
|
-
|
47
|
-
expect(cop.offenses).to be_empty
|
29
|
+
expect_no_offenses(<<~RUBY)
|
30
|
+
factory :reservation2 do
|
31
|
+
statuses { [Reservation2::STATUS_NEW] }
|
32
|
+
end
|
33
|
+
RUBY
|
48
34
|
end
|
49
35
|
|
50
36
|
it 'rejects with `attr_name [[CONST_NAME]]`' do
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
expect(cop.offenses.size).to eq(1)
|
59
|
-
expect(cop.offenses.map(&:line)).to eq([2])
|
37
|
+
expect_offense(<<~RUBY)
|
38
|
+
factory :reservation2 do
|
39
|
+
statuses [[Reservation2::STATUS_NEW]]
|
40
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
41
|
+
end
|
42
|
+
RUBY
|
60
43
|
end
|
61
44
|
|
62
45
|
it 'passes with `attr_name { [[CONST_NAME]] }`' do
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
inspect_source(source)
|
69
|
-
|
70
|
-
expect(cop.offenses).to be_empty
|
46
|
+
expect_no_offenses(<<~RUBY)
|
47
|
+
factory :reservation2 do
|
48
|
+
statuses { [[Reservation2::STATUS_NEW]] }
|
49
|
+
end
|
50
|
+
RUBY
|
71
51
|
end
|
72
52
|
|
73
53
|
it 'rejects with `attr_name({ ConstName => something })' do
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
expect(cop.offenses.size).to eq(1)
|
82
|
-
expect(cop.offenses.map(&:line)).to eq([2])
|
54
|
+
expect_offense(<<~RUBY)
|
55
|
+
factory :reservation2 do
|
56
|
+
status_names({ Reservation2::STATUS_NEW => "new" })
|
57
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
58
|
+
end
|
59
|
+
RUBY
|
83
60
|
end
|
84
61
|
|
85
62
|
it 'passes with `attr_name { { ConstName => something } }`' do
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
inspect_source(source)
|
92
|
-
|
93
|
-
expect(cop.offenses).to be_empty
|
63
|
+
expect_no_offenses(<<~RUBY)
|
64
|
+
factory :reservation2 do
|
65
|
+
status_names { { Reservation2::STATUS_NEW => "new" } }
|
66
|
+
end
|
67
|
+
RUBY
|
94
68
|
end
|
95
69
|
|
96
70
|
it 'rejects with `attr_name ConstName[:symbol]`' do
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
expect(cop.offenses.size).to eq(1)
|
105
|
-
expect(cop.offenses.map(&:line)).to eq([2])
|
71
|
+
expect_offense(<<~RUBY)
|
72
|
+
factory :airlock_rule do
|
73
|
+
stickiness Airlock::STICKINESS[:user]
|
74
|
+
^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
75
|
+
end
|
76
|
+
RUBY
|
106
77
|
end
|
107
78
|
|
108
79
|
it 'passes with `attr_name { ConstName[:symbol] }`' do
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
inspect_source(source)
|
115
|
-
|
116
|
-
expect(cop.offenses).to be_empty
|
80
|
+
expect_no_offenses(<<~RUBY)
|
81
|
+
factory :airlock_rule do
|
82
|
+
stickiness { Airlock::STICKINESS[:user] }
|
83
|
+
end
|
84
|
+
RUBY
|
117
85
|
end
|
118
86
|
|
119
87
|
it 'rejects even if the const is not the first attr' do
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
expect(cop.offenses.size).to eq(2)
|
131
|
-
expect(cop.offenses.map(&:line)).to eq([3, 4])
|
88
|
+
expect_offense(<<~RUBY)
|
89
|
+
factory :reservation2 do
|
90
|
+
trait :accepted do
|
91
|
+
cancel_policy Hosting::CANCEL_FLEXIBLE
|
92
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
93
|
+
status Reservation2::STATUS_NEW
|
94
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
95
|
+
end
|
96
|
+
end
|
97
|
+
RUBY
|
132
98
|
end
|
133
99
|
|
134
100
|
it 'rejects with `attr_name CONST_NAME` in a trait' do
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
expect(cop.offenses.size).to eq(1)
|
145
|
-
expect(cop.offenses.map(&:line)).to eq([3])
|
101
|
+
expect_offense(<<~RUBY)
|
102
|
+
factory :reservation2 do
|
103
|
+
trait :accepted do
|
104
|
+
status Reservation2::STATUS_NEW
|
105
|
+
^^^^^^^^^^^^^^^^^^^^^^^^ Instead of attr_name MyClass::MY_CONST, use attr_name { MyClass::MY_CONST }. [...]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
RUBY
|
146
109
|
end
|
147
110
|
|
148
111
|
it 'passes with `attr_name { CONST_NAME }` in a trait' do
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
inspect_source(source)
|
157
|
-
|
158
|
-
expect(cop.offenses).to be_empty
|
112
|
+
expect_no_offenses(<<~RUBY)
|
113
|
+
factory :reservation2 do
|
114
|
+
trait :accepted do
|
115
|
+
status { Reservation2::STATUS_NEW }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
RUBY
|
159
119
|
end
|
160
120
|
end
|
@@ -1,26 +1,18 @@
|
|
1
|
-
describe RuboCop::Cop::Airbnb::FactoryClassUseString do
|
2
|
-
subject(:cop) { described_class.new }
|
3
|
-
|
1
|
+
describe RuboCop::Cop::Airbnb::FactoryClassUseString, :config do
|
4
2
|
it 'rejects with :class => Model' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
expect(cop.offenses.size).to eq(1)
|
13
|
-
expect(cop.offenses.map(&:line)).to eq([1])
|
3
|
+
expect_offense(<<~RUBY)
|
4
|
+
factory :help_answer, :class => Help::Answer do
|
5
|
+
^^^^^^^^^^^^^^^^^^^^^^ Instead of :class => MyClass, use :class => "MyClass". [...]
|
6
|
+
text { Faker::Company.name }
|
7
|
+
end
|
8
|
+
RUBY
|
14
9
|
end
|
15
10
|
|
16
11
|
it 'passes with :class => "Model"' do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
inspect_source(source)
|
23
|
-
|
24
|
-
expect(cop.offenses).to be_empty
|
12
|
+
expect_no_offenses(<<~RUBY)
|
13
|
+
factory :help_answer, :class => "Help::Answer" do
|
14
|
+
text { Faker::Company.name }
|
15
|
+
end
|
16
|
+
RUBY
|
25
17
|
end
|
26
18
|
end
|
@@ -1,28 +1,23 @@
|
|
1
|
-
describe RuboCop::Cop::Airbnb::MassAssignmentAccessibleModifier do
|
2
|
-
subject(:cop) { described_class.new }
|
3
|
-
|
1
|
+
describe RuboCop::Cop::Airbnb::MassAssignmentAccessibleModifier, :config do
|
4
2
|
it 'rejects when accessible= is called' do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
expect(cop.offenses.size).to eq(1)
|
3
|
+
expect_offense(<<~RUBY)
|
4
|
+
def some_method
|
5
|
+
user = User.new
|
6
|
+
user.accessible = [:first_name, :last_name]
|
7
|
+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do no override and objects mass assignment restrictions.
|
8
|
+
user.update_attributes(:first_name => "Walter", :last_name => "Udoing")
|
9
|
+
end
|
10
|
+
RUBY
|
14
11
|
end
|
15
12
|
|
16
13
|
it 'accepts when accessible= is not called' do
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
inspect_source(source)
|
26
|
-
expect(cop.offenses).to be_empty
|
14
|
+
expect_no_offenses(<<~RUBY)
|
15
|
+
def some_method
|
16
|
+
user = User.new
|
17
|
+
user.first_name = "Walter"
|
18
|
+
user.last_name = "Udoing"
|
19
|
+
user.save!
|
20
|
+
end
|
21
|
+
RUBY
|
27
22
|
end
|
28
23
|
end
|
@@ -1,6 +1,4 @@
|
|
1
|
-
describe RuboCop::Cop::Airbnb::ModuleMethodInWrongFile do
|
2
|
-
subject(:cop) { described_class.new(config) }
|
3
|
-
|
1
|
+
describe RuboCop::Cop::Airbnb::ModuleMethodInWrongFile, :config do
|
4
2
|
let(:config) do
|
5
3
|
RuboCop::Config.new(
|
6
4
|
{
|
@@ -25,157 +23,120 @@ describe RuboCop::Cop::Airbnb::ModuleMethodInWrongFile do
|
|
25
23
|
end
|
26
24
|
|
27
25
|
it 'rejects if module method is in file with non-matching name' do
|
28
|
-
source = [
|
29
|
-
'module Hello',
|
30
|
-
' module Foo',
|
31
|
-
' def baz', # error is here if this file is named bar.rb
|
32
|
-
' 42',
|
33
|
-
' end',
|
34
|
-
' end',
|
35
|
-
'end',
|
36
|
-
].join("\n")
|
37
|
-
|
38
26
|
File.open "#{models_dir}/bar.rb", "w" do |file|
|
39
|
-
|
27
|
+
expect_offense(<<~RUBY, file)
|
28
|
+
module Hello
|
29
|
+
module Foo
|
30
|
+
def baz
|
31
|
+
^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone calls this method, move the method definition to a file that defines the module. This file just uses the module as a namespace for another class or module. Method baz should be defined in hello/foo.rb.
|
32
|
+
42
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
RUBY
|
40
37
|
end
|
41
|
-
|
42
|
-
expect(cop.offenses.size).to eq(1)
|
43
|
-
expect(cop.offenses.map(&:line).sort).to eq([3])
|
44
|
-
expect(cop.offenses.first.message).to include("Method baz should be defined in hello/foo.rb.")
|
45
38
|
end
|
46
39
|
|
47
40
|
it 'accepts if module method is in file with matching name' do
|
48
|
-
source = [
|
49
|
-
'module Foo',
|
50
|
-
' def baz',
|
51
|
-
' 42',
|
52
|
-
' end',
|
53
|
-
'end',
|
54
|
-
].join("\n")
|
55
|
-
|
56
41
|
File.open "#{models_dir}/foo.rb", "w" do |file|
|
57
|
-
|
42
|
+
expect_no_offenses(<<~RUBY, file)
|
43
|
+
module Foo
|
44
|
+
def baz
|
45
|
+
42
|
46
|
+
end
|
47
|
+
end
|
48
|
+
RUBY
|
58
49
|
end
|
59
|
-
|
60
|
-
expect(cop.offenses).to be_empty
|
61
50
|
end
|
62
51
|
|
63
52
|
it 'rejects with "self." static methods and a non-matching name' do
|
64
|
-
source = [
|
65
|
-
'module Foo',
|
66
|
-
' def self.baz',
|
67
|
-
' 42',
|
68
|
-
' end',
|
69
|
-
'end',
|
70
|
-
].join("\n")
|
71
|
-
|
72
53
|
File.open "#{models_dir}/bar.rb", "w" do |file|
|
73
|
-
|
54
|
+
expect_offense(<<~RUBY, file)
|
55
|
+
module Foo
|
56
|
+
def self.baz
|
57
|
+
^^^^^^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone calls this method, move the method definition to a file that defines the module. This file just uses the module as a namespace for another class or module. Method (self) should be defined in foo.rb.
|
58
|
+
42
|
59
|
+
end
|
60
|
+
end
|
61
|
+
RUBY
|
74
62
|
end
|
75
|
-
|
76
|
-
expect(cop.offenses.size).to eq(1)
|
77
|
-
expect(cop.offenses.map(&:line).sort).to eq([2])
|
78
63
|
end
|
79
64
|
|
80
65
|
it 'accepts with "self." static methods and a matching name' do
|
81
|
-
source = [
|
82
|
-
'module Foo',
|
83
|
-
' def self.baz',
|
84
|
-
' 42',
|
85
|
-
' end',
|
86
|
-
'end',
|
87
|
-
].join("\n")
|
88
|
-
|
89
66
|
File.open "#{models_dir}/foo.rb", "w" do |file|
|
90
|
-
|
67
|
+
expect_no_offenses(<<~RUBY, file)
|
68
|
+
module Foo
|
69
|
+
def self.baz
|
70
|
+
42
|
71
|
+
end
|
72
|
+
end
|
73
|
+
RUBY
|
91
74
|
end
|
92
|
-
|
93
|
-
expect(cop.offenses).to be_empty
|
94
75
|
end
|
95
76
|
|
96
|
-
|
97
|
-
source = [
|
98
|
-
'module Foo',
|
99
|
-
' class << self',
|
100
|
-
' def baz',
|
101
|
-
' 42',
|
102
|
-
' end',
|
103
|
-
' end',
|
104
|
-
'end',
|
105
|
-
].join("\n")
|
106
|
-
|
77
|
+
xit 'rejects with "<<" static methods and a non-matching name' do
|
107
78
|
File.open "#{models_dir}/bar.rb", "w" do |file|
|
108
|
-
|
79
|
+
expect_offense(<<~RUBY, file)
|
80
|
+
module Foo
|
81
|
+
class << self
|
82
|
+
def baz
|
83
|
+
^^^^^^^ In order for Rails autoloading to be able to find and load this file when someone calls this method, move the method definition to a file that defines the module. This file just uses the module as a namespace for another class or module. Method baz should be defined in foo.rb.
|
84
|
+
42
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
RUBY
|
109
89
|
end
|
110
|
-
|
111
|
-
expect(cop.offenses.size).to eq(1)
|
112
|
-
expect(cop.offenses.map(&:line).sort).to eq([3])
|
113
90
|
end
|
114
91
|
|
115
92
|
it 'accepts with "<<" static methods and a matching name' do
|
116
|
-
source = [
|
117
|
-
'module Foo',
|
118
|
-
' class << self',
|
119
|
-
' def baz',
|
120
|
-
' 42',
|
121
|
-
' end',
|
122
|
-
' end',
|
123
|
-
'end',
|
124
|
-
].join("\n")
|
125
|
-
|
126
93
|
File.open "#{models_dir}/foo.rb", "w" do |file|
|
127
|
-
|
94
|
+
expect_no_offenses(<<~RUBY, file)
|
95
|
+
module Foo
|
96
|
+
class << self
|
97
|
+
def baz
|
98
|
+
42
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
RUBY
|
128
103
|
end
|
129
|
-
|
130
|
-
expect(cop.offenses).to be_empty
|
131
104
|
end
|
132
105
|
|
133
106
|
it 'accepts methods defined in a nested class' do
|
134
|
-
source = [
|
135
|
-
'module Foo',
|
136
|
-
' class Bar',
|
137
|
-
' def qux',
|
138
|
-
' end',
|
139
|
-
' end',
|
140
|
-
'end',
|
141
|
-
].join("\n")
|
142
|
-
|
143
107
|
File.open "#{models_dir}/foo.rb", "w" do |file|
|
144
|
-
|
108
|
+
expect_no_offenses(<<~RUBY, file)
|
109
|
+
module Foo
|
110
|
+
class Bar
|
111
|
+
def qux
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
RUBY
|
145
116
|
end
|
146
|
-
|
147
|
-
expect(cop.offenses).to be_empty
|
148
117
|
end
|
149
118
|
|
150
119
|
it 'accepts methods where the containing class uses an acronym' do
|
151
|
-
source = [
|
152
|
-
'module CSVFoo',
|
153
|
-
' def baz',
|
154
|
-
' 42',
|
155
|
-
' end',
|
156
|
-
'end',
|
157
|
-
].join("\n")
|
158
|
-
|
159
120
|
File.open "#{models_dir}/csv_foo.rb", "w" do |file|
|
160
|
-
|
121
|
+
expect_no_offenses(<<~RUBY, file)
|
122
|
+
module CSVFoo
|
123
|
+
def baz
|
124
|
+
42
|
125
|
+
end
|
126
|
+
end
|
127
|
+
RUBY
|
161
128
|
end
|
162
|
-
|
163
|
-
expect(cop.offenses).to be_empty
|
164
129
|
end
|
165
130
|
|
166
131
|
it 'ignores rake tasks' do
|
167
|
-
source = [
|
168
|
-
'module Hello',
|
169
|
-
' def baz', # error is here if this file is named bar.rb
|
170
|
-
' 42',
|
171
|
-
' end',
|
172
|
-
'end',
|
173
|
-
].join("\n")
|
174
|
-
|
175
132
|
File.open "#{models_dir}/bar.rake", "w" do |file|
|
176
|
-
|
133
|
+
expect_no_offenses(<<~RUBY, file)
|
134
|
+
module Hello
|
135
|
+
def baz
|
136
|
+
42
|
137
|
+
end
|
138
|
+
end
|
139
|
+
RUBY
|
177
140
|
end
|
178
|
-
|
179
|
-
expect(cop.offenses).to be_empty
|
180
141
|
end
|
181
142
|
end
|
@@ -1,30 +1,24 @@
|
|
1
|
-
describe RuboCop::Cop::Airbnb::NoTimeout do
|
2
|
-
subject(:cop) { described_class.new }
|
3
|
-
|
1
|
+
describe RuboCop::Cop::Airbnb::NoTimeout, :config do
|
4
2
|
context 'send' do
|
5
3
|
it 'rejects Timeout.timeout' do
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
expect(cop.offenses.size).to eql(1)
|
15
|
-
expect(cop.offenses.first.message).to start_with('Do not use Timeout.timeout')
|
4
|
+
expect_offense(<<~RUBY)
|
5
|
+
def some_method(a)
|
6
|
+
Timeout.timeout(5) do
|
7
|
+
^^^^^^^^^^^^^^^^^^ Do not use Timeout.timeout. [...]
|
8
|
+
some_other_method(a)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
RUBY
|
16
12
|
end
|
17
13
|
|
18
14
|
it 'accepts foo.timeout' do
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
inspect_source(source)
|
27
|
-
expect(cop.offenses).to be_empty
|
15
|
+
expect_no_offenses(<<~RUBY)
|
16
|
+
def some_method(a)
|
17
|
+
foo.timeout do
|
18
|
+
some_other_method(a)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
RUBY
|
28
22
|
end
|
29
23
|
end
|
30
24
|
end
|