File: flat_map_spec.rb

package info (click to toggle)
ruby-rubocop-performance 1.7.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 792 kB
  • sloc: ruby: 6,722; makefile: 8
file content (124 lines) | stat: -rw-r--r-- 4,960 bytes parent folder | download | duplicates (3)
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# frozen_string_literal: true

RSpec.describe RuboCop::Cop::Performance::FlatMap, :config do
  subject(:cop) { described_class.new(config) }

  shared_examples 'map_and_collect' do |method, flatten|
    it "registers an offense when calling #{method}...#{flatten}(1)" do
      inspect_source("[1, 2, 3, 4].#{method} { |e| [e, e] }.#{flatten}(1)")

      expect(cop.messages)
        .to eq(["Use `flat_map` instead of `#{method}...#{flatten}`."])
      expect(cop.highlights).to eq(["#{method} { |e| [e, e] }.#{flatten}(1)"])
    end

    it "registers an offense when calling #{method}(&:foo).#{flatten}(1)" do
      inspect_source("[1, 2, 3, 4].#{method}(&:foo).#{flatten}(1)")

      expect(cop.messages)
        .to eq(["Use `flat_map` instead of `#{method}...#{flatten}`."])
      expect(cop.highlights).to eq(["#{method}(&:foo).#{flatten}(1)"])
    end

    it "registers an offense when calling #{method}(&foo).#{flatten}(1)" do
      inspect_source("[1, 2, 3, 4].#{method}(&foo).#{flatten}(1)")

      expect(cop.messages)
        .to eq(["Use `flat_map` instead of `#{method}...#{flatten}`."])
      expect(cop.highlights).to eq(["#{method}(&foo).#{flatten}(1)"])
    end

    it "does not register an offense when calling #{method}...#{flatten} " \
      'with a number greater than 1' do
      expect_no_offenses("[1, 2, 3, 4].#{method} { |e| [e, e] }.#{flatten}(3)")
    end

    it "does not register an offense when calling #{method}!...#{flatten}" do
      expect_no_offenses("[1, 2, 3, 4].#{method}! { |e| [e, e] }.#{flatten}")
    end

    it "corrects #{method}..#{flatten}(1) to flat_map" do
      source = "[1, 2].#{method} { |e| [e, e] }.#{flatten}(1)"
      new_source = autocorrect_source(source)

      expect(new_source).to eq('[1, 2].flat_map { |e| [e, e] }')
    end

    it "corrects #{method}(&:foo).#{flatten} to flat_map" do
      source = "[1, 2].#{method}(&:foo).#{flatten}(1)"
      new_source = autocorrect_source(source)

      expect(new_source).to eq('[1, 2].flat_map(&:foo)')
    end

    it "corrects #{method}(&foo).#{flatten} to flat_map" do
      source = "[1, 2].#{method}(&:foo).#{flatten}(1)"
      new_source = autocorrect_source(source)

      expect(new_source).to eq('[1, 2].flat_map(&:foo)')
    end
  end

  describe 'configured to only warn when flattening one level' do
    let(:config) do
      RuboCop::Config.new('Performance/FlatMap' => {
                            'Enabled' => true,
                            'EnabledForFlattenWithoutParams' => false
                          })
    end

    shared_examples 'flatten_with_params_disabled' do |method, flatten|
      it "does not register an offense when calling #{method}...#{flatten}" do
        expect_no_offenses("[1, 2, 3, 4].map { |e| [e, e] }.#{flatten}")
      end
    end

    it_behaves_like('map_and_collect', 'map', 'flatten')
    it_behaves_like('map_and_collect', 'map', 'flatten!')
    it_behaves_like('map_and_collect', 'collect', 'flatten')
    it_behaves_like('map_and_collect', 'collect', 'flatten!')

    it_behaves_like('flatten_with_params_disabled', 'map', 'flatten')
    it_behaves_like('flatten_with_params_disabled', 'collect', 'flatten')
    it_behaves_like('flatten_with_params_disabled', 'map', 'flatten!')
    it_behaves_like('flatten_with_params_disabled', 'collect', 'flatten!')
  end

  describe 'configured to warn when flatten is not called with parameters' do
    let(:config) do
      RuboCop::Config.new('Performance/FlatMap' => {
                            'Enabled' => true,
                            'EnabledForFlattenWithoutParams' => true
                          })
    end

    shared_examples 'flatten_with_params_enabled' do |method, flatten|
      it "registers an offense when calling #{method}...#{flatten}" do
        inspect_source("[1, 2, 3, 4].map { |e| [e, e] }.#{flatten}")

        expect(cop.messages)
          .to eq(["Use `flat_map` instead of `map...#{flatten}`. " \
               'Beware, `flat_map` only flattens 1 level and `flatten` ' \
               'can be used to flatten multiple levels.'])
        expect(cop.highlights).to eq(["map { |e| [e, e] }.#{flatten}"])
      end

      it "will not correct #{method}..#{flatten} to flat_map" do
        source = "[1, 2].map { |e| [e, e] }.#{flatten}"
        new_source = autocorrect_source(source)

        expect(new_source).to eq("[1, 2].map { |e| [e, e] }.#{flatten}")
      end
    end

    it_behaves_like('map_and_collect', 'map', 'flatten')
    it_behaves_like('map_and_collect', 'map', 'flatten!')
    it_behaves_like('map_and_collect', 'collect', 'flatten')
    it_behaves_like('map_and_collect', 'collect', 'flatten!')

    it_behaves_like('flatten_with_params_enabled', 'map', 'flatten')
    it_behaves_like('flatten_with_params_enabled', 'collect', 'flatten')
    it_behaves_like('flatten_with_params_enabled', 'map', 'flatten!')
    it_behaves_like('flatten_with_params_enabled', 'collect', 'flatten!')
  end
end