active_interaction 0.5.0 → 0.6.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 +27 -3
- data/README.md +8 -6
- data/lib/active_interaction.rb +5 -3
- data/lib/active_interaction/active_model.rb +29 -0
- data/lib/active_interaction/base.rb +82 -116
- data/lib/active_interaction/errors.rb +79 -5
- data/lib/active_interaction/filter.rb +195 -21
- data/lib/active_interaction/filters.rb +26 -0
- data/lib/active_interaction/filters/array_filter.rb +22 -25
- data/lib/active_interaction/filters/boolean_filter.rb +12 -12
- data/lib/active_interaction/filters/date_filter.rb +32 -5
- data/lib/active_interaction/filters/date_time_filter.rb +34 -7
- data/lib/active_interaction/filters/file_filter.rb +12 -9
- data/lib/active_interaction/filters/float_filter.rb +13 -11
- data/lib/active_interaction/filters/hash_filter.rb +36 -17
- data/lib/active_interaction/filters/integer_filter.rb +13 -11
- data/lib/active_interaction/filters/model_filter.rb +15 -15
- data/lib/active_interaction/filters/string_filter.rb +19 -8
- data/lib/active_interaction/filters/symbol_filter.rb +29 -0
- data/lib/active_interaction/filters/time_filter.rb +38 -16
- data/lib/active_interaction/method_missing.rb +18 -0
- data/lib/active_interaction/overload_hash.rb +1 -0
- data/lib/active_interaction/validation.rb +19 -0
- data/lib/active_interaction/version.rb +1 -1
- data/spec/active_interaction/active_model_spec.rb +33 -0
- data/spec/active_interaction/base_spec.rb +54 -48
- data/spec/active_interaction/errors_spec.rb +99 -0
- data/spec/active_interaction/filter_spec.rb +12 -20
- data/spec/active_interaction/filters/array_filter_spec.rb +50 -28
- data/spec/active_interaction/filters/boolean_filter_spec.rb +15 -15
- data/spec/active_interaction/filters/date_filter_spec.rb +30 -18
- data/spec/active_interaction/filters/date_time_filter_spec.rb +31 -19
- data/spec/active_interaction/filters/file_filter_spec.rb +7 -7
- data/spec/active_interaction/filters/float_filter_spec.rb +13 -11
- data/spec/active_interaction/filters/hash_filter_spec.rb +38 -29
- data/spec/active_interaction/filters/integer_filter_spec.rb +18 -8
- data/spec/active_interaction/filters/model_filter_spec.rb +24 -20
- data/spec/active_interaction/filters/string_filter_spec.rb +14 -8
- data/spec/active_interaction/filters/symbol_filter_spec.rb +24 -0
- data/spec/active_interaction/filters/time_filter_spec.rb +33 -69
- data/spec/active_interaction/filters_spec.rb +21 -0
- data/spec/active_interaction/i18n_spec.rb +0 -15
- data/spec/active_interaction/integration/array_interaction_spec.rb +2 -22
- data/spec/active_interaction/integration/hash_interaction_spec.rb +5 -25
- data/spec/active_interaction/integration/symbol_interaction_spec.rb +5 -0
- data/spec/active_interaction/method_missing_spec.rb +69 -0
- data/spec/active_interaction/validation_spec.rb +55 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/filters.rb +168 -14
- data/spec/support/interactions.rb +11 -13
- metadata +31 -13
- data/lib/active_interaction/filter_method.rb +0 -13
- data/lib/active_interaction/filter_methods.rb +0 -26
- data/lib/active_interaction/filters/abstract_date_time_filter.rb +0 -25
- data/spec/active_interaction/filter_method_spec.rb +0 -43
- data/spec/active_interaction/filter_methods_spec.rb +0 -30
@@ -1,58 +1,67 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe ActiveInteraction::HashFilter do
|
3
|
+
describe ActiveInteraction::HashFilter, :filter do
|
4
4
|
include_context 'filters'
|
5
5
|
it_behaves_like 'a filter'
|
6
6
|
|
7
|
-
|
7
|
+
context 'with a nested nameless filter' do
|
8
|
+
let(:block) { Proc.new { hash } }
|
9
|
+
|
10
|
+
it 'raises an error' do
|
11
|
+
expect { filter }.to raise_error ActiveInteraction::InvalidFilterError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#cast' do
|
8
16
|
context 'with a Hash' do
|
9
17
|
let(:value) { {} }
|
10
18
|
|
11
19
|
it 'returns the Hash' do
|
12
|
-
expect(
|
20
|
+
expect(filter.cast(value)).to eq value
|
13
21
|
end
|
14
22
|
end
|
15
23
|
|
16
|
-
context 'with a
|
24
|
+
context 'with a non-empty Hash' do
|
25
|
+
let(:value) { { a: {} } }
|
26
|
+
|
27
|
+
it 'returns an empty Hash' do
|
28
|
+
expect(filter.cast(value)).to eq({})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'with a nested filter' do
|
17
33
|
let(:block) { Proc.new { hash :a } }
|
18
34
|
|
19
|
-
context 'with a Hash
|
35
|
+
context 'with a Hash' do
|
20
36
|
let(:value) { { a: {} } }
|
21
37
|
|
22
38
|
it 'returns the Hash' do
|
23
|
-
expect(
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'with a Hash containing anything else' do
|
28
|
-
let(:value) { { a: Object.new } }
|
29
|
-
|
30
|
-
it 'raises an error' do
|
31
|
-
expect {
|
32
|
-
result
|
33
|
-
}.to raise_error ActiveInteraction::InvalidNestedValue
|
39
|
+
expect(filter.cast(value)).to eq value
|
34
40
|
end
|
35
41
|
end
|
36
42
|
end
|
43
|
+
end
|
37
44
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
45
|
+
describe '#default' do
|
46
|
+
context 'with a Hash' do
|
47
|
+
before do
|
48
|
+
options.merge!(default: {})
|
49
|
+
end
|
43
50
|
|
44
|
-
|
45
|
-
|
46
|
-
end
|
51
|
+
it 'returns the Hash' do
|
52
|
+
expect(filter.default).to eq options[:default]
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
50
|
-
context 'with a
|
51
|
-
|
52
|
-
|
56
|
+
context 'with a non-empty Hash' do
|
57
|
+
before do
|
58
|
+
options.merge!(default: { a: {} })
|
59
|
+
end
|
53
60
|
|
54
|
-
it '
|
55
|
-
expect
|
61
|
+
it 'raises an error' do
|
62
|
+
expect {
|
63
|
+
filter.default
|
64
|
+
}.to raise_error ActiveInteraction::InvalidDefaultError
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
@@ -1,31 +1,41 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe ActiveInteraction::IntegerFilter do
|
3
|
+
describe ActiveInteraction::IntegerFilter, :filter do
|
4
4
|
include_context 'filters'
|
5
5
|
it_behaves_like 'a filter'
|
6
6
|
|
7
|
-
describe '
|
7
|
+
describe '#cast' do
|
8
8
|
context 'with an Integer' do
|
9
9
|
let(:value) { rand(1 << 16) }
|
10
10
|
|
11
11
|
it 'returns the Integer' do
|
12
|
-
expect(
|
12
|
+
expect(filter.cast(value)).to eq value
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
context 'with a
|
16
|
+
context 'with a Numeric' do
|
17
|
+
let(:value) { rand(1 << 16) + rand }
|
18
|
+
|
19
|
+
it 'returns an Integer' do
|
20
|
+
expect(filter.cast(value)).to eq value.to_i
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'with a String' do
|
17
25
|
let(:value) { rand(1 << 16).to_s }
|
18
26
|
|
19
|
-
it '
|
20
|
-
expect(
|
27
|
+
it 'returns an Integer' do
|
28
|
+
expect(filter.cast(value)).to eq Integer(value)
|
21
29
|
end
|
22
30
|
end
|
23
31
|
|
24
32
|
context 'with an invalid String' do
|
25
|
-
let(:value) { '
|
33
|
+
let(:value) { 'invalid' }
|
26
34
|
|
27
35
|
it 'raises an error' do
|
28
|
-
expect {
|
36
|
+
expect {
|
37
|
+
filter.cast(value)
|
38
|
+
}.to raise_error ActiveInteraction::InvalidValueError
|
29
39
|
end
|
30
40
|
end
|
31
41
|
end
|
@@ -1,39 +1,43 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
3
|
+
class Model; end
|
4
4
|
|
5
|
-
describe ActiveInteraction::ModelFilter do
|
5
|
+
describe ActiveInteraction::ModelFilter, :filter do
|
6
6
|
include_context 'filters'
|
7
7
|
it_behaves_like 'a filter'
|
8
8
|
|
9
|
-
before
|
9
|
+
before do
|
10
|
+
options.merge!(class: Model)
|
11
|
+
end
|
10
12
|
|
11
|
-
describe '
|
12
|
-
|
13
|
-
context 'with the right class' do
|
14
|
-
let(:value) { TestModel.new }
|
13
|
+
describe '#cast' do
|
14
|
+
let(:value) { Model.new }
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
context 'with class as a Class' do
|
17
|
+
it 'returns the instance' do
|
18
|
+
expect(filter.cast(value)).to eq value
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
context 'with
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
context 'with options[:class] as a valid String' do
|
27
|
-
include_examples 'type checking'
|
22
|
+
context 'with class as a String' do
|
23
|
+
before do
|
24
|
+
options.merge!(class: Model.name)
|
25
|
+
end
|
28
26
|
|
29
|
-
|
27
|
+
it 'returns the instance' do
|
28
|
+
expect(filter.cast(value)).to eq value
|
29
|
+
end
|
30
30
|
end
|
31
31
|
|
32
|
-
context 'with
|
33
|
-
before
|
32
|
+
context 'with class as an invalid String' do
|
33
|
+
before do
|
34
|
+
options.merge!(class: 'invalid')
|
35
|
+
end
|
34
36
|
|
35
37
|
it 'raises an error' do
|
36
|
-
expect {
|
38
|
+
expect {
|
39
|
+
filter.cast(value)
|
40
|
+
}.to raise_error ActiveInteraction::InvalidClassError
|
37
41
|
end
|
38
42
|
end
|
39
43
|
end
|
@@ -1,30 +1,36 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe ActiveInteraction::StringFilter do
|
3
|
+
describe ActiveInteraction::StringFilter, :filter do
|
4
4
|
include_context 'filters'
|
5
5
|
it_behaves_like 'a filter'
|
6
6
|
|
7
|
-
|
7
|
+
shared_context 'without strip' do
|
8
|
+
before do
|
9
|
+
options.merge!(strip: false)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#cast' do
|
8
14
|
context 'with a String' do
|
9
15
|
let(:value) { SecureRandom.hex }
|
10
16
|
|
11
17
|
it 'returns the String' do
|
12
|
-
expect(
|
18
|
+
expect(filter.cast(value)).to eq value
|
13
19
|
end
|
14
20
|
end
|
15
21
|
|
16
22
|
context 'with a strippable String' do
|
17
23
|
let(:value) { " #{SecureRandom.hex} " }
|
18
24
|
|
19
|
-
it 'returns the stripped
|
20
|
-
expect(
|
25
|
+
it 'returns the stripped string' do
|
26
|
+
expect(filter.cast(value)).to eq value.strip
|
21
27
|
end
|
22
28
|
|
23
|
-
context '
|
24
|
-
|
29
|
+
context 'without strip' do
|
30
|
+
include_context 'without strip'
|
25
31
|
|
26
32
|
it 'returns the String' do
|
27
|
-
expect(
|
33
|
+
expect(filter.cast(value)).to eq value
|
28
34
|
end
|
29
35
|
end
|
30
36
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveInteraction::SymbolFilter, :filter do
|
4
|
+
include_context 'filters'
|
5
|
+
it_behaves_like 'a filter'
|
6
|
+
|
7
|
+
describe '#cast' do
|
8
|
+
context 'with a Symbol' do
|
9
|
+
let(:value) { SecureRandom.hex.to_sym }
|
10
|
+
|
11
|
+
it 'returns the Symbol' do
|
12
|
+
expect(filter.cast(value)).to eq value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'with a String' do
|
17
|
+
let(:value) { SecureRandom.hex }
|
18
|
+
|
19
|
+
it 'returns a Symbol' do
|
20
|
+
expect(filter.cast(value)).to eq value.to_sym
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,96 +1,60 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe ActiveInteraction::TimeFilter do
|
3
|
+
describe ActiveInteraction::TimeFilter, :filter do
|
4
4
|
include_context 'filters'
|
5
5
|
it_behaves_like 'a filter'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
let(:value) { Time.now }
|
7
|
+
shared_context 'with format' do
|
8
|
+
let(:format) { '%d/%m/%Y %H:%M:%S %z' }
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
end
|
10
|
+
before do
|
11
|
+
options.merge!(format: format)
|
14
12
|
end
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
it 'converts the Float' do
|
21
|
-
expect(result).to eql Time.at(value)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'with an Integer' do
|
26
|
-
let(:value) { rand(1 << 16) }
|
15
|
+
describe '#cast' do
|
16
|
+
context 'with a Time' do
|
17
|
+
let(:value) { Time.new }
|
27
18
|
|
28
|
-
|
29
|
-
|
30
|
-
end
|
19
|
+
it 'returns the Time' do
|
20
|
+
expect(filter.cast(value)).to eq value
|
31
21
|
end
|
22
|
+
end
|
32
23
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
it 'parses the String' do
|
37
|
-
expect(result).to eql Time.parse(value)
|
38
|
-
end
|
39
|
-
|
40
|
-
context 'with options[:format]' do
|
41
|
-
let(:value) { '01010101012001' }
|
42
|
-
|
43
|
-
before { options.merge!(format: '%S%M%H%d%m%Y') }
|
24
|
+
context 'with a String' do
|
25
|
+
let(:value) { '2011-12-13 14:15:16 +1718' }
|
44
26
|
|
45
|
-
|
46
|
-
|
47
|
-
end
|
48
|
-
end
|
27
|
+
it 'returns a Time' do
|
28
|
+
expect(filter.cast(value)).to eq Time.parse(value)
|
49
29
|
end
|
50
30
|
|
51
|
-
context 'with
|
52
|
-
|
31
|
+
context 'with format' do
|
32
|
+
include_context 'with format'
|
53
33
|
|
54
|
-
|
55
|
-
expect { result }.to raise_error ActiveInteraction::InvalidValue
|
56
|
-
end
|
57
|
-
|
58
|
-
context 'with options[:format]' do
|
59
|
-
before { options.merge!(format: '%S%M%H%d%m%Y') }
|
34
|
+
let(:value) { '13/12/2011 14:15:16 +1718' }
|
60
35
|
|
61
|
-
|
62
|
-
|
63
|
-
end
|
36
|
+
it 'returns a Time' do
|
37
|
+
expect(filter.cast(value)).to eq Time.strptime(value, format)
|
64
38
|
end
|
65
39
|
end
|
66
40
|
end
|
67
41
|
|
68
|
-
context '
|
69
|
-
|
70
|
-
end
|
42
|
+
context 'with an invalid String' do
|
43
|
+
let(:value) { 'invalid' }
|
71
44
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
before do
|
77
|
-
allow(Time).to receive(:zone).and_return(nil)
|
78
|
-
end
|
79
|
-
|
80
|
-
after do
|
81
|
-
expect(Time).to have_received(:zone).once.with(no_args)
|
82
|
-
end
|
45
|
+
it 'raises an error' do
|
46
|
+
expect {
|
47
|
+
filter.cast(value)
|
48
|
+
}.to raise_error ActiveInteraction::InvalidValueError
|
83
49
|
end
|
84
50
|
|
85
|
-
context '
|
86
|
-
|
87
|
-
|
88
|
-
before do
|
89
|
-
allow(Time).to receive(:zone).and_return(Time)
|
90
|
-
end
|
51
|
+
context 'with format' do
|
52
|
+
include_context 'with format'
|
91
53
|
|
92
|
-
|
93
|
-
expect
|
54
|
+
it do
|
55
|
+
expect {
|
56
|
+
filter.cast(value)
|
57
|
+
}.to raise_error ActiveInteraction::InvalidValueError
|
94
58
|
end
|
95
59
|
end
|
96
60
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveInteraction::Filters do
|
4
|
+
describe '#each' do
|
5
|
+
it 'returns an Enumerator' do
|
6
|
+
expect(subject.each).to be_an Enumerator
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '#add(filter)' do
|
11
|
+
it 'returns self' do
|
12
|
+
expect(subject.add(double)).to equal subject
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'adds the filter' do
|
16
|
+
filter = double
|
17
|
+
|
18
|
+
expect(subject.add(filter).to_a).to eql [filter]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -52,21 +52,6 @@ describe I18nInteraction do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
context ':invalid_nested' do
|
56
|
-
let(:key) {
|
57
|
-
"#{described_class.i18n_scope}.errors.messages.invalid_nested"
|
58
|
-
}
|
59
|
-
|
60
|
-
it 'has a translation' do
|
61
|
-
expect { translation }.to_not raise_error
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'returns the translation' do
|
65
|
-
options.merge!(a: { x: Object.new })
|
66
|
-
expect(outcome.errors[:a]).to eq [translation]
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
55
|
context ':missing' do
|
71
56
|
let(:key) { "#{described_class.i18n_scope}.errors.messages.missing" }
|
72
57
|
|