compel 0.2.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +88 -20
  3. data/lib/compel/builder/array.rb +31 -0
  4. data/lib/compel/builder/boolean.rb +7 -0
  5. data/lib/compel/builder/common.rb +2 -2
  6. data/lib/compel/builder/common_value.rb +4 -4
  7. data/lib/compel/builder/hash.rb +3 -1
  8. data/lib/compel/builder/methods.rb +5 -0
  9. data/lib/compel/builder/schema.rb +4 -0
  10. data/lib/compel/coercion/coercion.rb +47 -0
  11. data/lib/compel/coercion/nil_result.rb +13 -0
  12. data/lib/compel/coercion/result.rb +37 -0
  13. data/lib/compel/coercion/types/array.rb +15 -0
  14. data/lib/compel/coercion/{boolean.rb → types/boolean.rb} +1 -3
  15. data/lib/compel/coercion/types/date.rb +36 -0
  16. data/lib/compel/coercion/types/datetime.rb +36 -0
  17. data/lib/compel/coercion/{float.rb → types/float.rb} +2 -2
  18. data/lib/compel/coercion/{hash.rb → types/hash.rb} +2 -2
  19. data/lib/compel/coercion/{integer.rb → types/integer.rb} +2 -2
  20. data/lib/compel/coercion/{json.rb → types/json.rb} +2 -2
  21. data/lib/compel/coercion/{regexp.rb → types/regexp.rb} +2 -4
  22. data/lib/compel/coercion/{string.rb → types/string.rb} +3 -5
  23. data/lib/compel/coercion/types/time.rb +36 -0
  24. data/lib/compel/coercion/types/type.rb +29 -0
  25. data/lib/compel/contract.rb +14 -42
  26. data/lib/compel/errors.rb +13 -17
  27. data/lib/compel/exceptions/invalid_object_error.rb +9 -0
  28. data/lib/compel/result.rb +30 -0
  29. data/lib/compel/validation.rb +6 -4
  30. data/lib/compel/validators/array_validator.rb +107 -0
  31. data/lib/compel/validators/base.rb +11 -1
  32. data/lib/compel/validators/hash_validator.rb +77 -19
  33. data/lib/compel/validators/type_validator.rb +42 -11
  34. data/lib/compel/version.rb +1 -1
  35. data/lib/compel.rb +6 -15
  36. data/spec/compel/builder_spec.rb +354 -144
  37. data/spec/compel/coercion_spec.rb +16 -1
  38. data/spec/compel/compel_spec.rb +315 -302
  39. data/spec/compel/validation_spec.rb +97 -115
  40. data/spec/support/sinatra_app.rb +2 -2
  41. metadata +21 -15
  42. data/lib/compel/coercion/date.rb +0 -30
  43. data/lib/compel/coercion/datetime.rb +0 -30
  44. data/lib/compel/coercion/time.rb +0 -30
  45. data/lib/compel/coercion/type.rb +0 -17
  46. data/lib/compel/coercion.rb +0 -31
  47. data/lib/compel/exceptions/invalid_hash_error.rb +0 -9
@@ -1,185 +1,167 @@
1
1
  describe Compel::Validation do
2
2
 
3
- context 'Param validation' do
3
+ context 'required' do
4
4
 
5
- context 'required' do
5
+ it 'should validate without errors' do
6
+ errors = Compel::Validation.validate(123, Compel::Coercion::Integer, { required: true })
6
7
 
7
- it 'should validate without errors' do
8
- errors = Compel::Validation.validate(123, Compel::Coercion::Integer, { required: true })
9
-
10
- expect(errors.empty?).to eq(true)
11
- end
12
-
13
- it 'should validate with error' do
14
- errors = Compel::Validation.validate(nil, Compel::Coercion::Integer, { required: true })
8
+ expect(errors.empty?).to eq(true)
9
+ end
15
10
 
16
- expect(errors.empty?).to eq(false)
17
- expect(errors).to eq(['is required'])
18
- end
11
+ it 'should validate with error' do
12
+ errors = Compel::Validation.validate(nil, Compel::Coercion::Integer, { required: true })
19
13
 
14
+ expect(errors.empty?).to eq(false)
15
+ expect(errors).to eq(['is required'])
20
16
  end
21
17
 
22
- context 'length' do
18
+ end
23
19
 
24
- it 'should validate without errors' do
25
- errors = Compel::Validation.validate(123, Compel::Coercion::Integer, { length: 3 })
20
+ context 'length' do
26
21
 
27
- expect(errors.empty?).to eq(true)
28
- end
22
+ it 'should validate without errors' do
23
+ errors = Compel::Validation.validate(123, Compel::Coercion::Integer, { length: 3 })
29
24
 
25
+ expect(errors.empty?).to eq(true)
30
26
  end
31
27
 
32
- context 'in, within, range' do
28
+ end
33
29
 
34
- def expect_be_in_within_range(range, value)
35
- [:in, :within].each do |key|
36
- errors = Compel::Validation.validate(value, Compel::Coercion::String, { key => range })
37
- yield errors
38
- end
39
- end
30
+ context 'in, within, range' do
40
31
 
41
- it 'should validate without errors' do
42
- expect_be_in_within_range(['PT', 'UK'], 'PT') do |errors|
43
- expect(errors.empty?).to eq(true)
44
- end
32
+ def expect_be_in_within_range(range, value)
33
+ [:in, :within].each do |key|
34
+ errors = Compel::Validation.validate(value, Compel::Coercion::String, { key => range })
35
+ yield errors
45
36
  end
37
+ end
46
38
 
47
- it 'should validate with errors' do
48
- expect_be_in_within_range(['PT', 'UK'], 'US') do |errors|
49
- expect(errors).to include('must be within ["PT", "UK"]')
50
- end
39
+ it 'should validate without errors' do
40
+ expect_be_in_within_range(['PT', 'UK'], 'PT') do |errors|
41
+ expect(errors.empty?).to eq(true)
51
42
  end
43
+ end
52
44
 
53
- context 'range' do
54
-
55
- it 'should validate without errors' do
56
- errors = Compel::Validation.validate(2, Compel::Coercion::Integer, range: (1..3))
57
-
58
- expect(errors.empty?).to eq(true)
59
- end
45
+ it 'should validate with errors' do
46
+ expect_be_in_within_range(['PT', 'UK'], 'US') do |errors|
47
+ expect(errors).to include('must be within ["PT", "UK"]')
48
+ end
49
+ end
60
50
 
61
- it 'should validate with errors' do
62
- errors = Compel::Validation.validate(4, Compel::Coercion::Integer, range: (1..3))
51
+ context 'range' do
63
52
 
64
- expect(errors).to include('must be within 1..3')
65
- end
53
+ it 'should validate without errors' do
54
+ errors = Compel::Validation.validate(2, Compel::Coercion::Integer, range: (1..3))
66
55
 
56
+ expect(errors.empty?).to eq(true)
67
57
  end
68
58
 
69
- end
70
-
71
- context 'format' do
72
-
73
59
  it 'should validate with errors' do
74
- format = /^abcd/
75
- errors = Compel::Validation.validate('acb', Compel::Coercion::String, format: format)
60
+ errors = Compel::Validation.validate(4, Compel::Coercion::Integer, range: (1..3))
76
61
 
77
- expect(errors).to include("must match format ^abcd")
62
+ expect(errors).to include('must be within 1..3')
78
63
  end
79
64
 
80
- it 'should validate with errors 1' do
81
- format = /^abcd/
82
- errors = Compel::Validation.validate(123, Compel::Coercion::Integer, format: format)
65
+ end
83
66
 
84
- expect(errors).to include('must be a string if using the format validation')
85
- end
67
+ end
86
68
 
87
- it 'should validate with errors 2' do
88
- format = /^abcd/
89
- errors = Compel::Validation.validate(nil, Compel::Coercion::String, format: format)
69
+ context 'format' do
90
70
 
91
- expect(errors).to include('must be a string if using the format validation')
92
- end
71
+ it 'should validate with errors' do
72
+ format = /^abcd/
73
+ errors = Compel::Validation.validate('acb', Compel::Coercion::String, format: format)
93
74
 
94
- it 'should validate without errors' do
95
- format = /abcd/
96
- errors = Compel::Validation.validate('abcd', Compel::Coercion::String, format: format)
97
- expect(errors.empty?).to eq(true)
98
- end
75
+ expect(errors).to include("must match format ^abcd")
76
+ end
99
77
 
78
+ it 'should validate without errors' do
79
+ format = /abcd/
80
+ errors = Compel::Validation.validate('abcd', Compel::Coercion::String, format: format)
81
+ expect(errors.empty?).to eq(true)
100
82
  end
101
83
 
102
- context 'is' do
84
+ end
103
85
 
104
- it 'should validate with errors' do
105
- errors = Compel::Validation.validate('abcd', Compel::Coercion::Integer, is: 123)
106
- expect(errors).to include('must be 123')
107
- end
86
+ context 'is' do
108
87
 
109
- it 'should validate with errors 1' do
110
- errors = Compel::Validation.validate(nil, Compel::Coercion::Integer, is: 123)
111
- expect(errors).to include('must be 123')
112
- end
88
+ it 'should validate with errors' do
89
+ errors = Compel::Validation.validate('abcd', Compel::Coercion::Integer, is: 123)
90
+ expect(errors).to include('must be 123')
91
+ end
113
92
 
114
- it 'should validate without errors' do
115
- errors = Compel::Validation.validate(123, Compel::Coercion::Integer, is: 123)
116
- expect(errors.empty?).to eq(true)
117
- end
93
+ it 'should validate with errors 1' do
94
+ errors = Compel::Validation.validate(nil, Compel::Coercion::Integer, is: 123)
95
+ expect(errors).to include('must be 123')
96
+ end
118
97
 
98
+ it 'should validate without errors' do
99
+ errors = Compel::Validation.validate(123, Compel::Coercion::Integer, is: 123)
100
+ expect(errors.empty?).to eq(true)
119
101
  end
120
102
 
121
- context 'min' do
103
+ end
122
104
 
123
- it 'should validate with errors' do
124
- errors = Compel::Validation.validate(1, Compel::Coercion::Integer, min: 3)
105
+ context 'min' do
125
106
 
126
- expect(errors).to include('cannot be less than 3')
127
- end
107
+ it 'should validate with errors' do
108
+ errors = Compel::Validation.validate(1, Compel::Coercion::Integer, min: 3)
128
109
 
110
+ expect(errors).to include('cannot be less than 3')
129
111
  end
130
112
 
131
- context 'max' do
113
+ end
132
114
 
133
- it 'should validate with errors' do
134
- errors = Compel::Validation.validate(3, Compel::Coercion::Integer, max: 2)
115
+ context 'max' do
135
116
 
136
- expect(errors).to include('cannot be greater than 2')
137
- end
117
+ it 'should validate with errors' do
118
+ errors = Compel::Validation.validate(3, Compel::Coercion::Integer, max: 2)
138
119
 
120
+ expect(errors).to include('cannot be greater than 2')
139
121
  end
140
122
 
141
- context 'min_length' do
123
+ end
142
124
 
143
- it 'should validate with errors' do
144
- errors = Compel::Validation.validate(3, Compel::Coercion::Integer, min_length: 2)
125
+ context 'min_length' do
145
126
 
146
- expect(errors).to include('must be a string if using the min_length validation')
147
- end
127
+ it 'should validate with errors' do
128
+ errors = Compel::Validation.validate(3, Compel::Coercion::Integer, min_length: 2)
148
129
 
149
- it 'should validate with errors 1' do
150
- errors = Compel::Validation.validate('a', Compel::Coercion::String, min_length: 2)
130
+ expect(errors).to include('must be a string if using the min_length validation')
131
+ end
151
132
 
152
- expect(errors).to include('cannot have length less than 2')
153
- end
133
+ it 'should validate with errors 1' do
134
+ errors = Compel::Validation.validate('a', Compel::Coercion::String, min_length: 2)
154
135
 
155
- it 'should validate without errors' do
156
- errors = Compel::Validation.validate('ab', Compel::Coercion::String, min_length: 2)
136
+ expect(errors).to include('cannot have length less than 2')
137
+ end
157
138
 
158
- expect(errors.empty?).to eq(true)
159
- end
139
+ it 'should validate without errors' do
140
+ errors = Compel::Validation.validate('ab', Compel::Coercion::String, min_length: 2)
160
141
 
142
+ expect(errors.empty?).to eq(true)
161
143
  end
162
144
 
163
- context 'max_length' do
145
+ end
164
146
 
165
- it 'should validate with errors' do
166
- errors = Compel::Validation.validate(1, Compel::Coercion::Integer, max_length: 2)
147
+ context 'max_length' do
167
148
 
168
- expect(errors).to include('must be a string if using the max_length validation')
169
- end
149
+ it 'should validate with errors' do
150
+ errors = Compel::Validation.validate(1, Compel::Coercion::Integer, max_length: 2)
170
151
 
171
- it 'should validate with errors 1' do
172
- errors = Compel::Validation.validate('abcdef', Compel::Coercion::String, max_length: 5)
152
+ expect(errors).to include('must be a string if using the max_length validation')
153
+ end
173
154
 
174
- expect(errors).to include('cannot have length greater than 5')
175
- end
155
+ it 'should validate with errors 1' do
156
+ errors = Compel::Validation.validate('abcdef', Compel::Coercion::String, max_length: 5)
176
157
 
177
- it 'should validate without errors' do
178
- errors = Compel::Validation.validate('abcde', Compel::Coercion::String, max_length: 5)
158
+ expect(errors).to include('cannot have length greater than 5')
159
+ end
179
160
 
180
- expect(errors.empty?).to eq(true)
181
- end
161
+ it 'should validate without errors' do
162
+ errors = Compel::Validation.validate('abcde', Compel::Coercion::String, max_length: 5)
182
163
 
164
+ expect(errors.empty?).to eq(true)
183
165
  end
184
166
 
185
167
  end
@@ -18,9 +18,9 @@ class SinatraApp < Sinatra::Base
18
18
 
19
19
  end
20
20
 
21
- error Compel::InvalidHashError do |exception|
21
+ error Compel::InvalidObjectError do |exception|
22
22
  status 400
23
- { errors: exception.errors }.to_json
23
+ { errors: exception.object[:errors] }.to_json
24
24
  end
25
25
 
26
26
  configure :development do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: compel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joaquim Adráz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-28 00:00:00.000000000 Z
11
+ date: 2015-12-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
@@ -82,6 +82,7 @@ files:
82
82
  - Rakefile
83
83
  - compel.gemspec
84
84
  - lib/compel.rb
85
+ - lib/compel/builder/array.rb
85
86
  - lib/compel/builder/boolean.rb
86
87
  - lib/compel/builder/common.rb
87
88
  - lib/compel/builder/common_value.rb
@@ -95,24 +96,29 @@ files:
95
96
  - lib/compel/builder/schema.rb
96
97
  - lib/compel/builder/string.rb
97
98
  - lib/compel/builder/time.rb
98
- - lib/compel/coercion.rb
99
- - lib/compel/coercion/boolean.rb
100
- - lib/compel/coercion/date.rb
101
- - lib/compel/coercion/datetime.rb
102
- - lib/compel/coercion/float.rb
103
- - lib/compel/coercion/hash.rb
104
- - lib/compel/coercion/integer.rb
105
- - lib/compel/coercion/json.rb
106
- - lib/compel/coercion/regexp.rb
107
- - lib/compel/coercion/string.rb
108
- - lib/compel/coercion/time.rb
109
- - lib/compel/coercion/type.rb
99
+ - lib/compel/coercion/coercion.rb
100
+ - lib/compel/coercion/nil_result.rb
101
+ - lib/compel/coercion/result.rb
102
+ - lib/compel/coercion/types/array.rb
103
+ - lib/compel/coercion/types/boolean.rb
104
+ - lib/compel/coercion/types/date.rb
105
+ - lib/compel/coercion/types/datetime.rb
106
+ - lib/compel/coercion/types/float.rb
107
+ - lib/compel/coercion/types/hash.rb
108
+ - lib/compel/coercion/types/integer.rb
109
+ - lib/compel/coercion/types/json.rb
110
+ - lib/compel/coercion/types/regexp.rb
111
+ - lib/compel/coercion/types/string.rb
112
+ - lib/compel/coercion/types/time.rb
113
+ - lib/compel/coercion/types/type.rb
110
114
  - lib/compel/contract.rb
111
115
  - lib/compel/errors.rb
112
- - lib/compel/exceptions/invalid_hash_error.rb
116
+ - lib/compel/exceptions/invalid_object_error.rb
113
117
  - lib/compel/exceptions/type_error.rb
114
118
  - lib/compel/exceptions/validation_error.rb
119
+ - lib/compel/result.rb
115
120
  - lib/compel/validation.rb
121
+ - lib/compel/validators/array_validator.rb
116
122
  - lib/compel/validators/base.rb
117
123
  - lib/compel/validators/hash_validator.rb
118
124
  - lib/compel/validators/type_validator.rb
@@ -1,30 +0,0 @@
1
- module Compel
2
- module Coercion
3
-
4
- class Date < Type
5
-
6
- def coerce!
7
- format = options[:format] || '%Y-%m-%d'
8
-
9
- if value.is_a?(::Date)
10
- @value = value.strftime(format)
11
- end
12
-
13
- coerced = ::Date.strptime(value, format)
14
-
15
- if coerced.strftime(format) == value
16
- return coerced
17
- end
18
-
19
- fail
20
-
21
- rescue
22
- raise \
23
- Compel::TypeError,
24
- "'#{value}' is not a parsable date with format: #{format}"
25
- end
26
-
27
- end
28
-
29
- end
30
- end
@@ -1,30 +0,0 @@
1
- module Compel
2
- module Coercion
3
-
4
- class DateTime < Type
5
-
6
- def coerce!
7
- format = options[:format] || '%FT%T'
8
-
9
- if value.is_a?(::DateTime)
10
- @value = value.strftime(format)
11
- end
12
-
13
- coerced = ::DateTime.strptime(value, format)
14
-
15
- if coerced.strftime(format) == value
16
- return coerced
17
- end
18
-
19
- fail
20
-
21
- rescue
22
- raise \
23
- Compel::TypeError,
24
- "'#{value}' is not a parsable datetime with format: #{format}"
25
- end
26
-
27
- end
28
-
29
- end
30
- end
@@ -1,30 +0,0 @@
1
- module Compel
2
- module Coercion
3
-
4
- class Time < Type
5
-
6
- def coerce!
7
- format = options[:format] || '%FT%T'
8
-
9
- if value.is_a?(::Time)
10
- @value = value.strftime(format)
11
- end
12
-
13
- coerced = ::Time.strptime(value, format)
14
-
15
- if coerced.strftime(format) == value
16
- return coerced
17
- end
18
-
19
- fail
20
-
21
- rescue
22
- raise \
23
- Compel::TypeError,
24
- "'#{value}' is not a parsable time with format: #{format}"
25
- end
26
-
27
- end
28
-
29
- end
30
- end
@@ -1,17 +0,0 @@
1
- module Compel
2
- module Coercion
3
-
4
- class Type
5
-
6
- attr_accessor :value,
7
- :options
8
-
9
- def initialize(value, options = {})
10
- @value = value
11
- @options = options
12
- end
13
-
14
- end
15
-
16
- end
17
- end
@@ -1,31 +0,0 @@
1
- module Compel
2
-
3
- module Coercion
4
-
5
- def valid?(value, type, options = {})
6
- !!coerce!(value, type, options) rescue false
7
- end
8
-
9
- def coerce!(value, type, options = {})
10
- return nil if value.nil?
11
-
12
- begin
13
- coercion_klass(type).new(value, options).coerce!
14
- rescue Compel::TypeError => exception
15
- raise exception
16
- rescue
17
- type_split = "#{type}".split('::')
18
-
19
- raise Compel::TypeError, "'#{value}' is not a valid #{type_split[-1]}"
20
- end
21
- end
22
-
23
- def coercion_klass(type)
24
- Compel::Coercion.const_get("#{type}")
25
- end
26
-
27
- extend self
28
-
29
- end
30
-
31
- end
@@ -1,9 +0,0 @@
1
- module Compel
2
-
3
- class InvalidHashError < StandardError
4
-
5
- attr_accessor :object, :errors
6
-
7
- end
8
-
9
- end