active_interaction 5.3.0 → 5.4.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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +2 -2
  4. data/lib/active_interaction/errors.rb +1 -1
  5. data/lib/active_interaction/version.rb +1 -1
  6. metadata +26 -112
  7. data/spec/active_interaction/array_input_spec.rb +0 -164
  8. data/spec/active_interaction/base_spec.rb +0 -536
  9. data/spec/active_interaction/concerns/active_modelable_spec.rb +0 -43
  10. data/spec/active_interaction/concerns/active_recordable_spec.rb +0 -47
  11. data/spec/active_interaction/concerns/hashable_spec.rb +0 -44
  12. data/spec/active_interaction/concerns/missable_spec.rb +0 -97
  13. data/spec/active_interaction/concerns/runnable_spec.rb +0 -395
  14. data/spec/active_interaction/errors_spec.rb +0 -223
  15. data/spec/active_interaction/filter/column_spec.rb +0 -85
  16. data/spec/active_interaction/filter_spec.rb +0 -58
  17. data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +0 -11
  18. data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +0 -11
  19. data/spec/active_interaction/filters/array_filter_spec.rb +0 -248
  20. data/spec/active_interaction/filters/boolean_filter_spec.rb +0 -85
  21. data/spec/active_interaction/filters/date_filter_spec.rb +0 -176
  22. data/spec/active_interaction/filters/date_time_filter_spec.rb +0 -187
  23. data/spec/active_interaction/filters/decimal_filter_spec.rb +0 -124
  24. data/spec/active_interaction/filters/file_filter_spec.rb +0 -38
  25. data/spec/active_interaction/filters/float_filter_spec.rb +0 -109
  26. data/spec/active_interaction/filters/hash_filter_spec.rb +0 -127
  27. data/spec/active_interaction/filters/integer_filter_spec.rb +0 -102
  28. data/spec/active_interaction/filters/interface_filter_spec.rb +0 -459
  29. data/spec/active_interaction/filters/object_filter_spec.rb +0 -235
  30. data/spec/active_interaction/filters/record_filter_spec.rb +0 -204
  31. data/spec/active_interaction/filters/string_filter_spec.rb +0 -58
  32. data/spec/active_interaction/filters/symbol_filter_spec.rb +0 -44
  33. data/spec/active_interaction/filters/time_filter_spec.rb +0 -249
  34. data/spec/active_interaction/grouped_input_spec.rb +0 -15
  35. data/spec/active_interaction/hash_input_spec.rb +0 -56
  36. data/spec/active_interaction/i18n_spec.rb +0 -111
  37. data/spec/active_interaction/inputs_spec.rb +0 -264
  38. data/spec/active_interaction/integration/array_interaction_spec.rb +0 -87
  39. data/spec/active_interaction/integration/boolean_interaction_spec.rb +0 -11
  40. data/spec/active_interaction/integration/date_interaction_spec.rb +0 -3
  41. data/spec/active_interaction/integration/date_time_interaction_spec.rb +0 -3
  42. data/spec/active_interaction/integration/file_interaction_spec.rb +0 -17
  43. data/spec/active_interaction/integration/float_interaction_spec.rb +0 -3
  44. data/spec/active_interaction/integration/hash_interaction_spec.rb +0 -106
  45. data/spec/active_interaction/integration/integer_interaction_spec.rb +0 -3
  46. data/spec/active_interaction/integration/interface_interaction_spec.rb +0 -18
  47. data/spec/active_interaction/integration/object_interaction_spec.rb +0 -12
  48. data/spec/active_interaction/integration/record_integration_spec.rb +0 -3
  49. data/spec/active_interaction/integration/string_interaction_spec.rb +0 -3
  50. data/spec/active_interaction/integration/symbol_interaction_spec.rb +0 -3
  51. data/spec/active_interaction/integration/time_interaction_spec.rb +0 -86
  52. data/spec/active_interaction/modules/validation_spec.rb +0 -55
  53. data/spec/spec_helper.rb +0 -22
  54. data/spec/support/concerns.rb +0 -13
  55. data/spec/support/filters.rb +0 -227
  56. data/spec/support/interactions.rb +0 -124
@@ -1,204 +0,0 @@
1
- class RecordThing
2
- def self.find(_)
3
- raise 'error'
4
- end
5
-
6
- def self.finder(_)
7
- @finder ||= new
8
- end
9
-
10
- def self.finds_nil(_)
11
- nil
12
- end
13
-
14
- def self.finds_bad_value(_)
15
- Object.new
16
- end
17
- end
18
-
19
- class RecordThings; end # rubocop:disable Lint/EmptyClass
20
- BackupRecordThing = RecordThing
21
-
22
- RSpec.describe ActiveInteraction::RecordFilter, :filter do
23
- include_context 'filters'
24
- before do
25
- options[:class] = RecordThing
26
- end
27
-
28
- it_behaves_like 'a filter'
29
-
30
- describe '#process' do
31
- let(:value) { RecordThing.new }
32
- let(:result) { filter.process(value, nil) }
33
-
34
- context 'with an instance of the class' do
35
- it 'returns the instance' do
36
- expect(result.value).to eql value
37
- end
38
-
39
- context 'with an instance that is a subclass' do
40
- let(:subclass) { Class.new(RecordThing) }
41
- let(:value) { subclass.new }
42
-
43
- it 'returns the instance' do
44
- expect(result.value).to eql value
45
- end
46
- end
47
-
48
- it 'handles reconstantizing' do
49
- expect(result.value).to eql value
50
-
51
- Object.send(:remove_const, :RecordThing)
52
- RecordThing = BackupRecordThing # rubocop:disable Lint/ConstantDefinitionInBlock
53
- value = RecordThing.new
54
-
55
- expect(filter.process(value, nil).value).to eql value
56
- end
57
-
58
- it 'handles reconstantizing subclasses' do
59
- filter
60
-
61
- Object.send(:remove_const, :RecordThing)
62
- RecordThing = BackupRecordThing # rubocop:disable Lint/ConstantDefinitionInBlock
63
- class SubRecordThing < RecordThing; end # rubocop:disable Lint/ConstantDefinitionInBlock
64
- value = SubRecordThing.new
65
-
66
- expect(filter.process(value, nil).value).to eql value
67
- end
68
-
69
- context 'without the class available' do
70
- before { Object.send(:remove_const, :RecordThing) }
71
-
72
- after { RecordThing = BackupRecordThing } # rubocop:disable Lint/ConstantDefinitionInBlock
73
-
74
- it 'does not raise an error on initialization' do
75
- expect { filter }.to_not raise_error
76
- end
77
- end
78
- end
79
-
80
- context 'with class as a superclass' do
81
- before do
82
- options[:class] = RecordThing.superclass
83
- end
84
-
85
- it 'returns the instance' do
86
- expect(result.value).to eql value
87
- end
88
- end
89
-
90
- context 'with class as a String' do
91
- before do
92
- options[:class] = RecordThing.name
93
- end
94
-
95
- it 'returns the instance' do
96
- expect(result.value).to eql value
97
- end
98
- end
99
-
100
- context 'with a plural class' do
101
- let(:value) { RecordThings.new }
102
-
103
- before { options[:class] = RecordThings }
104
-
105
- it 'returns the instance' do
106
- expect(result.value).to eql value
107
- end
108
- end
109
-
110
- context 'with class as an invalid String' do
111
- before do
112
- options[:class] = 'invalid'
113
- end
114
-
115
- it 'raises an error' do
116
- expect do
117
- result
118
- end.to raise_error ActiveInteraction::InvalidNameError
119
- end
120
- end
121
-
122
- context 'with a value that does not match the class' do
123
- let(:value) { 1 }
124
-
125
- it 'calls the default finder' do
126
- allow(RecordThing).to receive(:find)
127
- result
128
- expect(RecordThing).to have_received(:find).with(value)
129
- end
130
-
131
- context 'with a custom finder' do
132
- before do
133
- options[:finder] = :finder
134
- end
135
-
136
- it 'calls the custom finder' do
137
- allow(RecordThing).to receive(:finder)
138
- result
139
- expect(RecordThing).to have_received(:finder).with(value)
140
- end
141
- end
142
-
143
- context 'that returns a nil' do
144
- let(:value) { 1 }
145
-
146
- before do
147
- options[:default] = RecordThing.new
148
- options[:finder] = :finds_nil
149
- end
150
-
151
- it 'indicates an error' do
152
- error = filter.process(value, nil).errors.first
153
-
154
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
155
- expect(error.type).to be :invalid_type
156
- end
157
- end
158
-
159
- context 'that returns an invalid value' do
160
- let(:value) { 1 }
161
-
162
- before do
163
- options[:finder] = :finds_bad_value
164
- end
165
-
166
- it 'indicates an error' do
167
- error = filter.process(value, nil).errors.first
168
-
169
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
170
- expect(error.type).to be :invalid_type
171
- end
172
- end
173
- end
174
-
175
- context 'with a blank String' do
176
- let(:value) { ' ' }
177
-
178
- context 'optional' do
179
- include_context 'optional'
180
-
181
- it 'returns the default' do
182
- expect(filter.process(value, nil).value).to eql options[:default]
183
- end
184
- end
185
-
186
- context 'required' do
187
- include_context 'required'
188
-
189
- it 'indicates an error' do
190
- error = filter.process(value, nil).errors.first
191
-
192
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
193
- expect(error.type).to be :missing
194
- end
195
- end
196
- end
197
- end
198
-
199
- describe '#database_column_type' do
200
- it 'returns :string' do
201
- expect(filter.database_column_type).to be :string
202
- end
203
- end
204
- end
@@ -1,58 +0,0 @@
1
- RSpec.describe ActiveInteraction::StringFilter, :filter do
2
- include_context 'filters'
3
- it_behaves_like 'a filter'
4
-
5
- shared_context 'without strip' do
6
- before do
7
- options[:strip] = false
8
- end
9
- end
10
-
11
- describe '#process' do
12
- let(:result) { filter.process(value, nil) }
13
-
14
- context 'with a String' do
15
- let(:value) { SecureRandom.hex }
16
-
17
- it 'returns the String' do
18
- expect(result.value).to eql value
19
- end
20
- end
21
-
22
- context 'with an implicit String' do
23
- let(:value) do
24
- Class.new do
25
- def to_str
26
- @to_str ||= SecureRandom.hex
27
- end
28
- end.new
29
- end
30
-
31
- it 'returns the String' do
32
- expect(result.value).to eql value.to_str
33
- end
34
- end
35
-
36
- context 'with a strippable String' do
37
- let(:value) { " #{SecureRandom.hex} " }
38
-
39
- it 'returns the stripped string' do
40
- expect(result.value).to eql value.strip
41
- end
42
-
43
- context 'without strip' do
44
- include_context 'without strip'
45
-
46
- it 'returns the String' do
47
- expect(result.value).to eql value
48
- end
49
- end
50
- end
51
- end
52
-
53
- describe '#database_column_type' do
54
- it 'returns :string' do
55
- expect(filter.database_column_type).to be :string
56
- end
57
- end
58
- end
@@ -1,44 +0,0 @@
1
- RSpec.describe ActiveInteraction::SymbolFilter, :filter do
2
- include_context 'filters'
3
- it_behaves_like 'a filter'
4
-
5
- describe '#process' do
6
- let(:result) { filter.process(value, nil) }
7
-
8
- context 'with a Symbol' do
9
- let(:value) { SecureRandom.hex.to_sym }
10
-
11
- it 'returns the Symbol' do
12
- expect(result.value).to eql value
13
- end
14
- end
15
-
16
- context 'with an implicit Symbol' do
17
- let(:value) do
18
- Class.new do
19
- def to_sym
20
- :symbol
21
- end
22
- end.new
23
- end
24
-
25
- it 'returns a symbol' do
26
- expect(result.value).to eql value.to_sym
27
- end
28
- end
29
-
30
- context 'with a String' do
31
- let(:value) { SecureRandom.hex }
32
-
33
- it 'returns a Symbol' do
34
- expect(result.value).to eql value.to_sym
35
- end
36
- end
37
- end
38
-
39
- describe '#database_column_type' do
40
- it 'returns :string' do
41
- expect(filter.database_column_type).to be :string
42
- end
43
- end
44
- end
@@ -1,249 +0,0 @@
1
- RSpec.describe ActiveInteraction::TimeFilter, :filter do
2
- include_context 'filters'
3
- it_behaves_like 'a filter'
4
-
5
- shared_context 'with format' do
6
- let(:format) { '%d/%m/%Y %H:%M:%S %z' }
7
-
8
- before do
9
- options[:format] = format
10
- end
11
- end
12
-
13
- describe '#initialize' do
14
- context 'with a format' do
15
- before { options[:format] = '%T' }
16
-
17
- context 'with a time zone' do
18
- before do
19
- time_with_zone = double
20
-
21
- time_zone = double
22
- allow(time_zone).to receive(:at).and_return(time_with_zone)
23
-
24
- allow(Time).to receive(:zone).and_return(time_zone)
25
- end
26
-
27
- it 'raises an error' do
28
- expect do
29
- filter
30
- end.to raise_error(ActiveInteraction::InvalidFilterError)
31
- end
32
- end
33
- end
34
- end
35
-
36
- describe '#process' do
37
- let(:result) { filter.process(value, nil) }
38
-
39
- context 'with a Time' do
40
- let(:value) { Time.new }
41
-
42
- it 'returns the Time' do
43
- expect(result.value).to eql value
44
- end
45
- end
46
-
47
- context 'with a String' do
48
- let(:value) { '2011-12-13 14:15:16 +1718' }
49
-
50
- it 'returns a Time' do
51
- expect(result.value).to eql Time.parse(value)
52
- end
53
-
54
- context 'with a time zone' do
55
- before do
56
- klass = double
57
- allow(klass).to receive(:parse).with(value).and_return(nil)
58
-
59
- allow(filter).to receive(:matches?).and_return(false)
60
- allow(filter).to receive(:klass).and_return(klass)
61
- end
62
-
63
- it 'indicates an error the string is not parsable' do
64
- error = result.errors.first
65
-
66
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
67
- expect(error.type).to be :invalid_type
68
- end
69
- end
70
-
71
- context 'with format' do
72
- include_context 'with format'
73
-
74
- let(:value) { '13/12/2011 14:15:16 +1718' }
75
-
76
- it 'returns a Time' do
77
- expect(result.value).to eql Time.strptime(value, format)
78
- end
79
- end
80
- end
81
-
82
- context 'with an invalid String' do
83
- let(:value) { 'invalid' }
84
-
85
- it 'indicates an error' do
86
- error = result.errors.first
87
-
88
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
89
- expect(error.type).to be :invalid_type
90
- end
91
-
92
- context 'with format' do
93
- include_context 'with format'
94
-
95
- it 'indicates an error' do
96
- error = result.errors.first
97
-
98
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
99
- expect(error.type).to be :invalid_type
100
- end
101
- end
102
- end
103
-
104
- context 'with an implicit String' do
105
- let(:value) do
106
- Class.new do
107
- def to_str
108
- '2011-12-13 14:15:16 +1718'
109
- end
110
- end.new
111
- end
112
-
113
- it 'returns a Time' do
114
- expect(result.value).to eql Time.parse(value)
115
- end
116
- end
117
-
118
- context 'with a blank String' do
119
- let(:value) do
120
- Class.new do
121
- def to_str
122
- ' '
123
- end
124
- end.new
125
- end
126
-
127
- context 'optional' do
128
- include_context 'optional'
129
-
130
- it 'returns the default' do
131
- expect(result.value).to eql options[:default]
132
- end
133
- end
134
-
135
- context 'required' do
136
- include_context 'required'
137
-
138
- it 'indicates an error' do
139
- error = result.errors.first
140
-
141
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
142
- expect(error.type).to be :missing
143
- end
144
- end
145
- end
146
-
147
- context 'with an Integer' do
148
- let(:value) { rand(1 << 16) }
149
-
150
- it 'returns the Time' do
151
- expect(result.value).to eql Time.at(value)
152
- end
153
- end
154
-
155
- context 'with an implicit Integer' do
156
- let(:value) do
157
- Class.new do
158
- def to_int
159
- @to_int ||= rand(1 << 16)
160
- end
161
- end.new
162
- end
163
-
164
- it 'returns the Time' do
165
- expect(result.value).to eql Time.at(value)
166
- end
167
- end
168
-
169
- context 'with a GroupedInput' do
170
- let(:year) { 2012 }
171
- let(:month) { 1 }
172
- let(:day) { 2 }
173
- let(:hour) { 3 }
174
- let(:min) { 4 }
175
- let(:sec) { 5 }
176
- let(:value) do
177
- ActiveInteraction::GroupedInput.new(
178
- '1' => year.to_s,
179
- '2' => month.to_s,
180
- '3' => day.to_s,
181
- '4' => hour.to_s,
182
- '5' => min.to_s,
183
- '6' => sec.to_s
184
- )
185
- end
186
-
187
- it 'returns a Time' do
188
- expect(
189
- result.value
190
- ).to eql Time.new(year, month, day, hour, min, sec)
191
- end
192
- end
193
-
194
- context 'with an invalid GroupedInput' do
195
- context 'empty' do
196
- let(:value) { ActiveInteraction::GroupedInput.new }
197
-
198
- it 'indicates an error' do
199
- error = result.errors.first
200
-
201
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
202
- expect(error.type).to be :invalid_type
203
- end
204
- end
205
-
206
- context 'partial inputs' do
207
- let(:value) do
208
- ActiveInteraction::GroupedInput.new(
209
- '2' => '1'
210
- )
211
- end
212
-
213
- it 'indicates an error' do
214
- error = result.errors.first
215
-
216
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
217
- expect(error.type).to be :invalid_type
218
- end
219
- end
220
- end
221
- end
222
-
223
- describe '#database_column_type' do
224
- it 'returns :datetime' do
225
- expect(filter.database_column_type).to be :datetime
226
- end
227
- end
228
-
229
- describe '#default' do
230
- context 'with a GroupedInput' do
231
- before do
232
- options[:default] = ActiveInteraction::GroupedInput.new(
233
- '1' => '2012',
234
- '2' => '1',
235
- '3' => '2',
236
- '4' => '3',
237
- '5' => '4',
238
- '6' => '5'
239
- )
240
- end
241
-
242
- it 'raises an error' do
243
- expect do
244
- filter.default(nil)
245
- end.to raise_error ActiveInteraction::InvalidDefaultError
246
- end
247
- end
248
- end
249
- end
@@ -1,15 +0,0 @@
1
- RSpec.describe ActiveInteraction::GroupedInput do
2
- subject(:grouped_input) { described_class.new }
3
-
4
- it 'subclasses OpenStruct' do
5
- expect(grouped_input).to be_an OpenStruct
6
- end
7
-
8
- it 'responds to #[]' do
9
- expect { grouped_input[:key] }.to_not raise_error
10
- end
11
-
12
- it 'responds to #[]=' do
13
- expect { grouped_input[:key] = :value }.to_not raise_error
14
- end
15
- end
@@ -1,56 +0,0 @@
1
- RSpec.describe ActiveInteraction::HashInput do
2
- subject(:input) do
3
- described_class.new(filter,
4
- value: value,
5
- error: error,
6
- children: children
7
- )
8
- end
9
-
10
- let(:filter) do
11
- ActiveInteraction::HashFilter.new(:h, &block)
12
- end
13
- let(:block) { proc { integer :i } }
14
- let(:value) { nil }
15
- let(:error) { nil }
16
- let(:children) { {} }
17
-
18
- describe '#errors' do
19
- context 'with no errors' do
20
- it 'returns an empty array' do
21
- expect(input.errors).to be_empty
22
- end
23
- end
24
-
25
- context 'with an error on the hash' do
26
- let(:error) { ActiveInteraction::Filter::Error.new(filter, :invalid_type) }
27
-
28
- it 'returns one error in the array' do
29
- expect(input.errors.size).to be 1
30
-
31
- error = input.errors.first
32
- expect(error.name).to be filter.name
33
- expect(error.type).to be :invalid_type
34
- end
35
- end
36
-
37
- context 'with children with errors' do
38
- let(:child_i) do
39
- filter = ActiveInteraction::IntegerFilter.new(:i)
40
- ActiveInteraction::Input.new(filter,
41
- value: nil,
42
- error: ActiveInteraction::Filter::Error.new(filter, :missing)
43
- )
44
- end
45
- let(:children) { { i: child_i } }
46
-
47
- it 'returns the error' do
48
- expect(input.errors.size).to be 1
49
-
50
- error = input.errors.first
51
- expect(error.name).to be :"#{filter.name}.i"
52
- expect(error.type).to be :missing
53
- end
54
- end
55
- end
56
- end