File: has.rb

package info (click to toggle)
ruby-rspec 3.5.0c3e0m0s0-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 6,312 kB
  • ctags: 4,788
  • sloc: ruby: 62,572; sh: 785; makefile: 100
file content (103 lines) | stat: -rw-r--r-- 3,081 bytes parent folder | download | duplicates (2)
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
module RSpec
  module Matchers
    module BuiltIn
      # @api private
      # Provides the implementation for `has_<predicate>`.
      # Not intended to be instantiated directly.
      class Has < BaseMatcher
        def initialize(method_name, *args, &block)
          @method_name, @args, @block = method_name, args, block
        end

        # @private
        def matches?(actual, &block)
          @actual = actual
          @block ||= block
          predicate_accessible? && predicate_matches?
        end

        # @private
        def does_not_match?(actual, &block)
          @actual = actual
          @block ||= block
          predicate_accessible? && !predicate_matches?
        end

        # @api private
        # @return [String]
        def failure_message
          validity_message || "expected ##{predicate}#{failure_message_args_description} to return true, got false"
        end

        # @api private
        # @return [String]
        def failure_message_when_negated
          validity_message || "expected ##{predicate}#{failure_message_args_description} to return false, got true"
        end

        # @api private
        # @return [String]
        def description
          [method_description, args_description].compact.join(' ')
        end

      private

        def predicate_accessible?
          !private_predicate? && predicate_exists?
        end

        # support 1.8.7, evaluate once at load time for performance
        if String === methods.first
          # :nocov:
          def private_predicate?
            @actual.private_methods.include? predicate.to_s
          end
          # :nocov:
        else
          def private_predicate?
            @actual.private_methods.include? predicate
          end
        end

        def predicate_exists?
          @actual.respond_to? predicate
        end

        def predicate_matches?
          @actual.__send__(predicate, *@args, &@block)
        end

        def predicate
          # On 1.9, there appears to be a bug where String#match can return `false`
          # rather than the match data object. Changing to Regex#match appears to
          # work around this bug. For an example of this bug, see:
          # https://travis-ci.org/rspec/rspec-expectations/jobs/27549635
          @predicate ||= :"has_#{Matchers::HAS_REGEX.match(@method_name.to_s).captures.first}?"
        end

        def method_description
          @method_name.to_s.gsub('_', ' ')
        end

        def args_description
          return nil if @args.empty?
          @args.map { |arg| RSpec::Support::ObjectFormatter.format(arg) }.join(', ')
        end

        def failure_message_args_description
          desc = args_description
          "(#{desc})" if desc
        end

        def validity_message
          if private_predicate?
            "expected #{@actual} to respond to `#{predicate}` but `#{predicate}` is a private method"
          elsif !predicate_exists?
            "expected #{@actual} to respond to `#{predicate}`"
          end
        end
      end
    end
  end
end