Module: RSpec::Mockbidden::MocksTeardown

Defined in:
lib/rspec/mockbidden/mocks_teardown.rb

Overview

Extends ‘RSpec::Mocks.teardown` with check for violation of forbidden mocks

Instance Method Summary collapse

Instance Method Details

#check_forbidden_mocksObject

rubocop:disable Layout/LineLength, Metrics/BlockLength



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
# File 'lib/rspec/mockbidden/mocks_teardown.rb', line 8

def check_forbidden_mocks # rubocop:disable Metrics
  forbidden_proxies = @root_space.forbidden_proxies.dup
  forbidden_proxies += space.forbidden_proxies if space != @root_space

  space.clear_forbidden_proxies

  return if forbidden_proxies.empty?

  space.proxies.each_value do |proxy|
    forbidden_proxies.each do |forbiddance_target|
      next unless forbiddance_target.matcher

      target = proxy.object
      targets_any_instance = forbiddance_target.targets_any_instance?

      next unless target_match?(forbiddance_target.target, target, targets_any_instance)

      method_doubles = proxy.instance_variable_get(:@method_doubles)
      if forbiddance_target.matcher.instance_of?(anything_class)
        next if method_doubles.values.all? { |proxied_method| calls_original?(proxied_method) }

        if forbiddance_target.target.instance_of?(anything_class)
          return "All instances are forbidden from mocking any method. Good for you!" if targets_any_instance

          return "All classes/modules are forbidden from mocking any method. Good for you!"
        end

        error_class = forbiddance_target.target.is_a?(Module) ? forbiddance_target.target : forbiddance_target.target.class

        return "`#{error_class}` is forbidden from mocking any instance method" if targets_any_instance

        return "`#{error_class}` is forbidden from mocking any class method"
      elsif (proxied_method = method_doubles[forbiddance_target.matcher.to_sym])
        next if calls_original?(proxied_method)

        if forbiddance_target.target.instance_of?(anything_class)
          if targets_any_instance
            return "All instances are forbidden from mocking `##{forbiddance_target.matcher}`"
          end

          return "All classes/modules are forbidden from mocking `.#{forbiddance_target.matcher}`"
        else
          if targets_any_instance
            return "`#{forbiddance_target.target}` is forbidden from mocking `##{forbiddance_target.matcher}`"
          end

          if forbiddance_target.target.is_a?(Module)
            return "`#{forbiddance_target.target}` is forbidden from mocking `.#{forbiddance_target.matcher}`"
          end

          return "`#{forbiddance_target.target.inspect}` (instance of `#{forbiddance_target.target.class}`) is forbidden from mocking `##{forbiddance_target.matcher}`"
        end
      end
    end
  end

  nil
end