/
chain_array_allocation_spec.rb
60 lines (50 loc) · 2 KB
/
chain_array_allocation_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# frozen_string_literal: true
RSpec.describe RuboCop::Cop::Performance::ChainArrayAllocation, :config do
subject(:cop) { described_class.new(config) }
def generate_message(method_one, method_two)
"Use unchained `#{method_one}!` and `#{method_two}!` "\
'(followed by `return array` if required) instead of '\
"chaining `#{method_one}...#{method_two}`."
end
shared_examples 'map_and_flat' do |method, method_two|
it "registers an offense when calling #{method}...#{method_two}" do
inspect_source("[1, 2, 3, 4].#{method} { |e| [e, e] }.#{method_two}")
expect(cop.messages)
.to eq([generate_message(method, method_two)])
expect(cop.highlights).to eq([".#{method_two}"])
end
end
describe 'configured to only warn when flattening one level' do
it_behaves_like('map_and_flat', 'map', 'flatten')
end
describe 'Methods that require an argument' do
it 'does not register an offense for `first.uniq`' do
# Yes I know this is not valid Ruby
expect_no_offenses(<<~RUBY)
[1, 2, 3, 4].first.uniq
RUBY
end
it 'registers an offense for `first(10).uniq`' do
expect_offense(<<~RUBY)
[1, 2, 3, 4].first(10).uniq
^^^^^ Use unchained `first!` and `uniq!` (followed by `return array` if required) instead of chaining `first...uniq`.
RUBY
end
it 'registers an offense for `first(variable).uniq`' do
expect_offense(<<~RUBY)
variable = 42
[1, 2, 3, 4].first(variable).uniq
^^^^^ Use unchained `first!` and `uniq!` (followed by `return array` if required) instead of chaining `first...uniq`.
RUBY
end
end
describe 'methods that only return an array with no block' do
it 'zip' do
# Yes I know this is not valid Ruby
inspect_source('[1, 2, 3, 4].zip {|f| }.uniq')
expect(cop.messages.empty?).to be(true)
inspect_source('[1, 2, 3, 4].zip.uniq')
expect(cop.messages.empty?).to be(false)
end
end
end