active_interaction 5.3.0 → 5.4.0

Sign up to get free protection for your applications and to get access to all the features.
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