objective 0.1.0
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 +7 -0
- data/lib/objective/allow.rb +10 -0
- data/lib/objective/deny.rb +10 -0
- data/lib/objective/discard.rb +10 -0
- data/lib/objective/errors/error_array.rb +21 -0
- data/lib/objective/errors/error_atom.rb +27 -0
- data/lib/objective/errors/error_hash.rb +65 -0
- data/lib/objective/errors/error_message_creator.rb +46 -0
- data/lib/objective/errors/validation_error.rb +14 -0
- data/lib/objective/filter.rb +166 -0
- data/lib/objective/filters/any_filter.rb +7 -0
- data/lib/objective/filters/array_filter.rb +49 -0
- data/lib/objective/filters/boolean_filter.rb +21 -0
- data/lib/objective/filters/date_filter.rb +29 -0
- data/lib/objective/filters/decimal_filter.rb +46 -0
- data/lib/objective/filters/duck_filter.rb +18 -0
- data/lib/objective/filters/file_filter.rb +22 -0
- data/lib/objective/filters/float_filter.rb +45 -0
- data/lib/objective/filters/hash_filter.rb +42 -0
- data/lib/objective/filters/integer_filter.rb +60 -0
- data/lib/objective/filters/model_filter.rb +23 -0
- data/lib/objective/filters/root_filter.rb +54 -0
- data/lib/objective/filters/string_filter.rb +30 -0
- data/lib/objective/filters/time_filter.rb +30 -0
- data/lib/objective/filters.rb +140 -0
- data/lib/objective/none.rb +10 -0
- data/lib/objective/outcome.rb +5 -0
- data/lib/objective/unit.rb +103 -0
- data/lib/objective.rb +53 -0
- data/spec/default_spec.rb +33 -0
- data/spec/errors_spec.rb +135 -0
- data/spec/filters/any_filter_spec.rb +34 -0
- data/spec/filters/array_filter_spec.rb +195 -0
- data/spec/filters/boolean_filter_spec.rb +66 -0
- data/spec/filters/date_filter_spec.rb +145 -0
- data/spec/filters/decimal_filter_spec.rb +199 -0
- data/spec/filters/duck_filter_spec.rb +49 -0
- data/spec/filters/file_filter_spec.rb +93 -0
- data/spec/filters/float_filter_spec.rb +140 -0
- data/spec/filters/hash_filter_spec.rb +65 -0
- data/spec/filters/integer_filter_spec.rb +150 -0
- data/spec/filters/model_filter_spec.rb +98 -0
- data/spec/filters/root_filter_spec.rb +113 -0
- data/spec/filters/string_filter_spec.rb +251 -0
- data/spec/filters/time_filter_spec.rb +123 -0
- data/spec/inheritance_spec.rb +36 -0
- data/spec/simple_unit.rb +18 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/unit_spec.rb +244 -0
- metadata +167 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Objective::Filters::AnyFilter' do
|
5
|
+
it 'Allows anything' do
|
6
|
+
f = Objective::Filters::AnyFilter.new
|
7
|
+
|
8
|
+
[true, 'hi', 1, [1, 2, 3], { one: 1 }, 1..3, nil].each do |v|
|
9
|
+
result = f.feed(v)
|
10
|
+
if v.nil?
|
11
|
+
assert_nil result.inputs
|
12
|
+
else
|
13
|
+
assert_equal v, result.inputs
|
14
|
+
end
|
15
|
+
assert_nil result.errors
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'Allows nils by default' do
|
20
|
+
f = Objective::Filters::AnyFilter.new
|
21
|
+
|
22
|
+
result = f.feed(nil)
|
23
|
+
assert_nil result.inputs
|
24
|
+
assert_nil result.errors
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'Does not allow nils if set to deny' do
|
28
|
+
f = Objective::Filters::AnyFilter.new(:a1, nils: Objective::DENY)
|
29
|
+
|
30
|
+
result = f.feed(nil)
|
31
|
+
assert_nil result.inputs
|
32
|
+
assert_equal :nils, result.errors
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'stringio'
|
4
|
+
|
5
|
+
describe 'Objective::Filters::ArrayFilter' do
|
6
|
+
it 'allows arrays' do
|
7
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { any }
|
8
|
+
|
9
|
+
result = f.feed([1])
|
10
|
+
assert_equal [1], result.inputs
|
11
|
+
assert_nil result.errors
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'considers non-arrays to be invalid' do
|
15
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { any }
|
16
|
+
|
17
|
+
['hi', true, 1, { a: '1' }, Object.new].each do |thing|
|
18
|
+
result = f.feed(thing)
|
19
|
+
assert_equal :array, result.errors
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'considers nil to be invalid' do
|
24
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { any }
|
25
|
+
|
26
|
+
result = f.feed(nil)
|
27
|
+
assert_nil result.inputs
|
28
|
+
assert_equal :nils, result.errors
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'considers nil to be valid' do
|
32
|
+
f = Objective::Filters::ArrayFilter.new(:arr, nils: Objective::ALLOW) { any }
|
33
|
+
|
34
|
+
result = f.feed(nil)
|
35
|
+
assert_nil result.errors
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'lets you use a block to supply an element filter' do
|
39
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { string }
|
40
|
+
|
41
|
+
result = f.feed(['hi', { stuff: 'ok' }])
|
42
|
+
assert_nil result.errors[0]
|
43
|
+
assert_equal :string, result.errors[1].codes
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'lets you wrap everything' do
|
47
|
+
f = Objective::Filters::ArrayFilter.new(:arr, wrap: true) { any }
|
48
|
+
|
49
|
+
[
|
50
|
+
[true, [true]],
|
51
|
+
['hi', ['hi']],
|
52
|
+
['', ['']],
|
53
|
+
[1, [1]],
|
54
|
+
[[1, 2, 3], [1, 2, 3]],
|
55
|
+
[{ one: 1 }, [{ one: 1 }]],
|
56
|
+
[1..3, [1..3]]
|
57
|
+
].each do |(given, expected)|
|
58
|
+
result = f.feed(given)
|
59
|
+
assert_equal expected, result.inputs
|
60
|
+
assert_nil result.errors
|
61
|
+
end
|
62
|
+
|
63
|
+
result = f.feed('foo')
|
64
|
+
assert_equal ['foo'], result.inputs
|
65
|
+
assert_nil result.errors
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'lets you pass integers in arrays' do
|
69
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { integer min: 4 }
|
70
|
+
|
71
|
+
result = f.feed([5, 6, 1, 'bob'])
|
72
|
+
assert_equal [5, 6, 1, 'bob'], result.inputs
|
73
|
+
assert_equal [nil, nil, :min, :integer], result.errors.codes
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'lets you pass floats in arrays' do
|
77
|
+
f = Objective::Filters::ArrayFilter.new(:float) { float min: 4.0 }
|
78
|
+
|
79
|
+
result = f.feed([5.0, 6.0, 1.0, 'bob'])
|
80
|
+
assert_equal [5.0, 6.0, 1.0, 'bob'], result.inputs
|
81
|
+
assert_equal [nil, nil, :min, :float], result.errors.codes
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'lets you pass ducks in arrays' do
|
85
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { duck(methods: :length) }
|
86
|
+
|
87
|
+
result = f.feed(['hi', [1], true])
|
88
|
+
assert_equal ['hi', [1], true], result.inputs
|
89
|
+
assert_equal [nil, nil, :duck], result.errors.codes
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'lets you pass dates in arrays' do
|
93
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { date(format: '%Y-%m-%d') }
|
94
|
+
|
95
|
+
result = f.feed(['2000-1-1', Date.new(2000, 1, 1), '2000-20-1'])
|
96
|
+
assert_equal [Date.new(2000, 1, 1), Date.new(2000, 1, 1), '2000-20-1'], result.inputs
|
97
|
+
assert_equal [nil, nil, :date], result.errors.codes
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'lets you pass files in arrays' do
|
101
|
+
sio = StringIO.new('bob')
|
102
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { file }
|
103
|
+
|
104
|
+
result = f.feed([sio, 'bob'])
|
105
|
+
assert_equal [sio, 'bob'], result.inputs
|
106
|
+
assert_equal [nil, :file], result.errors.codes
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'lets you pass booleans in arrays' do
|
110
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { boolean }
|
111
|
+
|
112
|
+
result = f.feed([true, false, '1'])
|
113
|
+
assert_equal [true, false, true], result.inputs
|
114
|
+
assert_nil result.errors
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'lets you pass model in arrays' do
|
118
|
+
f = Objective::Filters::ArrayFilter.new(:arr) { model :string }
|
119
|
+
|
120
|
+
result = f.feed(['hey'])
|
121
|
+
assert_equal ['hey'], result.inputs
|
122
|
+
assert_nil result.errors
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'lets you pass hashes in arrays' do
|
126
|
+
f = Objective::Filters::ArrayFilter.new(:arr) do
|
127
|
+
hash do
|
128
|
+
string :foo
|
129
|
+
integer :bar
|
130
|
+
boolean :baz, none: Objective::ALLOW
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
result = f.feed([{ foo: 'f', bar: 3, baz: true }, { foo: 'f', bar: 3 }, { foo: 'f' }])
|
135
|
+
assert_equal [{ 'foo' => 'f', 'bar' => 3, 'baz' => true }, { 'foo' => 'f', 'bar' => 3 }, { 'foo' => 'f' }], result.inputs
|
136
|
+
assert_nil result.errors[0]
|
137
|
+
assert_nil result.errors[1]
|
138
|
+
assert_equal ({ 'bar' => :required }), result.errors[2].codes
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'lets you pass arrays of arrays' do
|
142
|
+
f = Objective::Filters::ArrayFilter.new(:arr) do
|
143
|
+
array do
|
144
|
+
string
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
result = f.feed([%w(h e), ['l'], [], ['lo']])
|
149
|
+
assert_equal [%w(h e), ['l'], [], ['lo']], result.inputs
|
150
|
+
assert_nil result.errors
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'handles errors for arrays of arrays' do
|
154
|
+
f = Objective::Filters::ArrayFilter.new(:arr) do
|
155
|
+
array do
|
156
|
+
string
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
result = f.feed([['h', 'e', {}], ['l'], [], ['']])
|
161
|
+
assert_equal [[nil, nil, :string], nil, nil, [:empty]], result.errors.codes
|
162
|
+
assert_equal [[nil, nil, '3rd Item must be a string'], nil, nil, ['1st Item cannot be empty']], result.errors.message
|
163
|
+
assert_equal ['3rd Item must be a string', '1st Item cannot be empty'], result.errors.message_list
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'can discard invalid elements' do
|
167
|
+
f = Objective::Filters::ArrayFilter.new(:arr) do
|
168
|
+
integer invalid: Objective::DISCARD
|
169
|
+
end
|
170
|
+
|
171
|
+
result = f.feed([1, '2', 'three', '4', 5, [6]])
|
172
|
+
assert_nil result.errors
|
173
|
+
assert_equal [1, 2, 4, 5], result.inputs
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'can discard nil elements' do
|
177
|
+
f = Objective::Filters::ArrayFilter.new(:arr) do
|
178
|
+
integer nils: Objective::DISCARD
|
179
|
+
end
|
180
|
+
|
181
|
+
result = f.feed([nil, 1, '2', nil, nil, '4', 5, nil])
|
182
|
+
assert_nil result.errors
|
183
|
+
assert_equal [1, 2, 4, 5], result.inputs
|
184
|
+
end
|
185
|
+
|
186
|
+
it 'can discard empty elements' do
|
187
|
+
f = Objective::Filters::ArrayFilter.new(:arr) do
|
188
|
+
string empty: Objective::DISCARD
|
189
|
+
end
|
190
|
+
|
191
|
+
result = f.feed(['', 1, '2', '', '', '4', 5, ''])
|
192
|
+
assert_nil result.errors
|
193
|
+
assert_equal %w(1 2 4 5), result.inputs
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Objective::Filters::BooleanFilter' do
|
5
|
+
it 'allows booleans' do
|
6
|
+
f = Objective::Filters::BooleanFilter.new
|
7
|
+
result = f.feed(true)
|
8
|
+
assert_equal true, result.inputs
|
9
|
+
assert_nil result.errors
|
10
|
+
|
11
|
+
result = f.feed(false)
|
12
|
+
assert_equal false, result.inputs
|
13
|
+
assert_nil result.errors
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'considers non-booleans to be invalid' do
|
17
|
+
f = Objective::Filters::BooleanFilter.new
|
18
|
+
[[true], { a: '1' }, Object.new].each do |thing|
|
19
|
+
result = f.feed(thing)
|
20
|
+
assert_equal :boolean, result.errors
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'considers nil to be invalid' do
|
25
|
+
f = Objective::Filters::BooleanFilter.new(:bool)
|
26
|
+
result = f.feed(nil)
|
27
|
+
assert_nil result.inputs
|
28
|
+
assert_equal :nils, result.errors
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'considers nil to be valid' do
|
32
|
+
f = Objective::Filters::BooleanFilter.new(:bool, nils: Objective::ALLOW)
|
33
|
+
result = f.feed(nil)
|
34
|
+
assert_nil result.inputs
|
35
|
+
assert_nil result.errors
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'considers certain values to be true' do
|
39
|
+
f = Objective::Filters::BooleanFilter.new
|
40
|
+
|
41
|
+
['true', 'TRUE', 'TrUe', '1', 1].each do |value|
|
42
|
+
result = f.feed(value)
|
43
|
+
assert_equal true, result.inputs
|
44
|
+
assert_nil result.errors
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'considers certain values to be true' do
|
49
|
+
f = Objective::Filters::BooleanFilter.new
|
50
|
+
|
51
|
+
['false', 'FALSE', 'FalSe', '0', 0].each do |value|
|
52
|
+
result = f.feed(value)
|
53
|
+
assert_equal false, result.inputs
|
54
|
+
assert_nil result.errors
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'considers other string to be invalid' do
|
59
|
+
f = Objective::Filters::BooleanFilter.new
|
60
|
+
%w(truely 2).each do |str|
|
61
|
+
result = f.feed(str)
|
62
|
+
assert_equal str, result.inputs
|
63
|
+
assert_equal :boolean, result.errors
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Objective::Filters::DateFilter' do
|
5
|
+
it 'takes a date object' do
|
6
|
+
date = Date.new
|
7
|
+
f = Objective::Filters::DateFilter.new
|
8
|
+
result = f.feed(date)
|
9
|
+
assert_equal date, result.inputs
|
10
|
+
assert_nil result.errors
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'takes a DateTime object' do
|
14
|
+
date = DateTime.new
|
15
|
+
f = Objective::Filters::DateFilter.new
|
16
|
+
result = f.feed(date)
|
17
|
+
assert_equal date, result.inputs
|
18
|
+
assert_nil result.errors
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'takes a Time object and converts it to a date' do
|
22
|
+
time = Time.now
|
23
|
+
f = Objective::Filters::DateFilter.new
|
24
|
+
result = f.feed(time)
|
25
|
+
if time.respond_to?(:to_date)
|
26
|
+
assert_equal time.to_date, result.inputs
|
27
|
+
assert_nil result.errors
|
28
|
+
else
|
29
|
+
assert_equal :date, result.errors
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'checks if the given date is after a certain date' do
|
34
|
+
date = Date.new(2005, 1, 1)
|
35
|
+
after_date = Date.new(2000, 1, 1)
|
36
|
+
f = Objective::Filters::DateFilter.new(:d1, after: after_date)
|
37
|
+
result = f.feed(date)
|
38
|
+
|
39
|
+
assert_equal date, result.inputs
|
40
|
+
assert_nil result.errors
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'gives errors when the given date is before the after date' do
|
44
|
+
date = Date.new(1995, 1, 1)
|
45
|
+
after_date = Date.new(2000, 1, 1)
|
46
|
+
f = Objective::Filters::DateFilter.new(:d1, after: after_date)
|
47
|
+
result = f.feed(date)
|
48
|
+
|
49
|
+
assert_equal date, result.inputs
|
50
|
+
assert_equal :after, result.errors
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'checks if the given date is before a certain date' do
|
54
|
+
date = Date.new(1995, 1, 1)
|
55
|
+
after_date = Date.new(2000, 1, 1)
|
56
|
+
f = Objective::Filters::DateFilter.new(:d1, before: after_date)
|
57
|
+
result = f.feed(date)
|
58
|
+
|
59
|
+
assert_equal date, result.inputs
|
60
|
+
assert_nil result.errors
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'gives errors when the given date is after the before date' do
|
64
|
+
date = Date.new(2005, 1, 1)
|
65
|
+
before_date = Date.new(2000, 1, 1)
|
66
|
+
f = Objective::Filters::DateFilter.new(:d1, before: before_date)
|
67
|
+
result = f.feed(date)
|
68
|
+
|
69
|
+
assert_equal date, result.inputs
|
70
|
+
assert_equal :before, result.errors
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'checks if the given date is in the given range' do
|
74
|
+
date = Date.new(2005, 1, 1)
|
75
|
+
after_date = Date.new(2000, 1, 1)
|
76
|
+
before_date = Date.new(2010, 1, 1)
|
77
|
+
f = Objective::Filters::DateFilter.new(:d1, after: after_date, before: before_date)
|
78
|
+
result = f.feed(date)
|
79
|
+
|
80
|
+
assert_equal date, result.inputs
|
81
|
+
assert_nil result.errors
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should be able to parse a D-M-Y string to a date' do
|
85
|
+
date_string = '2-1-2000'
|
86
|
+
date = Date.new(2000, 1, 2)
|
87
|
+
f = Objective::Filters::DateFilter.new
|
88
|
+
result = f.feed(date_string)
|
89
|
+
|
90
|
+
assert_equal date, result.inputs
|
91
|
+
assert_nil result.errors
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should be able to parse a Y-M-D string to a date' do
|
95
|
+
date_string = '2000-1-2'
|
96
|
+
date = Date.new(2000, 1, 2)
|
97
|
+
f = Objective::Filters::DateFilter.new
|
98
|
+
result = f.feed(date_string)
|
99
|
+
|
100
|
+
assert_equal date, result.inputs
|
101
|
+
assert_nil result.errors
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should be able to handle date formatting' do
|
105
|
+
date_string = '2000-1-2'
|
106
|
+
date = Date.new(2000, 1, 2)
|
107
|
+
f = Objective::Filters::DateFilter.new(:d1, format: '%Y-%m-%d')
|
108
|
+
result = f.feed(date_string)
|
109
|
+
|
110
|
+
assert_equal date, result.inputs
|
111
|
+
assert_nil result.errors
|
112
|
+
|
113
|
+
date_string = '1, 2, 2000'
|
114
|
+
f = Objective::Filters::DateFilter.new(:d1, format: '%m, %d, %Y')
|
115
|
+
result = f.feed(date_string)
|
116
|
+
|
117
|
+
assert_equal date, result.inputs
|
118
|
+
assert_nil result.errors
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'considers nil to be invalid' do
|
122
|
+
f = Objective::Filters::DateFilter.new
|
123
|
+
result = f.feed(nil)
|
124
|
+
|
125
|
+
assert_nil result.inputs
|
126
|
+
assert_equal :nils, result.errors
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'allows the use of nil when specified' do
|
130
|
+
f = Objective::Filters::DateFilter.new(:d1, nils: Objective::ALLOW)
|
131
|
+
result = f.feed(nil)
|
132
|
+
|
133
|
+
assert_nil result.inputs
|
134
|
+
assert_nil result.errors
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'does not allow non-existing dates' do
|
138
|
+
date_string = '1, 20, 2013'
|
139
|
+
f = Objective::Filters::DateFilter.new
|
140
|
+
result = f.feed(date_string)
|
141
|
+
|
142
|
+
assert_equal '1, 20, 2013', result.inputs
|
143
|
+
assert_equal :date, result.errors
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Objective::Filters::DecimalFilter' do
|
5
|
+
it 'allows bigdecimals' do
|
6
|
+
f = Objective::Filters::DecimalFilter.new
|
7
|
+
result = f.feed(BigDecimal.new('0.99999999999999999'))
|
8
|
+
|
9
|
+
assert result.inputs.is_a?(BigDecimal)
|
10
|
+
assert_equal '0.99999999999999999', result.inputs.to_s('F')
|
11
|
+
assert_nil result.errors
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'allows integers' do
|
15
|
+
f = Objective::Filters::DecimalFilter.new
|
16
|
+
result = f.feed(3)
|
17
|
+
|
18
|
+
assert result.inputs.is_a?(BigDecimal)
|
19
|
+
assert_equal 3, result.inputs
|
20
|
+
assert_nil result.errors
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'allows floats' do
|
24
|
+
f = Objective::Filters::DecimalFilter.new
|
25
|
+
result = f.feed(3.1415926)
|
26
|
+
|
27
|
+
assert result.inputs.is_a?(BigDecimal)
|
28
|
+
assert_equal 3.1415926, result.inputs
|
29
|
+
assert_nil result.errors
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'allows strings that start with a digit' do
|
33
|
+
f = Objective::Filters::DecimalFilter.new
|
34
|
+
result = f.feed('3')
|
35
|
+
|
36
|
+
assert result.inputs.is_a?(BigDecimal)
|
37
|
+
assert_equal 3.0, result.inputs
|
38
|
+
assert_nil result.errors
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'allows string representation of float' do
|
42
|
+
f = Objective::Filters::DecimalFilter.new
|
43
|
+
result = f.feed('3.14')
|
44
|
+
|
45
|
+
assert result.inputs.is_a?(BigDecimal)
|
46
|
+
assert_equal 3.14, result.inputs
|
47
|
+
assert_nil result.errors
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'allows string representation of float without a number before dot' do
|
51
|
+
f = Objective::Filters::DecimalFilter.new
|
52
|
+
result = f.feed('.14')
|
53
|
+
|
54
|
+
assert result.inputs.is_a?(BigDecimal)
|
55
|
+
assert_equal 0.14, result.inputs
|
56
|
+
assert_nil result.errors
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'allows negative strings' do
|
60
|
+
f = Objective::Filters::DecimalFilter.new
|
61
|
+
result = f.feed('-.14')
|
62
|
+
|
63
|
+
assert result.inputs.is_a?(BigDecimal)
|
64
|
+
assert_equal(-0.14, result.inputs)
|
65
|
+
assert_nil result.errors
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'allows strings with a positive sign' do
|
69
|
+
f = Objective::Filters::DecimalFilter.new
|
70
|
+
result = f.feed('+.14')
|
71
|
+
|
72
|
+
assert result.inputs.is_a?(BigDecimal)
|
73
|
+
assert_equal 0.14, result.inputs
|
74
|
+
assert_nil result.errors
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'allows spaces in strings as a delimiter' do
|
78
|
+
f = Objective::Filters::DecimalFilter.new
|
79
|
+
result = f.feed('123 456.789')
|
80
|
+
|
81
|
+
assert result.inputs.is_a?(BigDecimal)
|
82
|
+
assert_equal 123_456.789, result.inputs
|
83
|
+
assert_nil result.errors
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'allows commas in strings as a delimiter' do
|
87
|
+
f = Objective::Filters::DecimalFilter.new
|
88
|
+
result = f.feed('123,456.789')
|
89
|
+
|
90
|
+
assert result.inputs.is_a?(BigDecimal)
|
91
|
+
assert_equal 123_456.789, result.inputs
|
92
|
+
assert_nil result.errors
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'does not allow random objects, symbols, or strings with non-numeric characters' do
|
96
|
+
f = Objective::Filters::DecimalFilter.new
|
97
|
+
|
98
|
+
['zero', 'a1', {}, [], Object.new, :d].each do |thing|
|
99
|
+
result = f.feed(thing)
|
100
|
+
|
101
|
+
assert_equal :decimal, result.errors
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'considers nil to be invalid' do
|
106
|
+
f = Objective::Filters::DecimalFilter.new(:x)
|
107
|
+
result = f.feed(nil)
|
108
|
+
|
109
|
+
assert_nil result.inputs
|
110
|
+
assert_equal :nils, result.errors
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'considers nil to be valid' do
|
114
|
+
f = Objective::Filters::DecimalFilter.new(:x, nils: Objective::ALLOW)
|
115
|
+
result = f.feed(nil)
|
116
|
+
|
117
|
+
assert_nil result.inputs
|
118
|
+
assert_nil result.errors
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'considers empty strings to be invalid' do
|
122
|
+
f = Objective::Filters::DecimalFilter.new
|
123
|
+
result = f.feed('')
|
124
|
+
|
125
|
+
assert_equal :decimal, result.errors
|
126
|
+
end
|
127
|
+
|
128
|
+
it 'can allow alternative number formats' do
|
129
|
+
f = Objective::Filters::DecimalFilter.new(:x, delimiter: '.', decimal_mark: ',')
|
130
|
+
result = f.feed('123.456,789')
|
131
|
+
|
132
|
+
assert result.inputs.is_a?(BigDecimal)
|
133
|
+
assert_equal 123_456.789, result.inputs
|
134
|
+
assert_nil result.errors
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'considers numbers with less decimal points than the scale value to be valid' do
|
138
|
+
f = Objective::Filters::DecimalFilter.new(:x, scale: 2)
|
139
|
+
result = f.feed('1.2')
|
140
|
+
|
141
|
+
assert result.inputs.is_a?(BigDecimal)
|
142
|
+
assert_equal 1.2, result.inputs
|
143
|
+
assert_nil result.errors
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'considers numbers with the same decimal points as the scale value to be valid' do
|
147
|
+
f = Objective::Filters::DecimalFilter.new(:x, scale: 2)
|
148
|
+
result = f.feed('1.23')
|
149
|
+
|
150
|
+
assert result.inputs.is_a?(BigDecimal)
|
151
|
+
assert_equal 1.23, result.inputs
|
152
|
+
assert_nil result.errors
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'considers numbers with more decimal points than scale value to be invalid' do
|
156
|
+
f = Objective::Filters::DecimalFilter.new(:x, scale: 2)
|
157
|
+
result = f.feed('1.234')
|
158
|
+
|
159
|
+
assert result.inputs.is_a?(BigDecimal)
|
160
|
+
assert_equal 1.234, result.inputs
|
161
|
+
assert_equal :scale, result.errors
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'considers low numbers invalid' do
|
165
|
+
f = Objective::Filters::DecimalFilter.new(:x, min: 10)
|
166
|
+
result = f.feed(3)
|
167
|
+
|
168
|
+
assert result.inputs.is_a?(BigDecimal)
|
169
|
+
assert_equal 3, result.inputs
|
170
|
+
assert_equal :min, result.errors
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'considers low numbers valid' do
|
174
|
+
f = Objective::Filters::DecimalFilter.new(:x, min: 10)
|
175
|
+
result = f.feed(31)
|
176
|
+
|
177
|
+
assert result.inputs.is_a?(BigDecimal)
|
178
|
+
assert_equal 31, result.inputs
|
179
|
+
assert_nil result.errors
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'considers high numbers invalid' do
|
183
|
+
f = Objective::Filters::DecimalFilter.new(:x, max: 10)
|
184
|
+
result = f.feed(31)
|
185
|
+
|
186
|
+
assert result.inputs.is_a?(BigDecimal)
|
187
|
+
assert_equal 31, result.inputs
|
188
|
+
assert_equal :max, result.errors
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'considers high numbers vaild' do
|
192
|
+
f = Objective::Filters::DecimalFilter.new(:x, max: 10)
|
193
|
+
result = f.feed(3)
|
194
|
+
|
195
|
+
assert result.inputs.is_a?(BigDecimal)
|
196
|
+
assert_equal 3, result.inputs
|
197
|
+
assert_nil result.errors
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Objective::Filters::DuckFilter' do
|
5
|
+
it 'allows objects that respond to a single specified method' do
|
6
|
+
f = Objective::Filters::DuckFilter.new(:quack, methods: [:length])
|
7
|
+
result = f.feed('test')
|
8
|
+
assert_equal 'test', result.inputs
|
9
|
+
assert_nil result.errors
|
10
|
+
|
11
|
+
result = f.feed([1, 2])
|
12
|
+
assert_equal [1, 2], result.inputs
|
13
|
+
assert_nil result.errors
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'does not allow objects that respond to a single specified method' do
|
17
|
+
f = Objective::Filters::DuckFilter.new(:quack, methods: [:length])
|
18
|
+
result = f.feed(true)
|
19
|
+
assert_equal true, result.inputs
|
20
|
+
assert_equal :duck, result.errors
|
21
|
+
|
22
|
+
result = f.feed(12)
|
23
|
+
assert_equal 12, result.inputs
|
24
|
+
assert_equal :duck, result.errors
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'considers nil to be invalid' do
|
28
|
+
f = Objective::Filters::DuckFilter.new(:quack)
|
29
|
+
result = f.feed(nil)
|
30
|
+
assert_nil result.inputs
|
31
|
+
assert_equal :nils, result.errors
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'considers nil to be valid' do
|
35
|
+
f = Objective::Filters::DuckFilter.new(:quack, nils: Objective::ALLOW)
|
36
|
+
result = f.feed(nil)
|
37
|
+
assert_nil result.inputs
|
38
|
+
assert_nil result.errors
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'Allows anything if no methods are specified' do
|
42
|
+
f = Objective::Filters::DuckFilter.new
|
43
|
+
[true, 'hi', 1, [1, 2, 3], { one: 1 }, 1..3].each do |v|
|
44
|
+
result = f.feed(v)
|
45
|
+
assert_equal v, result.inputs
|
46
|
+
assert_nil result.errors
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|