active_interaction 4.0.5 → 5.0.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +149 -6
- data/README.md +67 -32
- data/lib/active_interaction/array_input.rb +77 -0
- data/lib/active_interaction/base.rb +14 -98
- data/lib/active_interaction/concerns/active_recordable.rb +3 -3
- data/lib/active_interaction/concerns/missable.rb +2 -2
- data/lib/active_interaction/errors.rb +6 -88
- data/lib/active_interaction/exceptions.rb +47 -0
- data/lib/active_interaction/filter/column.rb +59 -0
- data/lib/active_interaction/filter/error.rb +40 -0
- data/lib/active_interaction/filter.rb +44 -53
- data/lib/active_interaction/filters/abstract_date_time_filter.rb +9 -6
- data/lib/active_interaction/filters/abstract_numeric_filter.rb +7 -3
- data/lib/active_interaction/filters/array_filter.rb +36 -10
- data/lib/active_interaction/filters/boolean_filter.rb +4 -3
- data/lib/active_interaction/filters/date_filter.rb +1 -1
- data/lib/active_interaction/filters/date_time_filter.rb +1 -1
- data/lib/active_interaction/filters/decimal_filter.rb +1 -1
- data/lib/active_interaction/filters/float_filter.rb +1 -1
- data/lib/active_interaction/filters/hash_filter.rb +23 -15
- data/lib/active_interaction/filters/integer_filter.rb +1 -1
- data/lib/active_interaction/filters/interface_filter.rb +12 -12
- data/lib/active_interaction/filters/object_filter.rb +9 -3
- data/lib/active_interaction/filters/record_filter.rb +21 -11
- data/lib/active_interaction/filters/string_filter.rb +1 -1
- data/lib/active_interaction/filters/symbol_filter.rb +1 -1
- data/lib/active_interaction/filters/time_filter.rb +4 -4
- data/lib/active_interaction/hash_input.rb +43 -0
- data/lib/active_interaction/input.rb +23 -0
- data/lib/active_interaction/inputs.rb +157 -46
- data/lib/active_interaction/locale/en.yml +0 -1
- data/lib/active_interaction/locale/fr.yml +0 -1
- data/lib/active_interaction/locale/it.yml +0 -1
- data/lib/active_interaction/locale/ja.yml +0 -1
- data/lib/active_interaction/locale/pt-BR.yml +0 -1
- data/lib/active_interaction/modules/validation.rb +6 -17
- data/lib/active_interaction/version.rb +1 -1
- data/lib/active_interaction.rb +43 -36
- data/spec/active_interaction/array_input_spec.rb +166 -0
- data/spec/active_interaction/base_spec.rb +15 -240
- data/spec/active_interaction/concerns/active_modelable_spec.rb +3 -3
- data/spec/active_interaction/concerns/active_recordable_spec.rb +7 -7
- data/spec/active_interaction/concerns/hashable_spec.rb +8 -8
- data/spec/active_interaction/concerns/missable_spec.rb +9 -9
- data/spec/active_interaction/concerns/runnable_spec.rb +34 -32
- data/spec/active_interaction/errors_spec.rb +60 -43
- data/spec/active_interaction/{filter_column_spec.rb → filter/column_spec.rb} +3 -10
- data/spec/active_interaction/filter_spec.rb +6 -6
- data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +2 -2
- data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +2 -2
- data/spec/active_interaction/filters/array_filter_spec.rb +99 -24
- data/spec/active_interaction/filters/boolean_filter_spec.rb +12 -11
- data/spec/active_interaction/filters/date_filter_spec.rb +32 -27
- data/spec/active_interaction/filters/date_time_filter_spec.rb +34 -29
- data/spec/active_interaction/filters/decimal_filter_spec.rb +20 -18
- data/spec/active_interaction/filters/file_filter_spec.rb +7 -7
- data/spec/active_interaction/filters/float_filter_spec.rb +19 -17
- data/spec/active_interaction/filters/hash_filter_spec.rb +16 -18
- data/spec/active_interaction/filters/integer_filter_spec.rb +24 -22
- data/spec/active_interaction/filters/interface_filter_spec.rb +105 -82
- data/spec/active_interaction/filters/object_filter_spec.rb +52 -36
- data/spec/active_interaction/filters/record_filter_spec.rb +61 -39
- data/spec/active_interaction/filters/string_filter_spec.rb +7 -7
- data/spec/active_interaction/filters/symbol_filter_spec.rb +6 -6
- data/spec/active_interaction/filters/time_filter_spec.rb +57 -34
- data/spec/active_interaction/hash_input_spec.rb +58 -0
- data/spec/active_interaction/i18n_spec.rb +22 -17
- data/spec/active_interaction/inputs_spec.rb +167 -23
- data/spec/active_interaction/integration/array_interaction_spec.rb +3 -7
- data/spec/active_interaction/modules/validation_spec.rb +8 -31
- data/spec/spec_helper.rb +8 -0
- data/spec/support/concerns.rb +2 -2
- data/spec/support/filters.rb +27 -51
- data/spec/support/interactions.rb +4 -4
- metadata +45 -95
- data/lib/active_interaction/filter_column.rb +0 -57
@@ -14,11 +14,7 @@ class RecordThing
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def self.finds_bad_value(_)
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.passthrough(obj)
|
21
|
-
obj
|
17
|
+
Object.new
|
22
18
|
end
|
23
19
|
end
|
24
20
|
|
@@ -27,23 +23,19 @@ BackupRecordThing = RecordThing
|
|
27
23
|
|
28
24
|
describe ActiveInteraction::RecordFilter, :filter do
|
29
25
|
include_context 'filters'
|
30
|
-
it_behaves_like 'a filter'
|
31
|
-
|
32
26
|
before do
|
33
27
|
options[:class] = RecordThing
|
34
28
|
end
|
35
29
|
|
36
|
-
|
37
|
-
before do
|
38
|
-
options[:finder] = :finder
|
39
|
-
end
|
30
|
+
it_behaves_like 'a filter'
|
40
31
|
|
32
|
+
describe '#process' do
|
41
33
|
let(:value) { RecordThing.new }
|
42
|
-
let(:result) { filter.
|
34
|
+
let(:result) { filter.process(value, nil) }
|
43
35
|
|
44
36
|
context 'with an instance of the class' do
|
45
37
|
it 'returns the instance' do
|
46
|
-
expect(result).to eql value
|
38
|
+
expect(result.value).to eql value
|
47
39
|
end
|
48
40
|
|
49
41
|
context 'with an instance that is a subclass' do
|
@@ -51,18 +43,18 @@ describe ActiveInteraction::RecordFilter, :filter do
|
|
51
43
|
let(:value) { subclass.new }
|
52
44
|
|
53
45
|
it 'returns the instance' do
|
54
|
-
expect(result).to eql value
|
46
|
+
expect(result.value).to eql value
|
55
47
|
end
|
56
48
|
end
|
57
49
|
|
58
50
|
it 'handles reconstantizing' do
|
59
|
-
expect(result).to eql value
|
51
|
+
expect(result.value).to eql value
|
60
52
|
|
61
53
|
Object.send(:remove_const, :RecordThing)
|
62
54
|
RecordThing = BackupRecordThing # rubocop:disable Lint/ConstantDefinitionInBlock
|
63
55
|
value = RecordThing.new
|
64
56
|
|
65
|
-
expect(filter.
|
57
|
+
expect(filter.process(value, nil).value).to eql value
|
66
58
|
end
|
67
59
|
|
68
60
|
it 'handles reconstantizing subclasses' do
|
@@ -73,11 +65,12 @@ describe ActiveInteraction::RecordFilter, :filter do
|
|
73
65
|
class SubRecordThing < RecordThing; end # rubocop:disable Lint/ConstantDefinitionInBlock
|
74
66
|
value = SubRecordThing.new
|
75
67
|
|
76
|
-
expect(filter.
|
68
|
+
expect(filter.process(value, nil).value).to eql value
|
77
69
|
end
|
78
70
|
|
79
71
|
context 'without the class available' do
|
80
72
|
before { Object.send(:remove_const, :RecordThing) }
|
73
|
+
|
81
74
|
after { RecordThing = BackupRecordThing } # rubocop:disable Lint/ConstantDefinitionInBlock
|
82
75
|
|
83
76
|
it 'does not raise an error on initialization' do
|
@@ -92,7 +85,7 @@ describe ActiveInteraction::RecordFilter, :filter do
|
|
92
85
|
end
|
93
86
|
|
94
87
|
it 'returns the instance' do
|
95
|
-
expect(result).to eql value
|
88
|
+
expect(result.value).to eql value
|
96
89
|
end
|
97
90
|
end
|
98
91
|
|
@@ -102,7 +95,7 @@ describe ActiveInteraction::RecordFilter, :filter do
|
|
102
95
|
end
|
103
96
|
|
104
97
|
it 'returns the instance' do
|
105
|
-
expect(result).to eql value
|
98
|
+
expect(result.value).to eql value
|
106
99
|
end
|
107
100
|
end
|
108
101
|
|
@@ -112,7 +105,7 @@ describe ActiveInteraction::RecordFilter, :filter do
|
|
112
105
|
before { options[:class] = RecordThings }
|
113
106
|
|
114
107
|
it 'returns the instance' do
|
115
|
-
expect(result).to eql value
|
108
|
+
expect(result.value).to eql value
|
116
109
|
end
|
117
110
|
end
|
118
111
|
|
@@ -129,48 +122,77 @@ describe ActiveInteraction::RecordFilter, :filter do
|
|
129
122
|
end
|
130
123
|
|
131
124
|
context 'with a value that does not match the class' do
|
132
|
-
let(:value) {
|
125
|
+
let(:value) { 1 }
|
133
126
|
|
134
|
-
it 'calls the finder' do
|
135
|
-
|
127
|
+
it 'calls the default finder' do
|
128
|
+
allow(RecordThing).to receive(:find)
|
129
|
+
result
|
130
|
+
expect(RecordThing).to have_received(:find).with(value)
|
136
131
|
end
|
137
132
|
|
138
133
|
context 'with a custom finder' do
|
134
|
+
before do
|
135
|
+
options[:finder] = :finder
|
136
|
+
end
|
137
|
+
|
139
138
|
it 'calls the custom finder' do
|
140
|
-
|
139
|
+
allow(RecordThing).to receive(:finder)
|
140
|
+
result
|
141
|
+
expect(RecordThing).to have_received(:finder).with(value)
|
141
142
|
end
|
142
143
|
end
|
143
|
-
end
|
144
|
-
end
|
145
144
|
|
146
|
-
describe '#clean' do
|
147
|
-
context 'with a value that does not match the class' do
|
148
145
|
context 'that returns a nil' do
|
149
|
-
let(:value) {
|
146
|
+
let(:value) { 1 }
|
150
147
|
|
151
148
|
before do
|
152
149
|
options[:default] = RecordThing.new
|
153
150
|
options[:finder] = :finds_nil
|
154
151
|
end
|
155
152
|
|
156
|
-
it '
|
157
|
-
|
158
|
-
|
159
|
-
|
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
|
160
158
|
end
|
161
159
|
end
|
162
160
|
|
163
161
|
context 'that returns an invalid value' do
|
164
|
-
let(:value) {
|
162
|
+
let(:value) { 1 }
|
165
163
|
|
166
164
|
before do
|
167
165
|
options[:finder] = :finds_bad_value
|
168
166
|
end
|
169
167
|
|
170
|
-
it '
|
171
|
-
|
172
|
-
|
173
|
-
|
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
|
174
196
|
end
|
175
197
|
end
|
176
198
|
end
|
@@ -178,7 +200,7 @@ describe ActiveInteraction::RecordFilter, :filter do
|
|
178
200
|
|
179
201
|
describe '#database_column_type' do
|
180
202
|
it 'returns :string' do
|
181
|
-
expect(filter.database_column_type).to
|
203
|
+
expect(filter.database_column_type).to be :string
|
182
204
|
end
|
183
205
|
end
|
184
206
|
end
|
@@ -10,14 +10,14 @@ describe ActiveInteraction::StringFilter, :filter do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
describe '#
|
14
|
-
let(:result) { filter.
|
13
|
+
describe '#process' do
|
14
|
+
let(:result) { filter.process(value, nil) }
|
15
15
|
|
16
16
|
context 'with a String' do
|
17
17
|
let(:value) { SecureRandom.hex }
|
18
18
|
|
19
19
|
it 'returns the String' do
|
20
|
-
expect(result).to eql value
|
20
|
+
expect(result.value).to eql value
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
@@ -31,7 +31,7 @@ describe ActiveInteraction::StringFilter, :filter do
|
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'returns the String' do
|
34
|
-
expect(result).to eql value.to_str
|
34
|
+
expect(result.value).to eql value.to_str
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -39,14 +39,14 @@ describe ActiveInteraction::StringFilter, :filter do
|
|
39
39
|
let(:value) { " #{SecureRandom.hex} " }
|
40
40
|
|
41
41
|
it 'returns the stripped string' do
|
42
|
-
expect(result).to eql value.strip
|
42
|
+
expect(result.value).to eql value.strip
|
43
43
|
end
|
44
44
|
|
45
45
|
context 'without strip' do
|
46
46
|
include_context 'without strip'
|
47
47
|
|
48
48
|
it 'returns the String' do
|
49
|
-
expect(result).to eql value
|
49
|
+
expect(result.value).to eql value
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -54,7 +54,7 @@ describe ActiveInteraction::StringFilter, :filter do
|
|
54
54
|
|
55
55
|
describe '#database_column_type' do
|
56
56
|
it 'returns :string' do
|
57
|
-
expect(filter.database_column_type).to
|
57
|
+
expect(filter.database_column_type).to be :string
|
58
58
|
end
|
59
59
|
end
|
60
60
|
end
|
@@ -4,14 +4,14 @@ describe ActiveInteraction::SymbolFilter, :filter do
|
|
4
4
|
include_context 'filters'
|
5
5
|
it_behaves_like 'a filter'
|
6
6
|
|
7
|
-
describe '#
|
8
|
-
let(:result) { filter.
|
7
|
+
describe '#process' do
|
8
|
+
let(:result) { filter.process(value, nil) }
|
9
9
|
|
10
10
|
context 'with a Symbol' do
|
11
11
|
let(:value) { SecureRandom.hex.to_sym }
|
12
12
|
|
13
13
|
it 'returns the Symbol' do
|
14
|
-
expect(result).to eql value
|
14
|
+
expect(result.value).to eql value
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
@@ -25,7 +25,7 @@ describe ActiveInteraction::SymbolFilter, :filter do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'returns a symbol' do
|
28
|
-
expect(result).to eql value.to_sym
|
28
|
+
expect(result.value).to eql value.to_sym
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -33,14 +33,14 @@ describe ActiveInteraction::SymbolFilter, :filter do
|
|
33
33
|
let(:value) { SecureRandom.hex }
|
34
34
|
|
35
35
|
it 'returns a Symbol' do
|
36
|
-
expect(result).to eql value.to_sym
|
36
|
+
expect(result.value).to eql value.to_sym
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
describe '#database_column_type' do
|
42
42
|
it 'returns :string' do
|
43
|
-
expect(filter.database_column_type).to
|
43
|
+
expect(filter.database_column_type).to be :string
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -18,11 +18,12 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
18
18
|
|
19
19
|
context 'with a time zone' do
|
20
20
|
before do
|
21
|
-
time_zone = double
|
22
|
-
allow(Time).to receive(:zone).and_return(time_zone)
|
23
|
-
|
24
21
|
time_with_zone = double
|
22
|
+
|
23
|
+
time_zone = double
|
25
24
|
allow(time_zone).to receive(:at).and_return(time_with_zone)
|
25
|
+
|
26
|
+
allow(Time).to receive(:zone).and_return(time_zone)
|
26
27
|
end
|
27
28
|
|
28
29
|
it 'raises an error' do
|
@@ -34,14 +35,14 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
37
|
-
describe '#
|
38
|
-
let(:result) { filter.
|
38
|
+
describe '#process' do
|
39
|
+
let(:result) { filter.process(value, nil) }
|
39
40
|
|
40
41
|
context 'with a Time' do
|
41
42
|
let(:value) { Time.new }
|
42
43
|
|
43
44
|
it 'returns the Time' do
|
44
|
-
expect(result).to eql value
|
45
|
+
expect(result.value).to eql value
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|
@@ -49,7 +50,24 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
49
50
|
let(:value) { '2011-12-13 14:15:16 +1718' }
|
50
51
|
|
51
52
|
it 'returns a Time' do
|
52
|
-
expect(result).to eql Time.parse(value)
|
53
|
+
expect(result.value).to eql Time.parse(value)
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with a time zone' do
|
57
|
+
before do
|
58
|
+
klass = double
|
59
|
+
allow(klass).to receive(:parse).with(value).and_return(nil)
|
60
|
+
|
61
|
+
allow(filter).to receive(:matches?).and_return(false)
|
62
|
+
allow(filter).to receive(:klass).and_return(klass)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'indicates an error the string is not parsable' do
|
66
|
+
error = result.errors.first
|
67
|
+
|
68
|
+
expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
|
69
|
+
expect(error.type).to be :invalid_type
|
70
|
+
end
|
53
71
|
end
|
54
72
|
|
55
73
|
context 'with format' do
|
@@ -58,7 +76,7 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
58
76
|
let(:value) { '13/12/2011 14:15:16 +1718' }
|
59
77
|
|
60
78
|
it 'returns a Time' do
|
61
|
-
expect(result).to eql Time.strptime(value, format)
|
79
|
+
expect(result.value).to eql Time.strptime(value, format)
|
62
80
|
end
|
63
81
|
end
|
64
82
|
end
|
@@ -66,19 +84,21 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
66
84
|
context 'with an invalid String' do
|
67
85
|
let(:value) { 'invalid' }
|
68
86
|
|
69
|
-
it '
|
70
|
-
|
71
|
-
|
72
|
-
|
87
|
+
it 'indicates an error' do
|
88
|
+
error = result.errors.first
|
89
|
+
|
90
|
+
expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
|
91
|
+
expect(error.type).to be :invalid_type
|
73
92
|
end
|
74
93
|
|
75
94
|
context 'with format' do
|
76
95
|
include_context 'with format'
|
77
96
|
|
78
|
-
it do
|
79
|
-
|
80
|
-
|
81
|
-
|
97
|
+
it 'indicates an error' do
|
98
|
+
error = result.errors.first
|
99
|
+
|
100
|
+
expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
|
101
|
+
expect(error.type).to be :invalid_type
|
82
102
|
end
|
83
103
|
end
|
84
104
|
end
|
@@ -93,7 +113,7 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
93
113
|
end
|
94
114
|
|
95
115
|
it 'returns a Time' do
|
96
|
-
expect(result).to eql Time.parse(value)
|
116
|
+
expect(result.value).to eql Time.parse(value)
|
97
117
|
end
|
98
118
|
end
|
99
119
|
|
@@ -110,17 +130,18 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
110
130
|
include_context 'optional'
|
111
131
|
|
112
132
|
it 'returns the default' do
|
113
|
-
expect(result).to eql options[:default]
|
133
|
+
expect(result.value).to eql options[:default]
|
114
134
|
end
|
115
135
|
end
|
116
136
|
|
117
137
|
context 'required' do
|
118
138
|
include_context 'required'
|
119
139
|
|
120
|
-
it '
|
121
|
-
|
122
|
-
|
123
|
-
|
140
|
+
it 'indicates an error' do
|
141
|
+
error = result.errors.first
|
142
|
+
|
143
|
+
expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
|
144
|
+
expect(error.type).to be :missing
|
124
145
|
end
|
125
146
|
end
|
126
147
|
end
|
@@ -129,7 +150,7 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
129
150
|
let(:value) { rand(1 << 16) }
|
130
151
|
|
131
152
|
it 'returns the Time' do
|
132
|
-
expect(result).to eql Time.at(value)
|
153
|
+
expect(result.value).to eql Time.at(value)
|
133
154
|
end
|
134
155
|
end
|
135
156
|
|
@@ -143,7 +164,7 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
143
164
|
end
|
144
165
|
|
145
166
|
it 'returns the Time' do
|
146
|
-
expect(result).to eql Time.at(value)
|
167
|
+
expect(result.value).to eql Time.at(value)
|
147
168
|
end
|
148
169
|
end
|
149
170
|
|
@@ -167,7 +188,7 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
167
188
|
|
168
189
|
it 'returns a Time' do
|
169
190
|
expect(
|
170
|
-
result
|
191
|
+
result.value
|
171
192
|
).to eql Time.new(year, month, day, hour, min, sec)
|
172
193
|
end
|
173
194
|
end
|
@@ -176,10 +197,11 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
176
197
|
context 'empty' do
|
177
198
|
let(:value) { ActiveInteraction::GroupedInput.new }
|
178
199
|
|
179
|
-
it '
|
180
|
-
|
181
|
-
|
182
|
-
|
200
|
+
it 'indicates an error' do
|
201
|
+
error = result.errors.first
|
202
|
+
|
203
|
+
expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
|
204
|
+
expect(error.type).to be :invalid_type
|
183
205
|
end
|
184
206
|
end
|
185
207
|
|
@@ -190,10 +212,11 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
190
212
|
)
|
191
213
|
end
|
192
214
|
|
193
|
-
it '
|
194
|
-
|
195
|
-
|
196
|
-
|
215
|
+
it 'indicates an error' do
|
216
|
+
error = result.errors.first
|
217
|
+
|
218
|
+
expect(error).to be_an_instance_of ActiveInteraction::Filter::Error
|
219
|
+
expect(error.type).to be :invalid_type
|
197
220
|
end
|
198
221
|
end
|
199
222
|
end
|
@@ -201,7 +224,7 @@ describe ActiveInteraction::TimeFilter, :filter do
|
|
201
224
|
|
202
225
|
describe '#database_column_type' do
|
203
226
|
it 'returns :datetime' do
|
204
|
-
expect(filter.database_column_type).to
|
227
|
+
expect(filter.database_column_type).to be :datetime
|
205
228
|
end
|
206
229
|
end
|
207
230
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveInteraction::HashInput do
|
4
|
+
subject(:input) do
|
5
|
+
described_class.new(filter,
|
6
|
+
value: value,
|
7
|
+
error: error,
|
8
|
+
children: children
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:filter) do
|
13
|
+
ActiveInteraction::HashFilter.new(:h, &block)
|
14
|
+
end
|
15
|
+
let(:block) { proc { integer :i } }
|
16
|
+
let(:value) { nil }
|
17
|
+
let(:error) { nil }
|
18
|
+
let(:children) { {} }
|
19
|
+
|
20
|
+
describe '#errors' do
|
21
|
+
context 'with no errors' do
|
22
|
+
it 'returns an empty array' do
|
23
|
+
expect(input.errors).to be_empty
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'with an error on the hash' do
|
28
|
+
let(:error) { ActiveInteraction::Filter::Error.new(filter, :invalid_type) }
|
29
|
+
|
30
|
+
it 'returns one error in the array' do
|
31
|
+
expect(input.errors.size).to be 1
|
32
|
+
|
33
|
+
error = input.errors.first
|
34
|
+
expect(error.name).to be filter.name
|
35
|
+
expect(error.type).to be :invalid_type
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'with children with errors' do
|
40
|
+
let(:child_i) do
|
41
|
+
filter = ActiveInteraction::IntegerFilter.new(:i)
|
42
|
+
ActiveInteraction::Input.new(filter,
|
43
|
+
value: nil,
|
44
|
+
error: ActiveInteraction::Filter::Error.new(filter, :missing)
|
45
|
+
)
|
46
|
+
end
|
47
|
+
let(:children) { { i: child_i } }
|
48
|
+
|
49
|
+
it 'returns the error' do
|
50
|
+
expect(input.errors.size).to be 1
|
51
|
+
|
52
|
+
error = input.errors.first
|
53
|
+
expect(error.name).to be :"#{filter.name}.i"
|
54
|
+
expect(error.type).to be :missing
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -15,20 +15,23 @@ I18nInteraction = Class.new(TestInteraction) do
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
TYPES = ActiveInteraction::Filter
|
19
|
+
.const_get(:CLASSES)
|
20
|
+
.keys
|
21
|
+
.map(&:to_s)
|
22
|
+
|
18
23
|
describe I18nInteraction do
|
19
24
|
include_context 'interactions'
|
20
25
|
|
21
|
-
TYPES = ActiveInteraction::Filter # rubocop:disable Lint/ConstantDefinitionInBlock
|
22
|
-
.const_get(:CLASSES)
|
23
|
-
.map { |slug, _| slug.to_s }
|
24
|
-
|
25
26
|
shared_examples 'translation' do |locale|
|
26
|
-
|
27
|
-
|
27
|
+
around do |example|
|
28
|
+
old_locale = I18n.locale
|
28
29
|
I18n.locale = locale
|
29
|
-
end
|
30
30
|
|
31
|
-
|
31
|
+
example.run
|
32
|
+
|
33
|
+
I18n.locale = old_locale
|
34
|
+
end
|
32
35
|
|
33
36
|
context 'types' do
|
34
37
|
TYPES.each do |type|
|
@@ -81,16 +84,12 @@ describe I18nInteraction do
|
|
81
84
|
end
|
82
85
|
|
83
86
|
context 'hsilgne' do
|
84
|
-
before
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
I18n.config.available_locales
|
89
|
-
end
|
87
|
+
# This must appear before including the translation examples so that the
|
88
|
+
# locale is available before it is assigned.
|
89
|
+
around do |example|
|
90
|
+
old_locals = I18n.config.available_locales
|
91
|
+
I18n.config.available_locales += [:hsilgne]
|
90
92
|
|
91
|
-
include_examples 'translation', :hsilgne
|
92
|
-
|
93
|
-
before do
|
94
93
|
I18n.backend.store_translations('hsilgne',
|
95
94
|
active_interaction: {
|
96
95
|
errors: {
|
@@ -103,6 +102,12 @@ describe I18nInteraction do
|
|
103
102
|
types: TYPES.each_with_object({}) { |e, a| a[e] = e.reverse }
|
104
103
|
}
|
105
104
|
)
|
105
|
+
|
106
|
+
example.run
|
107
|
+
|
108
|
+
I18n.config.available_locales = old_locals
|
106
109
|
end
|
110
|
+
|
111
|
+
include_examples 'translation', :hsilgne
|
107
112
|
end
|
108
113
|
end
|