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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -0
- data/README.md +11 -12
- data/lib/active_interaction/base.rb +2 -0
- data/lib/active_interaction/errors.rb +16 -16
- data/lib/active_interaction/filter.rb +9 -12
- data/lib/active_interaction/filters/array_filter.rb +1 -1
- data/lib/active_interaction/filters/hash_filter.rb +5 -1
- data/lib/active_interaction/grouped_input.rb +23 -3
- data/lib/active_interaction/locale/es.yml +23 -0
- data/lib/active_interaction/version.rb +1 -1
- metadata +13 -115
- data/spec/active_interaction/array_input_spec.rb +0 -166
- data/spec/active_interaction/base_spec.rb +0 -537
- data/spec/active_interaction/concerns/active_modelable_spec.rb +0 -45
- data/spec/active_interaction/concerns/active_recordable_spec.rb +0 -49
- data/spec/active_interaction/concerns/hashable_spec.rb +0 -46
- data/spec/active_interaction/concerns/missable_spec.rb +0 -99
- data/spec/active_interaction/concerns/runnable_spec.rb +0 -397
- data/spec/active_interaction/errors_spec.rb +0 -196
- data/spec/active_interaction/filter/column_spec.rb +0 -87
- data/spec/active_interaction/filter_spec.rb +0 -39
- data/spec/active_interaction/filters/abstract_date_time_filter_spec.rb +0 -13
- data/spec/active_interaction/filters/abstract_numeric_filter_spec.rb +0 -13
- data/spec/active_interaction/filters/array_filter_spec.rb +0 -245
- data/spec/active_interaction/filters/boolean_filter_spec.rb +0 -87
- data/spec/active_interaction/filters/date_filter_spec.rb +0 -178
- data/spec/active_interaction/filters/date_time_filter_spec.rb +0 -189
- data/spec/active_interaction/filters/decimal_filter_spec.rb +0 -126
- data/spec/active_interaction/filters/file_filter_spec.rb +0 -40
- data/spec/active_interaction/filters/float_filter_spec.rb +0 -110
- data/spec/active_interaction/filters/hash_filter_spec.rb +0 -129
- data/spec/active_interaction/filters/integer_filter_spec.rb +0 -104
- data/spec/active_interaction/filters/interface_filter_spec.rb +0 -461
- data/spec/active_interaction/filters/object_filter_spec.rb +0 -237
- data/spec/active_interaction/filters/record_filter_spec.rb +0 -206
- data/spec/active_interaction/filters/string_filter_spec.rb +0 -60
- data/spec/active_interaction/filters/symbol_filter_spec.rb +0 -46
- data/spec/active_interaction/filters/time_filter_spec.rb +0 -251
- data/spec/active_interaction/grouped_input_spec.rb +0 -17
- data/spec/active_interaction/hash_input_spec.rb +0 -58
- data/spec/active_interaction/i18n_spec.rb +0 -113
- data/spec/active_interaction/inputs_spec.rb +0 -266
- data/spec/active_interaction/integration/array_interaction_spec.rb +0 -88
- data/spec/active_interaction/integration/boolean_interaction_spec.rb +0 -5
- data/spec/active_interaction/integration/date_interaction_spec.rb +0 -5
- data/spec/active_interaction/integration/date_time_interaction_spec.rb +0 -5
- data/spec/active_interaction/integration/file_interaction_spec.rb +0 -18
- data/spec/active_interaction/integration/float_interaction_spec.rb +0 -5
- data/spec/active_interaction/integration/hash_interaction_spec.rb +0 -76
- data/spec/active_interaction/integration/integer_interaction_spec.rb +0 -5
- data/spec/active_interaction/integration/interface_interaction_spec.rb +0 -19
- data/spec/active_interaction/integration/object_interaction_spec.rb +0 -14
- data/spec/active_interaction/integration/record_integration_spec.rb +0 -5
- data/spec/active_interaction/integration/string_interaction_spec.rb +0 -5
- data/spec/active_interaction/integration/symbol_interaction_spec.rb +0 -5
- data/spec/active_interaction/integration/time_interaction_spec.rb +0 -88
- data/spec/active_interaction/modules/validation_spec.rb +0 -57
- data/spec/spec_helper.rb +0 -20
- data/spec/support/concerns.rb +0 -13
- data/spec/support/filters.rb +0 -227
- data/spec/support/interactions.rb +0 -124
@@ -1,251 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ActiveInteraction::TimeFilter, :filter do
|
4
|
-
include_context 'filters'
|
5
|
-
it_behaves_like 'a filter'
|
6
|
-
|
7
|
-
shared_context 'with format' do
|
8
|
-
let(:format) { '%d/%m/%Y %H:%M:%S %z' }
|
9
|
-
|
10
|
-
before do
|
11
|
-
options[:format] = format
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe '#initialize' do
|
16
|
-
context 'with a format' do
|
17
|
-
before { options[:format] = '%T' }
|
18
|
-
|
19
|
-
context 'with a time zone' do
|
20
|
-
before do
|
21
|
-
time_with_zone = double
|
22
|
-
|
23
|
-
time_zone = double
|
24
|
-
allow(time_zone).to receive(:at).and_return(time_with_zone)
|
25
|
-
|
26
|
-
allow(Time).to receive(:zone).and_return(time_zone)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'raises an error' do
|
30
|
-
expect do
|
31
|
-
filter
|
32
|
-
end.to raise_error(ActiveInteraction::InvalidFilterError)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe '#process' do
|
39
|
-
let(:result) { filter.process(value, nil) }
|
40
|
-
|
41
|
-
context 'with a Time' do
|
42
|
-
let(:value) { Time.new }
|
43
|
-
|
44
|
-
it 'returns the Time' do
|
45
|
-
expect(result.value).to eql value
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'with a String' do
|
50
|
-
let(:value) { '2011-12-13 14:15:16 +1718' }
|
51
|
-
|
52
|
-
it 'returns a Time' do
|
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
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'with format' do
|
74
|
-
include_context 'with format'
|
75
|
-
|
76
|
-
let(:value) { '13/12/2011 14:15:16 +1718' }
|
77
|
-
|
78
|
-
it 'returns a Time' do
|
79
|
-
expect(result.value).to eql Time.strptime(value, format)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
context 'with an invalid String' do
|
85
|
-
let(:value) { 'invalid' }
|
86
|
-
|
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
|
92
|
-
end
|
93
|
-
|
94
|
-
context 'with format' do
|
95
|
-
include_context 'with format'
|
96
|
-
|
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
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
context 'with an implicit String' do
|
107
|
-
let(:value) do
|
108
|
-
Class.new do
|
109
|
-
def to_str
|
110
|
-
'2011-12-13 14:15:16 +1718'
|
111
|
-
end
|
112
|
-
end.new
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'returns a Time' do
|
116
|
-
expect(result.value).to eql Time.parse(value)
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
context 'with a blank String' do
|
121
|
-
let(:value) do
|
122
|
-
Class.new do
|
123
|
-
def to_str
|
124
|
-
' '
|
125
|
-
end
|
126
|
-
end.new
|
127
|
-
end
|
128
|
-
|
129
|
-
context 'optional' do
|
130
|
-
include_context 'optional'
|
131
|
-
|
132
|
-
it 'returns the default' do
|
133
|
-
expect(result.value).to eql options[:default]
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'required' do
|
138
|
-
include_context 'required'
|
139
|
-
|
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
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
context 'with an Integer' do
|
150
|
-
let(:value) { rand(1 << 16) }
|
151
|
-
|
152
|
-
it 'returns the Time' do
|
153
|
-
expect(result.value).to eql Time.at(value)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
|
157
|
-
context 'with an implicit Integer' do
|
158
|
-
let(:value) do
|
159
|
-
Class.new do
|
160
|
-
def to_int
|
161
|
-
@to_int ||= rand(1 << 16)
|
162
|
-
end
|
163
|
-
end.new
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'returns the Time' do
|
167
|
-
expect(result.value).to eql Time.at(value)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
context 'with a GroupedInput' do
|
172
|
-
let(:year) { 2012 }
|
173
|
-
let(:month) { 1 }
|
174
|
-
let(:day) { 2 }
|
175
|
-
let(:hour) { 3 }
|
176
|
-
let(:min) { 4 }
|
177
|
-
let(:sec) { 5 }
|
178
|
-
let(:value) do
|
179
|
-
ActiveInteraction::GroupedInput.new(
|
180
|
-
'1' => year.to_s,
|
181
|
-
'2' => month.to_s,
|
182
|
-
'3' => day.to_s,
|
183
|
-
'4' => hour.to_s,
|
184
|
-
'5' => min.to_s,
|
185
|
-
'6' => sec.to_s
|
186
|
-
)
|
187
|
-
end
|
188
|
-
|
189
|
-
it 'returns a Time' do
|
190
|
-
expect(
|
191
|
-
result.value
|
192
|
-
).to eql Time.new(year, month, day, hour, min, sec)
|
193
|
-
end
|
194
|
-
end
|
195
|
-
|
196
|
-
context 'with an invalid GroupedInput' do
|
197
|
-
context 'empty' do
|
198
|
-
let(:value) { ActiveInteraction::GroupedInput.new }
|
199
|
-
|
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
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
context 'partial inputs' do
|
209
|
-
let(:value) do
|
210
|
-
ActiveInteraction::GroupedInput.new(
|
211
|
-
'2' => '1'
|
212
|
-
)
|
213
|
-
end
|
214
|
-
|
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
|
220
|
-
end
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
describe '#database_column_type' do
|
226
|
-
it 'returns :datetime' do
|
227
|
-
expect(filter.database_column_type).to be :datetime
|
228
|
-
end
|
229
|
-
end
|
230
|
-
|
231
|
-
describe '#default' do
|
232
|
-
context 'with a GroupedInput' do
|
233
|
-
before do
|
234
|
-
options[:default] = ActiveInteraction::GroupedInput.new(
|
235
|
-
'1' => '2012',
|
236
|
-
'2' => '1',
|
237
|
-
'3' => '2',
|
238
|
-
'4' => '3',
|
239
|
-
'5' => '4',
|
240
|
-
'6' => '5'
|
241
|
-
)
|
242
|
-
end
|
243
|
-
|
244
|
-
it 'raises an error' do
|
245
|
-
expect do
|
246
|
-
filter.default(nil)
|
247
|
-
end.to raise_error ActiveInteraction::InvalidDefaultError
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ActiveInteraction::GroupedInput do
|
4
|
-
subject(:grouped_input) { described_class.new }
|
5
|
-
|
6
|
-
it 'subclasses OpenStruct' do
|
7
|
-
expect(grouped_input).to be_an OpenStruct
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'responds to #[]' do
|
11
|
-
expect { grouped_input[:key] }.to_not raise_error
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'responds to #[]=' do
|
15
|
-
expect { grouped_input[:key] = :value }.to_not raise_error
|
16
|
-
end
|
17
|
-
end
|
@@ -1,58 +0,0 @@
|
|
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
|
@@ -1,113 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ActiveInteraction do
|
4
|
-
context 'I18n.load_path' do
|
5
|
-
it 'contains localization file paths' do
|
6
|
-
expect(I18n.load_path)
|
7
|
-
.to include a_string_ending_with('active_interaction/locale/en.yml')
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
I18nInteraction = Class.new(TestInteraction) do
|
13
|
-
hash :a do
|
14
|
-
hash :x
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
TYPES = ActiveInteraction::Filter
|
19
|
-
.const_get(:CLASSES)
|
20
|
-
.keys
|
21
|
-
.map(&:to_s)
|
22
|
-
|
23
|
-
describe I18nInteraction do
|
24
|
-
include_context 'interactions'
|
25
|
-
|
26
|
-
shared_examples 'translation' do |locale|
|
27
|
-
around do |example|
|
28
|
-
old_locale = I18n.locale
|
29
|
-
I18n.locale = locale
|
30
|
-
|
31
|
-
example.run
|
32
|
-
|
33
|
-
I18n.locale = old_locale
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'types' do
|
37
|
-
TYPES.each do |type|
|
38
|
-
it "has a translation for #{type}" do
|
39
|
-
key = "#{described_class.i18n_scope}.types.#{type}"
|
40
|
-
expect { I18n.translate(key, raise: true) }.to_not raise_error
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'error messages' do
|
46
|
-
let(:translation) { I18n.translate(key, type: type, raise: true) }
|
47
|
-
let(:type) { I18n.translate("#{described_class.i18n_scope}.types.hash") }
|
48
|
-
|
49
|
-
shared_examples 'translations' do |key, value|
|
50
|
-
context key.inspect do
|
51
|
-
let(:key) { "#{described_class.i18n_scope}.errors.messages.#{key}" }
|
52
|
-
|
53
|
-
before { inputs[:a] = value }
|
54
|
-
|
55
|
-
it 'has a translation' do
|
56
|
-
expect { translation }.to_not raise_error
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'returns the translation' do
|
60
|
-
expect(outcome.errors[:a]).to include translation
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
include_examples 'translations', :invalid_type, Object.new
|
66
|
-
include_examples 'translations', :missing, nil
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context 'english' do
|
71
|
-
include_examples 'translation', :en
|
72
|
-
end
|
73
|
-
|
74
|
-
context 'brazilian portuguese' do
|
75
|
-
include_examples 'translation', :'pt-BR'
|
76
|
-
end
|
77
|
-
|
78
|
-
context 'french' do
|
79
|
-
include_examples 'translation', :fr
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'italian' do
|
83
|
-
include_examples 'translation', :it
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'hsilgne' do
|
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]
|
92
|
-
|
93
|
-
I18n.backend.store_translations('hsilgne',
|
94
|
-
active_interaction: {
|
95
|
-
errors: {
|
96
|
-
messages: {
|
97
|
-
invalid: 'is invalid'.reverse,
|
98
|
-
invalid_type: "%<type>s} #{'is not a valid'.reverse}",
|
99
|
-
missing: 'missing'.reverse
|
100
|
-
}
|
101
|
-
},
|
102
|
-
types: TYPES.each_with_object({}) { |e, a| a[e] = e.reverse }
|
103
|
-
}
|
104
|
-
)
|
105
|
-
|
106
|
-
example.run
|
107
|
-
|
108
|
-
I18n.config.available_locales = old_locals
|
109
|
-
end
|
110
|
-
|
111
|
-
include_examples 'translation', :hsilgne
|
112
|
-
end
|
113
|
-
end
|
@@ -1,266 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe ActiveInteraction::Inputs do
|
4
|
-
subject(:inputs) { described_class.new(args, base_class.new) }
|
5
|
-
|
6
|
-
let(:args) { {} }
|
7
|
-
let(:base_class) { ActiveInteraction::Base }
|
8
|
-
|
9
|
-
describe '.reserved?(name)' do
|
10
|
-
it 'returns true for anything starting with "_interaction_"' do
|
11
|
-
expect(described_class).to be_reserved('_interaction_')
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'returns true for existing instance methods' do
|
15
|
-
(
|
16
|
-
(ActiveInteraction::Base.instance_methods - Object.instance_methods) +
|
17
|
-
(ActiveInteraction::Base.private_instance_methods - Object.private_instance_methods)
|
18
|
-
).each do |method|
|
19
|
-
expect(described_class).to be_reserved(method)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'returns false for anything else' do
|
24
|
-
expect(described_class).to_not be_reserved(SecureRandom.hex)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
describe '#normalized' do
|
29
|
-
let(:result) { inputs.normalized }
|
30
|
-
|
31
|
-
context 'with invalid inputs' do
|
32
|
-
let(:args) { nil }
|
33
|
-
|
34
|
-
it 'raises an error' do
|
35
|
-
expect { result }.to raise_error ArgumentError
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'with non-hash inputs' do
|
40
|
-
let(:args) { [%i[k v]] }
|
41
|
-
|
42
|
-
it 'raises an error' do
|
43
|
-
expect { result }.to raise_error ArgumentError
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context 'with ActiveInteraction::Inputs inputs' do
|
48
|
-
let(:args) { described_class.new({ key: :value }, base_class.new) }
|
49
|
-
|
50
|
-
it 'does not raise an error' do
|
51
|
-
expect { result }.to_not raise_error
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'with ActionController::Parameters inputs' do
|
56
|
-
let(:args) { ::ActionController::Parameters.new }
|
57
|
-
|
58
|
-
it 'does not raise an error' do
|
59
|
-
expect { result }.to_not raise_error
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
context 'with simple inputs' do
|
64
|
-
before { args[:key] = :value }
|
65
|
-
|
66
|
-
it 'sends them straight through' do
|
67
|
-
expect(result).to eql args
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'with groupable inputs' do
|
72
|
-
context 'without a matching simple input' do
|
73
|
-
before do
|
74
|
-
args.merge!(
|
75
|
-
'key(1i)' => :value1,
|
76
|
-
'key(2i)' => :value2
|
77
|
-
)
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'groups the inputs into a GroupedInput' do
|
81
|
-
expect(result).to eq(
|
82
|
-
key: ActiveInteraction::GroupedInput.new(
|
83
|
-
'1' => :value1,
|
84
|
-
'2' => :value2
|
85
|
-
)
|
86
|
-
)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
context 'with a matching simple input' do
|
91
|
-
before do
|
92
|
-
args.merge!(
|
93
|
-
'key(1i)' => :value1,
|
94
|
-
key: :value2
|
95
|
-
)
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'groups the inputs into a GroupedInput' do
|
99
|
-
expect(result).to eq(
|
100
|
-
key: ActiveInteraction::GroupedInput.new(
|
101
|
-
'1' => :value1
|
102
|
-
)
|
103
|
-
)
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context 'with a reserved name' do
|
109
|
-
before { args[:_interaction_key] = :value }
|
110
|
-
|
111
|
-
it 'skips the input' do
|
112
|
-
expect(result).to_not have_key(:_interaction_key)
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
describe '#given?' do
|
118
|
-
let(:base_class) do
|
119
|
-
Class.new(ActiveInteraction::Base) do
|
120
|
-
float :x,
|
121
|
-
default: nil
|
122
|
-
|
123
|
-
def execute; end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
it 'is false when the input is not given' do
|
128
|
-
expect(inputs.given?(:x)).to be false
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'is true when the input is nil' do
|
132
|
-
args[:x] = nil
|
133
|
-
expect(inputs.given?(:x)).to be true
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'is true when the input is given' do
|
137
|
-
args[:x] = rand
|
138
|
-
expect(inputs.given?(:x)).to be true
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'symbolizes its argument' do
|
142
|
-
args[:x] = rand
|
143
|
-
expect(inputs.given?('x')).to be true
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'only tracks inputs with filters' do
|
147
|
-
args[:y] = rand
|
148
|
-
expect(inputs.given?(:y)).to be false
|
149
|
-
end
|
150
|
-
|
151
|
-
context 'nested hash values' do
|
152
|
-
let(:base_class) do
|
153
|
-
Class.new(ActiveInteraction::Base) do
|
154
|
-
hash :x, default: {} do
|
155
|
-
boolean :y,
|
156
|
-
default: true
|
157
|
-
end
|
158
|
-
|
159
|
-
def execute; end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
it 'is true when the nested inputs symbols are given' do
|
164
|
-
described_class.class_exec do
|
165
|
-
def execute
|
166
|
-
given?(:x, :y)
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
args[:x] = { y: false }
|
171
|
-
expect(inputs.given?(:x, :y)).to be true
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'is true when the nested inputs strings are given' do
|
175
|
-
args['x'] = { 'y' => false }
|
176
|
-
expect(inputs.given?(:x, :y)).to be true
|
177
|
-
end
|
178
|
-
|
179
|
-
it 'is false when the nested input is not given' do
|
180
|
-
args[:x] = {}
|
181
|
-
expect(inputs.given?(:x, :y)).to be false
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'is false when the first input is not given' do
|
185
|
-
expect(inputs.given?(:x, :y)).to be false
|
186
|
-
end
|
187
|
-
|
188
|
-
it 'is false when the first input is nil' do
|
189
|
-
args[:x] = nil
|
190
|
-
expect(inputs.given?(:x, :y)).to be false
|
191
|
-
end
|
192
|
-
|
193
|
-
it 'returns false if you go too far' do
|
194
|
-
args[:x] = { y: true }
|
195
|
-
expect(inputs.given?(:x, :y, :z)).to be false
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
context 'nested array values' do
|
200
|
-
let(:base_class) do
|
201
|
-
Class.new(ActiveInteraction::Base) do
|
202
|
-
array :x do
|
203
|
-
hash do
|
204
|
-
boolean :y, default: true
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def execute; end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
context 'has a positive index' do
|
213
|
-
it 'returns true if found' do
|
214
|
-
args[:x] = [{ y: true }]
|
215
|
-
expect(inputs.given?(:x, 0, :y)).to be true
|
216
|
-
end
|
217
|
-
|
218
|
-
it 'returns false if not found' do
|
219
|
-
args[:x] = []
|
220
|
-
expect(inputs.given?(:x, 0, :y)).to be false
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
context 'has a negative index' do
|
225
|
-
it 'returns true if found' do
|
226
|
-
args[:x] = [{ y: true }]
|
227
|
-
expect(inputs.given?(:x, -1, :y)).to be true
|
228
|
-
end
|
229
|
-
|
230
|
-
it 'returns false if not found' do
|
231
|
-
args[:x] = []
|
232
|
-
expect(inputs.given?(:x, -1, :y)).to be false
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
it 'returns false if you go too far' do
|
237
|
-
args[:x] = [{}]
|
238
|
-
expect(inputs.given?(:x, 10, :y)).to be false
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
context 'multi-part date values' do
|
243
|
-
let(:base_class) do
|
244
|
-
Class.new(ActiveInteraction::Base) do
|
245
|
-
date :thing,
|
246
|
-
default: nil
|
247
|
-
|
248
|
-
def execute; end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
it 'returns true when the input is given' do
|
253
|
-
args.merge!(
|
254
|
-
'thing(1i)' => '2020',
|
255
|
-
'thing(2i)' => '12',
|
256
|
-
'thing(3i)' => '31'
|
257
|
-
)
|
258
|
-
expect(inputs.given?(:thing)).to be true
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'returns false if not found' do
|
262
|
-
expect(inputs.given?(:thing)).to be false
|
263
|
-
end
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|