Completed
Push — dev ( 6cb2fc...405831 )
by Fike
58s
created

Type.valid!   A

Complexity

Conditions 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 2
1
# frozen_string_literal: true
2
3
# rubocop:disable Lint/UnusedMethodArgument
4
5
require_relative 'mixin/errors'
6
require_relative 'context'
7
8
module AMA
9
  module Entity
10
    class Mapper
11
      # Base abstract class for all other types
12
      class Type
13
        include Mixin::Errors
14
15
        # :nocov:
16
        def initialize
17
          message = "#{self.class} is an abstract class " \
18
            'and can\'t be isntantiated directly'
19
          compliance_error(message)
20
        end
21
        # :nocov:
22
23
        # @return [Hash{Symbol, AMA::Entity::Mapper::Type::Attribute}]
24
        def attributes
25
          {}
26
        end
27
28
        # @return [Hash{Symbol, AMA::Entity::Mapper::Type}]
29
        def parameters
30
          {}
31
        end
32
33
        # @param [Symbol] id
34
        # @return [TrueClass, FalseClass]
35
        def attribute?(id)
36
          attributes.key?(id.to_sym)
37
        end
38
39
        # @param [Symbol] id
40
        # @return [TrueClass, FalseClass]
41
        def parameter?(id)
42
          parameters.key?(id.to_sym)
43
        end
44
45
        # :nocov:
46
        # Creates parameter if it doesn't yet exist and returns it
47
        #
48
        # @param [Symbol] id
49
        def parameter!(id)
50
          abstract_method
51
        end
52
53
        # @param [AMA::Entity::Mapper::Type] parameter
54
        # @param [AMA::Entity::Mapper::Type] substitution
55
        # @return [AMA::Entity::Mapper::Type]
56
        def resolve_parameter(parameter, substitution)
57
          abstract_method
58
        end
59
        # :nocov:
60
61
        # rubocop:disable Metrics/LineLength
62
63
        # @param [Hash<AMA::Entity::Mapper::Type, AMA::Entity::Mapper::Type>] parameters
64
        # @return [AMA::Entity::Mapper::Type]
65
        def resolve(parameters)
66
          parameters.reduce(self) do |carrier, tuple|
67
            carrier.resolve_parameter(*tuple)
68
          end
69
        end
70
71
        # rubocop:enable Metrics/LineLength
72
73
        # @return [TrueClass, FalseClass]
74
        def resolved?
75
          attributes.values.all?(&:resolved?)
76
        end
77
78
        # Validates that type is fully resolved, otherwise raises an error
79
        # @param [AMA::Entity::Mapper::Context] context
80
        def resolved!(context = nil)
81
          context ||= Context.new
82
          attributes.values.each do |attribute|
83
            attribute.resolved!(context)
84
          end
85
        end
86
87
        # :nocov:
88
        # @param [Object] object
89
        def instance?(object)
90
          abstract_method
91
        end
92
        # :nocov:
93
94
        # @param [Object] object
95
        # @param [AMA::Entity::Mapper::Context] context
96
        def instance!(object, context = nil)
97
          return if instance?(object)
98
          message = "Expected to receive instance of #{self}, got " \
99
            "#{object.class}"
100
          validation_error(message, context: context)
101
        end
102
103
        def valid?(object, context)
104
          instance?(object) && violations(object, context).empty?
105
        end
106
107
        def valid!(object, context)
108
          instance!(object, context)
109
          violations = self.violations(object, context)
110
          return if violations.empty?
111
          message = 'Validation failed, following violations were discovered: '
112
          violations = violations.map do |attribute, violation, segment|
113
            "[#{attribute}: #{violation} (#{segment})]"
114
          end
115
          message += violations.join(', ')
116
          validation_error(message, context: context)
117
        end
118
119
        # :nocov:
120
        # @deprecated
121
        def satisfied_by?(object)
122
          abstract_method
123
        end
124
125
        def violations(object, context)
126
          abstract_method
127
        end
128
129
        def hash
130
          abstract_method
131
        end
132
133
        def eql?(other)
134
          abstract_method
135
        end
136
        # :nocov:
137
138
        def ==(other)
139
          eql?(other)
140
        end
141
142
        # :nocov:
143
        def to_s
144
          abstract_method
145
        end
146
        # :nocov:
147
148
        protected
149
150
        # :nocov:
151
        # rubocop:disable Performance/Caller
152
        def abstract_method
153
          message = "Abstract method #{caller[1]} hasn't been implemented " \
154
            "in class #{self.class}"
155
          raise message
156
        end
157
        # rubocop:enable Performance/Caller
158
        # :nocov:
159
      end
160
    end
161
  end
162
end
163