compel 0.2.0 → 0.3.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 (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