active_interaction 1.0.0 → 1.0.1
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 +10 -2
- data/README.md +13 -14
- data/lib/active_interaction.rb +1 -1
- data/lib/active_interaction/base.rb +35 -28
- data/lib/active_interaction/concerns/runnable.rb +7 -1
- data/lib/active_interaction/errors.rb +3 -4
- data/lib/active_interaction/filters/time_filter.rb +4 -1
- data/lib/active_interaction/modules/validation.rb +1 -1
- data/lib/active_interaction/version.rb +1 -1
- data/spec/active_interaction/base_spec.rb +44 -36
- data/spec/active_interaction/concerns/runnable_spec.rb +23 -6
- data/spec/active_interaction/errors_spec.rb +17 -1
- data/spec/active_interaction/filters/model_filter_spec.rb +20 -0
- data/spec/active_interaction/i18n_spec.rb +15 -21
- data/spec/active_interaction/integration/time_interaction_spec.rb +6 -0
- data/spec/active_interaction/modules/validation_spec.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 152f0300bf27243acb0d7f0068b44a8b7c66fa8c
|
4
|
+
data.tar.gz: d2741f24682a5ede49215e0ddb7191625f27e189
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2976e0ff9e7b3ad09181672922fad54b821b46f8e4380afa1eb6579121f4b7cc6fc854cd59bdbf983c5ab0047dc56744ebb010585016511cd8ea193a13b733c
|
7
|
+
data.tar.gz: a2f08efa2b55ebb4ebbc86f1ea51cce4d5adc465fe6d5cc8d2c6667a4aebeac40e87041d8690fd94b36a6f753b541ee58e70662c1836a56269fe71c932413a8d
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# [Master][]
|
2
2
|
|
3
|
-
# [1.0.
|
3
|
+
# [1.0.1][] (2014-02-04)
|
4
|
+
|
5
|
+
- Short circuit `valid?` after successfully running an interaction.
|
6
|
+
- Fix a bug that prevented merging interpolated symbolic errors.
|
7
|
+
- Use `:invalid_type` instead of `:invalid` as I18n key for type errors.
|
8
|
+
- Fix a bug that skipped setting up accessors for imported filters.
|
9
|
+
|
10
|
+
# [1.0.0][] (2014-01-21)
|
4
11
|
|
5
12
|
- **Replace `Filters` with a hash.** To iterate over `Filter` objects, use
|
6
13
|
`Interaction.filters.values`.
|
@@ -118,7 +125,8 @@
|
|
118
125
|
|
119
126
|
- Initial release.
|
120
127
|
|
121
|
-
[master]: https://github.com/orgsync/active_interaction/compare/v1.0.
|
128
|
+
[master]: https://github.com/orgsync/active_interaction/compare/v1.0.1...master
|
129
|
+
[1.0.0]: https://github.com/orgsync/active_interaction/compare/v1.0.0...v1.0.1
|
122
130
|
[1.0.0]: https://github.com/orgsync/active_interaction/compare/v0.10.2...v1.0.0
|
123
131
|
[0.10.2]: https://github.com/orgsync/active_interaction/compare/v0.10.1...v0.10.2
|
124
132
|
[0.10.1]: https://github.com/orgsync/active_interaction/compare/v0.10.0...v0.10.1
|
data/README.md
CHANGED
@@ -208,27 +208,26 @@ called it with `run!`). If something went wrong, execution will halt
|
|
208
208
|
immediately and the errors will be moved onto the caller.
|
209
209
|
|
210
210
|
```ruby
|
211
|
-
class
|
212
|
-
integer :x
|
211
|
+
class AddThree < ActiveInteraction::Base
|
212
|
+
integer :x
|
213
213
|
def execute
|
214
|
-
|
215
|
-
square = compose(Square, x: sum)
|
216
|
-
compose(Add, x: square, y: square)
|
214
|
+
compose(Add, x: x, y: 3)
|
217
215
|
end
|
218
216
|
end
|
219
|
-
|
220
|
-
#
|
217
|
+
AddThree.run!(x: 5)
|
218
|
+
# => 8
|
221
219
|
```
|
222
220
|
|
221
|
+
To bring in filters from another interaction, use `import_filters`. Combined
|
222
|
+
with `inputs`, delegating to another interaction is a piece of cake.
|
223
|
+
|
223
224
|
```ruby
|
224
|
-
class
|
225
|
-
|
225
|
+
class AddAndDouble < ActiveInteraction::Base
|
226
|
+
import_filters Add
|
226
227
|
def execute
|
227
|
-
compose(Add,
|
228
|
+
compose(Add, inputs) * 2
|
228
229
|
end
|
229
230
|
end
|
230
|
-
AddThree.run!(y: nil)
|
231
|
-
# => ActiveInteraction::InvalidInteractionError: Y is required
|
232
231
|
```
|
233
232
|
|
234
233
|
## How do I translate an interaction?
|
@@ -258,7 +257,7 @@ hsilgne:
|
|
258
257
|
errors:
|
259
258
|
messages:
|
260
259
|
invalid: dilavni si
|
261
|
-
|
260
|
+
invalid_type: '%{type} dilav a ton si'
|
262
261
|
missing: deriuqer si
|
263
262
|
```
|
264
263
|
|
@@ -283,7 +282,7 @@ work done in [Mutations][17].
|
|
283
282
|
[0]: https://github.com/orgsync/active_interaction
|
284
283
|
[1]: https://badge.fury.io/rb/active_interaction.png
|
285
284
|
[2]: https://badge.fury.io/rb/active_interaction "Gem Version"
|
286
|
-
[3]: https://travis-ci.org/orgsync/active_interaction.png
|
285
|
+
[3]: https://travis-ci.org/orgsync/active_interaction.png?branch=master
|
287
286
|
[4]: https://travis-ci.org/orgsync/active_interaction "Build Status"
|
288
287
|
[5]: https://coveralls.io/repos/orgsync/active_interaction/badge.png
|
289
288
|
[6]: https://coveralls.io/r/orgsync/active_interaction "Coverage Status"
|
data/lib/active_interaction.rb
CHANGED
@@ -37,6 +37,27 @@ module ActiveInteraction
|
|
37
37
|
include Hashable
|
38
38
|
include Missable
|
39
39
|
|
40
|
+
# @!method run(inputs = {})
|
41
|
+
# @note If the interaction inputs are valid and there are no runtime
|
42
|
+
# errors and execution completed successfully, {#valid?} will always
|
43
|
+
# return true.
|
44
|
+
#
|
45
|
+
# Runs validations and if there are no errors it will call {#execute}.
|
46
|
+
#
|
47
|
+
# @param (see ActiveInteraction::Base#initialize)
|
48
|
+
#
|
49
|
+
# @return [Base]
|
50
|
+
|
51
|
+
# @!method run!(inputs = {})
|
52
|
+
# Like {.run} except that it returns the value of {#execute} or raises
|
53
|
+
# an exception if there were any validation errors.
|
54
|
+
#
|
55
|
+
# @param (see ActiveInteraction::Base.run)
|
56
|
+
#
|
57
|
+
# @return (see ActiveInteraction::Runnable::ClassMethods#run!)
|
58
|
+
#
|
59
|
+
# @raise (see ActiveInteraction::Runnable::ClassMethods#run!)
|
60
|
+
|
40
61
|
# Get or set the description.
|
41
62
|
#
|
42
63
|
# @example
|
@@ -77,25 +98,6 @@ module ActiveInteraction
|
|
77
98
|
end
|
78
99
|
end
|
79
100
|
|
80
|
-
# @!method run(inputs = {})
|
81
|
-
# Runs validations and if there are no errors it will call {#execute}.
|
82
|
-
#
|
83
|
-
# @param (see ActiveInteraction::Base#initialize)
|
84
|
-
#
|
85
|
-
# @return [Base]
|
86
|
-
loop
|
87
|
-
|
88
|
-
# @!method run!(inputs = {})
|
89
|
-
# Like {.run} except that it returns the value of {#execute} or raises
|
90
|
-
# an exception if there were any validation errors.
|
91
|
-
#
|
92
|
-
# @param (see ActiveInteraction::Base.run)
|
93
|
-
#
|
94
|
-
# @return (see ActiveInteraction::Runnable::ClassMethods#run!)
|
95
|
-
#
|
96
|
-
# @raise (see ActiveInteraction::Runnable::ClassMethods#run!)
|
97
|
-
loop
|
98
|
-
|
99
101
|
private
|
100
102
|
|
101
103
|
# @param klass [Class]
|
@@ -104,12 +106,7 @@ module ActiveInteraction
|
|
104
106
|
def add_filter(klass, name, options, &block)
|
105
107
|
fail InvalidFilterError, name.inspect if reserved?(name)
|
106
108
|
|
107
|
-
|
108
|
-
filters[name] = filter
|
109
|
-
attr_accessor name
|
110
|
-
define_method("#{name}?") { !public_send(name).nil? }
|
111
|
-
|
112
|
-
filter.default if filter.default?
|
109
|
+
initialize_filter(klass.new(name, options, &block))
|
113
110
|
end
|
114
111
|
|
115
112
|
# Import filters from another interaction.
|
@@ -123,6 +120,8 @@ module ActiveInteraction
|
|
123
120
|
#
|
124
121
|
# @return (see .filters)
|
125
122
|
#
|
123
|
+
# @raise [ArgumentError] If both `:only` and `:except` are given.
|
124
|
+
#
|
126
125
|
# @!visibility public
|
127
126
|
def import_filters(klass, options = {})
|
128
127
|
if options.key?(:only) && options.key?(:except)
|
@@ -136,7 +135,7 @@ module ActiveInteraction
|
|
136
135
|
other_filters.select! { |k, _| only.include?(k) } if only
|
137
136
|
other_filters.reject! { |k, _| except.include?(k) } if except
|
138
137
|
|
139
|
-
|
138
|
+
other_filters.values.each { |filter| initialize_filter(filter) }
|
140
139
|
end
|
141
140
|
|
142
141
|
# @param klass [Class]
|
@@ -144,6 +143,16 @@ module ActiveInteraction
|
|
144
143
|
klass.instance_variable_set(:@_interaction_filters, filters.dup)
|
145
144
|
end
|
146
145
|
|
146
|
+
# @param filter [Filter]
|
147
|
+
def initialize_filter(filter)
|
148
|
+
filters[filter.name] = filter
|
149
|
+
|
150
|
+
attr_accessor filter.name
|
151
|
+
define_method("#{filter.name}?") { !public_send(filter.name).nil? }
|
152
|
+
|
153
|
+
filter.default if filter.default?
|
154
|
+
end
|
155
|
+
|
147
156
|
# @param symbol [Symbol]
|
148
157
|
#
|
149
158
|
# @return [Boolean]
|
@@ -169,7 +178,6 @@ module ActiveInteraction
|
|
169
178
|
# @param inputs (see ActiveInteraction::Base#initialize)
|
170
179
|
#
|
171
180
|
# @return (see ActiveInteraction::Base.run!)
|
172
|
-
loop
|
173
181
|
|
174
182
|
# @!method execute
|
175
183
|
# @abstract
|
@@ -180,7 +188,6 @@ module ActiveInteraction
|
|
180
188
|
# ActiveRecord is available.
|
181
189
|
#
|
182
190
|
# @raise (see ActiveInteraction::Runnable#execute)
|
183
|
-
loop
|
184
191
|
|
185
192
|
# Returns the inputs provided to {.run} or {.run!} after being cast based
|
186
193
|
# on the filters in the class.
|
@@ -56,15 +56,21 @@ module ActiveInteraction
|
|
56
56
|
if errors.empty?
|
57
57
|
@_interaction_result = result
|
58
58
|
@_interaction_runtime_errors = nil
|
59
|
+
@_interaction_valid = true
|
59
60
|
else
|
60
61
|
@_interaction_result = nil
|
61
62
|
@_interaction_runtime_errors = errors.dup
|
63
|
+
@_interaction_valid = false
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
65
67
|
# @return [Boolean]
|
66
68
|
def valid?(*)
|
67
|
-
|
69
|
+
unless instance_variable_defined?(:@_interaction_valid)
|
70
|
+
@_interaction_valid = false
|
71
|
+
end
|
72
|
+
|
73
|
+
@_interaction_valid || super || (self.result = nil)
|
68
74
|
end
|
69
75
|
|
70
76
|
private
|
@@ -90,15 +90,14 @@ module ActiveInteraction
|
|
90
90
|
def add_sym(attribute, symbol = :invalid, message = nil, options = {})
|
91
91
|
add(attribute, message || symbol, options)
|
92
92
|
|
93
|
-
symbolic[attribute]
|
94
|
-
symbolic[attribute] << symbol
|
93
|
+
symbolic[attribute] += [symbol]
|
95
94
|
end
|
96
95
|
|
97
96
|
# @see ActiveModel::Errors#initialize
|
98
97
|
#
|
99
98
|
# @private
|
100
99
|
def initialize(*)
|
101
|
-
@symbolic =
|
100
|
+
@symbolic = Hash.new([]).with_indifferent_access
|
102
101
|
|
103
102
|
super
|
104
103
|
end
|
@@ -128,7 +127,7 @@ module ActiveInteraction
|
|
128
127
|
# @return [Errors]
|
129
128
|
def merge!(other)
|
130
129
|
other.symbolic.each do |attribute, symbols|
|
131
|
-
symbols.each { |s|
|
130
|
+
symbols.each { |s| symbolic[attribute] += [s] }
|
132
131
|
end
|
133
132
|
|
134
133
|
other.messages.each do |attribute, messages|
|
@@ -21,6 +21,9 @@ module ActiveInteraction
|
|
21
21
|
|
22
22
|
# @private
|
23
23
|
class TimeFilter < AbstractDateTimeFilter
|
24
|
+
alias_method :_klass, :klass
|
25
|
+
private :_klass
|
26
|
+
|
24
27
|
def cast(value)
|
25
28
|
case value
|
26
29
|
when Numeric
|
@@ -41,7 +44,7 @@ module ActiveInteraction
|
|
41
44
|
end
|
42
45
|
|
43
46
|
def klasses
|
44
|
-
[
|
47
|
+
[_klass, klass.at(0).class]
|
45
48
|
end
|
46
49
|
end
|
47
50
|
end
|
@@ -12,7 +12,7 @@ module ActiveInteraction
|
|
12
12
|
begin
|
13
13
|
filter.cast(inputs[name])
|
14
14
|
rescue InvalidValueError
|
15
|
-
errors << [name, :
|
15
|
+
errors << [name, :invalid_type, nil, type: type(filter)]
|
16
16
|
rescue MissingValueError
|
17
17
|
errors << [name, :missing]
|
18
18
|
end
|
@@ -389,60 +389,68 @@ describe ActiveInteraction::Base do
|
|
389
389
|
end
|
390
390
|
|
391
391
|
describe '.import_filters' do
|
392
|
-
|
393
|
-
|
394
|
-
|
392
|
+
shared_context 'import_filters context' do
|
393
|
+
let(:klass) { AddInteraction }
|
394
|
+
let(:only) { nil }
|
395
|
+
let(:except) { nil }
|
396
|
+
|
397
|
+
let(:described_class) do
|
398
|
+
interaction = klass
|
399
|
+
options = {}
|
400
|
+
options[:only] = only unless only.nil?
|
401
|
+
options[:except] = except unless except.nil?
|
402
|
+
|
403
|
+
Class.new(TestInteraction) { import_filters interaction, options }
|
395
404
|
end
|
396
405
|
end
|
397
406
|
|
398
|
-
|
399
|
-
|
400
|
-
end
|
407
|
+
shared_examples 'import_filters examples' do
|
408
|
+
include_context 'import_filters context'
|
401
409
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
end
|
410
|
+
it 'imports the filters' do
|
411
|
+
expect(described_class.filters).to eq klass.filters
|
412
|
+
.select { |k, _| only.nil? ? true : only.include?(k) }
|
413
|
+
.reject { |k, _| except.nil? ? false : except.include?(k) }
|
407
414
|
end
|
408
415
|
|
409
416
|
it 'does not modify the source' do
|
410
|
-
filters =
|
417
|
+
filters = klass.filters.dup
|
411
418
|
described_class
|
412
|
-
expect(
|
419
|
+
expect(klass.filters).to eq filters
|
413
420
|
end
|
414
421
|
|
415
|
-
it '
|
416
|
-
|
417
|
-
.select { |k, _| k == :x }
|
418
|
-
end
|
419
|
-
end
|
422
|
+
it 'responds to readers, writers, and predicates' do
|
423
|
+
instance = described_class.new
|
420
424
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
+
described_class.filters.keys.each do |name|
|
426
|
+
[name, "#{name}=", "#{name}?"].each do |method|
|
427
|
+
expect(instance).to respond_to method
|
428
|
+
end
|
425
429
|
end
|
426
430
|
end
|
431
|
+
end
|
427
432
|
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
expect(AddInteraction.filters).to eq filters
|
432
|
-
end
|
433
|
+
context 'with neither :only nor :except' do
|
434
|
+
include_examples 'import_filters examples'
|
435
|
+
end
|
433
436
|
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
437
|
+
context 'with :only' do
|
438
|
+
include_examples 'import_filters examples'
|
439
|
+
|
440
|
+
let(:only) { [:x] }
|
441
|
+
end
|
442
|
+
|
443
|
+
context 'with :except' do
|
444
|
+
include_examples 'import_filters examples'
|
445
|
+
|
446
|
+
let(:except) { [:x] }
|
438
447
|
end
|
439
448
|
|
440
449
|
context 'with :only & :except' do
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
end
|
450
|
+
include_context 'import_filters context'
|
451
|
+
|
452
|
+
let(:only) { [] }
|
453
|
+
let(:except) { [] }
|
446
454
|
|
447
455
|
it 'raises an error' do
|
448
456
|
expect { described_class }.to raise_error ArgumentError
|
@@ -123,12 +123,6 @@ describe ActiveInteraction::Runnable do
|
|
123
123
|
it 'returns false' do
|
124
124
|
expect(instance).to_not be_valid
|
125
125
|
end
|
126
|
-
|
127
|
-
it 'sets the result to nil' do
|
128
|
-
instance.result = result
|
129
|
-
instance.valid?
|
130
|
-
expect(instance.result).to be_nil
|
131
|
-
end
|
132
126
|
end
|
133
127
|
end
|
134
128
|
|
@@ -162,6 +156,29 @@ describe ActiveInteraction::Runnable do
|
|
162
156
|
end
|
163
157
|
end
|
164
158
|
end
|
159
|
+
|
160
|
+
context 'with invalid post-execution state' do
|
161
|
+
before do
|
162
|
+
klass.class_exec do
|
163
|
+
attr_accessor :attribute
|
164
|
+
|
165
|
+
validate { errors.add(:attribute) if attribute }
|
166
|
+
|
167
|
+
def execute
|
168
|
+
self.attribute = true
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'is valid' do
|
174
|
+
expect(outcome).to be_valid
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'stays valid' do
|
178
|
+
outcome.attribute = true
|
179
|
+
expect(outcome).to be_valid
|
180
|
+
end
|
181
|
+
end
|
165
182
|
end
|
166
183
|
|
167
184
|
describe '.run!' do
|
@@ -10,7 +10,7 @@ describe ActiveInteraction::Errors do
|
|
10
10
|
attr_reader :attribute
|
11
11
|
|
12
12
|
def self.name
|
13
|
-
SecureRandom.hex
|
13
|
+
@name ||= SecureRandom.hex
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
@@ -129,5 +129,21 @@ describe ActiveInteraction::Errors do
|
|
129
129
|
expect(errors.symbolic[:attribute]).to eq [:invalid]
|
130
130
|
end
|
131
131
|
end
|
132
|
+
|
133
|
+
context 'with an interpolated symbolic error' do
|
134
|
+
before do
|
135
|
+
I18n.backend.store_translations('en', activemodel: {
|
136
|
+
errors: { models: { klass.name => { attributes: { attribute: {
|
137
|
+
invalid_type: 'is not a valid %{type}'
|
138
|
+
} } } } }
|
139
|
+
})
|
140
|
+
|
141
|
+
other.add_sym(:attribute, :invalid_type, type: nil)
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'does not raise an error' do
|
145
|
+
expect { errors.merge!(other) }.to_not raise_error
|
146
|
+
end
|
147
|
+
end
|
132
148
|
end
|
133
149
|
end
|
@@ -19,6 +19,26 @@ describe ActiveInteraction::ModelFilter, :filter do
|
|
19
19
|
it 'returns the instance' do
|
20
20
|
expect(filter.cast(value)).to eq value
|
21
21
|
end
|
22
|
+
|
23
|
+
it 'handles reconstantizing' do
|
24
|
+
expect(filter.cast(value)).to eq value
|
25
|
+
|
26
|
+
Object.send(:remove_const, :Model)
|
27
|
+
Model = Class.new
|
28
|
+
value = Model.new
|
29
|
+
|
30
|
+
expect(filter.cast(value)).to eq value
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with class as a superclass' do
|
35
|
+
before do
|
36
|
+
options.merge!(class: Model.superclass)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'returns the instance' do
|
40
|
+
expect(filter.cast(value)).to eq value
|
41
|
+
end
|
22
42
|
end
|
23
43
|
|
24
44
|
context 'with class as a String' do
|
@@ -39,30 +39,24 @@ describe I18nInteraction do
|
|
39
39
|
let(:translation) { I18n.translate(key, type: type, raise: true) }
|
40
40
|
let(:type) { I18n.translate("#{described_class.i18n_scope}.types.hash") }
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
shared_examples 'translations' do |key, value|
|
43
|
+
context key.inspect do
|
44
|
+
let(:key) { "#{described_class.i18n_scope}.errors.messages.#{key}" }
|
44
45
|
|
45
|
-
|
46
|
-
expect { translation }.to_not raise_error
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'returns the translation' do
|
50
|
-
inputs.merge!(a: Object.new)
|
51
|
-
expect(outcome.errors[:a]).to eq [translation]
|
52
|
-
end
|
53
|
-
end
|
46
|
+
before { inputs[:a] = value }
|
54
47
|
|
55
|
-
|
56
|
-
|
48
|
+
it 'has a translation' do
|
49
|
+
expect { translation }.to_not raise_error
|
50
|
+
end
|
57
51
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
it 'returns the translation' do
|
63
|
-
expect(outcome.errors[:a]).to eq [translation]
|
52
|
+
it 'returns the translation' do
|
53
|
+
expect(outcome.errors[:a]).to include translation
|
54
|
+
end
|
64
55
|
end
|
65
56
|
end
|
57
|
+
|
58
|
+
include_examples 'translations', :invalid_type, Object.new
|
59
|
+
include_examples 'translations', :missing, nil
|
66
60
|
end
|
67
61
|
end
|
68
62
|
|
@@ -80,8 +74,8 @@ describe I18nInteraction do
|
|
80
74
|
before do
|
81
75
|
I18n.backend.store_translations('hsilgne', active_interaction: {
|
82
76
|
errors: { messages: {
|
83
|
-
invalid:
|
84
|
-
|
77
|
+
invalid: 'is invalid'.reverse,
|
78
|
+
invalid_type: "%{type} #{'is not a valid'.reverse}",
|
85
79
|
missing: 'missing'.reverse
|
86
80
|
} },
|
87
81
|
types: TYPES.each_with_object({}) { |e, a| a[e] = e.reverse }
|
@@ -71,6 +71,12 @@ describe TimeInteraction do
|
|
71
71
|
it 'returns the correct value' do
|
72
72
|
expect(result[:a]).to eq a
|
73
73
|
end
|
74
|
+
|
75
|
+
it 'handles time zone changes' do
|
76
|
+
outcome
|
77
|
+
allow(Time).to receive(:zone).and_return(nil)
|
78
|
+
expect(described_class.run(inputs)).to be_invalid
|
79
|
+
end
|
74
80
|
end
|
75
81
|
end
|
76
82
|
end
|
@@ -38,18 +38,18 @@ describe ActiveInteraction::Validation do
|
|
38
38
|
let(:exception) { ActiveInteraction::InvalidValueError }
|
39
39
|
let(:filter) { ActiveInteraction::FloatFilter.new(:name, {}) }
|
40
40
|
|
41
|
-
it 'returns an :
|
41
|
+
it 'returns an :invalid_type error' do
|
42
42
|
type = I18n.translate(
|
43
43
|
"#{ActiveInteraction::Base.i18n_scope}.types.#{filter.class.slug}")
|
44
44
|
|
45
|
-
expect(result).to eq [[filter.name, :
|
45
|
+
expect(result).to eq [[filter.name, :invalid_type, nil, type: type]]
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
49
|
context 'MissingValueError' do
|
50
50
|
let(:exception) { ActiveInteraction::MissingValueError }
|
51
51
|
|
52
|
-
it 'returns an :
|
52
|
+
it 'returns an :msising error' do
|
53
53
|
expect(result).to eq [[filter.name, :missing]]
|
54
54
|
end
|
55
55
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_interaction
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Lasseigne
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-02-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activemodel
|