yas 0.1.1 → 0.2.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 +4 -4
- data/README.markdown +56 -26
- data/lib/yas/ext/attribute.rb +40 -28
- data/lib/yas/ext/rename.rb +6 -6
- data/lib/yas/ext/symbolize.rb +30 -0
- data/lib/yas/schema.rb +2 -1
- data/lib/yas/version.rb +1 -1
- data/lib/yas.rb +1 -2
- data/test/ext/test_attribute.rb +15 -1
- data/test/ext/test_rename.rb +4 -1
- data/test/ext/test_symbolize.rb +23 -0
- data/test/test_schema.rb +23 -0
- metadata +4 -3
- data/lib/yas/helper.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14bc3ae92e4d7b9e86b4231edfb5f44cb5d04e1f
|
4
|
+
data.tar.gz: 149294a84a65f4eb2bc726c8cdbf41fe6c16593c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04efb2cbe5b897de52da85c02244b127b2ba65bc512ba8e510c7b1a516814cb8f37a71bdda8b62cdd3b94898ef262503754428b138346260a2494d30d937ead4
|
7
|
+
data.tar.gz: 69c588d7f01c2f2a2a96ba37fdebcc5b82a78beb6e1ef3c85586e70b782b988bbea57f50128d58bcd4ec64a70ccfb7c027cab7d759aeede50cf01131b45bba83
|
data/README.markdown
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# YAS
|
2
2
|
|
3
|
-
YAS (Yet Another Schema) is an extensible hash validator for Ruby.
|
3
|
+
YAS (Yet Another Schema) is an extensible hash validator for Ruby used to maintain hash integrity.
|
4
4
|
Using YAS, you can enforce a specific key to be required, rename them, perform automatic type conversion, and other goodies.
|
5
5
|
|
6
6
|
|
@@ -14,39 +14,34 @@ Using YAS, you can enforce a specific key to be required, rename them, perform a
|
|
14
14
|
require 'yas'
|
15
15
|
|
16
16
|
class MySchema < YAS::Schema
|
17
|
-
rename :
|
17
|
+
rename :bar => :foo
|
18
18
|
end
|
19
19
|
|
20
20
|
h = { bar: "value" }
|
21
21
|
h.validate! MySchema
|
22
|
-
|
23
|
-
|
22
|
+
h[:foo] # "value"
|
23
|
+
h[:bar] # nil
|
24
24
|
|
25
25
|
|
26
26
|
## Extensions
|
27
27
|
|
28
|
-
You can extend the behavior of YAS by writing your own custom extensions
|
28
|
+
You can extend the behavior of YAS by writing your own custom extensions.
|
29
|
+
`YAS::Schema` already comes with a set of awesome default extensions that you can immediately use.
|
30
|
+
Optionally, you may also use `YAS::SchemaBase` if you want to start off from a clean slate.
|
29
31
|
|
30
|
-
* `attribute name, &block` or `key name, &block`
|
31
32
|
|
32
|
-
|
33
|
+
### Default Extensions
|
33
34
|
|
34
|
-
* `rename`
|
35
35
|
|
36
|
-
|
36
|
+
#### Attribute
|
37
37
|
|
38
|
-
|
38
|
+
Declares an attribute/key with various requirements.
|
39
|
+
The Attribute extension allows you to specify certain requirements/restrictions for a given key.
|
39
40
|
|
40
|
-
|
41
|
+
attribute name, &block
|
42
|
+
key name, &block
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
Provide a set of keys that you only care to see.
|
45
|
-
|
46
|
-
|
47
|
-
### Attribute Extension
|
48
|
-
|
49
|
-
The Attribute extension allows you to specify certain requirements/restrictions for a given key:
|
44
|
+
Example:
|
50
45
|
|
51
46
|
class MySchema < YAS::Schema
|
52
47
|
key :email do
|
@@ -71,7 +66,7 @@ List of directives you can use:
|
|
71
66
|
|
72
67
|
* `type(T)`
|
73
68
|
|
74
|
-
Sets the type of this key. Will perform type check if specified. Can be nested if type is a YAS::Schema
|
69
|
+
Sets the type of this key. Will perform type check if specified. Can be nested if type is a `YAS::Schema`!
|
75
70
|
|
76
71
|
* `auto_convert`
|
77
72
|
|
@@ -81,14 +76,24 @@ List of directives you can use:
|
|
81
76
|
|
82
77
|
Runs the block to set the default value for this key, if it's missing or nil.
|
83
78
|
|
79
|
+
* `alter(&block)`
|
80
|
+
|
81
|
+
Adjust the value of this key. Can be useful if you want to enforce certain formatting, such as upper/lowercase, unique arrays, etc.
|
82
|
+
Value returned by block will be used as the new value for this key, which then gets validated by the `validate_value` block.
|
83
|
+
|
84
84
|
* `validate_value(&block)`
|
85
85
|
|
86
|
-
Custom validation method to check the value of a key. This is useful in cases where you only want certain values to be stored (e.g a number between 1-10 only)
|
86
|
+
Custom validation method to check the value of a key. This is useful in cases where you only want certain values to be stored (e.g a number between 1-10 only).
|
87
|
+
Return true to indicate value passes validation, false for fail.
|
87
88
|
|
88
89
|
|
89
|
-
|
90
|
+
#### Rename
|
90
91
|
|
91
|
-
Using `rename` to rename keys.
|
92
|
+
Using `rename` to rename keys.
|
93
|
+
|
94
|
+
rename :from => :to
|
95
|
+
|
96
|
+
Example:
|
92
97
|
|
93
98
|
class UserSchema < YAS::Schema
|
94
99
|
rename :username => :nickname
|
@@ -98,9 +103,13 @@ Using `rename` to rename keys. Useful to maintain hash integrity.
|
|
98
103
|
hash[:nickname] # 'jdoe'
|
99
104
|
|
100
105
|
|
101
|
-
|
106
|
+
#### Migrate
|
107
|
+
|
108
|
+
Migrate the value of a key. This is useful if you have keys whose values are in the old format and you want to convert them to the new format.
|
102
109
|
|
103
|
-
|
110
|
+
migrate :key, &block
|
111
|
+
|
112
|
+
Example:
|
104
113
|
|
105
114
|
class UserSchema < YAS::Schema
|
106
115
|
migrate :nicknames do |v|
|
@@ -112,10 +121,14 @@ You can also migrate the values. This is useful if you have hash whose values ar
|
|
112
121
|
hash[:nicknames] # ['jdoe']
|
113
122
|
|
114
123
|
|
115
|
-
|
124
|
+
#### Whitelist
|
116
125
|
|
117
126
|
Whitelist allows you to remove unneeded keys.
|
118
127
|
|
128
|
+
whitelist [keys]
|
129
|
+
|
130
|
+
Example:
|
131
|
+
|
119
132
|
class UserSchema < YAS::Schema
|
120
133
|
whitelist :name, :address
|
121
134
|
end
|
@@ -125,3 +138,20 @@ Whitelist allows you to remove unneeded keys.
|
|
125
138
|
hash[:address] # ['123 Main St']
|
126
139
|
hash[:phone] # nil
|
127
140
|
hash[:comment] # nil
|
141
|
+
|
142
|
+
|
143
|
+
#### Symbolize
|
144
|
+
|
145
|
+
Symbolize keys in your hash.
|
146
|
+
This does not perform deep symbolize. See nested Attribute validation if you want deep symbolize.
|
147
|
+
|
148
|
+
symbolize true|false
|
149
|
+
|
150
|
+
Example:
|
151
|
+
|
152
|
+
class UserSchema < YAS::Schema
|
153
|
+
symbolize true
|
154
|
+
end
|
155
|
+
hash = { 'name' => 'jdoe', 'address' => '123 Main St' }
|
156
|
+
hash.validate!(UserSchema)
|
157
|
+
hash[:name] # ['jdoe']
|
data/lib/yas/ext/attribute.rb
CHANGED
@@ -6,7 +6,6 @@ class YAS::AttributeExt
|
|
6
6
|
module ClassMethods
|
7
7
|
|
8
8
|
def key attr, &block
|
9
|
-
attr = attr.to_s.to_sym
|
10
9
|
new_attr = Attribute.new(attr)
|
11
10
|
new_attr.instance_eval &block if block
|
12
11
|
attributes[attr] = new_attr
|
@@ -50,11 +49,12 @@ class YAS::AttributeExt
|
|
50
49
|
@type = nil
|
51
50
|
@auto_convert = false
|
52
51
|
@default_block = nil
|
53
|
-
@
|
52
|
+
@alter_block = nil
|
53
|
+
@validate_value_block = nil
|
54
54
|
|
55
55
|
|
56
56
|
def initialize name
|
57
|
-
@name = name
|
57
|
+
@name = name
|
58
58
|
end
|
59
59
|
|
60
60
|
|
@@ -116,33 +116,44 @@ class YAS::AttributeExt
|
|
116
116
|
# validate_value { |v| v == "John" }
|
117
117
|
#
|
118
118
|
def validate_value &block
|
119
|
-
@
|
119
|
+
@validate_value_block = block
|
120
120
|
self
|
121
121
|
end
|
122
122
|
|
123
123
|
|
124
|
-
#
|
124
|
+
# Perform adjustment to the value of this Attribute.
|
125
125
|
#
|
126
|
-
# @
|
126
|
+
# @yield [v] Value of the Attribute.
|
127
127
|
#
|
128
|
-
|
129
|
-
|
128
|
+
# @example
|
129
|
+
# alter { |v| v == "John" }
|
130
|
+
#
|
131
|
+
def alter &block
|
132
|
+
@alter_block = block
|
133
|
+
self
|
130
134
|
end
|
131
135
|
|
132
136
|
|
133
|
-
#
|
137
|
+
# Validates attribute, except the required directive.
|
138
|
+
# First it executes the {default} directive, then {auto_convert} to type,
|
139
|
+
# then {type} validation, then finally the {validate} directive.
|
134
140
|
#
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
+
# @return The final value after the validation.
|
142
|
+
#
|
143
|
+
def validate value
|
144
|
+
value = trigger_default_directive if value.nil?
|
145
|
+
trigger_validate_value_directive(trigger_alter_directive(trigger_type_directive(value)))
|
146
|
+
end
|
147
|
+
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
|
152
|
+
def trigger_default_directive
|
153
|
+
@default_block.call if has_default?
|
141
154
|
end
|
142
155
|
|
143
156
|
|
144
|
-
# Check type.
|
145
|
-
#
|
146
157
|
def trigger_type_directive value
|
147
158
|
if @type
|
148
159
|
# Run auto-conversion first.
|
@@ -162,8 +173,6 @@ class YAS::AttributeExt
|
|
162
173
|
end
|
163
174
|
|
164
175
|
|
165
|
-
# Auto convert the value
|
166
|
-
#
|
167
176
|
def trigger_auto_convert_directive value
|
168
177
|
if @auto_convert
|
169
178
|
if @type == Integer
|
@@ -184,15 +193,18 @@ class YAS::AttributeExt
|
|
184
193
|
end
|
185
194
|
|
186
195
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
def
|
194
|
-
|
195
|
-
|
196
|
+
def trigger_alter_directive value
|
197
|
+
value = @alter_block.call(value) if @alter_block
|
198
|
+
value
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
def trigger_validate_value_directive value
|
203
|
+
if @validate_value_block
|
204
|
+
raise YAS::ValidationError, "Content validation error: #{value}" unless
|
205
|
+
@validate_value_block.call(value)
|
206
|
+
end
|
207
|
+
value
|
196
208
|
end
|
197
209
|
|
198
210
|
end
|
data/lib/yas/ext/rename.rb
CHANGED
@@ -10,8 +10,7 @@ class YAS::RenameExt
|
|
10
10
|
|
11
11
|
module ClassMethods
|
12
12
|
def rename map
|
13
|
-
|
14
|
-
rename_keys.merge!(smap)
|
13
|
+
rename_keys.merge!(map)
|
15
14
|
end
|
16
15
|
|
17
16
|
def rename_keys
|
@@ -26,17 +25,18 @@ class YAS::RenameExt
|
|
26
25
|
|
27
26
|
|
28
27
|
def self.when_schema_inherited superschema, subschema
|
29
|
-
superschema.rename_keys.each do |from,
|
30
|
-
subschema.rename_keys[key] =
|
28
|
+
superschema.rename_keys.each do |from, to|
|
29
|
+
subschema.rename_keys[key] = to
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
33
|
|
35
34
|
def self.apply schema, hash
|
36
35
|
schema.rename_keys.each do |from, to|
|
37
|
-
hash.has_key?(from)
|
38
|
-
hash[to] = hash[from]
|
36
|
+
if hash.has_key?(from)
|
37
|
+
hash[to] = hash[from]
|
39
38
|
hash.delete(from)
|
39
|
+
end
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Symbolize keys
|
2
|
+
#
|
3
|
+
|
4
|
+
class YAS::SymbolizeExt
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def symbolize sym = nil
|
8
|
+
@symbolize = sym if !sym.nil? && (sym.class == TrueClass || sym.class == FalseClass)
|
9
|
+
@symbolize
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
def self.when_used schema
|
15
|
+
schema.extend ClassMethods
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def self.when_schema_inherited superschema, subschema
|
20
|
+
subschema.symbolize(superschema.symbolize)
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
def self.apply schema, hash
|
25
|
+
hash.keys.each do |key|
|
26
|
+
hash[(key.to_sym rescue key) || key] = hash.delete(key)
|
27
|
+
end if schema.symbolize
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
data/lib/yas/schema.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class YAS::SchemaBase
|
2
2
|
|
3
3
|
def self.use ext
|
4
|
-
raise YAS::ExtensionError, "Duplicate Extension" if exts.
|
4
|
+
raise YAS::ExtensionError, "Duplicate Extension. Extension #{ext} is already used." if exts.include?(ext)
|
5
5
|
raise YAS::ExtensionError, "Wrong Extension Format" unless ext.respond_to?(:apply) && ext.respond_to?(:when_used)
|
6
6
|
exts << ext
|
7
7
|
ext.when_used(self)
|
@@ -38,6 +38,7 @@ end
|
|
38
38
|
|
39
39
|
class YAS::Schema < YAS::SchemaBase
|
40
40
|
|
41
|
+
use YAS::SymbolizeExt
|
41
42
|
use YAS::RenameExt
|
42
43
|
use YAS::WhitelistExt
|
43
44
|
use YAS::MigrateExt
|
data/lib/yas/version.rb
CHANGED
data/lib/yas.rb
CHANGED
data/test/ext/test_attribute.rb
CHANGED
@@ -87,7 +87,14 @@ class TestAttribute < Minitest::Test
|
|
87
87
|
end
|
88
88
|
|
89
89
|
|
90
|
-
def
|
90
|
+
def test_alter
|
91
|
+
attr = Attribute.new(:batman).alter { |v| v.uniq!; v.compact!; v }
|
92
|
+
value = attr.validate(["Jim", "John", "Jim", "Kim", "Sally"])
|
93
|
+
assert_equal ["Jim", "John", "Kim", "Sally"], value
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
def test_validate_value
|
91
98
|
attr = Attribute.new(:batman).validate_value { |v| v == "John" }
|
92
99
|
assert_raises YAS::ValidationError do
|
93
100
|
attr.validate("Jim")
|
@@ -138,6 +145,11 @@ class AttributeSchema < YAS::Schema
|
|
138
145
|
auto_convert
|
139
146
|
end
|
140
147
|
|
148
|
+
key 'geo' do
|
149
|
+
type Float
|
150
|
+
auto_convert
|
151
|
+
end
|
152
|
+
|
141
153
|
end
|
142
154
|
|
143
155
|
|
@@ -157,9 +169,11 @@ class TestAttributeExt < Minitest::Test
|
|
157
169
|
hash = {
|
158
170
|
name: "someone",
|
159
171
|
number: 10,
|
172
|
+
'geo' => '10.20',
|
160
173
|
}
|
161
174
|
hash.validate! AttributeSchema
|
162
175
|
assert_equal "someone", hash[:name]
|
176
|
+
assert_equal 10.20, hash['geo']
|
163
177
|
end
|
164
178
|
|
165
179
|
|
data/test/ext/test_rename.rb
CHANGED
@@ -2,21 +2,24 @@ require './test/helper.rb'
|
|
2
2
|
|
3
3
|
class RenameSchema < YAS::Schema
|
4
4
|
rename :addr => :address
|
5
|
+
rename 'home' => 'office'
|
5
6
|
end
|
6
7
|
|
7
8
|
|
9
|
+
|
8
10
|
class TestRenameExt < Minitest::Test
|
9
11
|
|
10
12
|
def test_rename_ext
|
11
13
|
hash = {
|
12
14
|
addr: "Some address",
|
15
|
+
'home' => 'home address',
|
13
16
|
untouched: "Nothing"
|
14
17
|
}
|
15
18
|
hash.validate! RenameSchema
|
16
19
|
assert_equal "Some address", hash[:address]
|
20
|
+
assert_equal "home address", hash['office']
|
17
21
|
assert_equal "Nothing", hash[:untouched]
|
18
22
|
assert_nil hash[:addr]
|
19
|
-
assert_equal 2, hash.length
|
20
23
|
end
|
21
24
|
|
22
25
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require './test/helper.rb'
|
2
|
+
|
3
|
+
|
4
|
+
class SymbolizedSchema < YAS::Schema
|
5
|
+
symbolize true
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
class TestSymbolizeExt < Minitest::Test
|
10
|
+
|
11
|
+
def test_symbolize
|
12
|
+
hash = {
|
13
|
+
'first_name': "john",
|
14
|
+
'last_name': "doe",
|
15
|
+
}
|
16
|
+
hash.validate! SymbolizedSchema
|
17
|
+
assert_equal "john", hash[:first_name]
|
18
|
+
assert_equal "doe", hash[:last_name]
|
19
|
+
assert_nil hash['first_name']
|
20
|
+
assert_nil hash['last_name']
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/test/test_schema.rb
CHANGED
@@ -57,6 +57,27 @@ end
|
|
57
57
|
|
58
58
|
class TestSchema < Minitest::Test
|
59
59
|
|
60
|
+
def test_duplicate_ext
|
61
|
+
assert_raises YAS::ExtensionError do
|
62
|
+
Class.new(YAS::Schema) do
|
63
|
+
use YAS::RenameExt
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def test_invalid_ext_format
|
70
|
+
bad_ext = Class.new do
|
71
|
+
end
|
72
|
+
|
73
|
+
assert_raises YAS::ExtensionError do
|
74
|
+
Class.new(YAS::Schema) do
|
75
|
+
use bad_ext
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
|
60
81
|
def test_validate_not_bang_does_not_overwrite_original
|
61
82
|
hash = {
|
62
83
|
names: "john",
|
@@ -66,6 +87,7 @@ class TestSchema < Minitest::Test
|
|
66
87
|
assert_equal "john", hash[:names]
|
67
88
|
end
|
68
89
|
|
90
|
+
|
69
91
|
def test_inherited_schema_should_inherit_extensions
|
70
92
|
hash = {
|
71
93
|
names: "john",
|
@@ -77,6 +99,7 @@ class TestSchema < Minitest::Test
|
|
77
99
|
assert_nil hash[:book]
|
78
100
|
end
|
79
101
|
|
102
|
+
|
80
103
|
def test_complex_schema
|
81
104
|
hash = {
|
82
105
|
name: "john",
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albert Tedja
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|
@@ -66,14 +66,15 @@ files:
|
|
66
66
|
- lib/yas/ext/attribute.rb
|
67
67
|
- lib/yas/ext/migrate.rb
|
68
68
|
- lib/yas/ext/rename.rb
|
69
|
+
- lib/yas/ext/symbolize.rb
|
69
70
|
- lib/yas/ext/whitelist.rb
|
70
71
|
- lib/yas/hash.rb
|
71
|
-
- lib/yas/helper.rb
|
72
72
|
- lib/yas/schema.rb
|
73
73
|
- lib/yas/version.rb
|
74
74
|
- test/ext/test_attribute.rb
|
75
75
|
- test/ext/test_migrate.rb
|
76
76
|
- test/ext/test_rename.rb
|
77
|
+
- test/ext/test_symbolize.rb
|
77
78
|
- test/ext/test_whitelist.rb
|
78
79
|
- test/helper.rb
|
79
80
|
- test/test_schema.rb
|