yas 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e35b3a0968c6150304165fe2217c029c2a3aba84
4
- data.tar.gz: 3af1252eebbdf6c190cb6ec37d1fd5dd43d03e8c
3
+ metadata.gz: 14bc3ae92e4d7b9e86b4231edfb5f44cb5d04e1f
4
+ data.tar.gz: 149294a84a65f4eb2bc726c8cdbf41fe6c16593c
5
5
  SHA512:
6
- metadata.gz: f85ed79e75ff056a7da1916d8c3bd1e977e2095eb8f59d630362f2db0ecfedde39f2a60076a7a6597002039a70624363729480ce14f9c2d1a5cddc62eea84789
7
- data.tar.gz: ff1c0ff63ca04b9fbc5b2076eb54d53f9bef8b1ce318e052d2af2fffb88ba638fc0ed50370d7a4c4d6d22b3e04c5d0ed5e414a7e2a20ff36dbc79cdc67983e6f
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 :foo => :bar
17
+ rename :bar => :foo
18
18
  end
19
19
 
20
20
  h = { bar: "value" }
21
21
  h.validate! MySchema
22
- puts h[:foo] # "value"
23
- puts h[:bar] # nil
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, but `YAS::Schema` already comes with a set of awesome default extensions that you can immediately use:
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
- Declares an attribute/key with various requirements.
33
+ ### Default Extensions
33
34
 
34
- * `rename`
35
35
 
36
- Rename keys.
36
+ #### Attribute
37
37
 
38
- * `migrate`
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
- Migrate the value of a key.
41
+ attribute name, &block
42
+ key name, &block
41
43
 
42
- * `whitelist`
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
- ### Rename Extension
90
+ #### Rename
90
91
 
91
- Using `rename` to rename keys. Useful to maintain hash integrity.
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
- ### Migrate Extension
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
- You can also migrate the values. This is useful if you have hash whose values are in the old format and you want to convert them to the new format.
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
- ### Whitelist Extension
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']
@@ -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
- @check_value_block = nil
52
+ @alter_block = nil
53
+ @validate_value_block = nil
54
54
 
55
55
 
56
56
  def initialize name
57
- @name = name.to_s.to_sym
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
- @check_value_block = block
119
+ @validate_value_block = block
120
120
  self
121
121
  end
122
122
 
123
123
 
124
- # Check the default value.
124
+ # Perform adjustment to the value of this Attribute.
125
125
  #
126
- # @param value The value of this attribute to validate.
126
+ # @yield [v] Value of the Attribute.
127
127
  #
128
- def trigger_default_directive
129
- @default_block.call if has_default?
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
- # Check value.
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
- def trigger_content_directive value
136
- if @check_value_block
137
- raise YAS::ValidationError, "Content validation error: #{value}" unless
138
- @check_value_block.call(value)
139
- end
140
- value
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
- # Validates attribute, except the required directive.
188
- # First it executes the {default} directive, then {auto_convert} to type,
189
- # then {type} validation, then finally the {validate} directive.
190
- #
191
- # @return The final value after the validation.
192
- #
193
- def validate value
194
- value = trigger_default_directive if value.nil?
195
- trigger_content_directive(trigger_type_directive(value))
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
@@ -10,8 +10,7 @@ class YAS::RenameExt
10
10
 
11
11
  module ClassMethods
12
12
  def rename map
13
- smap = YAS.symbolize(map)
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, value|
30
- subschema.rename_keys[key] = value
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) and
38
- hash[to] = hash[from] and
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.any? { |e| e == ext }
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
@@ -1,5 +1,5 @@
1
1
  module YAS
2
2
  GEM_NAME = "yas"
3
3
  NAME = "YAS"
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/yas.rb CHANGED
@@ -1,11 +1,10 @@
1
- require 'securerandom'
2
- require 'json'
3
1
  require 'time'
4
2
 
5
3
  require 'yas/version'
6
4
  require 'yas/errors'
7
5
  require 'yas/helper'
8
6
 
7
+ require 'yas/ext/symbolize'
9
8
  require 'yas/ext/rename'
10
9
  require 'yas/ext/attribute'
11
10
  require 'yas/ext/migrate'
@@ -87,7 +87,14 @@ class TestAttribute < Minitest::Test
87
87
  end
88
88
 
89
89
 
90
- def test_content
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
 
@@ -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.1.1
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-01 00:00:00.000000000 Z
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
data/lib/yas/helper.rb DELETED
@@ -1,10 +0,0 @@
1
- module YAS
2
-
3
- def self.symbolize hash
4
- hash.inject({}) do |memo,(k,v)|
5
- memo[k.to_sym] = v
6
- memo
7
- end
8
- end
9
-
10
- end