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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +27 -3
  3. data/README.md +8 -6
  4. data/lib/active_interaction.rb +5 -3
  5. data/lib/active_interaction/active_model.rb +29 -0
  6. data/lib/active_interaction/base.rb +82 -116
  7. data/lib/active_interaction/errors.rb +79 -5
  8. data/lib/active_interaction/filter.rb +195 -21
  9. data/lib/active_interaction/filters.rb +26 -0
  10. data/lib/active_interaction/filters/array_filter.rb +22 -25
  11. data/lib/active_interaction/filters/boolean_filter.rb +12 -12
  12. data/lib/active_interaction/filters/date_filter.rb +32 -5
  13. data/lib/active_interaction/filters/date_time_filter.rb +34 -7
  14. data/lib/active_interaction/filters/file_filter.rb +12 -9
  15. data/lib/active_interaction/filters/float_filter.rb +13 -11
  16. data/lib/active_interaction/filters/hash_filter.rb +36 -17
  17. data/lib/active_interaction/filters/integer_filter.rb +13 -11
  18. data/lib/active_interaction/filters/model_filter.rb +15 -15
  19. data/lib/active_interaction/filters/string_filter.rb +19 -8
  20. data/lib/active_interaction/filters/symbol_filter.rb +29 -0
  21. data/lib/active_interaction/filters/time_filter.rb +38 -16
  22. data/lib/active_interaction/method_missing.rb +18 -0
  23. data/lib/active_interaction/overload_hash.rb +1 -0
  24. data/lib/active_interaction/validation.rb +19 -0
  25. data/lib/active_interaction/version.rb +1 -1
  26. data/spec/active_interaction/active_model_spec.rb +33 -0
  27. data/spec/active_interaction/base_spec.rb +54 -48
  28. data/spec/active_interaction/errors_spec.rb +99 -0
  29. data/spec/active_interaction/filter_spec.rb +12 -20
  30. data/spec/active_interaction/filters/array_filter_spec.rb +50 -28
  31. data/spec/active_interaction/filters/boolean_filter_spec.rb +15 -15
  32. data/spec/active_interaction/filters/date_filter_spec.rb +30 -18
  33. data/spec/active_interaction/filters/date_time_filter_spec.rb +31 -19
  34. data/spec/active_interaction/filters/file_filter_spec.rb +7 -7
  35. data/spec/active_interaction/filters/float_filter_spec.rb +13 -11
  36. data/spec/active_interaction/filters/hash_filter_spec.rb +38 -29
  37. data/spec/active_interaction/filters/integer_filter_spec.rb +18 -8
  38. data/spec/active_interaction/filters/model_filter_spec.rb +24 -20
  39. data/spec/active_interaction/filters/string_filter_spec.rb +14 -8
  40. data/spec/active_interaction/filters/symbol_filter_spec.rb +24 -0
  41. data/spec/active_interaction/filters/time_filter_spec.rb +33 -69
  42. data/spec/active_interaction/filters_spec.rb +21 -0
  43. data/spec/active_interaction/i18n_spec.rb +0 -15
  44. data/spec/active_interaction/integration/array_interaction_spec.rb +2 -22
  45. data/spec/active_interaction/integration/hash_interaction_spec.rb +5 -25
  46. data/spec/active_interaction/integration/symbol_interaction_spec.rb +5 -0
  47. data/spec/active_interaction/method_missing_spec.rb +69 -0
  48. data/spec/active_interaction/validation_spec.rb +55 -0
  49. data/spec/spec_helper.rb +6 -0
  50. data/spec/support/filters.rb +168 -14
  51. data/spec/support/interactions.rb +11 -13
  52. metadata +31 -13
  53. data/lib/active_interaction/filter_method.rb +0 -13
  54. data/lib/active_interaction/filter_methods.rb +0 -26
  55. data/lib/active_interaction/filters/abstract_date_time_filter.rb +0 -25
  56. data/spec/active_interaction/filter_method_spec.rb +0 -43
  57. data/spec/active_interaction/filter_methods_spec.rb +0 -30
@@ -1,29 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
- module ActiveInteraction
4
- TestFilter = Class.new(Filter)
5
- end
6
-
7
- describe ActiveInteraction::Filter do
8
- it_behaves_like 'a filter'
9
-
10
- describe '.factory(type)' do
11
- let(:result) { described_class.factory(type) }
3
+ class ActiveInteraction::TestFilter < ActiveInteraction::Filter; end
12
4
 
13
- context 'with a valid type' do
14
- let(:type) { :test }
5
+ describe ActiveInteraction::Filter, :filter do
6
+ include_context 'filters'
15
7
 
16
- it 'returns the Class' do
17
- expect(result).to eql ActiveInteraction::TestFilter
18
- end
8
+ describe '.slug' do
9
+ it 'raises an error' do
10
+ expect {
11
+ described_class.slug
12
+ }.to raise_error ActiveInteraction::InvalidClassError
19
13
  end
14
+ end
20
15
 
21
- context 'with an invalid type' do
22
- let(:type) { :not_a_valid_type }
16
+ context ActiveInteraction::TestFilter do
17
+ it_behaves_like 'a filter'
23
18
 
24
- it 'raises an error' do
25
- expect { result }.to raise_error NoMethodError
26
- end
27
- end
19
+ let(:described_class) { ActiveInteraction::TestFilter }
28
20
  end
29
21
  end
@@ -1,55 +1,77 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveInteraction::ArrayFilter do
3
+ describe ActiveInteraction::ArrayFilter, :filter do
4
4
  include_context 'filters'
5
5
  it_behaves_like 'a filter'
6
6
 
7
- describe '.prepare(key, value, options = {}, &block)' do
7
+ context 'with multiple nested filters' do
8
+ let(:block) { Proc.new { array; array } }
9
+
10
+ it 'raises an error' do
11
+ expect { filter }.to raise_error ActiveInteraction::InvalidFilterError
12
+ end
13
+ end
14
+
15
+ context 'with a nested name' do
16
+ let(:block) { Proc.new { array :a } }
17
+
18
+ it 'raises an error' do
19
+ expect { filter }.to raise_error ActiveInteraction::InvalidFilterError
20
+ end
21
+ end
22
+
23
+ context 'with a nested default' do
24
+ let(:block) { Proc.new { array default: nil } }
25
+
26
+ it 'raises an error' do
27
+ expect { filter }.to raise_error ActiveInteraction::InvalidDefaultError
28
+ end
29
+ end
30
+
31
+ describe '#cast' do
8
32
  context 'with an Array' do
9
33
  let(:value) { [] }
10
34
 
11
35
  it 'returns the Array' do
12
- expect(result).to eql value
36
+ expect(filter.cast(value)).to eq value
37
+ end
38
+ end
39
+
40
+ context 'with a heterogenous Array' do
41
+ let(:value) { [[], false, 0.0, {}, 0, '', :''] }
42
+
43
+ it 'returns the Array' do
44
+ expect(filter.cast(value)).to eq value
13
45
  end
14
46
  end
15
47
 
16
- context 'with a block' do
48
+ context 'with a nested filter' do
17
49
  let(:block) { Proc.new { array } }
18
50
 
19
- context 'with an Array of Arrays' do
20
- let(:value) { [[]] }
51
+ context 'with an Array' do
52
+ let(:value) { [] }
21
53
 
22
54
  it 'returns the Array' do
23
- expect(result).to eql value
55
+ expect(filter.cast(value)).to eq value
24
56
  end
25
57
  end
26
58
 
27
- context 'with an Array of anything else' do
28
- let(:value) { [Object.new] }
59
+ context 'with an Array of Arrays' do
60
+ let(:value) { [[]] }
29
61
 
30
- it 'raises an error' do
31
- expect {
32
- result
33
- }.to raise_error ActiveInteraction::InvalidNestedValue
62
+ it 'returns the Array' do
63
+ expect(filter.cast(value)).to eq value
34
64
  end
35
65
  end
36
- end
37
-
38
- context 'with a nested block' do
39
- let(:block) { Proc.new { array { array } } }
40
- let(:value) { [[[]]] }
41
-
42
- it 'returns the Array' do
43
- expect(result).to eql value
44
- end
45
- end
46
66
 
47
- context 'with an invalid block' do
48
- let(:block) { Proc.new { array; array } }
49
- let(:value) { [] }
67
+ context 'with a heterogenous Array' do
68
+ let(:value) { [[], false, 0.0, {}, 0, '', :''] }
50
69
 
51
- it 'raises an error' do
52
- expect { result }.to raise_error ArgumentError
70
+ it 'raises an error' do
71
+ expect{
72
+ filter.cast(value)
73
+ }.to raise_error ActiveInteraction::InvalidValueError
74
+ end
53
75
  end
54
76
  end
55
77
  end
@@ -1,31 +1,23 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveInteraction::BooleanFilter do
3
+ describe ActiveInteraction::BooleanFilter, :filter do
4
4
  include_context 'filters'
5
5
  it_behaves_like 'a filter'
6
6
 
7
- describe '.prepare(key, value, options = {}, &block)' do
8
- context 'with true' do
9
- let(:value) { true }
10
-
11
- it 'returns true' do
12
- expect(result).to eql true
13
- end
14
- end
15
-
7
+ describe '#cast' do
16
8
  context 'with false' do
17
9
  let(:value) { false }
18
10
 
19
11
  it 'returns false' do
20
- expect(result).to eql false
12
+ expect(filter.cast(value)).to be_false
21
13
  end
22
14
  end
23
15
 
24
- context 'with "1"' do
25
- let(:value) { '1' }
16
+ context 'with true' do
17
+ let(:value) { true }
26
18
 
27
19
  it 'returns true' do
28
- expect(result).to eql true
20
+ expect(filter.cast(value)).to be_true
29
21
  end
30
22
  end
31
23
 
@@ -33,7 +25,15 @@ describe ActiveInteraction::BooleanFilter do
33
25
  let(:value) { '0' }
34
26
 
35
27
  it 'returns false' do
36
- expect(result).to eql false
28
+ expect(filter.cast(value)).to be_false
29
+ end
30
+ end
31
+
32
+ context 'with "1"' do
33
+ let(:value) { '1' }
34
+
35
+ it 'returns true' do
36
+ expect(filter.cast(value)).to be_true
37
37
  end
38
38
  end
39
39
  end
@@ -1,48 +1,60 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveInteraction::DateFilter do
3
+ describe ActiveInteraction::DateFilter, :filter do
4
4
  include_context 'filters'
5
5
  it_behaves_like 'a filter'
6
6
 
7
- describe '.prepare(key, value, options = {}, &block)' do
7
+ shared_context 'with format' do
8
+ let(:format) { '%d/%m/%Y' }
9
+
10
+ before do
11
+ options.merge!(format: format)
12
+ end
13
+ end
14
+
15
+ describe '#cast' do
8
16
  context 'with a Date' do
9
- let(:value) { Date.today }
17
+ let(:value) { Date.new }
10
18
 
11
19
  it 'returns the Date' do
12
- expect(result).to eql value
20
+ expect(filter.cast(value)).to eq value
13
21
  end
14
22
  end
15
23
 
16
- context 'with a valid String' do
17
- let(:value) { '2001-01-01' }
24
+ context 'with a String' do
25
+ let(:value) { '2011-12-13' }
18
26
 
19
- it 'parses the String' do
20
- expect(result).to eql Date.parse(value)
27
+ it 'returns a Date' do
28
+ expect(filter.cast(value)).to eq Date.parse(value)
21
29
  end
22
30
 
23
- context 'with options[:format]' do
24
- let(:value) { '01012001' }
31
+ context 'with format' do
32
+ include_context 'with format'
25
33
 
26
- before { options.merge!(format: '%m%d%Y') }
34
+ let(:value) { '13/12/2011' }
27
35
 
28
- it 'parses the String' do
29
- expect(result).to eql Date.strptime(value, options[:format])
36
+ it 'returns a Date' do
37
+ expect(filter.cast(value)).to eq Date.strptime(value, format)
30
38
  end
31
39
  end
32
40
  end
33
41
 
34
42
  context 'with an invalid String' do
35
- let(:value) { 'not a valid Date' }
43
+ let(:value) { 'invalid' }
36
44
 
37
45
  it 'raises an error' do
38
- expect { result }.to raise_error ActiveInteraction::InvalidValue
46
+ expect {
47
+ filter.cast(value)
48
+ }.to raise_error ActiveInteraction::InvalidValueError
39
49
  end
40
50
 
41
- context 'with options[:format]' do
42
- before { options.merge!(format: '%m%d%Y') }
51
+ context 'with format' do
52
+ include_context 'with format'
43
53
 
44
54
  it 'raises an error' do
45
- expect { result }.to raise_error ActiveInteraction::InvalidValue
55
+ expect {
56
+ filter.cast(value)
57
+ }.to raise_error ActiveInteraction::InvalidValueError
46
58
  end
47
59
  end
48
60
  end
@@ -1,48 +1,60 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveInteraction::DateTimeFilter do
3
+ describe ActiveInteraction::DateTimeFilter, :filter do
4
4
  include_context 'filters'
5
5
  it_behaves_like 'a filter'
6
6
 
7
- describe '.prepare(key, value, options = {}, &block)' do
8
- context 'with a DateTime' do
9
- let(:value) { DateTime.now }
7
+ shared_context 'with format' do
8
+ let(:format) { '%d/%m/%Y %H:%M:%S %:z' }
9
+
10
+ before do
11
+ options.merge!(format: format)
12
+ end
13
+ end
14
+
15
+ describe '#cast' do
16
+ context 'with a Datetime' do
17
+ let(:value) { DateTime.new }
10
18
 
11
19
  it 'returns the DateTime' do
12
- expect(result).to eql value
20
+ expect(filter.cast(value)).to eq value
13
21
  end
14
22
  end
15
23
 
16
- context 'with a valid String' do
17
- let(:value) { '2001-01-01T01:01:01+01:01' }
24
+ context 'with a String' do
25
+ let(:value) { '2011-12-13T14:15:16+17:18' }
18
26
 
19
- it 'parses the String' do
20
- expect(result).to eql DateTime.parse(value)
27
+ it 'returns a DateTime' do
28
+ expect(filter.cast(value)).to eq DateTime.parse(value)
21
29
  end
22
30
 
23
- context 'with options[:format]' do
24
- let(:value) { '01010101012001' }
31
+ context 'with format' do
32
+ include_context 'with format'
25
33
 
26
- before { options.merge!(format: '%S%M%H%m%d%Y') }
34
+ let(:value) { '13/12/2011 14:15:16 +17:18' }
27
35
 
28
- it 'parses the String' do
29
- expect(result).to eql DateTime.strptime(value, options[:format])
36
+ it 'returns a DateTime' do
37
+ expect(filter.cast(value)).to eq DateTime.strptime(value, format)
30
38
  end
31
39
  end
32
40
  end
33
41
 
34
42
  context 'with an invalid String' do
35
- let(:value) { 'not a valid DateTine' }
43
+ let(:value) { 'invalid' }
36
44
 
37
45
  it 'raises an error' do
38
- expect { result }.to raise_error ActiveInteraction::InvalidValue
46
+ expect {
47
+ filter.cast(value)
48
+ }.to raise_error ActiveInteraction::InvalidValueError
39
49
  end
40
50
 
41
- context 'with options[:format]' do
42
- before { options.merge!(format: '%S%M%H%m%d%Y') }
51
+ context 'with format' do
52
+ include_context 'with format'
43
53
 
44
54
  it 'raises an error' do
45
- expect { result }.to raise_error ActiveInteraction::InvalidValue
55
+ expect {
56
+ filter.cast(value)
57
+ }.to raise_error ActiveInteraction::InvalidValueError
46
58
  end
47
59
  end
48
60
  end
@@ -1,15 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveInteraction::FileFilter do
3
+ describe ActiveInteraction::FileFilter, :filter do
4
4
  include_context 'filters'
5
5
  it_behaves_like 'a filter'
6
6
 
7
- describe '.prepare(key, value, options = {}, &block)' do
7
+ describe '#cast' do
8
8
  context 'with a File' do
9
- let(:value) { File.open(__FILE__) }
9
+ let(:value) { File.new(__FILE__) }
10
10
 
11
11
  it 'returns the File' do
12
- expect(result).to equal value
12
+ expect(filter.cast(value)).to eq value
13
13
  end
14
14
  end
15
15
 
@@ -17,15 +17,15 @@ describe ActiveInteraction::FileFilter do
17
17
  let(:value) { Tempfile.new(SecureRandom.hex) }
18
18
 
19
19
  it 'returns the Tempfile' do
20
- expect(result).to equal value
20
+ expect(filter.cast(value)).to eq value
21
21
  end
22
22
  end
23
23
 
24
- context 'with a object that responds to `tempfile`' do
24
+ context 'with an object that responds to #tempfile' do
25
25
  let(:value) { double(tempfile: Tempfile.new(SecureRandom.hex)) }
26
26
 
27
27
  it 'returns the Tempfile' do
28
- expect(result).to equal value.tempfile
28
+ expect(filter.cast(value)).to eq value.tempfile
29
29
  end
30
30
  end
31
31
  end
@@ -1,39 +1,41 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe ActiveInteraction::FloatFilter do
3
+ describe ActiveInteraction::FloatFilter, :filter do
4
4
  include_context 'filters'
5
5
  it_behaves_like 'a filter'
6
6
 
7
- describe '.prepare(key, value, options = {}, &block)' do
7
+ describe '#cast' do
8
8
  context 'with a Float' do
9
9
  let(:value) { rand }
10
10
 
11
11
  it 'returns the Float' do
12
- expect(result).to eql value
12
+ expect(filter.cast(value)).to eq value
13
13
  end
14
14
  end
15
15
 
16
- context 'with an Integer' do
16
+ context 'with a Numeric' do
17
17
  let(:value) { rand(1 << 16) }
18
18
 
19
- it 'converts the Integer' do
20
- expect(result).to eql Float(value)
19
+ it 'returns a Float' do
20
+ expect(filter.cast(value)).to eq value.to_f
21
21
  end
22
22
  end
23
23
 
24
- context 'with a valid String' do
24
+ context 'with a String' do
25
25
  let(:value) { rand.to_s }
26
26
 
27
- it 'converts the String' do
28
- expect(result).to eql Float(value)
27
+ it 'returns a Float' do
28
+ expect(filter.cast(value)).to eq Float(value)
29
29
  end
30
30
  end
31
31
 
32
32
  context 'with an invalid String' do
33
- let(:value) { 'not a valid Float' }
33
+ let(:value) { 'invalid' }
34
34
 
35
35
  it 'raises an error' do
36
- expect { result }.to raise_error ActiveInteraction::InvalidValue
36
+ expect {
37
+ filter.cast(value)
38
+ }.to raise_error ActiveInteraction::InvalidValueError
37
39
  end
38
40
  end
39
41
  end