active_interaction 3.8.1 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +190 -0
  3. data/CONTRIBUTING.md +1 -1
  4. data/README.md +93 -107
  5. data/lib/active_interaction.rb +1 -7
  6. data/lib/active_interaction/base.rb +31 -35
  7. data/lib/active_interaction/concerns/active_modelable.rb +1 -3
  8. data/lib/active_interaction/concerns/active_recordable.rb +1 -6
  9. data/lib/active_interaction/concerns/hashable.rb +0 -1
  10. data/lib/active_interaction/concerns/missable.rb +0 -1
  11. data/lib/active_interaction/concerns/runnable.rb +12 -24
  12. data/lib/active_interaction/errors.rb +6 -19
  13. data/lib/active_interaction/filter.rb +51 -37
  14. data/lib/active_interaction/filter_column.rb +0 -3
  15. data/lib/active_interaction/filters/abstract_date_time_filter.rb +34 -36
  16. data/lib/active_interaction/filters/abstract_numeric_filter.rb +27 -17
  17. data/lib/active_interaction/filters/array_filter.rb +59 -36
  18. data/lib/active_interaction/filters/boolean_filter.rb +26 -12
  19. data/lib/active_interaction/filters/date_filter.rb +1 -2
  20. data/lib/active_interaction/filters/date_time_filter.rb +1 -2
  21. data/lib/active_interaction/filters/decimal_filter.rb +10 -28
  22. data/lib/active_interaction/filters/file_filter.rb +6 -5
  23. data/lib/active_interaction/filters/float_filter.rb +1 -2
  24. data/lib/active_interaction/filters/hash_filter.rb +37 -27
  25. data/lib/active_interaction/filters/integer_filter.rb +7 -8
  26. data/lib/active_interaction/filters/interface_filter.rb +48 -14
  27. data/lib/active_interaction/filters/object_filter.rb +23 -50
  28. data/lib/active_interaction/filters/record_filter.rb +10 -35
  29. data/lib/active_interaction/filters/string_filter.rb +21 -12
  30. data/lib/active_interaction/filters/symbol_filter.rb +13 -7
  31. data/lib/active_interaction/filters/time_filter.rb +24 -19
  32. data/lib/active_interaction/grouped_input.rb +0 -3
  33. data/lib/active_interaction/inputs.rb +95 -0
  34. data/lib/active_interaction/modules/validation.rb +9 -12
  35. data/lib/active_interaction/version.rb +1 -3
  36. data/spec/active_interaction/base_spec.rb +22 -70
  37. data/spec/active_interaction/concerns/active_modelable_spec.rb +0 -2
  38. data/spec/active_interaction/concerns/active_recordable_spec.rb +0 -2
  39. data/spec/active_interaction/concerns/hashable_spec.rb +0 -2
  40. data/spec/active_interaction/concerns/missable_spec.rb +0 -2
  41. data/spec/active_interaction/concerns/runnable_spec.rb +26 -12
  42. data/spec/active_interaction/errors_spec.rb +4 -25
  43. data/spec/active_interaction/filter_column_spec.rb +0 -2
  44. data/spec/active_interaction/filter_spec.rb +0 -2
  45. data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +1 -3
  46. data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +1 -3
  47. data/spec/active_interaction/filters/array_filter_spec.rb +51 -14
  48. data/spec/active_interaction/filters/boolean_filter_spec.rb +58 -4
  49. data/spec/active_interaction/filters/date_filter_spec.rb +43 -3
  50. data/spec/active_interaction/filters/date_time_filter_spec.rb +43 -3
  51. data/spec/active_interaction/filters/decimal_filter_spec.rb +57 -3
  52. data/spec/active_interaction/filters/file_filter_spec.rb +1 -3
  53. data/spec/active_interaction/filters/float_filter_spec.rb +60 -4
  54. data/spec/active_interaction/filters/hash_filter_spec.rb +19 -9
  55. data/spec/active_interaction/filters/integer_filter_spec.rb +49 -7
  56. data/spec/active_interaction/filters/interface_filter_spec.rb +397 -24
  57. data/spec/active_interaction/filters/object_filter_spec.rb +23 -59
  58. data/spec/active_interaction/filters/record_filter_spec.rb +23 -49
  59. data/spec/active_interaction/filters/string_filter_spec.rb +15 -3
  60. data/spec/active_interaction/filters/symbol_filter_spec.rb +15 -3
  61. data/spec/active_interaction/filters/time_filter_spec.rb +65 -3
  62. data/spec/active_interaction/grouped_input_spec.rb +0 -2
  63. data/spec/active_interaction/i18n_spec.rb +3 -7
  64. data/spec/active_interaction/{modules/input_processor_spec.rb → inputs_spec.rb} +3 -5
  65. data/spec/active_interaction/integration/array_interaction_spec.rb +18 -22
  66. data/spec/active_interaction/integration/boolean_interaction_spec.rb +0 -2
  67. data/spec/active_interaction/integration/date_interaction_spec.rb +0 -2
  68. data/spec/active_interaction/integration/date_time_interaction_spec.rb +0 -2
  69. data/spec/active_interaction/integration/file_interaction_spec.rb +0 -2
  70. data/spec/active_interaction/integration/float_interaction_spec.rb +0 -2
  71. data/spec/active_interaction/integration/hash_interaction_spec.rb +0 -2
  72. data/spec/active_interaction/integration/integer_interaction_spec.rb +0 -2
  73. data/spec/active_interaction/integration/interface_interaction_spec.rb +1 -3
  74. data/spec/active_interaction/integration/object_interaction_spec.rb +0 -2
  75. data/spec/active_interaction/integration/string_interaction_spec.rb +0 -2
  76. data/spec/active_interaction/integration/symbol_interaction_spec.rb +0 -2
  77. data/spec/active_interaction/integration/time_interaction_spec.rb +14 -18
  78. data/spec/active_interaction/modules/validation_spec.rb +1 -3
  79. data/spec/spec_helper.rb +2 -6
  80. data/spec/support/concerns.rb +0 -2
  81. data/spec/support/filters.rb +13 -9
  82. data/spec/support/interactions.rb +22 -14
  83. metadata +81 -57
  84. data/lib/active_interaction/backports.rb +0 -59
  85. data/lib/active_interaction/filters/abstract_filter.rb +0 -19
  86. data/lib/active_interaction/modules/input_processor.rb +0 -52
  87. data/spec/active_interaction/filters/abstract_filter_spec.rb +0 -8
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'active_model'
@@ -7,8 +6,6 @@ require 'active_model'
7
6
  #
8
7
  # @author Aaron Lasseigne <aaron.lasseigne@gmail.com>
9
8
  # @author Taylor Fausak <taylor@fausak.me>
10
- #
11
- # @since 1.0.0
12
9
  module ActiveInteraction
13
10
  end
14
11
 
@@ -22,13 +19,12 @@ require 'active_interaction/concerns/missable'
22
19
  require 'active_interaction/concerns/runnable'
23
20
 
24
21
  require 'active_interaction/grouped_input'
22
+ require 'active_interaction/inputs'
25
23
 
26
- require 'active_interaction/modules/input_processor'
27
24
  require 'active_interaction/modules/validation'
28
25
 
29
26
  require 'active_interaction/filter_column'
30
27
  require 'active_interaction/filter'
31
- require 'active_interaction/filters/abstract_filter'
32
28
  require 'active_interaction/filters/interface_filter'
33
29
  require 'active_interaction/filters/abstract_date_time_filter'
34
30
  require 'active_interaction/filters/abstract_numeric_filter'
@@ -49,8 +45,6 @@ require 'active_interaction/filters/time_filter'
49
45
 
50
46
  require 'active_interaction/base'
51
47
 
52
- require 'active_interaction/backports'
53
-
54
48
  I18n.load_path.unshift(
55
49
  *Dir.glob(
56
50
  File.expand_path(
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'active_support/core_ext/hash/indifferent_access'
@@ -28,7 +27,7 @@ module ActiveInteraction
28
27
  # else
29
28
  # outcome.errors
30
29
  # end
31
- class Base # rubocop:disable Metrics/ClassLength
30
+ class Base
32
31
  include ActiveModelable
33
32
  include ActiveRecordable
34
33
  include Runnable
@@ -74,9 +73,7 @@ module ActiveInteraction
74
73
  # @return [String, nil] The description.
75
74
  def desc(desc = nil)
76
75
  if desc.nil?
77
- unless instance_variable_defined?(:@_interaction_desc)
78
- @_interaction_desc = nil
79
- end
76
+ @_interaction_desc = nil unless instance_variable_defined?(:@_interaction_desc)
80
77
  else
81
78
  @_interaction_desc = desc
82
79
  end
@@ -88,17 +85,21 @@ module ActiveInteraction
88
85
  #
89
86
  # @return [Hash{Symbol => Filter}]
90
87
  def filters
88
+ # rubocop:disable Naming/MemoizedInstanceVariableName
91
89
  @_interaction_filters ||= {}
90
+ # rubocop:enable Naming/MemoizedInstanceVariableName
92
91
  end
93
92
 
94
93
  # @private
95
- def method_missing(*args, &block) # rubocop:disable Style/MethodMissing
94
+ # rubocop:disable Style/MissingRespondToMissing
95
+ def method_missing(*args, &block)
96
96
  super do |klass, names, options|
97
97
  raise InvalidFilterError, 'missing attribute name' if names.empty?
98
98
 
99
99
  names.each { |name| add_filter(klass, name, options, &block) }
100
100
  end
101
101
  end
102
+ # rubocop:enable Style/MissingRespondToMissing
102
103
 
103
104
  private
104
105
 
@@ -106,9 +107,7 @@ module ActiveInteraction
106
107
  # @param name [Symbol]
107
108
  # @param options [Hash]
108
109
  def add_filter(klass, name, options, &block)
109
- if InputProcessor.reserved?(name)
110
- raise InvalidFilterError, %("#{name}" is a reserved name)
111
- end
110
+ raise InvalidFilterError, %("#{name}" is a reserved name) if ActiveInteraction::Inputs.reserved?(name)
112
111
 
113
112
  initialize_filter(klass.new(name, options, &block))
114
113
  end
@@ -133,7 +132,7 @@ module ActiveInteraction
133
132
  other_filters.select! { |k, _| [*only].include?(k) } if only
134
133
  other_filters.reject! { |k, _| [*except].include?(k) } if except
135
134
 
136
- other_filters.values.each { |filter| initialize_filter(filter) }
135
+ other_filters.each_value { |filter| initialize_filter(filter) }
137
136
  end
138
137
 
139
138
  # @param klass [Class]
@@ -146,13 +145,10 @@ module ActiveInteraction
146
145
  # @param filter [Filter]
147
146
  def initialize_filter(filter)
148
147
  attribute = filter.name
149
- if filters.key?(attribute)
150
- warn "WARNING: Redefining #{name}##{attribute} filter"
151
- end
148
+ warn "WARNING: Redefining #{name}##{attribute} filter" if filters.key?(attribute)
152
149
  filters[attribute] = filter
153
150
 
154
151
  attr_accessor attribute
155
- define_method("#{attribute}?") { !public_send(attribute).nil? }
156
152
 
157
153
  eagerly_evaluate_default(filter)
158
154
  end
@@ -195,9 +191,7 @@ module ActiveInteraction
195
191
  #
196
192
  # @return [Hash{Symbol => Object}] All inputs passed to {.run} or {.run!}.
197
193
  def inputs
198
- self.class.filters.keys.each_with_object({}) do |name, h|
199
- h[name] = public_send(name)
200
- end
194
+ @_interaction_inputs
201
195
  end
202
196
 
203
197
  # Returns `true` if the given key was in the hash passed to {.run}.
@@ -241,7 +235,7 @@ module ActiveInteraction
241
235
  # rubocop:disable all
242
236
  def given?(input, *rest)
243
237
  filter_level = self.class
244
- input_level = @_interaction_inputs
238
+ input_level = @_interaction_raw_inputs
245
239
 
246
240
  [input, *rest].each do |key_or_index|
247
241
  if key_or_index.is_a?(Symbol) || key_or_index.is_a?(String)
@@ -291,33 +285,35 @@ module ActiveInteraction
291
285
 
292
286
  # @param inputs [Hash{Symbol => Object}]
293
287
  def process_inputs(inputs)
294
- @_interaction_inputs = inputs
295
-
296
- inputs.each do |key, value|
297
- populate_reader(key, value) unless InputProcessor.reserved?(key)
298
- end
288
+ @_interaction_raw_inputs = inputs
299
289
 
300
- populate_filters(InputProcessor.process(inputs))
290
+ populate_filters_and_inputs(ActiveInteraction::Inputs.process(inputs))
301
291
  end
302
292
 
303
- def populate_reader(key, value)
304
- instance_variable_set("@#{key}", value) if respond_to?(key)
305
- end
293
+ def populate_filters_and_inputs(inputs)
294
+ @_interaction_inputs = ActiveInteraction::Inputs.new
306
295
 
307
- def populate_filters(inputs)
308
296
  self.class.filters.each do |name, filter|
309
- begin
310
- public_send("#{name}=", filter.clean(inputs[name], self))
311
- rescue InvalidValueError, MissingValueError, NoDefaultError
312
- nil # #type_check will add errors if appropriate.
313
- end
297
+ value =
298
+ begin
299
+ filter.clean(inputs[name], self)
300
+ rescue InvalidValueError, MissingValueError, NoDefaultError
301
+ # #type_check will add errors if appropriate.
302
+ # We'll get the original value for the error.
303
+ inputs[name]
304
+ end
305
+
306
+ @_interaction_inputs[name] = value
307
+ public_send("#{name}=", value)
314
308
  end
309
+
310
+ @_interaction_inputs.freeze
315
311
  end
316
312
 
317
313
  def type_check
318
314
  run_callbacks(:type_check) do
319
- Validation.validate(self, self.class.filters, inputs).each do |error|
320
- errors.add(*error)
315
+ Validation.validate(self, self.class.filters, inputs).each do |attr, type, kwargs = {}|
316
+ errors.add(attr, type, **kwargs)
321
317
  end
322
318
  end
323
319
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module ActiveInteraction
@@ -34,8 +33,7 @@ module ActiveInteraction
34
33
  false
35
34
  end
36
35
 
37
- #
38
- module ClassMethods
36
+ module ClassMethods # rubocop:disable Style/Documentation
39
37
  # @return [Symbol]
40
38
  #
41
39
  # @see ActiveModel::Translation#i18n_scope
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module ActiveInteraction
@@ -24,8 +23,6 @@ module ActiveInteraction
24
23
  # # => nil
25
24
  #
26
25
  # @return [FilterColumn, nil]
27
- #
28
- # @since 1.2.0
29
26
  def column_for_attribute(name)
30
27
  filter = self.class.filters[name]
31
28
  FilterColumn.intern(filter.database_column_type) if filter
@@ -49,9 +46,7 @@ module ActiveInteraction
49
46
  # # => false
50
47
  #
51
48
  # @return [Boolean]
52
- #
53
- # @since 1.5.0
54
- def has_attribute?(name) # rubocop:disable Style/PredicateName
49
+ def has_attribute?(name) # rubocop:disable Naming/PredicateName
55
50
  self.class.filters.key?(name.to_sym)
56
51
  end
57
52
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module ActiveInteraction
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module ActiveInteraction
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module ActiveInteraction
@@ -46,9 +45,7 @@ module ActiveInteraction
46
45
 
47
46
  # @return [Boolean]
48
47
  def valid?(*)
49
- if instance_variable_defined?(:@_interaction_valid)
50
- return @_interaction_valid
51
- end
48
+ return @_interaction_valid if instance_variable_defined?(:@_interaction_valid)
52
49
 
53
50
  super
54
51
  end
@@ -71,24 +68,15 @@ module ActiveInteraction
71
68
 
72
69
  # @return (see #result=)
73
70
  # @return [nil]
74
- def run # rubocop:disable MethodLength
75
- self.result =
76
- if valid?
77
- run_callbacks(:execute) do
78
- result_or_errors =
79
- begin
80
- execute
81
- rescue Interrupt => interrupt
82
- interrupt.errors
83
- end
84
-
85
- if result_or_errors.is_a?(ActiveInteraction::Errors)
86
- errors.merge!(result_or_errors)
87
- else
88
- result_or_errors
89
- end
90
- end
91
- end
71
+ def run
72
+ return self.result = nil unless valid?
73
+
74
+ self.result = run_callbacks(:execute) do
75
+ execute
76
+ rescue Interrupt => e
77
+ errors.backtrace = e.errors.backtrace || e.backtrace
78
+ errors.merge!(e.errors)
79
+ end
92
80
  end
93
81
 
94
82
  # @return [Object]
@@ -101,11 +89,11 @@ module ActiveInteraction
101
89
 
102
90
  e = InvalidInteractionError.new(errors.full_messages.join(', '))
103
91
  e.interaction = self
92
+ e.set_backtrace(errors.backtrace) if errors.backtrace
104
93
  raise e
105
94
  end
106
95
 
107
- #
108
- module ClassMethods
96
+ module ClassMethods # rubocop:disable Style/Documentation
109
97
  def new(*)
110
98
  super.tap do |instance|
111
99
  {
@@ -1,17 +1,15 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
- #
5
3
  module ActiveInteraction
6
4
  # Top-level error class. All other errors subclass this.
7
5
  #
8
6
  # @return [Class]
9
7
  Error = Class.new(StandardError)
10
8
 
11
- # Raised if a class name is invalid.
9
+ # Raised if a constant name is invalid.
12
10
  #
13
11
  # @return [Class]
14
- InvalidClassError = Class.new(Error)
12
+ InvalidNameError = Class.new(Error)
15
13
 
16
14
  # Raised if a converter is invalid.
17
15
  #
@@ -92,17 +90,15 @@ module ActiveInteraction
92
90
 
93
91
  # An extension that provides the ability to merge other errors into itself.
94
92
  class Errors < ActiveModel::Errors
93
+ attr_accessor :backtrace
94
+
95
95
  # Merge other errors into this one.
96
96
  #
97
97
  # @param other [Errors]
98
98
  #
99
99
  # @return [Errors]
100
100
  def merge!(other)
101
- if other.respond_to?(:details)
102
- merge_details!(other)
103
- else
104
- merge_messages!(other)
105
- end
101
+ merge_details!(other)
106
102
 
107
103
  self
108
104
  end
@@ -117,14 +113,6 @@ module ActiveInteraction
117
113
  detail[:error].is_a?(Symbol)
118
114
  end
119
115
 
120
- def merge_messages!(other)
121
- other.messages.each do |attribute, messages|
122
- messages.each do |message|
123
- merge_message!(attribute, message)
124
- end
125
- end
126
- end
127
-
128
116
  def merge_message!(attribute, message)
129
117
  unless attribute?(attribute)
130
118
  message = full_message(attribute, message)
@@ -149,9 +137,8 @@ module ActiveInteraction
149
137
  if attribute?(attribute) || attribute == :base
150
138
  options = detail.dup
151
139
  error = options.delete(:error)
152
- options[:message] = message
153
140
 
154
- add(attribute, error, options) unless added?(attribute, error, options)
141
+ add(attribute, error, **options.merge(message: message)) unless added?(attribute, error, **options)
155
142
  else
156
143
  merge_message!(attribute, message)
157
144
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'active_support/inflector'
@@ -78,16 +77,16 @@ module ActiveInteraction
78
77
  # to the default value.
79
78
  #
80
79
  # @example
81
- # ActiveInteraction::Filter.new(:example).clean(nil)
80
+ # ActiveInteraction::Filter.new(:example).clean(nil, nil)
82
81
  # # => ActiveInteraction::MissingValueError: example
83
82
  # @example
84
- # ActiveInteraction::Filter.new(:example).clean(0)
83
+ # ActiveInteraction::Filter.new(:example).clean(0, nil)
85
84
  # # => ActiveInteraction::InvalidValueError: example: 0
86
85
  # @example
87
- # ActiveInteraction::Filter.new(:example, default: nil).clean(nil)
86
+ # ActiveInteraction::Filter.new(:example, default: nil).clean(nil, nil)
88
87
  # # => nil
89
88
  # @example
90
- # ActiveInteraction::Filter.new(:example, default: 0).clean(nil)
89
+ # ActiveInteraction::Filter.new(:example, default: 0).clean(nil, nil)
91
90
  # # => ActiveInteraction::InvalidDefaultError: example: 0
92
91
  #
93
92
  # @param value [Object]
@@ -95,7 +94,9 @@ module ActiveInteraction
95
94
  #
96
95
  # @return [Object]
97
96
  #
98
- # @raise (see #cast)
97
+ # @raise [MissingValueError] If the value is missing and there is no
98
+ # default.
99
+ # @raise [InvalidValueError] If the value is invalid.
99
100
  # @raise (see #default)
100
101
  def clean(value, context)
101
102
  value = cast(value, context)
@@ -120,7 +121,7 @@ module ActiveInteraction
120
121
  #
121
122
  # @param context [Base, nil]
122
123
  #
123
- # @return (see #raw_default)
124
+ # @return [Object]
124
125
  #
125
126
  # @raise [NoDefaultError] If the default is missing.
126
127
  # @raise [InvalidDefaultError] If the default is invalid.
@@ -131,8 +132,8 @@ module ActiveInteraction
131
132
  raise InvalidValueError if value.is_a?(GroupedInput)
132
133
 
133
134
  cast(value, context)
134
- rescue InvalidNestedValueError => error
135
- raise InvalidDefaultError, "#{name}: #{value.inspect} (#{error})"
135
+ rescue InvalidNestedValueError => e
136
+ raise InvalidDefaultError, "#{name}: #{value.inspect} (#{e})"
136
137
  rescue InvalidValueError, MissingValueError
137
138
  raise InvalidDefaultError, "#{name}: #{value.inspect}"
138
139
  end
@@ -162,27 +163,6 @@ module ActiveInteraction
162
163
  options.key?(:default)
163
164
  end
164
165
 
165
- # @param value [Object]
166
- # @param _interaction [Base, nil]
167
- #
168
- # @return [Object]
169
- #
170
- # @raise [MissingValueError] If the value is missing and there is no
171
- # default.
172
- # @raise [InvalidValueError] If the value is invalid.
173
- #
174
- # @private
175
- def cast(value, _interaction)
176
- case value
177
- when NilClass
178
- raise MissingValueError, name unless default?
179
-
180
- nil
181
- else
182
- raise InvalidValueError, "#{name}: #{describe(value)}"
183
- end
184
- end
185
-
186
166
  # Gets the type of database column that would represent the filter data.
187
167
  #
188
168
  # @example
@@ -194,25 +174,59 @@ module ActiveInteraction
194
174
  #
195
175
  # @return [Symbol] A database column type. If no sensible mapping exists,
196
176
  # returns `:string`.
197
- #
198
- # @since 1.2.0
199
177
  def database_column_type
200
178
  :string
201
179
  end
202
180
 
203
181
  private
204
182
 
205
- # @param value [Object]
206
- # @return [String]
183
+ # rubocop:disable Metrics/MethodLength
184
+ def cast(value, context, convert: true, reconstantize: true)
185
+ if matches?(value)
186
+ adjust_output(value, context)
187
+ # we can't use `nil?` because BasicObject doesn't have it
188
+ elsif value == nil # rubocop:disable Style/NilComparison
189
+ raise MissingValueError, name unless default?
190
+
191
+ nil
192
+ elsif reconstantize
193
+ send(__method__, value, context,
194
+ convert: convert,
195
+ reconstantize: false
196
+ )
197
+ elsif convert
198
+ send(__method__, convert(value), context,
199
+ convert: false,
200
+ reconstantize: reconstantize
201
+ )
202
+ else
203
+ raise InvalidValueError, "#{name}: #{describe(value)}"
204
+ end
205
+ end
206
+ # rubocop:enable Metrics/MethodLength
207
+
208
+ def matches?(_value)
209
+ false
210
+ end
211
+
212
+ def adjust_output(value, _context)
213
+ value
214
+ end
215
+
216
+ def convert(value)
217
+ value
218
+ end
219
+
220
+ def klass
221
+ @klass ||= Object.const_get(self.class.slug.to_s.camelize, false)
222
+ end
223
+
207
224
  def describe(value)
208
225
  value.inspect
209
226
  rescue NoMethodError
210
227
  "(Object doesn't support #inspect)"
211
228
  end
212
229
 
213
- # @param context [Base, nil]
214
- #
215
- # @return [Object]
216
230
  def raw_default(context)
217
231
  value = options.fetch(:default)
218
232
  return value unless value.is_a?(Proc)