hash_params 0.0.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +8 -8
- data/README.md +167 -109
- data/coverage/assets/0.9.0/application.css +799 -0
- data/coverage/assets/0.9.0/application.js +1707 -0
- data/coverage/assets/0.9.0/colorbox/border.png +0 -0
- data/coverage/assets/0.9.0/colorbox/controls.png +0 -0
- data/coverage/assets/0.9.0/colorbox/loading.gif +0 -0
- data/coverage/assets/0.9.0/colorbox/loading_background.png +0 -0
- data/coverage/assets/0.9.0/favicon_green.png +0 -0
- data/coverage/assets/0.9.0/favicon_red.png +0 -0
- data/coverage/assets/0.9.0/favicon_yellow.png +0 -0
- data/coverage/assets/0.9.0/loading.gif +0 -0
- data/coverage/assets/0.9.0/magnify.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
- data/coverage/assets/0.9.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/coverage/index.html +1597 -369
- data/hash_params.gemspec +14 -5
- data/lib/hash_params/binding_validator.rb +26 -0
- data/lib/hash_params/hash_validator.rb +71 -0
- data/lib/hash_params/validator.rb +119 -0
- data/lib/hash_params/yaml_params.rb +93 -0
- data/lib/hash_params.rb +15 -142
- data/spec/hash_params_spec.rb +100 -63
- data/spec/spec_helper.rb +0 -11
- data/tmp/hash_params.rb +181 -0
- data/tmp/hash_params_spec.rb +102 -0
- data/tmp/module_spec.rb +27 -0
- data/tmp/var_spec.rb +9 -0
- data/tmp/yaml_params.rb +109 -0
- metadata +36 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 65d13d16e642e22b531b671ea8315bc477fd6bd3
|
4
|
+
data.tar.gz: 5f600d5a2f1172920a37870367e9f8e232f35df1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e7207b5832175aa5f2aa9b0e151c1537209d8effc8ad13d480275362d4b1ef0615428ab27151cfa8b7d048ec5f19b9b95af01490d1a016110271850c2edb102
|
7
|
+
data.tar.gz: 1bf66afcaca1c077dabe5e9b46ad9f26201f4c9349f99aff490ce3df9cd102746327764f04be01e61636353d04144e1ba16f291ebb5755ee2ccf51db9519fee2
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
hash_params (0.0
|
4
|
+
hash_params (2.0.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -9,20 +9,20 @@ GEM
|
|
9
9
|
coderay (1.1.0)
|
10
10
|
docile (1.1.5)
|
11
11
|
method_source (0.8.2)
|
12
|
-
minitest (5.
|
12
|
+
minitest (5.5.1)
|
13
13
|
minitest-spec (0.0.2.1)
|
14
14
|
minitest (>= 3.0)
|
15
|
-
multi_json (1.
|
15
|
+
multi_json (1.11.0)
|
16
16
|
pry (0.10.1)
|
17
17
|
coderay (~> 1.1.0)
|
18
18
|
method_source (~> 0.8.1)
|
19
19
|
slop (~> 3.4)
|
20
|
-
rake (10.
|
21
|
-
simplecov (0.9.
|
20
|
+
rake (10.4.2)
|
21
|
+
simplecov (0.9.2)
|
22
22
|
docile (~> 1.1.0)
|
23
|
-
multi_json
|
24
|
-
simplecov-html (~> 0.
|
25
|
-
simplecov-html (0.
|
23
|
+
multi_json (~> 1.0)
|
24
|
+
simplecov-html (~> 0.9.0)
|
25
|
+
simplecov-html (0.9.0)
|
26
26
|
slop (3.6.0)
|
27
27
|
|
28
28
|
PLATFORMS
|
data/README.md
CHANGED
@@ -4,69 +4,131 @@ _Lightweight Parameter Validation & Type Coercion_
|
|
4
4
|
This is a variation of the sinatra-param gem https://github.com/mattt/sinatra-param
|
5
5
|
with the sinatra specific things taken out and slight modifications to make it more useful for generic applications.
|
6
6
|
|
7
|
-
|
7
|
+
`hash-params` allows you to declare, validate, and transform endpoint parameters as you would in frameworks like [ActiveModel](http://rubydoc.info/gems/activemodel/3.2.3/frames) or [DataMapper](http://datamapper.org/). but in a lighterweight fashion
|
8
8
|
|
9
|
+
See the spec down the page for usage scenarios
|
10
|
+
|
11
|
+
## Validations
|
12
|
+
|
13
|
+
- Validations are passed as a hash.
|
14
|
+
- You can validate either individual values or hashes.
|
15
|
+
- Hashes can be validated recursively
|
16
|
+
- You can call the coersion methods separately if you wish
|
17
|
+
- If you don't pass in any validations you'll get the same hash back unless you set the strict option (see below)
|
18
|
+
|
19
|
+
## Coercions
|
20
|
+
|
21
|
+
By declaring parameter types, incoming parameters will automatically be coerced into an object of that type.
|
22
|
+
|
23
|
+
- `String`
|
24
|
+
- `Integer`
|
25
|
+
- `Float`
|
26
|
+
- `Array` _("1,2,3,4,5")_
|
27
|
+
- `Hash` _(key1:value1,key2:value2)_
|
28
|
+
- `Date`, `Time`, & `DateTime`
|
29
|
+
- `:boolean` _("1/0", "true/false", "t/f", "yes/no", "y/n")_
|
30
|
+
|
31
|
+
|
32
|
+
Note that the `Hash` and `Array` coercions are not deep (only one level). The internal elements are not validated or coerced, everything is returned as a string.
|
33
|
+
|
34
|
+
Since Ruby doesn't have a Boolean type use the symbol :boolean. This will attempt to cast the commonly used values to either true or false (`TrueClass` or `FalseClass`)
|
35
|
+
|
36
|
+
You can also use anything that will respond to `to_proc` such as `:to_i`, `:downcase`, etc. It's up to you to make sure the value will obey the method
|
37
|
+
|
38
|
+
|
39
|
+
## Validation Options (Only applies to validating hashes and yaml files)
|
40
|
+
|
41
|
+
You can pass in the following options along with your validations
|
42
|
+
|
43
|
+
- `strict`: Defaults to true. Only the elements mentioned in the validation will be returned. If set to false all elements will be returned by the validated values will replace the originals
|
44
|
+
- `make_methods`: If passed the returned hash will have methods defined for each key in the new hash. This will allow you access the values using standard dot notation.
|
45
|
+
- `raise_errors`: Defaults to true. All errors will be collected during processing and raised just once. If you set this to false no error will be raised, you can check the ```hash.valid?``` method or the ```hash.errors``` collection
|
46
|
+
|
47
|
+
|
48
|
+
## Yaml files
|
49
|
+
|
50
|
+
```validate_yaml_file``` and ```validate_default_yaml_files``` methods are provided for convenience.
|
51
|
+
|
52
|
+
```validate_yaml_file``` works exactly like ```validate_hash``` but takes a file name instead of a hash
|
53
|
+
|
54
|
+
```validate_default_file_names``` scours various directories for yaml files and intelligently merges them together before validation. See the source code for the standard paths and file name patterns.
|
55
|
+
|
56
|
+
|
57
|
+
You can specify the following in the options hash they will all have sensible defaults except the ```app_name```
|
58
|
+
|
59
|
+
- app_name
|
60
|
+
- env
|
61
|
+
- roots
|
62
|
+
- file_separator
|
63
|
+
- file_extension
|
9
64
|
|
10
65
|
## Example
|
11
66
|
|
12
67
|
``` ruby
|
13
68
|
describe HashParams do
|
69
|
+
let (:sample_hash) {
|
70
|
+
|
71
|
+
h= {
|
72
|
+
ignored: "this will be ignored because it's not mentioned",
|
73
|
+
to_be_renamed: :to_be_renamed,
|
74
|
+
integer_coercion: "1",
|
75
|
+
bad_number: '1aaa2',
|
76
|
+
array_with_delim: '1|2|3',
|
77
|
+
hash_as_string: "{a => 1,b => 2,c => d}",
|
78
|
+
proc_validation: "is_this_valid?",
|
79
|
+
some_number: 122,
|
80
|
+
some_string: 'this is a test string',
|
81
|
+
is_true: 'true',
|
82
|
+
is_false: 'f',
|
83
|
+
recursive: {}
|
84
|
+
}
|
14
85
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
86
|
+
}
|
87
|
+
let (:validations) {
|
88
|
+
v={
|
89
|
+
doesnt_exist: {required: true},
|
90
|
+
to_be_renamed: {as: :renamed},
|
91
|
+
no_value: {default: 1},
|
92
|
+
#proc default relying on previously set value
|
93
|
+
proc_default: {default: lambda { |o| 1 * 5 }},
|
94
|
+
integer_coercion: {coerce: Integer},
|
95
|
+
#chained coersions of various types
|
96
|
+
bad_number: {coerce: [lambda { |o| o.gsub('a', '') }, :to_i, Float]},
|
97
|
+
#arrays and hashes
|
98
|
+
array_with_delim: {coerce: Array, delimiter: '|'},
|
99
|
+
hash_as_string: {coerce: Hash, delimiter: ',', separator: '=>'},
|
100
|
+
proc_validation: {validate: lambda { |v| v == 'Failed_proc_validation' }},
|
101
|
+
#validations
|
102
|
+
some_number: {min: 120, max: 500, in: (100..200), is: 122},
|
103
|
+
some_string: {min_length: 21, max_length: 30, format: /^t.*g$/},
|
104
|
+
#combinations
|
105
|
+
missing_with_validation: {coerce: Integer, :default => 60 * 60, :validate => lambda { |v| v >= 60 * 60 }},
|
106
|
+
is_true: {coerce: :boolean},
|
107
|
+
is_false: {coerce: :boolean},
|
108
|
+
#recursive}
|
109
|
+
recursive: {
|
110
|
+
wasnt_here_before: {default: true}
|
30
111
|
}
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
#proc default relying on previously set value
|
36
|
-
param :proc_default, default: lambda { |o| o[:no_value] * 5 }
|
37
|
-
param :integer_coercion, coerce: Integer
|
38
|
-
#chained coersions of various types
|
39
|
-
param :bad_number, coerce: [lambda { |o| o.gsub('a', '') }, :to_i, Float]
|
40
|
-
#arrays and hashes
|
41
|
-
param :array_with_delim, coerce: Array, delimiter: '|'
|
42
|
-
param :hash_as_string, coerce: Hash, delimiter: ',', separator: '=>'
|
43
|
-
param :proc_validation, validate: lambda { |v| v == 'Failed_proc_validation' }
|
44
|
-
#validations
|
45
|
-
param :some_number, min: 120, max: 500, in: (100..200), is: 122
|
46
|
-
param :some_string, min_length: 21, max_length: 30, format: /^t.*g$/
|
47
|
-
#combinations
|
48
|
-
param :missing_with_validation, coerce: Integer, :default => 60 * 60, :validate => lambda { |v| v >= 60 * 60 }
|
49
|
-
param :is_true, coerce: :boolean
|
50
|
-
param :is_false, coerce: :boolean
|
51
|
-
#recursive
|
52
|
-
param :recursive do
|
53
|
-
param :wasnt_here_before, default: true
|
54
|
-
end
|
55
|
-
end
|
112
|
+
}
|
113
|
+
}
|
114
|
+
let (:r) {
|
115
|
+
HashParams.validate_hash(sample_hash, validations, {raise_errors: false})
|
56
116
|
}
|
57
117
|
|
58
118
|
|
59
119
|
it 'does amazing things' do
|
120
|
+
|
60
121
|
(r.valid?).must_equal false
|
122
|
+
|
61
123
|
r[:ignored].must_be_nil
|
62
124
|
r[:no_value].must_equal 1
|
63
125
|
r[:proc_default].must_equal 5
|
64
|
-
r[:
|
126
|
+
r[:to_be_renamed].must_equal :to_be_renamed
|
65
127
|
r[:integer_coercion].must_equal 1
|
66
128
|
r[:bad_number].must_equal 12.0
|
67
129
|
|
68
130
|
r[:array_with_delim].must_equal ["1", "2", "3"]
|
69
|
-
r[:hash_as_string].must_equal ({
|
131
|
+
r[:hash_as_string].must_equal ({"a" => "1", "b" => "2", "c" => "d"})
|
70
132
|
r[:missing_with_validation].must_equal 60 * 60
|
71
133
|
r[:is_true].must_equal true
|
72
134
|
r[:is_false].must_equal false
|
@@ -74,98 +136,94 @@ describe HashParams do
|
|
74
136
|
#recursive checking
|
75
137
|
r[:recursive][:wasnt_here_before].must_equal true
|
76
138
|
|
139
|
+
|
77
140
|
#failed items don't show up
|
78
141
|
r.errors.size.must_equal 2
|
79
142
|
r[:doesnt_exist].must_be_nil
|
80
143
|
r[:proc_validation].must_be_nil
|
81
|
-
r.errors[
|
82
|
-
r.errors[
|
144
|
+
r.errors[:doesnt_exist].must_equal 'Required Parameter missing and has no default specified'
|
145
|
+
r.errors[:proc_validation].must_equal 'is_this_valid? failed validation using proc'
|
83
146
|
|
84
147
|
end
|
85
148
|
|
86
|
-
it 'injects into
|
87
|
-
|
88
|
-
|
89
|
-
|
149
|
+
it 'injects methods into returned hash' do
|
150
|
+
|
151
|
+
#set strict to false so all keys will pass trough
|
152
|
+
hash={will_be_injected: 12345}
|
153
|
+
opts={make_methods: true, strict: false}
|
154
|
+
|
155
|
+
r=HashParams.validate_hash(hash, {}, opts)
|
90
156
|
r[:will_be_injected].must_equal 12345
|
91
|
-
|
92
|
-
will_be_injected.must_equal 12345
|
157
|
+
r.will_be_injected.must_equal 12345
|
93
158
|
end
|
94
159
|
|
95
160
|
end
|
96
161
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
### Defaults
|
101
|
-
|
102
|
-
Passing a `default` option will provide a default value for a parameter if none is passed. A `default` can defined as either a default or as a `Proc`:
|
103
|
-
|
104
|
-
```ruby
|
105
|
-
param :attribution, String, default: "©"
|
106
|
-
param :year, Integer, default: lambda { Time.now.year }
|
107
|
-
```
|
108
|
-
|
109
|
-
|
110
|
-
### Coercions
|
111
|
-
|
112
|
-
By declaring parameter types, incoming parameters will automatically be coerced into an object of that type.
|
113
|
-
|
114
|
-
- `String`
|
115
|
-
- `Integer`
|
116
|
-
- `Float`
|
117
|
-
- `Array` _("1,2,3,4,5")_
|
118
|
-
- `Hash` _(key1:value1,key2:value2)_
|
119
|
-
- `Date`, `Time`, & `DateTime`
|
120
|
-
|
121
|
-
Note that the `Hash` and `Array` coercions are not deep (only one level). The internal elements are not validated or coerced, everything is returned as a string.
|
122
|
-
|
123
|
-
Since Ruby doesn't have a Boolean type use the symbol :boolean. This will attempt to cast the commonly used values to either true or false (`TrueClass` or `FalseClass`)
|
124
|
-
- `:boolean` _("1/0", "true/false", "t/f", "yes/no", "y/n")_
|
162
|
+
describe HashParams do
|
163
|
+
let(:v) { HashParams}
|
125
164
|
|
126
|
-
|
165
|
+
it 'raises error if required and missing' do
|
166
|
+
proc {
|
167
|
+
v.validate(nil, required: true)
|
168
|
+
}.must_raise HashParams::ValidationError
|
169
|
+
end
|
170
|
+
it 'runs multiple coersions' do
|
171
|
+
v.validate('1aaa2', coerce: [lambda { |o| o.gsub('a', '') }, :to_i, Float]).must_equal 12.0
|
172
|
+
end
|
127
173
|
|
174
|
+
it 'defaults missing values' do
|
175
|
+
v.validate(nil, default: 1).must_equal 1
|
176
|
+
v.validate(nil, default: lambda { |o| 2 * 5 }).must_equal 10
|
177
|
+
end
|
128
178
|
|
129
|
-
|
179
|
+
it 'applies defaults before other actions' do
|
180
|
+
v.validate(nil, coerce: Integer, :default => 60 * 60, :validate => lambda { |v| v >= 60 * 60 }).must_equal 60 * 60
|
181
|
+
end
|
130
182
|
|
131
|
-
|
183
|
+
it 'validates with procs' do
|
184
|
+
proc {
|
185
|
+
v.validate('is_this_valid?') do |v|
|
186
|
+
v == 'Failed_proc_validation'
|
187
|
+
end
|
188
|
+
}.must_raise HashParams::ValidationError
|
189
|
+
end
|
132
190
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
191
|
+
it 'verifies numbers with common params' do
|
192
|
+
v.validate(122, min: 120, max: 500, in: (100..200), is: 122).must_equal 122
|
193
|
+
end
|
194
|
+
it 'verifies strings with common params' do
|
195
|
+
v.validate('this is a test string', min_length: 21, max_length: 30, format: /^t.*g$/).must_equal 'this is a test string'
|
196
|
+
end
|
139
197
|
|
140
|
-
|
198
|
+
it 'coerces true' do
|
199
|
+
v.coerce('t', :boolean).must_equal true
|
200
|
+
v.coerce('true', :boolean).must_equal true
|
201
|
+
v.coerce('yes', :boolean).must_equal true
|
202
|
+
v.coerce('1',:boolean).must_equal true
|
203
|
+
v.coerce(1,:boolean).must_equal true
|
204
|
+
end
|
205
|
+
it 'coerces false' do
|
206
|
+
v.coerce('f', :boolean).must_equal false
|
207
|
+
v.coerce('false', :boolean).must_equal false
|
208
|
+
v.coerce('no', :boolean).must_equal false
|
209
|
+
v.coerce('0',:boolean).must_equal false
|
210
|
+
v.coerce(0,:boolean).must_equal false
|
211
|
+
end
|
212
|
+
it 'coerces array' do
|
213
|
+
v.coerce('1|2|3', Array, delimiter: '|').must_equal ["1", "2", "3"]
|
214
|
+
end
|
215
|
+
it 'coerces hash' do
|
216
|
+
v.coerce('{a => 1,b => 2,c => d}', Hash, delimiter: ',', separator: '=>').must_equal({"a" => "1", "b" => "2", "c" => "d"})
|
217
|
+
end
|
141
218
|
|
142
219
|
|
143
|
-
|
220
|
+
end
|
144
221
|
|
145
|
-
All recorded validation errors, coercion errors, and exceptions are in the errors collection of the returned object. You can also call the valid? method to check to see if everything went OK.
|
146
222
|
|
147
|
-
```ruby
|
148
|
-
p = HashParams.new({a: :b}) do
|
149
|
-
param :a
|
150
|
-
end
|
151
223
|
|
152
|
-
p.errors.inspect unless p.valid?
|
153
224
|
```
|
154
225
|
|
155
|
-
### Injection into classes
|
156
|
-
|
157
|
-
You can if you choose inject all passing variables (but not valid? or errors collection) into a given class. The injection is done via `attr_accessor` The values are injected into the singleton so no need to worry about polluting other objects.
|
158
226
|
|
159
|
-
```ruby
|
160
|
-
it 'injects into current class' do
|
161
|
-
r = HashParams.new({will_be_injected: 12345}, self) do
|
162
|
-
param :will_be_injected
|
163
|
-
end
|
164
|
-
r[:will_be_injected].must_equal 12345
|
165
|
-
@will_be_injected.must_equal 12345
|
166
|
-
will_be_injected.must_equal 12345
|
167
|
-
end
|
168
|
-
```
|
169
227
|
|
170
228
|
|
171
229
|
## Contact
|