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