active_interaction 1.1.7 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -1
  3. data/README.md +3 -2
  4. data/lib/active_interaction.rb +7 -1
  5. data/lib/active_interaction/base.rb +61 -13
  6. data/lib/active_interaction/concerns/runnable.rb +2 -18
  7. data/lib/active_interaction/concerns/transactable.rb +72 -0
  8. data/lib/active_interaction/errors.rb +7 -0
  9. data/lib/active_interaction/filter.rb +23 -2
  10. data/lib/active_interaction/filter_column.rb +59 -0
  11. data/lib/active_interaction/filters/abstract_date_time_filter.rb +14 -0
  12. data/lib/active_interaction/filters/abstract_filter.rb +4 -7
  13. data/lib/active_interaction/filters/abstract_numeric_filter.rb +4 -0
  14. data/lib/active_interaction/filters/boolean_filter.rb +4 -0
  15. data/lib/active_interaction/filters/date_time_filter.rb +3 -0
  16. data/lib/active_interaction/filters/decimal_filter.rb +54 -0
  17. data/lib/active_interaction/filters/file_filter.rb +4 -0
  18. data/lib/active_interaction/filters/time_filter.rb +4 -0
  19. data/lib/active_interaction/grouped_input.rb +24 -0
  20. data/lib/active_interaction/locale/en.yml +1 -0
  21. data/lib/active_interaction/modules/input_processor.rb +40 -0
  22. data/lib/active_interaction/version.rb +1 -1
  23. data/spec/active_interaction/base_spec.rb +90 -29
  24. data/spec/active_interaction/concerns/runnable_spec.rb +0 -26
  25. data/spec/active_interaction/concerns/transactable_spec.rb +114 -0
  26. data/spec/active_interaction/filter_column_spec.rb +96 -0
  27. data/spec/active_interaction/filter_spec.rb +15 -11
  28. data/spec/active_interaction/filters/array_filter_spec.rb +13 -5
  29. data/spec/active_interaction/filters/boolean_filter_spec.rb +6 -0
  30. data/spec/active_interaction/filters/date_filter_spec.rb +76 -5
  31. data/spec/active_interaction/filters/date_time_filter_spec.rb +87 -5
  32. data/spec/active_interaction/filters/decimal_filter_spec.rb +70 -0
  33. data/spec/active_interaction/filters/file_filter_spec.rb +11 -3
  34. data/spec/active_interaction/filters/float_filter_spec.rb +12 -4
  35. data/spec/active_interaction/filters/hash_filter_spec.rb +16 -8
  36. data/spec/active_interaction/filters/integer_filter_spec.rb +12 -4
  37. data/spec/active_interaction/filters/model_filter_spec.rb +12 -5
  38. data/spec/active_interaction/filters/string_filter_spec.rb +11 -3
  39. data/spec/active_interaction/filters/symbol_filter_spec.rb +10 -2
  40. data/spec/active_interaction/filters/time_filter_spec.rb +87 -5
  41. data/spec/active_interaction/grouped_input_spec.rb +19 -0
  42. data/spec/active_interaction/modules/input_processor_spec.rb +75 -0
  43. data/spec/support/filters.rb +6 -0
  44. metadata +16 -1
@@ -0,0 +1,70 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ActiveInteraction::DecimalFilter, :filter do
6
+ include_context 'filters'
7
+ it_behaves_like 'a filter'
8
+
9
+ shared_context 'with digits' do
10
+ let(:digits) { 4 }
11
+
12
+ before do
13
+ options.merge!(digits: digits)
14
+ end
15
+ end
16
+
17
+ describe '#cast' do
18
+ let(:result) { filter.cast(value) }
19
+
20
+ context 'with a Float' do
21
+ let(:value) { rand }
22
+
23
+ it 'returns the BigDecimal' do
24
+ expect(result).to eql BigDecimal.new(value, 0)
25
+ end
26
+
27
+ context 'with :digits option' do
28
+ include_context 'with digits'
29
+
30
+ let(:value) { 1.23456789 }
31
+
32
+ it 'returns BigDecimal with given digits' do
33
+ expect(result).to eql BigDecimal.new('1.235')
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'with a Numeric' do
39
+ let(:value) { rand(1 << 16) }
40
+
41
+ it 'returns a BigDecimal' do
42
+ expect(result).to eql BigDecimal.new(value)
43
+ end
44
+ end
45
+
46
+ context 'with a String' do
47
+ let(:value) { rand.to_s }
48
+
49
+ it 'returns a BigDecimal' do
50
+ expect(result).to eql BigDecimal.new(value)
51
+ end
52
+ end
53
+
54
+ context 'with an invalid String' do
55
+ let(:value) { 'invalid' }
56
+
57
+ it 'raises an error' do
58
+ expect do
59
+ result
60
+ end.to raise_error ActiveInteraction::InvalidValueError
61
+ end
62
+ end
63
+ end
64
+
65
+ describe '#database_column_type' do
66
+ it 'returns :decimal' do
67
+ expect(filter.database_column_type).to eql :decimal
68
+ end
69
+ end
70
+ end
@@ -7,11 +7,13 @@ describe ActiveInteraction::FileFilter, :filter do
7
7
  it_behaves_like 'a filter'
8
8
 
9
9
  describe '#cast' do
10
+ let(:result) { filter.cast(value) }
11
+
10
12
  context 'with a File' do
11
13
  let(:value) { File.new(__FILE__) }
12
14
 
13
15
  it 'returns the File' do
14
- expect(filter.cast(value)).to eql value
16
+ expect(result).to eql value
15
17
  end
16
18
  end
17
19
 
@@ -19,7 +21,7 @@ describe ActiveInteraction::FileFilter, :filter do
19
21
  let(:value) { Tempfile.new(SecureRandom.hex) }
20
22
 
21
23
  it 'returns the Tempfile' do
22
- expect(filter.cast(value)).to eq value
24
+ expect(result).to eq value
23
25
  end
24
26
  end
25
27
 
@@ -27,8 +29,14 @@ describe ActiveInteraction::FileFilter, :filter do
27
29
  let(:value) { double(tempfile: Tempfile.new(SecureRandom.hex)) }
28
30
 
29
31
  it 'returns the Tempfile' do
30
- expect(filter.cast(value)).to eq value.tempfile
32
+ expect(result).to eq value.tempfile
31
33
  end
32
34
  end
33
35
  end
36
+
37
+ describe '#database_column_type' do
38
+ it 'returns :file' do
39
+ expect(filter.database_column_type).to eql :file
40
+ end
41
+ end
34
42
  end
@@ -7,11 +7,13 @@ describe ActiveInteraction::FloatFilter, :filter do
7
7
  it_behaves_like 'a filter'
8
8
 
9
9
  describe '#cast' do
10
+ let(:result) { filter.cast(value) }
11
+
10
12
  context 'with a Float' do
11
13
  let(:value) { rand }
12
14
 
13
15
  it 'returns the Float' do
14
- expect(filter.cast(value)).to eql value
16
+ expect(result).to eql value
15
17
  end
16
18
  end
17
19
 
@@ -19,7 +21,7 @@ describe ActiveInteraction::FloatFilter, :filter do
19
21
  let(:value) { rand(1 << 16) }
20
22
 
21
23
  it 'returns a Float' do
22
- expect(filter.cast(value)).to eql value.to_f
24
+ expect(result).to eql value.to_f
23
25
  end
24
26
  end
25
27
 
@@ -27,7 +29,7 @@ describe ActiveInteraction::FloatFilter, :filter do
27
29
  let(:value) { rand.to_s }
28
30
 
29
31
  it 'returns a Float' do
30
- expect(filter.cast(value)).to eql Float(value)
32
+ expect(result).to eql Float(value)
31
33
  end
32
34
  end
33
35
 
@@ -36,9 +38,15 @@ describe ActiveInteraction::FloatFilter, :filter do
36
38
 
37
39
  it 'raises an error' do
38
40
  expect do
39
- filter.cast(value)
41
+ result
40
42
  end.to raise_error ActiveInteraction::InvalidValueError
41
43
  end
42
44
  end
43
45
  end
46
+
47
+ describe '#database_column_type' do
48
+ it 'returns :float' do
49
+ expect(filter.database_column_type).to eql :float
50
+ end
51
+ end
44
52
  end
@@ -15,11 +15,13 @@ describe ActiveInteraction::HashFilter, :filter do
15
15
  end
16
16
 
17
17
  describe '#cast' do
18
+ let(:result) { filter.cast(value) }
19
+
18
20
  context 'with a Hash' do
19
21
  let(:value) { {} }
20
22
 
21
23
  it 'returns the Hash' do
22
- expect(filter.cast(value)).to eql value
24
+ expect(result).to eql value
23
25
  end
24
26
  end
25
27
 
@@ -27,7 +29,7 @@ describe ActiveInteraction::HashFilter, :filter do
27
29
  let(:value) { { a: {} } }
28
30
 
29
31
  it 'returns an empty Hash' do
30
- expect(filter.cast(value)).to eql({})
32
+ expect(result).to eql({})
31
33
  end
32
34
  end
33
35
 
@@ -38,7 +40,7 @@ describe ActiveInteraction::HashFilter, :filter do
38
40
  let(:value) { { a: {} } }
39
41
 
40
42
  it 'returns the Hash' do
41
- expect(filter.cast(value)).to eql value
43
+ expect(result).to eql value
42
44
  end
43
45
 
44
46
  context 'with String keys' do
@@ -47,7 +49,7 @@ describe ActiveInteraction::HashFilter, :filter do
47
49
  end
48
50
 
49
51
  it 'does not raise an error' do
50
- expect { filter.cast(value) }.to_not raise_error
52
+ expect { result }.to_not raise_error
51
53
  end
52
54
  end
53
55
  end
@@ -59,13 +61,13 @@ describe ActiveInteraction::HashFilter, :filter do
59
61
 
60
62
  it 'raises an error' do
61
63
  expect do
62
- filter.cast(value)
64
+ result
63
65
  end.to raise_error ActiveInteraction::InvalidNestedValueError
64
66
  end
65
67
 
66
68
  it 'populates the error' do
67
69
  begin
68
- filter.cast(value)
70
+ result
69
71
  rescue ActiveInteraction::InvalidNestedValueError => e
70
72
  expect(e.filter_name).to eql k
71
73
  expect(e.input_value).to eql v
@@ -82,11 +84,11 @@ describe ActiveInteraction::HashFilter, :filter do
82
84
  end
83
85
 
84
86
  it 'symbolizes String keys' do
85
- expect(filter.cast(value)).to have_key :a
87
+ expect(result).to have_key :a
86
88
  end
87
89
 
88
90
  it 'leaves other keys alone' do
89
- expect(filter.cast(value)).to have_key 1
91
+ expect(result).to have_key 1
90
92
  end
91
93
  end
92
94
  end
@@ -114,4 +116,10 @@ describe ActiveInteraction::HashFilter, :filter do
114
116
  end
115
117
  end
116
118
  end
119
+
120
+ describe '#database_column_type' do
121
+ it 'returns :string' do
122
+ expect(filter.database_column_type).to eql :string
123
+ end
124
+ end
117
125
  end
@@ -7,11 +7,13 @@ describe ActiveInteraction::IntegerFilter, :filter do
7
7
  it_behaves_like 'a filter'
8
8
 
9
9
  describe '#cast' do
10
+ let(:result) { filter.cast(value) }
11
+
10
12
  context 'with an Integer' do
11
13
  let(:value) { rand(1 << 16) }
12
14
 
13
15
  it 'returns the Integer' do
14
- expect(filter.cast(value)).to eql value
16
+ expect(result).to eql value
15
17
  end
16
18
  end
17
19
 
@@ -19,7 +21,7 @@ describe ActiveInteraction::IntegerFilter, :filter do
19
21
  let(:value) { rand(1 << 16) + rand }
20
22
 
21
23
  it 'returns an Integer' do
22
- expect(filter.cast(value)).to eql value.to_i
24
+ expect(result).to eql value.to_i
23
25
  end
24
26
  end
25
27
 
@@ -27,7 +29,7 @@ describe ActiveInteraction::IntegerFilter, :filter do
27
29
  let(:value) { rand(1 << 16).to_s }
28
30
 
29
31
  it 'returns an Integer' do
30
- expect(filter.cast(value)).to eql Integer(value)
32
+ expect(result).to eql Integer(value)
31
33
  end
32
34
  end
33
35
 
@@ -36,9 +38,15 @@ describe ActiveInteraction::IntegerFilter, :filter do
36
38
 
37
39
  it 'raises an error' do
38
40
  expect do
39
- filter.cast(value)
41
+ result
40
42
  end.to raise_error ActiveInteraction::InvalidValueError
41
43
  end
42
44
  end
43
45
  end
46
+
47
+ describe '#database_column_type' do
48
+ it 'returns :integer' do
49
+ expect(filter.database_column_type).to eql :integer
50
+ end
51
+ end
44
52
  end
@@ -14,14 +14,15 @@ describe ActiveInteraction::ModelFilter, :filter do
14
14
 
15
15
  describe '#cast' do
16
16
  let(:value) { Model.new }
17
+ let(:result) { filter.cast(value) }
17
18
 
18
19
  context 'with class as a Class' do
19
20
  it 'returns the instance' do
20
- expect(filter.cast(value)).to eql value
21
+ expect(result).to eql value
21
22
  end
22
23
 
23
24
  it 'handles reconstantizing' do
24
- expect(filter.cast(value)).to eql value
25
+ expect(result).to eql value
25
26
 
26
27
  Object.send(:remove_const, :Model)
27
28
  class Model; end
@@ -69,7 +70,7 @@ describe ActiveInteraction::ModelFilter, :filter do
69
70
  end
70
71
 
71
72
  it 'returns the instance' do
72
- expect(filter.cast(value)).to eql value
73
+ expect(result).to eql value
73
74
  end
74
75
  end
75
76
 
@@ -79,7 +80,7 @@ describe ActiveInteraction::ModelFilter, :filter do
79
80
  end
80
81
 
81
82
  it 'returns the instance' do
82
- expect(filter.cast(value)).to eql value
83
+ expect(result).to eql value
83
84
  end
84
85
  end
85
86
 
@@ -90,9 +91,15 @@ describe ActiveInteraction::ModelFilter, :filter do
90
91
 
91
92
  it 'raises an error' do
92
93
  expect do
93
- filter.cast(value)
94
+ result
94
95
  end.to raise_error ActiveInteraction::InvalidClassError
95
96
  end
96
97
  end
97
98
  end
99
+
100
+ describe '#database_column_type' do
101
+ it 'returns :string' do
102
+ expect(filter.database_column_type).to eql :string
103
+ end
104
+ end
98
105
  end
@@ -13,11 +13,13 @@ describe ActiveInteraction::StringFilter, :filter do
13
13
  end
14
14
 
15
15
  describe '#cast' do
16
+ let(:result) { filter.cast(value) }
17
+
16
18
  context 'with a String' do
17
19
  let(:value) { SecureRandom.hex }
18
20
 
19
21
  it 'returns the String' do
20
- expect(filter.cast(value)).to eql value
22
+ expect(result).to eql value
21
23
  end
22
24
  end
23
25
 
@@ -25,16 +27,22 @@ describe ActiveInteraction::StringFilter, :filter do
25
27
  let(:value) { " #{SecureRandom.hex} " }
26
28
 
27
29
  it 'returns the stripped string' do
28
- expect(filter.cast(value)).to eql value.strip
30
+ expect(result).to eql value.strip
29
31
  end
30
32
 
31
33
  context 'without strip' do
32
34
  include_context 'without strip'
33
35
 
34
36
  it 'returns the String' do
35
- expect(filter.cast(value)).to eql value
37
+ expect(result).to eql value
36
38
  end
37
39
  end
38
40
  end
39
41
  end
42
+
43
+ describe '#database_column_type' do
44
+ it 'returns :string' do
45
+ expect(filter.database_column_type).to eql :string
46
+ end
47
+ end
40
48
  end
@@ -7,11 +7,13 @@ describe ActiveInteraction::SymbolFilter, :filter do
7
7
  it_behaves_like 'a filter'
8
8
 
9
9
  describe '#cast' do
10
+ let(:result) { filter.cast(value) }
11
+
10
12
  context 'with a Symbol' do
11
13
  let(:value) { SecureRandom.hex.to_sym }
12
14
 
13
15
  it 'returns the Symbol' do
14
- expect(filter.cast(value)).to eql value
16
+ expect(result).to eql value
15
17
  end
16
18
  end
17
19
 
@@ -19,8 +21,14 @@ describe ActiveInteraction::SymbolFilter, :filter do
19
21
  let(:value) { SecureRandom.hex }
20
22
 
21
23
  it 'returns a Symbol' do
22
- expect(filter.cast(value)).to eql value.to_sym
24
+ expect(result).to eql value.to_sym
23
25
  end
24
26
  end
25
27
  end
28
+
29
+ describe '#database_column_type' do
30
+ it 'returns :string' do
31
+ expect(filter.database_column_type).to eql :string
32
+ end
33
+ end
26
34
  end
@@ -15,11 +15,13 @@ describe ActiveInteraction::TimeFilter, :filter do
15
15
  end
16
16
 
17
17
  describe '#cast' do
18
+ let(:result) { filter.cast(value) }
19
+
18
20
  context 'with a Time' do
19
21
  let(:value) { Time.new }
20
22
 
21
23
  it 'returns the Time' do
22
- expect(filter.cast(value)).to eql value
24
+ expect(result).to eql value
23
25
  end
24
26
  end
25
27
 
@@ -27,7 +29,7 @@ describe ActiveInteraction::TimeFilter, :filter do
27
29
  let(:value) { '2011-12-13 14:15:16 +1718' }
28
30
 
29
31
  it 'returns a Time' do
30
- expect(filter.cast(value)).to eql Time.parse(value)
32
+ expect(result).to eql Time.parse(value)
31
33
  end
32
34
 
33
35
  context 'with format' do
@@ -36,7 +38,7 @@ describe ActiveInteraction::TimeFilter, :filter do
36
38
  let(:value) { '13/12/2011 14:15:16 +1718' }
37
39
 
38
40
  it 'returns a Time' do
39
- expect(filter.cast(value)).to eql Time.strptime(value, format)
41
+ expect(result).to eql Time.strptime(value, format)
40
42
  end
41
43
  end
42
44
  end
@@ -46,7 +48,7 @@ describe ActiveInteraction::TimeFilter, :filter do
46
48
 
47
49
  it 'raises an error' do
48
50
  expect do
49
- filter.cast(value)
51
+ result
50
52
  end.to raise_error ActiveInteraction::InvalidValueError
51
53
  end
52
54
 
@@ -55,10 +57,90 @@ describe ActiveInteraction::TimeFilter, :filter do
55
57
 
56
58
  it do
57
59
  expect do
58
- filter.cast(value)
60
+ result
61
+ end.to raise_error ActiveInteraction::InvalidValueError
62
+ end
63
+ end
64
+ end
65
+
66
+ context 'with a GroupedInput' do
67
+ let(:year) { 2012 }
68
+ let(:month) { 1 }
69
+ let(:day) { 2 }
70
+ let(:hour) { 3 }
71
+ let(:min) { 4 }
72
+ let(:sec) { 5 }
73
+ let(:value) do
74
+ ActiveInteraction::GroupedInput.new(
75
+ '1' => year.to_s,
76
+ '2' => month.to_s,
77
+ '3' => day.to_s,
78
+ '4' => hour.to_s,
79
+ '5' => min.to_s,
80
+ '6' => sec.to_s
81
+ )
82
+ end
83
+
84
+ it 'returns a Time' do
85
+ expect(
86
+ result
87
+ ).to eql Time.new(year, month, day, hour, min, sec)
88
+ end
89
+ end
90
+
91
+ context 'with an invalid GroupedInput' do
92
+ context 'empty' do
93
+ let(:value) { ActiveInteraction::GroupedInput.new }
94
+
95
+ it 'raises an error' do
96
+ expect do
97
+ result
98
+ end.to raise_error ActiveInteraction::InvalidValueError
99
+ end
100
+ end
101
+
102
+ context 'partial inputs' do
103
+ let(:value) do
104
+ ActiveInteraction::GroupedInput.new(
105
+ '2' => '1'
106
+ )
107
+ end
108
+
109
+ it 'raises an error' do
110
+ expect do
111
+ result
59
112
  end.to raise_error ActiveInteraction::InvalidValueError
60
113
  end
61
114
  end
62
115
  end
63
116
  end
117
+
118
+ describe '#database_column_type' do
119
+ it 'returns :datetime' do
120
+ expect(filter.database_column_type).to eql :datetime
121
+ end
122
+ end
123
+
124
+ describe '#default' do
125
+ context 'with a GroupedInput' do
126
+ before do
127
+ options.merge!(
128
+ default: ActiveInteraction::GroupedInput.new(
129
+ '1' => '2012',
130
+ '2' => '1',
131
+ '3' => '2',
132
+ '4' => '3',
133
+ '5' => '4',
134
+ '6' => '5'
135
+ )
136
+ )
137
+ end
138
+
139
+ it 'raises an error' do
140
+ expect do
141
+ filter.default
142
+ end.to raise_error ActiveInteraction::InvalidDefaultError
143
+ end
144
+ end
145
+ end
64
146
  end