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,85 +0,0 @@
1
- RSpec.describe ActiveInteraction::Filter::Column do
2
- subject(:column) { described_class.intern(type) }
3
-
4
- let(:type) { :float }
5
-
6
- describe '.intern(type)' do
7
- it 'returns the same object for each type' do
8
- expect(described_class.intern(type)).to equal column
9
- end
10
-
11
- it 'returns different objects for different types' do
12
- expect(described_class.intern(:integer)).to_not equal column
13
- end
14
- end
15
-
16
- describe '.new(type)' do
17
- it 'is private' do
18
- expect { described_class.new(type) }.to raise_error NoMethodError
19
- end
20
- end
21
-
22
- describe '#limit' do
23
- it 'returns nil' do
24
- expect(column.limit).to be_nil
25
- end
26
- end
27
-
28
- describe '#type' do
29
- it 'returns the type' do
30
- expect(column.type).to eql type
31
- end
32
- end
33
-
34
- describe '#number?' do
35
- let(:number?) { column.number? }
36
-
37
- context 'type is' do
38
- context ':integer' do
39
- let(:type) { :integer }
40
-
41
- it 'returns true' do
42
- expect(number?).to be_truthy
43
- end
44
- end
45
-
46
- context ':float' do
47
- let(:type) { :float }
48
-
49
- it 'returns true' do
50
- expect(number?).to be_truthy
51
- end
52
- end
53
-
54
- context 'anything else' do
55
- let(:type) { :string }
56
-
57
- it 'returns false' do
58
- expect(number?).to be_falsey
59
- end
60
- end
61
- end
62
- end
63
-
64
- describe '#text?' do
65
- let(:text?) { column.text? }
66
-
67
- context 'type is' do
68
- context ':string' do
69
- let(:type) { :string }
70
-
71
- it 'returns true' do
72
- expect(text?).to be_truthy
73
- end
74
- end
75
-
76
- context 'anything else' do
77
- let(:type) { :float }
78
-
79
- it 'returns false' do
80
- expect(text?).to be_falsey
81
- end
82
- end
83
- end
84
- end
85
- end
@@ -1,58 +0,0 @@
1
- RSpec.describe ActiveInteraction::Filter, :filter do
2
- include_context 'filters'
3
-
4
- describe '#database_column_type' do
5
- it 'returns `:string`' do
6
- expect(filter.database_column_type).to be :string
7
- end
8
- end
9
-
10
- context 'with an unregistered subclass' do
11
- let(:klass) { Class.new(described_class) }
12
-
13
- describe '.slug' do
14
- it 'is nil' do
15
- expect(klass.slug).to be_nil
16
- end
17
- end
18
- end
19
-
20
- context 'with a registered subclass' do
21
- let(:slug) { SecureRandom.hex.to_sym }
22
- let(:described_class) do
23
- s = slug
24
- Class.new(ActiveInteraction::Filter) do
25
- register s
26
- end
27
- end
28
-
29
- it_behaves_like 'a filter'
30
-
31
- describe '.slug' do
32
- it 'returns the registered slug' do
33
- expect(described_class.slug).to eql slug
34
- end
35
- end
36
- end
37
-
38
- describe '#default' do
39
- subject(:filter) { ActiveInteraction::IntegerFilter.new(:test, default: default) }
40
-
41
- context 'when it is a value' do
42
- let(:default) { 1 }
43
-
44
- it 'returns the default' do
45
- expect(filter.default).to be 1
46
- end
47
- end
48
-
49
- context 'when it is a proc' do
50
- let(:default) { -> { i + 1 } }
51
-
52
- it 'returns the default' do
53
- expect(filter.default(double(i: 0))).to be 1 # rubocop:disable RSpec/VerifiedDoubles
54
- expect(filter.default(double(i: 1))).to be 2 # rubocop:disable RSpec/VerifiedDoubles
55
- end
56
- end
57
- end
58
- end
@@ -1,11 +0,0 @@
1
- RSpec.describe ActiveInteraction::AbstractDateTimeFilter, :filter do
2
- include_context 'filters'
3
-
4
- describe '#process' do
5
- let(:value) { nil }
6
-
7
- it 'raises an error' do
8
- expect { filter.process(value, nil) }.to raise_error NameError
9
- end
10
- end
11
- end
@@ -1,11 +0,0 @@
1
- RSpec.describe ActiveInteraction::AbstractNumericFilter, :filter do
2
- include_context 'filters'
3
-
4
- describe '#process' do
5
- let(:value) { nil }
6
-
7
- it 'raises an error' do
8
- expect { filter.process(value, nil) }.to raise_error NameError
9
- end
10
- end
11
- end
@@ -1,248 +0,0 @@
1
- RSpec.describe ActiveInteraction::ArrayFilter, :filter do
2
- include_context 'filters'
3
- it_behaves_like 'a filter'
4
-
5
- context 'with multiple nested filters' do
6
- let(:block) do
7
- proc do
8
- array
9
- array
10
- end
11
- end
12
-
13
- it 'raises an error' do
14
- expect { filter }.to raise_error ActiveInteraction::InvalidFilterError
15
- end
16
- end
17
-
18
- context 'with a nested name' do
19
- let(:block) { proc { array :a } }
20
-
21
- it 'raises an error' do
22
- expect { filter }.to raise_error ActiveInteraction::InvalidFilterError
23
- end
24
- end
25
-
26
- describe '#process' do
27
- let(:result) { filter.process(value, nil) }
28
-
29
- context 'with an Array' do
30
- let(:value) { [] }
31
-
32
- it 'returns an ArrayInput' do
33
- expect(result).to be_an_instance_of ActiveInteraction::ArrayInput
34
- end
35
-
36
- it 'returns the Array' do
37
- expect(result.value).to eql value
38
- end
39
-
40
- it 'has no children' do
41
- expect(result.children).to eql []
42
- end
43
- end
44
-
45
- context 'with an implicit Array' do
46
- let(:value) do
47
- Class.new do
48
- def to_ary
49
- [1, 2, 3]
50
- end
51
- end.new
52
- end
53
-
54
- it 'returns the Array' do
55
- expect(result.value).to eql value.to_ary
56
- end
57
- end
58
-
59
- context 'with a heterogenous Array' do
60
- let(:value) { [[], false, 0.0, {}, 0, '', :''] }
61
-
62
- it 'returns the Array' do
63
- expect(result.value).to eql value
64
- end
65
- end
66
-
67
- context 'with a nested filter where the value transforms' do
68
- let(:block) { proc { symbol } }
69
- let(:name) { :test }
70
- let(:value) { ['test'] }
71
-
72
- it 'returns the transformed value' do
73
- expect(result.value).to eql [:test]
74
- end
75
-
76
- it 'does not modify the original value' do
77
- expect(result.value.object_id).to_not eql value.object_id
78
- expect(value).to eql ['test']
79
- end
80
- end
81
-
82
- context 'with a nested filter' do
83
- let(:block) { proc { array } }
84
-
85
- context 'with an Array' do
86
- let(:child_value) { [] }
87
- let(:value) { [child_value, child_value] }
88
-
89
- it 'returns the Array' do
90
- expect(result.value).to eql value
91
- end
92
-
93
- it 'has children' do
94
- expect(result.children.size).to be 2
95
- result.children.each do |child|
96
- expect(child).to be_an_instance_of ActiveInteraction::ArrayInput
97
- expect(child.value).to eql child_value
98
- end
99
- end
100
-
101
- context 'given a nil value' do
102
- let(:value) { nil }
103
-
104
- it 'returns an error' do
105
- error = result.errors.first
106
-
107
- expect(result.value).to eql value
108
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
109
- expect(error.type).to be :missing
110
- end
111
- end
112
- end
113
-
114
- context 'with an Array of Arrays' do
115
- let(:value) { [[]] }
116
-
117
- it 'returns the Array' do
118
- expect(result.value).to eql value
119
- end
120
- end
121
-
122
- context 'with a heterogenous Array' do
123
- let(:value) { [[], false, 0.0] }
124
-
125
- it 'indicates an error' do
126
- error = result.errors.first
127
-
128
- expect(result.errors.size).to be 1
129
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
130
- expect(error.name).to be filter.name
131
- expect(error.type).to be :invalid_type
132
- end
133
-
134
- context 'when :index_errors is true' do
135
- before do
136
- options[:index_errors] = true
137
- end
138
-
139
- it 'shows the index of where the error occurred' do
140
- expect(result.errors.size).to be 2
141
-
142
- result.errors.each.with_index(1) do |error, i|
143
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
144
- expect(error.name).to be :"#{filter.name}[#{i}]"
145
- expect(error.type).to be :invalid_type
146
- end
147
- end
148
- end
149
-
150
- context 'when ActiveRecord.index_nested_attribute_errors is true' do
151
- before do
152
- if ActiveRecord.respond_to?(:index_nested_attribute_errors)
153
- allow(ActiveRecord).to receive(:index_nested_attribute_errors).and_return(true)
154
- else
155
- allow(ActiveRecord::Base).to receive(:index_nested_attribute_errors).and_return(true)
156
- end
157
- end
158
-
159
- it 'shows the index of where the error occurred' do
160
- expect(result.errors.size).to be 2
161
-
162
- result.errors.each.with_index(1) do |error, i|
163
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
164
- expect(error.name).to be :"#{filter.name}[#{i}]"
165
- expect(error.type).to be :invalid_type
166
- end
167
- end
168
-
169
- context 'when :index_errors is false' do
170
- before do
171
- options[:index_errors] = false
172
- end
173
-
174
- it 'does not attach the index' do
175
- error = result.errors.first
176
-
177
- expect(result.errors.size).to be 1
178
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
179
- expect(error.name).to be filter.name
180
- expect(error.type).to be :invalid_type
181
- end
182
- end
183
- end
184
- end
185
- end
186
-
187
- [
188
- %i[object class],
189
- %i[record class],
190
- %i[interface from]
191
- ].each do |(type, option)|
192
- context "with a nested #{type} filter" do
193
- let(:block) { proc { public_send(type) } }
194
- let(:name) { :objects }
195
- let(:value) { [''] }
196
-
197
- it 'does not raise an error' do
198
- expect { result }.to_not raise_error
199
- end
200
-
201
- it 'has a filter with the right key' do
202
- expect(filter.filters).to have_key(:'0')
203
- end
204
-
205
- it 'has a filter with the right option' do
206
- expect(filter.filters[:'0'].options).to have_key(option)
207
- end
208
-
209
- context 'with a class set' do
210
- let(:block) { proc { public_send(type, "#{option}": String) } }
211
-
212
- it "does not override the #{option}" do
213
- expect(filter.filters[:'0'].options[option]).to eql String
214
- end
215
- end
216
- end
217
- end
218
-
219
- context 'with a nested interface type' do
220
- context 'with the methods option set' do
221
- let(:block) { proc { public_send(:interface, methods: %i[to_s]) } }
222
-
223
- it 'has a filter with the right option' do
224
- expect(filter.filters[:'0'].options).to have_key(:methods)
225
- expect(filter.filters[:'0'].options[:methods]).to eql %i[to_s]
226
- end
227
- end
228
-
229
- context 'with another option set' do
230
- let(:block) { proc { public_send(:object, converter: :new) } }
231
- let(:name) { :objects }
232
-
233
- it 'has a filter with the right options' do
234
- expect(filter.filters[:'0'].options).to have_key(:class)
235
- expect(filter.filters[:'0'].options[:class]).to be :Object
236
- expect(filter.filters[:'0'].options).to have_key(:converter)
237
- expect(filter.filters[:'0'].options[:converter]).to be :new
238
- end
239
- end
240
- end
241
- end
242
-
243
- describe '#database_column_type' do
244
- it 'returns :string' do
245
- expect(filter.database_column_type).to be :string
246
- end
247
- end
248
- end
@@ -1,85 +0,0 @@
1
- RSpec.describe ActiveInteraction::BooleanFilter, :filter do
2
- include_context 'filters'
3
- it_behaves_like 'a filter'
4
-
5
- describe '#process' do
6
- context 'falsey' do
7
- [false, '0', 'false', 'FALSE', 'off', 'OFF'].each do |value|
8
- it "returns false for #{value.inspect}" do
9
- expect(filter.process(value, nil).value).to be_falsey
10
- end
11
- end
12
-
13
- context 'with an implicit string' do
14
- let(:value) do
15
- Class.new do
16
- def to_str
17
- 'false'
18
- end
19
- end.new
20
- end
21
-
22
- it 'returns false' do
23
- expect(filter.process(value, nil).value).to be_falsey
24
- end
25
- end
26
- end
27
-
28
- context 'truthy' do
29
- [true, '1', 'true', 'TRUE', 'on', 'ON'].each do |value|
30
- it "returns true for #{value.inspect}" do
31
- expect(filter.process(value, nil).value).to be_truthy
32
- end
33
- end
34
-
35
- context 'with an implicit string' do
36
- let(:value) do
37
- Class.new do
38
- def to_str
39
- 'true'
40
- end
41
- end.new
42
- end
43
-
44
- it 'returns true' do
45
- expect(filter.process(value, nil).value).to be_truthy
46
- end
47
- end
48
- end
49
-
50
- context 'with a blank String' do
51
- let(:value) do
52
- Class.new do
53
- def to_str
54
- ' '
55
- end
56
- end.new
57
- end
58
-
59
- context 'optional' do
60
- include_context 'optional'
61
-
62
- it 'returns the default' do
63
- expect(filter.process(value, nil).value).to eql options[:default]
64
- end
65
- end
66
-
67
- context 'required' do
68
- include_context 'required'
69
-
70
- it 'indicates an error' do
71
- error = filter.process(value, nil).errors.first
72
-
73
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
74
- expect(error.type).to be :missing
75
- end
76
- end
77
- end
78
- end
79
-
80
- describe '#database_column_type' do
81
- it 'returns :boolean' do
82
- expect(filter.database_column_type).to be :boolean
83
- end
84
- end
85
- end
@@ -1,176 +0,0 @@
1
- RSpec.describe ActiveInteraction::DateFilter, :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' }
7
-
8
- before do
9
- options[:format] = format
10
- end
11
- end
12
-
13
- describe '#process' do
14
- let(:result) { filter.process(value, nil) }
15
-
16
- context 'with a Date' do
17
- let(:value) { Date.new }
18
-
19
- it 'returns the Date' do
20
- expect(result.value).to eql value
21
- end
22
- end
23
-
24
- context 'with a String' do
25
- let(:value) { '2011-12-13' }
26
-
27
- it 'returns a Date' do
28
- expect(result.value).to eql Date.parse(value)
29
- end
30
-
31
- context 'with format' do
32
- include_context 'with format'
33
-
34
- let(:value) { '13/12/2011' }
35
-
36
- it 'returns a Date' do
37
- expect(result.value).to eql Date.strptime(value, format)
38
- end
39
- end
40
- end
41
-
42
- context 'with an invalid String' do
43
- let(:value) { 'invalid' }
44
-
45
- it 'indicates an error' do
46
- error = result.errors.first
47
-
48
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
49
- expect(error.type).to be :invalid_type
50
- end
51
-
52
- context 'with format' do
53
- include_context 'with format'
54
-
55
- it 'raises 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
- end
63
-
64
- context 'with an implicit String' do
65
- let(:value) do
66
- Class.new do
67
- def to_str
68
- '2011-12-13'
69
- end
70
- end.new
71
- end
72
-
73
- it 'returns a Date' do
74
- expect(result.value).to eql Date.parse(value)
75
- end
76
- end
77
-
78
- context 'with a blank String' do
79
- let(:value) do
80
- Class.new do
81
- def to_str
82
- ' '
83
- end
84
- end.new
85
- end
86
-
87
- context 'optional' do
88
- include_context 'optional'
89
-
90
- it 'returns the default' do
91
- expect(result.value).to eql options[:default]
92
- end
93
- end
94
-
95
- context 'required' do
96
- include_context 'required'
97
-
98
- it 'indicates an error' do
99
- error = result.errors.first
100
-
101
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
102
- expect(error.type).to be :missing
103
- end
104
- end
105
- end
106
-
107
- context 'with a GroupedInput' do
108
- let(:year) { 2012 }
109
- let(:month) { 1 }
110
- let(:day) { 2 }
111
- let(:value) do
112
- ActiveInteraction::GroupedInput.new(
113
- '1' => year.to_s,
114
- '2' => month.to_s,
115
- '3' => day.to_s
116
- )
117
- end
118
-
119
- it 'returns a Date' do
120
- expect(result.value).to eql Date.new(year, month, day)
121
- end
122
- end
123
-
124
- context 'with an invalid GroupedInput' do
125
- context 'empty' do
126
- let(:value) { ActiveInteraction::GroupedInput.new }
127
-
128
- it 'indicates an error' do
129
- error = result.errors.first
130
-
131
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
132
- expect(error.type).to be :invalid_type
133
- end
134
- end
135
-
136
- context 'partial inputs' do
137
- let(:value) do
138
- ActiveInteraction::GroupedInput.new(
139
- '2' => '1'
140
- )
141
- end
142
-
143
- it 'raises an error' do
144
- error = result.errors.first
145
-
146
- expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
147
- expect(error.type).to be :invalid_type
148
- end
149
- end
150
- end
151
- end
152
-
153
- describe '#database_column_type' do
154
- it 'returns :date' do
155
- expect(filter.database_column_type).to be :date
156
- end
157
- end
158
-
159
- describe '#default' do
160
- context 'with a GroupedInput' do
161
- before do
162
- options[:default] = ActiveInteraction::GroupedInput.new(
163
- '1' => '2012',
164
- '2' => '1',
165
- '3' => '2'
166
- )
167
- end
168
-
169
- it 'raises an error' do
170
- expect do
171
- filter.default(nil)
172
- end.to raise_error ActiveInteraction::InvalidDefaultError
173
- end
174
- end
175
- end
176
- end