active_interaction 5.1.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +61 -0
  3. data/README.md +11 -12
  4. data/lib/active_interaction/base.rb +2 -0
  5. data/lib/active_interaction/errors.rb +16 -16
  6. data/lib/active_interaction/filter.rb +9 -12
  7. data/lib/active_interaction/filters/array_filter.rb +1 -1
  8. data/lib/active_interaction/filters/hash_filter.rb +5 -1
  9. data/lib/active_interaction/grouped_input.rb +23 -3
  10. data/lib/active_interaction/locale/es.yml +23 -0
  11. data/lib/active_interaction/version.rb +1 -1
  12. metadata +13 -115
  13. data/spec/active_interaction/array_input_spec.rb +0 -166
  14. data/spec/active_interaction/base_spec.rb +0 -537
  15. data/spec/active_interaction/concerns/active_modelable_spec.rb +0 -45
  16. data/spec/active_interaction/concerns/active_recordable_spec.rb +0 -49
  17. data/spec/active_interaction/concerns/hashable_spec.rb +0 -46
  18. data/spec/active_interaction/concerns/missable_spec.rb +0 -99
  19. data/spec/active_interaction/concerns/runnable_spec.rb +0 -397
  20. data/spec/active_interaction/errors_spec.rb +0 -196
  21. data/spec/active_interaction/filter/column_spec.rb +0 -87
  22. data/spec/active_interaction/filter_spec.rb +0 -39
  23. data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +0 -13
  24. data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +0 -13
  25. data/spec/active_interaction/filters/array_filter_spec.rb +0 -245
  26. data/spec/active_interaction/filters/boolean_filter_spec.rb +0 -87
  27. data/spec/active_interaction/filters/date_filter_spec.rb +0 -178
  28. data/spec/active_interaction/filters/date_time_filter_spec.rb +0 -189
  29. data/spec/active_interaction/filters/decimal_filter_spec.rb +0 -126
  30. data/spec/active_interaction/filters/file_filter_spec.rb +0 -40
  31. data/spec/active_interaction/filters/float_filter_spec.rb +0 -110
  32. data/spec/active_interaction/filters/hash_filter_spec.rb +0 -129
  33. data/spec/active_interaction/filters/integer_filter_spec.rb +0 -104
  34. data/spec/active_interaction/filters/interface_filter_spec.rb +0 -461
  35. data/spec/active_interaction/filters/object_filter_spec.rb +0 -237
  36. data/spec/active_interaction/filters/record_filter_spec.rb +0 -206
  37. data/spec/active_interaction/filters/string_filter_spec.rb +0 -60
  38. data/spec/active_interaction/filters/symbol_filter_spec.rb +0 -46
  39. data/spec/active_interaction/filters/time_filter_spec.rb +0 -251
  40. data/spec/active_interaction/grouped_input_spec.rb +0 -17
  41. data/spec/active_interaction/hash_input_spec.rb +0 -58
  42. data/spec/active_interaction/i18n_spec.rb +0 -113
  43. data/spec/active_interaction/inputs_spec.rb +0 -266
  44. data/spec/active_interaction/integration/array_interaction_spec.rb +0 -88
  45. data/spec/active_interaction/integration/boolean_interaction_spec.rb +0 -5
  46. data/spec/active_interaction/integration/date_interaction_spec.rb +0 -5
  47. data/spec/active_interaction/integration/date_time_interaction_spec.rb +0 -5
  48. data/spec/active_interaction/integration/file_interaction_spec.rb +0 -18
  49. data/spec/active_interaction/integration/float_interaction_spec.rb +0 -5
  50. data/spec/active_interaction/integration/hash_interaction_spec.rb +0 -76
  51. data/spec/active_interaction/integration/integer_interaction_spec.rb +0 -5
  52. data/spec/active_interaction/integration/interface_interaction_spec.rb +0 -19
  53. data/spec/active_interaction/integration/object_interaction_spec.rb +0 -14
  54. data/spec/active_interaction/integration/record_integration_spec.rb +0 -5
  55. data/spec/active_interaction/integration/string_interaction_spec.rb +0 -5
  56. data/spec/active_interaction/integration/symbol_interaction_spec.rb +0 -5
  57. data/spec/active_interaction/integration/time_interaction_spec.rb +0 -88
  58. data/spec/active_interaction/modules/validation_spec.rb +0 -57
  59. data/spec/spec_helper.rb +0 -20
  60. data/spec/support/concerns.rb +0 -13
  61. data/spec/support/filters.rb +0 -227
  62. data/spec/support/interactions.rb +0 -124
@@ -1,237 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class ObjectThing
4
- def self.converter(_)
5
- @converter ||= new
6
- end
7
-
8
- def self.converter_with_error(_)
9
- raise 'error'
10
- end
11
- end
12
-
13
- class ObjectThings; end # rubocop:disable Lint/EmptyClass
14
- BackupObjectThing = ObjectThing
15
-
16
- describe ActiveInteraction::ObjectFilter, :filter do
17
- include_context 'filters'
18
- before do
19
- options[:class] = ObjectThing
20
- end
21
-
22
- it_behaves_like 'a filter'
23
-
24
- describe '#process' do
25
- let(:value) { ObjectThing.new }
26
- let(:result) { filter.process(value, nil) }
27
-
28
- context 'with an instance of the class' do
29
- it 'returns the instance' do
30
- expect(result.value).to eql value
31
- end
32
-
33
- context 'with an instance that is a subclass' do
34
- let(:subclass) { Class.new(ObjectThing) }
35
- let(:value) { subclass.new }
36
-
37
- it 'returns the instance' do
38
- expect(result.value).to eql value
39
- end
40
- end
41
-
42
- it 'handles reconstantizing' do
43
- expect(result.value).to eql value
44
-
45
- Object.send(:remove_const, :ObjectThing)
46
- ObjectThing = BackupObjectThing # rubocop:disable Lint/ConstantDefinitionInBlock
47
- value = ObjectThing.new
48
-
49
- expect(filter.process(value, nil).value).to eql value
50
- end
51
-
52
- it 'handles reconstantizing subclasses' do
53
- filter
54
-
55
- Object.send(:remove_const, :ObjectThing)
56
- ObjectThing = BackupObjectThing # rubocop:disable Lint/ConstantDefinitionInBlock
57
- class SubObjectThing < ObjectThing; end # rubocop:disable Lint/ConstantDefinitionInBlock
58
- value = SubObjectThing.new
59
-
60
- expect(filter.process(value, nil).value).to eql value
61
- end
62
-
63
- context 'without the class available' do
64
- before { Object.send(:remove_const, :ObjectThing) }
65
-
66
- after { ObjectThing = BackupObjectThing } # rubocop:disable Lint/ConstantDefinitionInBlock
67
-
68
- it 'does not raise an error on initialization' do
69
- expect { filter }.to_not raise_error
70
- end
71
- end
72
- end
73
-
74
- context 'with class as a String' do
75
- before do
76
- options[:class] = ObjectThing.name
77
- end
78
-
79
- it 'returns the instance' do
80
- expect(result.value).to eql value
81
- end
82
- end
83
-
84
- context 'with a plural class' do
85
- let(:value) { ObjectThings.new }
86
-
87
- before { options[:class] = ObjectThings }
88
-
89
- it 'returns the instance' do
90
- expect(result.value).to eql value
91
- end
92
- end
93
-
94
- context 'with class as an invalid String' do
95
- before do
96
- options[:class] = 'invalid'
97
- end
98
-
99
- it 'raises an error' do
100
- expect do
101
- result
102
- end.to raise_error ActiveInteraction::InvalidNameError
103
- end
104
- end
105
-
106
- context 'with a converter' do
107
- let(:value) { '' }
108
-
109
- context 'that is a symbol' do
110
- before do
111
- options[:converter] = :converter
112
- end
113
-
114
- it 'calls the class method' do
115
- expect(result.value).to eql ObjectThing.converter(value)
116
- end
117
- end
118
-
119
- context 'that is a proc' do
120
- before do
121
- options[:converter] = ->(x) { ObjectThing.converter(x) }
122
- end
123
-
124
- it 'gets called' do
125
- expect(result.value).to eql ObjectThing.converter(value)
126
- end
127
- end
128
-
129
- context 'with an object of the correct class' do
130
- let(:value) { ObjectThing.new }
131
-
132
- it 'does not call the converter' do
133
- allow(ObjectThing).to receive(:converter)
134
- result.value
135
- expect(ObjectThing).to_not have_received(:converter)
136
- end
137
-
138
- it 'returns the correct value' do
139
- expect(result.value).to eql value
140
- end
141
- end
142
-
143
- context 'with an object that is a subclass' do
144
- let(:subclass) { Class.new(ObjectThing) }
145
- let(:value) { subclass.new }
146
-
147
- it 'does not call the converter' do
148
- allow(subclass).to receive(:converter)
149
- result.value
150
- expect(subclass).to_not have_received(:converter)
151
- end
152
-
153
- it 'returns the correct value' do
154
- expect(result.value).to eql value
155
- end
156
- end
157
-
158
- context 'with a nil value' do
159
- let(:value) { nil }
160
-
161
- include_context 'optional'
162
-
163
- it 'returns nil' do
164
- allow(ObjectThing).to receive(:converter)
165
- result.value
166
- expect(ObjectThing).to_not have_received(:converter)
167
- end
168
-
169
- it 'returns the correct value' do
170
- expect(result.value).to eql value
171
- end
172
- end
173
-
174
- context 'that is invalid' do
175
- before do
176
- options[:converter] = 'invalid converter'
177
- end
178
-
179
- it 'raises an error' do
180
- expect do
181
- result
182
- end.to raise_error ActiveInteraction::InvalidConverterError
183
- end
184
- end
185
-
186
- context 'that throws an error' do
187
- before do
188
- options[:converter] = :converter_with_error
189
- end
190
-
191
- it 'indicates an error' do
192
- error = result.errors.first
193
-
194
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
195
- expect(error.type).to be :invalid_type
196
- end
197
- end
198
-
199
- context 'that returns a nil' do
200
- let(:value) { '' }
201
-
202
- before do
203
- options[:default] = ObjectThing.new
204
- options[:converter] = ->(_) {}
205
- end
206
-
207
- it 'indicates an error' do
208
- error = filter.process(value, nil).errors.first
209
-
210
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
211
- expect(error.type).to be :invalid_type
212
- end
213
- end
214
-
215
- context 'that returns an invalid value' do
216
- let(:value) { '' }
217
-
218
- before do
219
- options[:converter] = ->(_) { 'invalid' }
220
- end
221
-
222
- it 'indicates an error' do
223
- error = filter.process(value, nil).errors.first
224
-
225
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
226
- expect(error.type).to be :invalid_type
227
- end
228
- end
229
- end
230
- end
231
-
232
- describe '#database_column_type' do
233
- it 'returns :string' do
234
- expect(filter.database_column_type).to be :string
235
- end
236
- end
237
- end
@@ -1,206 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class RecordThing
4
- def self.find(_)
5
- raise 'error'
6
- end
7
-
8
- def self.finder(_)
9
- @finder ||= new
10
- end
11
-
12
- def self.finds_nil(_)
13
- nil
14
- end
15
-
16
- def self.finds_bad_value(_)
17
- Object.new
18
- end
19
- end
20
-
21
- class RecordThings; end # rubocop:disable Lint/EmptyClass
22
- BackupRecordThing = RecordThing
23
-
24
- describe ActiveInteraction::RecordFilter, :filter do
25
- include_context 'filters'
26
- before do
27
- options[:class] = RecordThing
28
- end
29
-
30
- it_behaves_like 'a filter'
31
-
32
- describe '#process' do
33
- let(:value) { RecordThing.new }
34
- let(:result) { filter.process(value, nil) }
35
-
36
- context 'with an instance of the class' do
37
- it 'returns the instance' do
38
- expect(result.value).to eql value
39
- end
40
-
41
- context 'with an instance that is a subclass' do
42
- let(:subclass) { Class.new(RecordThing) }
43
- let(:value) { subclass.new }
44
-
45
- it 'returns the instance' do
46
- expect(result.value).to eql value
47
- end
48
- end
49
-
50
- it 'handles reconstantizing' do
51
- expect(result.value).to eql value
52
-
53
- Object.send(:remove_const, :RecordThing)
54
- RecordThing = BackupRecordThing # rubocop:disable Lint/ConstantDefinitionInBlock
55
- value = RecordThing.new
56
-
57
- expect(filter.process(value, nil).value).to eql value
58
- end
59
-
60
- it 'handles reconstantizing subclasses' do
61
- filter
62
-
63
- Object.send(:remove_const, :RecordThing)
64
- RecordThing = BackupRecordThing # rubocop:disable Lint/ConstantDefinitionInBlock
65
- class SubRecordThing < RecordThing; end # rubocop:disable Lint/ConstantDefinitionInBlock
66
- value = SubRecordThing.new
67
-
68
- expect(filter.process(value, nil).value).to eql value
69
- end
70
-
71
- context 'without the class available' do
72
- before { Object.send(:remove_const, :RecordThing) }
73
-
74
- after { RecordThing = BackupRecordThing } # rubocop:disable Lint/ConstantDefinitionInBlock
75
-
76
- it 'does not raise an error on initialization' do
77
- expect { filter }.to_not raise_error
78
- end
79
- end
80
- end
81
-
82
- context 'with class as a superclass' do
83
- before do
84
- options[:class] = RecordThing.superclass
85
- end
86
-
87
- it 'returns the instance' do
88
- expect(result.value).to eql value
89
- end
90
- end
91
-
92
- context 'with class as a String' do
93
- before do
94
- options[:class] = RecordThing.name
95
- end
96
-
97
- it 'returns the instance' do
98
- expect(result.value).to eql value
99
- end
100
- end
101
-
102
- context 'with a plural class' do
103
- let(:value) { RecordThings.new }
104
-
105
- before { options[:class] = RecordThings }
106
-
107
- it 'returns the instance' do
108
- expect(result.value).to eql value
109
- end
110
- end
111
-
112
- context 'with class as an invalid String' do
113
- before do
114
- options[:class] = 'invalid'
115
- end
116
-
117
- it 'raises an error' do
118
- expect do
119
- result
120
- end.to raise_error ActiveInteraction::InvalidNameError
121
- end
122
- end
123
-
124
- context 'with a value that does not match the class' do
125
- let(:value) { 1 }
126
-
127
- it 'calls the default finder' do
128
- allow(RecordThing).to receive(:find)
129
- result
130
- expect(RecordThing).to have_received(:find).with(value)
131
- end
132
-
133
- context 'with a custom finder' do
134
- before do
135
- options[:finder] = :finder
136
- end
137
-
138
- it 'calls the custom finder' do
139
- allow(RecordThing).to receive(:finder)
140
- result
141
- expect(RecordThing).to have_received(:finder).with(value)
142
- end
143
- end
144
-
145
- context 'that returns a nil' do
146
- let(:value) { 1 }
147
-
148
- before do
149
- options[:default] = RecordThing.new
150
- options[:finder] = :finds_nil
151
- end
152
-
153
- it 'indicates an error' do
154
- error = filter.process(value, nil).errors.first
155
-
156
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
157
- expect(error.type).to be :invalid_type
158
- end
159
- end
160
-
161
- context 'that returns an invalid value' do
162
- let(:value) { 1 }
163
-
164
- before do
165
- options[:finder] = :finds_bad_value
166
- end
167
-
168
- it 'indicates an error' do
169
- error = filter.process(value, nil).errors.first
170
-
171
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
172
- expect(error.type).to be :invalid_type
173
- end
174
- end
175
- end
176
-
177
- context 'with a blank String' do
178
- let(:value) { ' ' }
179
-
180
- context 'optional' do
181
- include_context 'optional'
182
-
183
- it 'returns the default' do
184
- expect(filter.process(value, nil).value).to eql options[:default]
185
- end
186
- end
187
-
188
- context 'required' do
189
- include_context 'required'
190
-
191
- it 'indicates an error' do
192
- error = filter.process(value, nil).errors.first
193
-
194
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
195
- expect(error.type).to be :missing
196
- end
197
- end
198
- end
199
- end
200
-
201
- describe '#database_column_type' do
202
- it 'returns :string' do
203
- expect(filter.database_column_type).to be :string
204
- end
205
- end
206
- end
@@ -1,60 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveInteraction::StringFilter, :filter do
4
- include_context 'filters'
5
- it_behaves_like 'a filter'
6
-
7
- shared_context 'without strip' do
8
- before do
9
- options[:strip] = false
10
- end
11
- end
12
-
13
- describe '#process' do
14
- let(:result) { filter.process(value, nil) }
15
-
16
- context 'with a String' do
17
- let(:value) { SecureRandom.hex }
18
-
19
- it 'returns the String' do
20
- expect(result.value).to eql value
21
- end
22
- end
23
-
24
- context 'with an implicit String' do
25
- let(:value) do
26
- Class.new do
27
- def to_str
28
- @to_str ||= SecureRandom.hex
29
- end
30
- end.new
31
- end
32
-
33
- it 'returns the String' do
34
- expect(result.value).to eql value.to_str
35
- end
36
- end
37
-
38
- context 'with a strippable String' do
39
- let(:value) { " #{SecureRandom.hex} " }
40
-
41
- it 'returns the stripped string' do
42
- expect(result.value).to eql value.strip
43
- end
44
-
45
- context 'without strip' do
46
- include_context 'without strip'
47
-
48
- it 'returns the String' do
49
- expect(result.value).to eql value
50
- end
51
- end
52
- end
53
- end
54
-
55
- describe '#database_column_type' do
56
- it 'returns :string' do
57
- expect(filter.database_column_type).to be :string
58
- end
59
- end
60
- end
@@ -1,46 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveInteraction::SymbolFilter, :filter do
4
- include_context 'filters'
5
- it_behaves_like 'a filter'
6
-
7
- describe '#process' do
8
- let(:result) { filter.process(value, nil) }
9
-
10
- context 'with a Symbol' do
11
- let(:value) { SecureRandom.hex.to_sym }
12
-
13
- it 'returns the Symbol' do
14
- expect(result.value).to eql value
15
- end
16
- end
17
-
18
- context 'with an implicit Symbol' do
19
- let(:value) do
20
- Class.new do
21
- def to_sym
22
- :symbol
23
- end
24
- end.new
25
- end
26
-
27
- it 'returns a symbol' do
28
- expect(result.value).to eql value.to_sym
29
- end
30
- end
31
-
32
- context 'with a String' do
33
- let(:value) { SecureRandom.hex }
34
-
35
- it 'returns a Symbol' do
36
- expect(result.value).to eql value.to_sym
37
- end
38
- end
39
- end
40
-
41
- describe '#database_column_type' do
42
- it 'returns :string' do
43
- expect(filter.database_column_type).to be :string
44
- end
45
- end
46
- end