File: matcher.rb

package info (click to toggle)
ruby-enumerize 2.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 432 kB
  • sloc: ruby: 3,712; makefile: 6
file content (164 lines) | stat: -rw-r--r-- 4,762 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
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# frozen_string_literal: true

module Enumerize
  module Integrations
    module RSpec
      class Matcher

        def initialize(expected_attr)
          self.expected_attr = expected_attr
        end

        def in(*expected_values)
          self.expected_values = expected_values.flatten
          self
        end

        def with_default(expected_default)
          self.expected_default = expected_default.to_s
          self
        end

        def with_i18n_scope(expected_i18n_scope)
          self.expected_i18n_scope = expected_i18n_scope
          self
        end

        def with_predicates(expected_predicates)
          self.expected_predicates = expected_predicates
          self
        end

        def with_multiple(expected_multiple)
          self.expected_multiple = expected_multiple
          self
        end

        def with_scope(expected_scope)
          self.expected_scope = expected_scope
          self
        end

        def failure_message
          "Expected #{expectation}"
        end

        def failure_message_when_negated
          "Did not expect #{expectation}"
        end

        def description
          description  = "define enumerize :#{expected_attr}"
          description += " in: #{quote_values(expected_values)}" if expected_values
          description += " with #{expected_default.inspect} as default value" if expected_default
          description += " i18n_scope: #{expected_i18n_scope.inspect}" if expected_i18n_scope
          description += " predicates: #{expected_predicates.inspect}" if expected_predicates
          description += " multiple: #{expected_multiple.inspect}" if expected_multiple
          description += " scope: #{expected_scope.inspect}" if expected_scope

          description
        end

        def matches?(subject)
          self.subject = subject
          matches      = true

          matches &= matches_attribute?
          matches &= matches_values? if expected_values
          matches &= matches_default_value? if expected_default
          matches &= matches_i18n_scope? if expected_i18n_scope
          matches &= matches_predicates? if expected_predicates
          matches &= matches_multiple? if expected_multiple
          matches &= matches_scope? if expected_scope

          matches
        end

        private
        attr_accessor :expected_attr, :expected_values, :subject, :expected_default,
                      :expected_i18n_scope, :expected_predicates, :expected_multiple,
                      :expected_scope

        def expectation
          "#{subject.class.name} to #{description}"
        end

        def matches_attribute?
          attributes.present?
        end

        def matches_values?
          matches_array_values? || matches_hash_values?
        end

        def matches_array_values?
          sorted_values == enumerized_values
        end

        def matches_hash_values?
          return unless expected_values.first.is_a?(Hash)
          expected_values.first.all? { |k, v| enumerized_value_hash[k.to_s] == v; }
        end

        def matches_default_value?
          expected_default == enumerized_default
        end

        def matches_i18n_scope?
          attributes.i18n_scope == expected_i18n_scope
        end

        def matches_predicates?
          if expected_predicates.is_a?(TrueClass)
            subject.respond_to?("#{enumerized_values.first}?")
          else
            subject.respond_to?("#{expected_attr}_#{attributes.values.first}?")
          end
        end

        def matches_multiple?
          subject.public_send(expected_attr).is_a?(Enumerize::Set)
        end

        def matches_scope?
          case expected_scope
          when TrueClass
            subject_class.respond_to?("with_#{expected_attr}")
          when :shallow
            enumerized_values.all? { |value| subject_class.respond_to?(value) }
          else
            subject_class.respond_to?(expected_scope[:scope])
          end
        end

        def sorted_values
          @sorted_values ||=expected_values.map(&:to_s).sort
        end

        def enumerized_values
          @enumerized_values ||= attributes.values.sort
        end

        def enumerized_default
          @enumerized_default ||= attributes.default_value
        end

        def enumerized_value_hash
          @enumerized_value_hash ||= attributes.instance_variable_get('@value_hash')
        end

        def attributes
          subject_class.enumerized_attributes.attributes[expected_attr.to_s]
        end

        def subject_class
          @subject_class ||= subject.class
        end

        def quote_values(values)
          sorted_values.map(&:inspect).join(', ')
        end
      end
    end
  end
end