summaryrefslogtreecommitdiff
path: root/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
blob: 71311b9df7f77ca65ef626ce0796e017efb08047 (plain)
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
125
126
127
128
129
130
# frozen_string_literal: true

require 'fast_spec_helper'
require 'rubocop'
require_relative '../../../rubocop/cop/avoid_return_from_blocks'

RSpec.describe RuboCop::Cop::AvoidReturnFromBlocks do
  include CopHelper

  subject(:cop) { described_class.new }

  it 'flags violation for return inside a block' do
    expect_offense(<<~RUBY)
      call do
        do_something
        return if something_else
        ^^^^^^ Do not return from a block, use next or break instead.
      end
    RUBY
  end

  it "doesn't call add_offense twice for nested blocks" do
    source = <<~RUBY
      call do
        call do
          something
          return if something_else
        end
      end
    RUBY
    expect_any_instance_of(described_class) do |instance|
      expect(instance).to receive(:add_offense).once
    end

    inspect_source(source)
  end

  it 'flags violation for return inside included > def > block' do
    expect_offense(<<~RUBY)
      included do
        def a_method
          return if something

          call do
            return if something_else
            ^^^^^^ Do not return from a block, use next or break instead.
          end
        end
      end
    RUBY
  end

  shared_examples 'examples with whitelisted method' do |whitelisted_method|
    it "doesn't flag violation for return inside #{whitelisted_method}" do
      expect_no_offenses(<<~RUBY)
        items.#{whitelisted_method} do |item|
          do_something
          return if something_else
        end
      RUBY
    end
  end

  %i[each each_filename times loop].each do |whitelisted_method|
    it_behaves_like 'examples with whitelisted method', whitelisted_method
  end

  shared_examples 'examples with def methods' do |def_method|
    it "doesn't flag violation for return inside #{def_method}" do
      expect_no_offenses(<<~RUBY)
        helpers do
          #{def_method} do
            return if something

            do_something_more
          end
        end
      RUBY
    end
  end

  %i[define_method lambda].each do |def_method|
    it_behaves_like 'examples with def methods', def_method
  end

  it "doesn't flag violation for return inside a lambda" do
    expect_no_offenses(<<~RUBY)
      lambda do
        do_something
        return if something_else
      end
    RUBY
  end

  it "doesn't flag violation for return used inside a method definition" do
    expect_no_offenses(<<~RUBY)
      describe Klass do
        def a_method
          do_something
          return if something_else
        end
      end
    RUBY
  end

  it "doesn't flag violation for next inside a block" do
    expect_no_offenses(<<~RUBY)
      call do
        do_something
        next if something_else
      end
    RUBY
  end

  it "doesn't flag violation for break inside a block" do
    expect_no_offenses(<<~RUBY)
      call do
        do_something
        break if something_else
      end
    RUBY
  end

  it "doesn't check when block is empty" do
    expect_no_offenses(<<~RUBY)
      call do
      end
    RUBY
  end
end