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,251 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Objective::Filters::StringFilter' do
|
5
|
+
it 'allows valid strings' do
|
6
|
+
sf = Objective::Filters::StringFilter.new
|
7
|
+
result = sf.feed('hello')
|
8
|
+
assert_equal 'hello', result.inputs
|
9
|
+
assert_nil result.errors
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'allows symbols' do
|
13
|
+
sf = Objective::Filters::StringFilter.new
|
14
|
+
result = sf.feed(:hello)
|
15
|
+
assert_equal 'hello', result.inputs
|
16
|
+
assert_nil result.errors
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'allows fixnums' do
|
20
|
+
sf = Objective::Filters::StringFilter.new
|
21
|
+
result = sf.feed(1)
|
22
|
+
assert_equal '1', result.inputs
|
23
|
+
assert_nil result.errors
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'allows bignums' do
|
27
|
+
sf = Objective::Filters::StringFilter.new
|
28
|
+
result = sf.feed(11_111_111_111_111_111_111)
|
29
|
+
assert_equal '11111111111111111111', result.inputs
|
30
|
+
assert_nil result.errors
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'disallows non-string' do
|
34
|
+
sf = Objective::Filters::StringFilter.new
|
35
|
+
[['foo'], { a: '1' }, Object.new].each do |thing|
|
36
|
+
result = sf.feed(thing)
|
37
|
+
assert_equal :string, result.errors
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'strips' do
|
42
|
+
sf = Objective::Filters::StringFilter.new(:s, strip: true)
|
43
|
+
result = sf.feed(' hello ')
|
44
|
+
assert_equal 'hello', result.inputs
|
45
|
+
assert_nil result.errors
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'doesn\'t strip' do
|
49
|
+
sf = Objective::Filters::StringFilter.new(:s, strip: false)
|
50
|
+
result = sf.feed(' hello ')
|
51
|
+
assert_equal ' hello ', result.inputs
|
52
|
+
assert_nil result.errors
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'considers nil to be invalid' do
|
56
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
57
|
+
result = sf.feed(nil)
|
58
|
+
assert_nil result.inputs
|
59
|
+
assert_equal :nils, result.errors
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'considers nil to be valid' do
|
63
|
+
sf = Objective::Filters::StringFilter.new(:s, nils: Objective::ALLOW)
|
64
|
+
result = sf.feed(nil)
|
65
|
+
assert_nil result.inputs
|
66
|
+
assert_nil result.errors
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'considers empty strings to be invalid' do
|
70
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
71
|
+
result = sf.feed('')
|
72
|
+
assert_equal '', result.inputs
|
73
|
+
assert_equal :empty, result.errors
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'considers empty strings to be valid' do
|
77
|
+
sf = Objective::Filters::StringFilter.new(:s, empty: Objective::ALLOW)
|
78
|
+
result = sf.feed('')
|
79
|
+
assert_equal '', result.inputs
|
80
|
+
assert_nil result.errors
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'considers stripped strings that are empty to be invalid' do
|
84
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
85
|
+
result = sf.feed(' ')
|
86
|
+
assert_equal '', result.inputs
|
87
|
+
assert_equal :empty, result.errors
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'considers strings that contain only unprintable characters to be invalid' do
|
91
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
92
|
+
result = sf.feed("\u0000\u0000")
|
93
|
+
assert_equal '', result.inputs
|
94
|
+
assert_equal :empty, result.errors
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'considers long strings to be invalid' do
|
98
|
+
sf = Objective::Filters::StringFilter.new(:s, max: 5)
|
99
|
+
result = sf.feed('123456')
|
100
|
+
assert_equal '123456', result.inputs
|
101
|
+
assert_equal :max, result.errors
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'considers long strings to be valid' do
|
105
|
+
sf = Objective::Filters::StringFilter.new(:s, max: 5)
|
106
|
+
result = sf.feed('12345')
|
107
|
+
assert_equal '12345', result.inputs
|
108
|
+
assert_nil result.errors
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'considers short strings to be invalid' do
|
112
|
+
sf = Objective::Filters::StringFilter.new(:s, min: 5)
|
113
|
+
result = sf.feed('1234')
|
114
|
+
assert_equal '1234', result.inputs
|
115
|
+
assert_equal :min, result.errors
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'considers short strings to be valid' do
|
119
|
+
sf = Objective::Filters::StringFilter.new(:s, min: 5)
|
120
|
+
result = sf.feed('12345')
|
121
|
+
assert_equal '12345', result.inputs
|
122
|
+
assert_nil result.errors
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'considers bad matches to be invalid' do
|
126
|
+
sf = Objective::Filters::StringFilter.new(:s, matches: /aaa/)
|
127
|
+
result = sf.feed('aab')
|
128
|
+
assert_equal 'aab', result.inputs
|
129
|
+
assert_equal :matches, result.errors
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'considers good matches to be valid' do
|
133
|
+
sf = Objective::Filters::StringFilter.new(:s, matches: /aaa/)
|
134
|
+
result = sf.feed('baaab')
|
135
|
+
assert_equal 'baaab', result.inputs
|
136
|
+
assert_nil result.errors
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'considers non-inclusion to be invalid' do
|
140
|
+
sf = Objective::Filters::StringFilter.new(:s, in: %w(red blue green))
|
141
|
+
result = sf.feed('orange')
|
142
|
+
assert_equal 'orange', result.inputs
|
143
|
+
assert_equal :in, result.errors
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'considers inclusion to be valid' do
|
147
|
+
sf = Objective::Filters::StringFilter.new(:s, in: %w(red blue green))
|
148
|
+
result = sf.feed('red')
|
149
|
+
assert_equal 'red', result.inputs
|
150
|
+
assert_nil result.errors
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'converts symbols to strings' do
|
154
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
155
|
+
result = sf.feed(:my_sym)
|
156
|
+
assert_equal 'my_sym', result.inputs
|
157
|
+
assert_nil result.errors
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'converts integers to strings' do
|
161
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
162
|
+
result = sf.feed(1)
|
163
|
+
assert_equal '1', result.inputs
|
164
|
+
assert_nil result.errors
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'converts bigdecimals to strings' do
|
168
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
169
|
+
result = sf.feed(BigDecimal.new('0.00000123'))
|
170
|
+
assert_equal '0.00000123', result.inputs
|
171
|
+
assert_nil result.errors
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'converts bigdecimals to scientific notation strings' do
|
175
|
+
sf = Objective::Filters::StringFilter.new(:s, decimal_format: 'E')
|
176
|
+
result = sf.feed(BigDecimal.new('0.00000123'))
|
177
|
+
assert_equal '0.123e-5', result.inputs
|
178
|
+
assert_nil result.errors
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'converts floats to strings' do
|
182
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
183
|
+
result = sf.feed(0.0001)
|
184
|
+
assert_equal '0.0001', result.inputs
|
185
|
+
assert_nil result.errors
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'converts booleans to strings' do
|
189
|
+
sf = Objective::Filters::StringFilter.new(:s)
|
190
|
+
result = sf.feed(true)
|
191
|
+
assert_equal 'true', result.inputs
|
192
|
+
assert_nil result.errors
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'disallows symbols' do
|
196
|
+
sf = Objective::Filters::StringFilter.new(:s, strict: true)
|
197
|
+
result = sf.feed(:my_sym)
|
198
|
+
assert_equal :my_sym, result.inputs
|
199
|
+
assert_equal :string, result.errors
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'disallows integers' do
|
203
|
+
sf = Objective::Filters::StringFilter.new(:s, strict: true)
|
204
|
+
result = sf.feed(1)
|
205
|
+
assert_equal 1, result.inputs
|
206
|
+
assert_equal :string, result.errors
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'disallows bigdecimals' do
|
210
|
+
sf = Objective::Filters::StringFilter.new(:s, strict: true)
|
211
|
+
big_decimal = BigDecimal.new('0.0001')
|
212
|
+
result = sf.feed(big_decimal)
|
213
|
+
assert_equal big_decimal, result.inputs
|
214
|
+
assert_equal :string, result.errors
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'disallows floats' do
|
218
|
+
sf = Objective::Filters::StringFilter.new(:s, strict: true)
|
219
|
+
result = sf.feed(0.0001)
|
220
|
+
assert_equal 0.0001, result.inputs
|
221
|
+
assert_equal :string, result.errors
|
222
|
+
end
|
223
|
+
|
224
|
+
it 'disallows booleans' do
|
225
|
+
sf = Objective::Filters::StringFilter.new(:s, strict: true)
|
226
|
+
result = sf.feed(true)
|
227
|
+
assert_equal true, result.inputs
|
228
|
+
assert_equal :string, result.errors
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'removes unprintable characters' do
|
232
|
+
sf = Objective::Filters::StringFilter.new(:s, allow_control_characters: false)
|
233
|
+
result = sf.feed("Hello\u0000\u0000World!")
|
234
|
+
assert_equal 'Hello World!', result.inputs
|
235
|
+
assert_nil result.errors
|
236
|
+
end
|
237
|
+
|
238
|
+
it "doesn't remove unprintable characters" do
|
239
|
+
sf = Objective::Filters::StringFilter.new(:s, allow_control_characters: true)
|
240
|
+
result = sf.feed("Hello\u0000\u0000World!")
|
241
|
+
assert_equal "Hello\u0000\u0000World!", result.inputs
|
242
|
+
assert_nil result.errors
|
243
|
+
end
|
244
|
+
|
245
|
+
it "doesn't remove tabs, spaces and line breaks" do
|
246
|
+
sf = Objective::Filters::StringFilter.new(:s, allow_control_characters: false)
|
247
|
+
result = sf.feed("Hello,\tWorld !\r\nNew Line")
|
248
|
+
assert_equal "Hello,\tWorld !\r\nNew Line", result.inputs
|
249
|
+
assert_nil result.errors
|
250
|
+
end
|
251
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Objective::Filters::TimeFilter' do
|
5
|
+
it 'takes a Time object' do
|
6
|
+
time = Time.now
|
7
|
+
f = Objective::Filters::TimeFilter.new
|
8
|
+
result = f.feed(time)
|
9
|
+
assert_equal time, result.inputs
|
10
|
+
assert_nil result.errors
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'takes a Date object and converts it to a time' do
|
14
|
+
date = Date.new
|
15
|
+
f = Objective::Filters::TimeFilter.new
|
16
|
+
result = f.feed(date)
|
17
|
+
assert_equal date.to_time, result.inputs
|
18
|
+
assert_nil result.errors
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'takes a DateTime object and converts it to a time' do
|
22
|
+
date = DateTime.new
|
23
|
+
f = Objective::Filters::TimeFilter.new
|
24
|
+
result = f.feed(date)
|
25
|
+
assert_equal date.to_time, result.inputs
|
26
|
+
assert_nil result.errors
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'checks if the given time is after a certain time' do
|
30
|
+
time = Time.now
|
31
|
+
f = Objective::Filters::TimeFilter.new(:t, after: time - 1)
|
32
|
+
result = f.feed(time)
|
33
|
+
assert_equal time, result.inputs
|
34
|
+
assert_nil result.errors
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'gives errors when the given time is before the after time' do
|
38
|
+
time = Time.now
|
39
|
+
f = Objective::Filters::TimeFilter.new(:t, after: time + 1)
|
40
|
+
result = f.feed(time)
|
41
|
+
assert_equal time, result.inputs
|
42
|
+
assert_equal :after, result.errors
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'checks if the given time is before a certain time' do
|
46
|
+
time = Time.now
|
47
|
+
f = Objective::Filters::TimeFilter.new(:t, before: time + 1)
|
48
|
+
result = f.feed(time)
|
49
|
+
assert_equal time, result.inputs
|
50
|
+
assert_nil result.errors
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'gives errors when the given time is after the before time' do
|
54
|
+
time = Time.now
|
55
|
+
f = Objective::Filters::TimeFilter.new(:t, before: time - 1)
|
56
|
+
result = f.feed(time)
|
57
|
+
assert_equal time, result.inputs
|
58
|
+
assert_equal :before, result.errors
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'checks if the given time is in the given range' do
|
62
|
+
time = Time.now
|
63
|
+
f = Objective::Filters::TimeFilter.new(:t, after: time - 1, before: time + 1)
|
64
|
+
result = f.feed(time)
|
65
|
+
assert_equal time, result.inputs
|
66
|
+
assert_nil result.errors
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should be able to parse a D-M-Y string to a time' do
|
70
|
+
date_string = '2-1-2000'
|
71
|
+
date = Date.new(2000, 1, 2)
|
72
|
+
f = Objective::Filters::TimeFilter.new
|
73
|
+
result = f.feed(date_string)
|
74
|
+
assert_equal date.to_time, result.inputs
|
75
|
+
assert_nil result.errors
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should be able to parse a Y-M-D string to a time' do
|
79
|
+
date_string = '2000-1-2'
|
80
|
+
date = Date.new(2000, 1, 2)
|
81
|
+
f = Objective::Filters::TimeFilter.new
|
82
|
+
result = f.feed(date_string)
|
83
|
+
assert_equal date.to_time, result.inputs
|
84
|
+
assert_nil result.errors
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should be able to handle time formatting' do
|
88
|
+
time_string = '2000-1-2 12:13:14'
|
89
|
+
time = Time.new(2000, 1, 2, 12, 13, 14)
|
90
|
+
f = Objective::Filters::TimeFilter.new(:t, format: '%Y-%m-%d %H:%M:%S')
|
91
|
+
result = f.feed(time_string)
|
92
|
+
assert_equal time, result.inputs
|
93
|
+
assert_nil result.errors
|
94
|
+
|
95
|
+
time_string = '1, 2, 2000, 121314'
|
96
|
+
f = Objective::Filters::TimeFilter.new(:t, format: '%m, %d, %Y, %H%M%S')
|
97
|
+
result = f.feed(time_string)
|
98
|
+
assert_equal time, result.inputs
|
99
|
+
assert_nil result.errors
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'considers nil to be invalid' do
|
103
|
+
f = Objective::Filters::TimeFilter.new
|
104
|
+
result = f.feed(nil)
|
105
|
+
assert_nil result.inputs
|
106
|
+
assert_equal :nils, result.errors
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'allows the use of nil when specified' do
|
110
|
+
f = Objective::Filters::TimeFilter.new(:t, nils: Objective::ALLOW)
|
111
|
+
result = f.feed(nil)
|
112
|
+
assert_nil result.inputs
|
113
|
+
assert_nil result.errors
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'doesn\'t allow non-existing times' do
|
117
|
+
invalid_time_string = '1, 20, 2013 25:13'
|
118
|
+
f = Objective::Filters::TimeFilter.new
|
119
|
+
result = f.feed(invalid_time_string)
|
120
|
+
assert_equal '1, 20, 2013 25:13', result.inputs
|
121
|
+
assert_equal :time, result.errors
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'simple_unit'
|
4
|
+
|
5
|
+
describe 'Objective - inheritance' do
|
6
|
+
class SimpleInherited < SimpleUnit
|
7
|
+
filter do
|
8
|
+
integer :age
|
9
|
+
end
|
10
|
+
|
11
|
+
def execute
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should filter with inherited unit' do
|
16
|
+
outcome = SimpleInherited.run(name: 'bob', email: 'jon@jones.com', age: 10, amount: 22)
|
17
|
+
assert outcome.success
|
18
|
+
assert_equal OpenStruct.new(name: 'bob', email: 'jon@jones.com', age: 10, amount: 22), outcome.inputs
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should filter with original unit' do
|
22
|
+
outcome = SimpleUnit.run(name: 'bob', email: 'jon@jones.com', age: 10, amount: 22)
|
23
|
+
assert outcome.success
|
24
|
+
assert_equal OpenStruct.new(name: 'bob', email: 'jon@jones.com', amount: 22), outcome.inputs
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'shouldnt collide' do
|
28
|
+
outcome = SimpleInherited.run(name: 'bob', email: 'jon@jones.com', age: 10, amount: 22)
|
29
|
+
assert outcome.success
|
30
|
+
assert_equal OpenStruct.new(name: 'bob', email: 'jon@jones.com', age: 10, amount: 22), outcome.inputs
|
31
|
+
|
32
|
+
outcome = SimpleUnit.run(name: 'bob', email: 'jon@jones.com', age: 10, amount: 22)
|
33
|
+
assert outcome.success
|
34
|
+
assert_equal OpenStruct.new(name: 'bob', email: 'jon@jones.com', amount: 22), outcome.inputs
|
35
|
+
end
|
36
|
+
end
|
data/spec/simple_unit.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
class SimpleUnit
|
3
|
+
include Objective::Unit
|
4
|
+
|
5
|
+
filter do
|
6
|
+
string :name, max: 10
|
7
|
+
string :email
|
8
|
+
integer :amount, none: ALLOW
|
9
|
+
end
|
10
|
+
|
11
|
+
def validate
|
12
|
+
return if email&.include?('@')
|
13
|
+
add_error(:email, :invalid, 'Email must contain @')
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/spec/unit_spec.rb
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'simple_unit'
|
4
|
+
|
5
|
+
describe 'Unit' do
|
6
|
+
describe 'SimpleUnit' do
|
7
|
+
it 'should allow valid input' do
|
8
|
+
outcome = SimpleUnit.run(name: 'John', email: 'john@gmail.com', amount: 5)
|
9
|
+
|
10
|
+
assert outcome.success
|
11
|
+
assert_equal OpenStruct.new(name: 'John', email: 'john@gmail.com', amount: 5), outcome.inputs
|
12
|
+
assert_nil outcome.errors
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should filter out extra inputs' do
|
16
|
+
outcome = SimpleUnit.run(name: 'John', email: 'john@gmail.com', amount: 5, buggers: true)
|
17
|
+
|
18
|
+
assert outcome.success
|
19
|
+
assert_equal OpenStruct.new(name: 'John', email: 'john@gmail.com', amount: 5), outcome.inputs
|
20
|
+
assert_nil outcome.errors
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should discover errors in inputs' do
|
24
|
+
outcome = SimpleUnit.run(name: 'JohnTooLong', email: 'john@gmail.com')
|
25
|
+
|
26
|
+
assert !outcome.success
|
27
|
+
assert_equal :max, outcome.errors.codes[:name]
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'shouldn\'t throw an exception with run!' do
|
31
|
+
result = SimpleUnit.run!(name: 'John', email: 'john@gmail.com', amount: 5)
|
32
|
+
assert_nil result
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should throw an exception with run!' do
|
36
|
+
assert_raises Objective::ValidationError do
|
37
|
+
SimpleUnit.run!(name: 'John', email: 'john@gmail.com', amount: 'bob')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should do standalone validation' do
|
42
|
+
outcome = SimpleUnit.build(name: 'JohnLong', email: 'john@gmail.com')
|
43
|
+
assert outcome.success
|
44
|
+
assert_nil outcome.errors
|
45
|
+
|
46
|
+
outcome = SimpleUnit.build(name: 'JohnTooLong', email: 'john@gmail.com')
|
47
|
+
assert !outcome.success
|
48
|
+
assert_nil outcome.result
|
49
|
+
assert_equal :max, outcome.errors.codes[:name]
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should execute a custom validate method' do
|
53
|
+
outcome = SimpleUnit.build(name: 'JohnLong', email: 'xxxx')
|
54
|
+
|
55
|
+
assert !outcome.success
|
56
|
+
assert_equal :invalid, outcome.errors.codes[:email]
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should execute custom validate method during run' do
|
60
|
+
outcome = SimpleUnit.run(name: 'JohnLong', email: 'xxxx')
|
61
|
+
|
62
|
+
assert !outcome.success
|
63
|
+
assert_nil outcome.result
|
64
|
+
assert_equal :invalid, outcome.errors.codes[:email]
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should execute custom validate method only if regular validations succeed' do
|
68
|
+
outcome = SimpleUnit.build(name: 'JohnTooLong', email: 'xxxx')
|
69
|
+
|
70
|
+
assert !outcome.success
|
71
|
+
assert_equal :max, outcome.errors.codes[:name]
|
72
|
+
assert_nil outcome.errors.codes[:email]
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'should merge multiple hashes' do
|
76
|
+
outcome = SimpleUnit.run({ name: 'John', email: 'john@gmail.com' }, email: 'bob@jones.com', amount: 5)
|
77
|
+
|
78
|
+
assert outcome.success
|
79
|
+
assert_equal OpenStruct.new(name: 'John', email: 'bob@jones.com', amount: 5), outcome.inputs
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should merge hashes indifferently' do
|
83
|
+
outcome = SimpleUnit.run({ name: 'John', email: 'john@gmail.com' }, 'email' => 'bob@jones.com', 'amount' => 5)
|
84
|
+
|
85
|
+
assert outcome.success
|
86
|
+
assert_equal OpenStruct.new(name: 'John', email: 'bob@jones.com', amount: 5), outcome.inputs
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'shouldn\'t accept non-hashes' do
|
90
|
+
assert_raises ArgumentError do
|
91
|
+
SimpleUnit.run(nil)
|
92
|
+
end
|
93
|
+
|
94
|
+
assert_raises ArgumentError do
|
95
|
+
SimpleUnit.run(1)
|
96
|
+
end
|
97
|
+
|
98
|
+
assert_raises ArgumentError do
|
99
|
+
SimpleUnit.run({ name: 'John' }, 1)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should accept nothing at all' do
|
104
|
+
SimpleUnit.run # make sure nothing is raised
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should return the filtered inputs in the outcome' do
|
108
|
+
outcome = SimpleUnit.run(name: ' John ', email: 'john@gmail.com', amount: '5')
|
109
|
+
assert_equal(OpenStruct.new(name: 'John', email: 'john@gmail.com', amount: 5), outcome.inputs)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe 'EigenUnit' do
|
114
|
+
class EigenUnit
|
115
|
+
include Objective::Unit
|
116
|
+
filter do
|
117
|
+
string :name
|
118
|
+
string :email, none: ALLOW
|
119
|
+
end
|
120
|
+
|
121
|
+
def execute
|
122
|
+
{ name: name, email: email }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'should define methods for input keys' do
|
127
|
+
outcome = EigenUnit.run(name: 'John', email: 'john@gmail.com')
|
128
|
+
assert_equal({ name: 'John', email: 'john@gmail.com' }, outcome.result)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe 'MutatatedUnit' do
|
133
|
+
class MutatatedUnit
|
134
|
+
include Objective::Unit
|
135
|
+
filter do
|
136
|
+
string :name
|
137
|
+
string :email, none: ALLOW
|
138
|
+
end
|
139
|
+
|
140
|
+
def execute
|
141
|
+
inputs.name = 'bob'
|
142
|
+
inputs.email = 'bob@jones.com'
|
143
|
+
{ name: inputs[:name], email: inputs[:email] }
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should allow inputs to be changed' do
|
148
|
+
outcome = MutatatedUnit.run(name: 'John', email: 'john@gmail.com')
|
149
|
+
assert_equal({ name: 'bob', email: 'bob@jones.com' }, outcome.result)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe 'ErrorfulUnit' do
|
154
|
+
class ErrorfulUnit
|
155
|
+
include Objective::Unit
|
156
|
+
filter do
|
157
|
+
string :name
|
158
|
+
string :email, none: ALLOW
|
159
|
+
end
|
160
|
+
|
161
|
+
def execute
|
162
|
+
add_error('bob', :is_a_bob)
|
163
|
+
1
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should let you add errors' do
|
168
|
+
outcome = ErrorfulUnit.run(name: 'John', email: 'john@gmail.com')
|
169
|
+
|
170
|
+
assert !outcome.success
|
171
|
+
assert 1, outcome.result
|
172
|
+
assert :is_a_bob, outcome.errors.codes[:bob]
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe 'NestingErrorfulUnit' do
|
177
|
+
class NestingErrorfulUnit
|
178
|
+
include Objective::Unit
|
179
|
+
filter do
|
180
|
+
string :name
|
181
|
+
string :email, none: ALLOW
|
182
|
+
end
|
183
|
+
|
184
|
+
def execute
|
185
|
+
add_error('people.bob', :is_a_bob)
|
186
|
+
1
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
it 'should let you add errors nested under a namespace' do
|
191
|
+
outcome = NestingErrorfulUnit.run(name: 'John', email: 'john@gmail.com')
|
192
|
+
|
193
|
+
assert !outcome.success
|
194
|
+
assert 1, outcome.result
|
195
|
+
assert :is_a_bob, outcome.errors[:people].codes[:bob]
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe 'MultiErrorUnit' do
|
200
|
+
class MultiErrorUnit
|
201
|
+
include Objective::Unit
|
202
|
+
filter do
|
203
|
+
string :name
|
204
|
+
string :email, none: ALLOW
|
205
|
+
end
|
206
|
+
|
207
|
+
def execute
|
208
|
+
moar_errors = Objective::Errors::ErrorHash.new
|
209
|
+
moar_errors[:bob] = Objective::Errors::ErrorAtom.new(:bob, :is_short)
|
210
|
+
moar_errors[:sally] = Objective::Errors::ErrorAtom.new(:sally, :is_fat)
|
211
|
+
|
212
|
+
merge_errors(moar_errors)
|
213
|
+
1
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should let you merge errors' do
|
218
|
+
outcome = ErrorfulUnit.run(name: 'John', email: 'john@gmail.com')
|
219
|
+
|
220
|
+
assert !outcome.success
|
221
|
+
assert 1, outcome.result
|
222
|
+
assert :is_short, outcome.errors.codes[:bob]
|
223
|
+
assert :is_fat, outcome.errors.codes[:sally]
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
describe 'RawInputsUnit' do
|
228
|
+
class RawInputsUnit
|
229
|
+
include Objective::Unit
|
230
|
+
filter do
|
231
|
+
string :name
|
232
|
+
end
|
233
|
+
|
234
|
+
def execute
|
235
|
+
raw_inputs
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'should return the raw input data' do
|
240
|
+
input = { 'name' => 'Hello World', 'other' => 'Foo Bar Baz' }
|
241
|
+
assert_equal OpenStruct.new(input), RawInputsUnit.run!(input)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|