active_interaction 5.3.0 → 5.5.0

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +2 -2
  4. data/lib/active_interaction/errors.rb +1 -1
  5. data/lib/active_interaction/grouped_input.rb +23 -3
  6. data/lib/active_interaction/version.rb +1 -1
  7. metadata +12 -115
  8. data/spec/active_interaction/array_input_spec.rb +0 -164
  9. data/spec/active_interaction/base_spec.rb +0 -536
  10. data/spec/active_interaction/concerns/active_modelable_spec.rb +0 -43
  11. data/spec/active_interaction/concerns/active_recordable_spec.rb +0 -47
  12. data/spec/active_interaction/concerns/hashable_spec.rb +0 -44
  13. data/spec/active_interaction/concerns/missable_spec.rb +0 -97
  14. data/spec/active_interaction/concerns/runnable_spec.rb +0 -395
  15. data/spec/active_interaction/errors_spec.rb +0 -223
  16. data/spec/active_interaction/filter/column_spec.rb +0 -85
  17. data/spec/active_interaction/filter_spec.rb +0 -58
  18. data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +0 -11
  19. data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +0 -11
  20. data/spec/active_interaction/filters/array_filter_spec.rb +0 -248
  21. data/spec/active_interaction/filters/boolean_filter_spec.rb +0 -85
  22. data/spec/active_interaction/filters/date_filter_spec.rb +0 -176
  23. data/spec/active_interaction/filters/date_time_filter_spec.rb +0 -187
  24. data/spec/active_interaction/filters/decimal_filter_spec.rb +0 -124
  25. data/spec/active_interaction/filters/file_filter_spec.rb +0 -38
  26. data/spec/active_interaction/filters/float_filter_spec.rb +0 -109
  27. data/spec/active_interaction/filters/hash_filter_spec.rb +0 -127
  28. data/spec/active_interaction/filters/integer_filter_spec.rb +0 -102
  29. data/spec/active_interaction/filters/interface_filter_spec.rb +0 -459
  30. data/spec/active_interaction/filters/object_filter_spec.rb +0 -235
  31. data/spec/active_interaction/filters/record_filter_spec.rb +0 -204
  32. data/spec/active_interaction/filters/string_filter_spec.rb +0 -58
  33. data/spec/active_interaction/filters/symbol_filter_spec.rb +0 -44
  34. data/spec/active_interaction/filters/time_filter_spec.rb +0 -249
  35. data/spec/active_interaction/grouped_input_spec.rb +0 -15
  36. data/spec/active_interaction/hash_input_spec.rb +0 -56
  37. data/spec/active_interaction/i18n_spec.rb +0 -111
  38. data/spec/active_interaction/inputs_spec.rb +0 -264
  39. data/spec/active_interaction/integration/array_interaction_spec.rb +0 -87
  40. data/spec/active_interaction/integration/boolean_interaction_spec.rb +0 -11
  41. data/spec/active_interaction/integration/date_interaction_spec.rb +0 -3
  42. data/spec/active_interaction/integration/date_time_interaction_spec.rb +0 -3
  43. data/spec/active_interaction/integration/file_interaction_spec.rb +0 -17
  44. data/spec/active_interaction/integration/float_interaction_spec.rb +0 -3
  45. data/spec/active_interaction/integration/hash_interaction_spec.rb +0 -106
  46. data/spec/active_interaction/integration/integer_interaction_spec.rb +0 -3
  47. data/spec/active_interaction/integration/interface_interaction_spec.rb +0 -18
  48. data/spec/active_interaction/integration/object_interaction_spec.rb +0 -12
  49. data/spec/active_interaction/integration/record_integration_spec.rb +0 -3
  50. data/spec/active_interaction/integration/string_interaction_spec.rb +0 -3
  51. data/spec/active_interaction/integration/symbol_interaction_spec.rb +0 -3
  52. data/spec/active_interaction/integration/time_interaction_spec.rb +0 -86
  53. data/spec/active_interaction/modules/validation_spec.rb +0 -55
  54. data/spec/spec_helper.rb +0 -22
  55. data/spec/support/concerns.rb +0 -13
  56. data/spec/support/filters.rb +0 -227
  57. data/spec/support/interactions.rb +0 -124
@@ -1,459 +0,0 @@
1
- module InterfaceModule; end
2
-
3
- class InterfaceClass; end # rubocop:disable Lint/EmptyClass
4
-
5
- RSpec.describe ActiveInteraction::InterfaceFilter, :filter do
6
- include_context 'filters'
7
- it_behaves_like 'a filter' do
8
- let(:name) { :interface_module }
9
- end
10
-
11
- describe '#process' do
12
- let(:result) { filter.process(value, nil) }
13
-
14
- context 'with an implicit constant name' do
15
- context 'passed an instance' do
16
- context 'with the module included' do
17
- let(:name) { :interface_module }
18
- let(:value) do
19
- Class.new do
20
- include InterfaceModule
21
- end.new
22
- end
23
-
24
- it 'returns a the value' do
25
- expect(result.value).to eql value
26
- end
27
- end
28
-
29
- context 'with the class inherited from' do
30
- let(:name) { :interface_class }
31
- let(:value) do
32
- Class.new(InterfaceClass) {}.new # rubocop:disable Lint/EmptyBlock
33
- end
34
-
35
- it 'returns a the value' do
36
- expect(result.value).to eql value
37
- end
38
- end
39
-
40
- context 'that is extended by the ancestor' do
41
- let(:name) { :interface_module }
42
- let(:value) do
43
- Class.new {}.new.extend(InterfaceModule) # rubocop:disable Lint/EmptyBlock
44
- end
45
-
46
- it 'returns a the value' do
47
- expect(result.value).to eql value
48
- end
49
- end
50
-
51
- context 'that does not match' do
52
- let(:name) { :interface_module }
53
- let(:value) { Class.new }
54
-
55
- it 'indicates an error' do
56
- error = result.errors.first
57
-
58
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
59
- expect(error.type).to be :invalid_type
60
- end
61
- end
62
-
63
- context 'that is nil' do
64
- let(:name) { :interface_module }
65
- let(:value) { nil }
66
-
67
- it 'indicates an error' do
68
- error = result.errors.first
69
-
70
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
71
- expect(error.type).to be :missing
72
- end
73
- end
74
-
75
- context 'with the class itself' do
76
- let(:name) { :interface_class }
77
- let(:value) do
78
- InterfaceClass.new
79
- end
80
-
81
- it 'indicates an error' do
82
- error = result.errors.first
83
-
84
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
85
- expect(error.type).to be :invalid_type
86
- end
87
- end
88
- end
89
-
90
- context 'passed a class' do
91
- context 'with the class inherited from' do
92
- let(:name) { :interface_class }
93
- let(:value) do
94
- Class.new(InterfaceClass) {} # rubocop:disable Lint/EmptyBlock
95
- end
96
-
97
- it 'returns a the value' do
98
- expect(result.value).to eql value
99
- end
100
- end
101
-
102
- context 'that is extended by the ancestor' do
103
- let(:name) { :interface_module }
104
- let(:value) do
105
- Class.new do
106
- extend InterfaceModule
107
- end
108
- end
109
-
110
- it 'returns a the value' do
111
- expect(result.value).to eql value
112
- end
113
- end
114
-
115
- context 'that does not match' do
116
- let(:name) { :interface_class }
117
- let(:value) { Class }
118
-
119
- it 'indicates an error' do
120
- error = result.errors.first
121
-
122
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
123
- expect(error.type).to be :invalid_type
124
- end
125
- end
126
-
127
- context 'with the class itself' do
128
- let(:name) { :interface_class }
129
- let(:value) { InterfaceClass }
130
-
131
- it 'indicates an error' do
132
- error = result.errors.first
133
-
134
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
135
- expect(error.type).to be :invalid_type
136
- end
137
- end
138
- end
139
-
140
- context 'passed a module' do
141
- context 'that is extended by the ancestor' do
142
- let(:name) { :interface_module }
143
- let(:value) do
144
- Module.new do
145
- extend InterfaceModule
146
- end
147
- end
148
-
149
- it 'returns a the value' do
150
- expect(result.value).to eql value
151
- end
152
- end
153
-
154
- context 'that does not match' do
155
- let(:name) { :interface_module }
156
- let(:value) { Module.new }
157
-
158
- it 'indicates an error' do
159
- error = result.errors.first
160
-
161
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
162
- expect(error.type).to be :invalid_type
163
- end
164
- end
165
-
166
- context 'with the module itself' do
167
- let(:name) { :interface_module }
168
- let(:value) { InterfaceModule }
169
-
170
- it 'indicates an error' do
171
- error = result.errors.first
172
-
173
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
174
- expect(error.type).to be :invalid_type
175
- end
176
- end
177
- end
178
-
179
- context 'given an invalid name' do
180
- let(:name) { :invalid }
181
- let(:value) { Object }
182
-
183
- it 'raises an error' do
184
- expect do
185
- result
186
- end.to raise_error ActiveInteraction::InvalidNameError
187
- end
188
- end
189
- end
190
-
191
- context 'with a constant given' do
192
- context 'passed an instance' do
193
- context 'with the module included' do
194
- before { options.merge!(from: :interface_module) }
195
-
196
- let(:value) do
197
- Class.new do
198
- include InterfaceModule
199
- end.new
200
- end
201
-
202
- it 'returns a the value' do
203
- expect(result.value).to eql value
204
- end
205
- end
206
-
207
- context 'with the class inherited from' do
208
- before { options.merge!(from: :interface_class) }
209
-
210
- let(:value) do
211
- Class.new(InterfaceClass) {}.new # rubocop:disable Lint/EmptyBlock
212
- end
213
-
214
- it 'returns a the value' do
215
- expect(result.value).to eql value
216
- end
217
- end
218
-
219
- context 'that is extended by the ancestor' do
220
- before { options.merge!(from: :interface_module) }
221
-
222
- let(:value) do
223
- Class.new {}.new.extend(InterfaceModule) # rubocop:disable Lint/EmptyBlock
224
- end
225
-
226
- it 'returns a the value' do
227
- expect(result.value).to eql value
228
- end
229
- end
230
-
231
- context 'that does not match' do
232
- let(:name) { :interface_class }
233
- let(:value) { Class.new }
234
-
235
- it 'indicates an error' do
236
- error = result.errors.first
237
-
238
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
239
- expect(error.type).to be :invalid_type
240
- end
241
- end
242
-
243
- context 'with the class itself' do
244
- let(:name) { :interface_class }
245
- let(:value) { InterfaceClass.new }
246
-
247
- it 'indicates an error' do
248
- error = result.errors.first
249
-
250
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
251
- expect(error.type).to be :invalid_type
252
- end
253
- end
254
- end
255
-
256
- context 'passed a class' do
257
- context 'with the class inherited from' do
258
- before { options.merge!(from: :interface_class) }
259
-
260
- let(:value) do
261
- Class.new(InterfaceClass) {} # rubocop:disable Lint/EmptyBlock
262
- end
263
-
264
- it 'returns a the value' do
265
- expect(result.value).to eql value
266
- end
267
- end
268
-
269
- context 'that is extended by the ancestor' do
270
- before { options.merge!(from: :interface_module) }
271
-
272
- let(:value) do
273
- Class.new do
274
- extend InterfaceModule
275
- end
276
- end
277
-
278
- it 'returns a the value' do
279
- expect(result.value).to eql value
280
- end
281
- end
282
-
283
- context 'that does not match' do
284
- let(:name) { :interface_class }
285
- let(:value) { Class }
286
-
287
- it 'indicates an error' do
288
- error = result.errors.first
289
-
290
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
291
- expect(error.type).to be :invalid_type
292
- end
293
- end
294
-
295
- context 'with the class itself' do
296
- let(:name) { :interface_class }
297
- let(:value) { InterfaceClass }
298
-
299
- it 'indicates an error' do
300
- error = result.errors.first
301
-
302
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
303
- expect(error.type).to be :invalid_type
304
- end
305
- end
306
- end
307
-
308
- context 'passed a module' do
309
- context 'that is extended by the ancestor' do
310
- before { options.merge!(from: :interface_module) }
311
-
312
- let(:value) do
313
- Module.new do
314
- extend InterfaceModule
315
- end
316
- end
317
-
318
- it 'returns a the value' do
319
- expect(result.value).to eql value
320
- end
321
- end
322
-
323
- context 'that does not match' do
324
- let(:name) { :interface_module }
325
- let(:value) { Module.new }
326
-
327
- it 'indicates an error' do
328
- error = result.errors.first
329
-
330
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
331
- expect(error.type).to be :invalid_type
332
- end
333
- end
334
-
335
- context 'with the module itself' do
336
- let(:name) { :interface_module }
337
- let(:value) { InterfaceModule }
338
-
339
- it 'indicates an error' do
340
- error = result.errors.first
341
-
342
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
343
- expect(error.type).to be :invalid_type
344
- end
345
- end
346
- end
347
-
348
- context 'given an invalid name' do
349
- before { options.merge!(from: :invalid) }
350
-
351
- let(:value) { Object }
352
-
353
- it 'raises an error' do
354
- expect do
355
- result
356
- end.to raise_error ActiveInteraction::InvalidNameError
357
- end
358
- end
359
- end
360
-
361
- context 'with methods passed' do
362
- before { options[:methods] = %i[dump load] }
363
-
364
- context 'passed an valid instance' do
365
- let(:value) do
366
- Class.new do
367
- def dump; end
368
-
369
- def load; end
370
- end.new
371
- end
372
-
373
- it 'returns a the value' do
374
- expect(result.value).to eql value
375
- end
376
- end
377
-
378
- context 'passed an invalid instance' do
379
- let(:value) { Class.new }
380
-
381
- it 'indicates an error' do
382
- error = result.errors.first
383
-
384
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
385
- expect(error.type).to be :invalid_type
386
- end
387
- end
388
-
389
- context 'passed a class' do
390
- let(:value) do
391
- Class.new do
392
- def self.dump; end
393
-
394
- def self.load; end
395
- end
396
- end
397
-
398
- it 'returns a the value' do
399
- expect(result.value).to eql value
400
- end
401
- end
402
-
403
- context 'passed an invalid class' do
404
- let(:value) { Class }
405
-
406
- it 'indicates an error' do
407
- error = result.errors.first
408
-
409
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
410
- expect(error.type).to be :invalid_type
411
- end
412
- end
413
-
414
- context 'passed a module' do
415
- let(:value) do
416
- Module.new do
417
- def self.dump; end
418
-
419
- def self.load; end
420
- end
421
- end
422
-
423
- it 'returns a the value' do
424
- expect(result.value).to eql value
425
- end
426
- end
427
-
428
- context 'passed an invalid module' do
429
- let(:value) { Module.new }
430
-
431
- it 'indicates an error' do
432
- error = result.errors.first
433
-
434
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
435
- expect(error.type).to be :invalid_type
436
- end
437
- end
438
- end
439
-
440
- context 'with from and methods passed' do
441
- before do
442
- options[:from] = :module
443
- options[:methods] = %i[dump load]
444
- end
445
-
446
- it 'raises an error' do
447
- expect do
448
- filter
449
- end.to raise_error ActiveInteraction::InvalidFilterError
450
- end
451
- end
452
- end
453
-
454
- describe '#database_column_type' do
455
- it 'returns :string' do
456
- expect(filter.database_column_type).to be :string
457
- end
458
- end
459
- end
@@ -1,235 +0,0 @@
1
- class ObjectThing
2
- def self.converter(_)
3
- @converter ||= new
4
- end
5
-
6
- def self.converter_with_error(_)
7
- raise 'error'
8
- end
9
- end
10
-
11
- class ObjectThings; end # rubocop:disable Lint/EmptyClass
12
- BackupObjectThing = ObjectThing
13
-
14
- RSpec.describe ActiveInteraction::ObjectFilter, :filter do
15
- include_context 'filters'
16
- before do
17
- options[:class] = ObjectThing
18
- end
19
-
20
- it_behaves_like 'a filter'
21
-
22
- describe '#process' do
23
- let(:value) { ObjectThing.new }
24
- let(:result) { filter.process(value, nil) }
25
-
26
- context 'with an instance of the class' do
27
- it 'returns the instance' do
28
- expect(result.value).to eql value
29
- end
30
-
31
- context 'with an instance that is a subclass' do
32
- let(:subclass) { Class.new(ObjectThing) }
33
- let(:value) { subclass.new }
34
-
35
- it 'returns the instance' do
36
- expect(result.value).to eql value
37
- end
38
- end
39
-
40
- it 'handles reconstantizing' do
41
- expect(result.value).to eql value
42
-
43
- Object.send(:remove_const, :ObjectThing)
44
- ObjectThing = BackupObjectThing # rubocop:disable Lint/ConstantDefinitionInBlock
45
- value = ObjectThing.new
46
-
47
- expect(filter.process(value, nil).value).to eql value
48
- end
49
-
50
- it 'handles reconstantizing subclasses' do
51
- filter
52
-
53
- Object.send(:remove_const, :ObjectThing)
54
- ObjectThing = BackupObjectThing # rubocop:disable Lint/ConstantDefinitionInBlock
55
- class SubObjectThing < ObjectThing; end # rubocop:disable Lint/ConstantDefinitionInBlock
56
- value = SubObjectThing.new
57
-
58
- expect(filter.process(value, nil).value).to eql value
59
- end
60
-
61
- context 'without the class available' do
62
- before { Object.send(:remove_const, :ObjectThing) }
63
-
64
- after { ObjectThing = BackupObjectThing } # rubocop:disable Lint/ConstantDefinitionInBlock
65
-
66
- it 'does not raise an error on initialization' do
67
- expect { filter }.to_not raise_error
68
- end
69
- end
70
- end
71
-
72
- context 'with class as a String' do
73
- before do
74
- options[:class] = ObjectThing.name
75
- end
76
-
77
- it 'returns the instance' do
78
- expect(result.value).to eql value
79
- end
80
- end
81
-
82
- context 'with a plural class' do
83
- let(:value) { ObjectThings.new }
84
-
85
- before { options[:class] = ObjectThings }
86
-
87
- it 'returns the instance' do
88
- expect(result.value).to eql value
89
- end
90
- end
91
-
92
- context 'with class as an invalid String' do
93
- before do
94
- options[:class] = 'invalid'
95
- end
96
-
97
- it 'raises an error' do
98
- expect do
99
- result
100
- end.to raise_error ActiveInteraction::InvalidNameError
101
- end
102
- end
103
-
104
- context 'with a converter' do
105
- let(:value) { '' }
106
-
107
- context 'that is a symbol' do
108
- before do
109
- options[:converter] = :converter
110
- end
111
-
112
- it 'calls the class method' do
113
- expect(result.value).to eql ObjectThing.converter(value)
114
- end
115
- end
116
-
117
- context 'that is a proc' do
118
- before do
119
- options[:converter] = ->(x) { ObjectThing.converter(x) }
120
- end
121
-
122
- it 'gets called' do
123
- expect(result.value).to eql ObjectThing.converter(value)
124
- end
125
- end
126
-
127
- context 'with an object of the correct class' do
128
- let(:value) { ObjectThing.new }
129
-
130
- it 'does not call the converter' do
131
- allow(ObjectThing).to receive(:converter)
132
- result.value
133
- expect(ObjectThing).to_not have_received(:converter)
134
- end
135
-
136
- it 'returns the correct value' do
137
- expect(result.value).to eql value
138
- end
139
- end
140
-
141
- context 'with an object that is a subclass' do
142
- let(:subclass) { Class.new(ObjectThing) }
143
- let(:value) { subclass.new }
144
-
145
- it 'does not call the converter' do
146
- allow(subclass).to receive(:converter)
147
- result.value
148
- expect(subclass).to_not have_received(:converter)
149
- end
150
-
151
- it 'returns the correct value' do
152
- expect(result.value).to eql value
153
- end
154
- end
155
-
156
- context 'with a nil value' do
157
- let(:value) { nil }
158
-
159
- include_context 'optional'
160
-
161
- it 'returns nil' do
162
- allow(ObjectThing).to receive(:converter)
163
- result.value
164
- expect(ObjectThing).to_not have_received(:converter)
165
- end
166
-
167
- it 'returns the correct value' do
168
- expect(result.value).to eql value
169
- end
170
- end
171
-
172
- context 'that is invalid' do
173
- before do
174
- options[:converter] = 'invalid converter'
175
- end
176
-
177
- it 'raises an error' do
178
- expect do
179
- result
180
- end.to raise_error ActiveInteraction::InvalidConverterError
181
- end
182
- end
183
-
184
- context 'that throws an error' do
185
- before do
186
- options[:converter] = :converter_with_error
187
- end
188
-
189
- it 'indicates an error' do
190
- error = result.errors.first
191
-
192
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
193
- expect(error.type).to be :invalid_type
194
- end
195
- end
196
-
197
- context 'that returns a nil' do
198
- let(:value) { '' }
199
-
200
- before do
201
- options[:default] = ObjectThing.new
202
- options[:converter] = ->(_) {}
203
- end
204
-
205
- it 'indicates an error' do
206
- error = filter.process(value, nil).errors.first
207
-
208
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
209
- expect(error.type).to be :invalid_type
210
- end
211
- end
212
-
213
- context 'that returns an invalid value' do
214
- let(:value) { '' }
215
-
216
- before do
217
- options[:converter] = ->(_) { 'invalid' }
218
- end
219
-
220
- it 'indicates an error' do
221
- error = filter.process(value, nil).errors.first
222
-
223
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
224
- expect(error.type).to be :invalid_type
225
- end
226
- end
227
- end
228
- end
229
-
230
- describe '#database_column_type' do
231
- it 'returns :string' do
232
- expect(filter.database_column_type).to be :string
233
- end
234
- end
235
- end