validate 1.0.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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in validations.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Kenneth Ballenegger
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Validations
2
+
3
+ Validations is a validations library that can validate *any* object that can be
4
+ converted to a hash using `to_hash`.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'validations'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install validations
19
+
20
+ ## Usage
21
+
22
+ This is what a validation looks like, with this library:
23
+
24
+ ```ruby
25
+ # Here, we have a custom DSL for expressing validations. We put the
26
+ # validations for the model in an extension which we require
27
+ # independently. Doing `include Validations` in the module adds
28
+ # the required method to make the DSL work, and adds a `validates`
29
+ # method which will perform the validations are return whether they
30
+ # pass, or whether there are any errors.
31
+
32
+ module Store
33
+
34
+ module ItemValidations
35
+
36
+ # Order matters, first include library. Also: validations are
37
+ # executed and checked in the order in which they are defined.
38
+ include Validations
39
+
40
+ # Validations are contained within a block, so as to not pollute
41
+ # the class namespace with a DSL's implementation.
42
+ validations do
43
+
44
+ # simple ActiveRecord style validation
45
+ validates_presence_of :name
46
+
47
+ # multiple keys can be included in one validation
48
+ validates_type_of :description, :long_description, is: String
49
+
50
+ # or the key could be validated with a block
51
+ validates :type, with: -> { ['currency', 'iap'].include?(self) }
52
+
53
+ # or we could build a validation for enums
54
+ validates_inclusion_of :reward_type, in: %w(currency consumable permanent)
55
+
56
+ # inline `when`, validation only performed when block returns true
57
+ validates_numericality_of :amount, when: -> { type == :currency }
58
+ validates_type_of :currency, is: String, when: -> { type == :currency }
59
+
60
+ # or alternatively `when` as a block
61
+ run_when -> { type == :currency } do
62
+ validates_numericality_of :amount
63
+ validates_type_of :currency, is: String
64
+ end
65
+
66
+ # also, validates subdocuments
67
+ validates_child_hash :iap, when: -> { type == :iap } do
68
+ # the validation is now scoped to the subdocument,
69
+ # ie. we're validating the sub-doc
70
+ validates_type_of :id, is: BSON::ObjectId
71
+ validates_type_of :iap_id, is: String
72
+ validates_type_of :tier, is: Numeric
73
+ end
74
+
75
+ # arrays can be validated, too:
76
+ validates_array :tags do
77
+ # use regular validate function with the key self to
78
+ # validate array elements
79
+ validates_type_of :self, is: String
80
+ end
81
+
82
+ # arrays of hashes can be validated by just adding regular
83
+ # validations inside the block
84
+ validates_array :logic do
85
+ validates_inclusion_of :type, in: [:one, :two]
86
+ validates_type_of :one, is: String, when: -> { type == :one }
87
+ end
88
+ end
89
+ end
90
+ ::Kongo::Model.add_extension(:store_items, ItemValidations)
91
+
92
+ end
93
+ ```
94
+
95
+ ## Contributing
96
+
97
+ 1. Fork it
98
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
99
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
100
+ 4. Push to the branch (`git push origin my-new-feature`)
101
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,65 @@
1
+
2
+ module Validate
3
+
4
+ # The rules for parsing validations are such:
5
+ #
6
+ # - Validations are method calls (starting with the string `validates_`)
7
+ # - followed by field names as regular arguments (as symbols)
8
+ # - any options are included in an options hash, eg. is: String
9
+ # - and native blocks are reserved for children-validations
10
+ #
11
+ # For example:
12
+ #
13
+ # validates_subhash :iap1, :iap2, when: -> { type == :iap } do
14
+ # validates_type_of :id, is: String
15
+ # validates_type_of :tier, is: Numeric
16
+ # end
17
+ #
18
+ class BlockParsingContext
19
+
20
+ def self.parse(&block)
21
+ # execute block, return array of validation methods called
22
+ context = BlockParsingContext.new
23
+ context.instance_exec(&block)
24
+ context.validations
25
+ end
26
+
27
+ def initialize
28
+ @validations = []
29
+ end
30
+
31
+ attr_reader :validations
32
+
33
+ def method_missing(method, *args, &block)
34
+ raise NoMethodError.new("No method #{method} to call in the context of a validation block.") unless method.to_s =~ /^validates/
35
+ raise NoMethodError.new("Undefined validation method: #{method}...") unless ValidationMethods.respond_to?(method)
36
+ opts = args.pop if args.last.is_a?(::Hash)
37
+ children = if block
38
+ BlockParsingContext.parse(&block)
39
+ end
40
+ @validations << {
41
+ name: method,
42
+ fields: args,
43
+ opts: opts,
44
+ validations: children
45
+ }
46
+ end
47
+
48
+ # `when` is a special case, its syntax is as follows:
49
+ #
50
+ # when -> { ... } do
51
+ # # validations go here
52
+ # end
53
+ #
54
+ def run_when(condition, &block)
55
+ validations = BlockParsingContext.parse(&block)
56
+ validations.map do |v|
57
+ v[:opts] ||= {}
58
+ v[:opts][:when] = condition
59
+ v
60
+ end
61
+ @validations += validations
62
+ end
63
+ end
64
+ end
65
+
@@ -0,0 +1,107 @@
1
+
2
+ module Validate
3
+
4
+ # Every validation method has four arguments:
5
+ #
6
+ # obj: the `to_hash` of the object to validate
7
+ # field: the field to validate
8
+ # opts: the options for the validation
9
+ # validator: a Validator object that can be used for children
10
+ #
11
+ module ValidationMethods
12
+
13
+ # Validate a field by executing a block in the context of the field.
14
+ #
15
+ # `self` in the block is bound to the field's value, or `nil`.
16
+ #
17
+ # validates :type, with: -> { is_a?(String) && self =~ /^a/ }
18
+ #
19
+ def self.validates(obj, field, opts, validator)
20
+ true == obj[field].instance_exec(&opts[:with])
21
+ end
22
+
23
+ # Validates that a field exists.
24
+ #
25
+ # `nil` is acceptable as a value for the field.
26
+ #
27
+ # validates_presence_of :field
28
+ #
29
+ def self.validates_presence_of(obj, field, opts, validator)
30
+ obj.include?(field)
31
+ end
32
+
33
+ # Validates that a field exists and is an instance of a class or module.
34
+ #
35
+ # validates_type_of :name, is: String
36
+ #
37
+ def self.validates_type_of(obj, field, opts, validator)
38
+ obj.include?(field) && obj[field].is_a?(opts[:is])
39
+ end
40
+
41
+ # Validates that the value of the field appears in an array.
42
+ #
43
+ # validates_inclusion_of :type, in: %w(paid free)
44
+ #
45
+ def self.validates_inclusion_of(obj, field, opts, validator)
46
+ opts[:in].include?(obj[field])
47
+ end
48
+
49
+ # Validates that a field's value is numeric.
50
+ #
51
+ # validates_numericality_of :amount
52
+ #
53
+ def self.validates_numericality_of(obj, field, opts, validator)
54
+ obj[field].is_a?(Numeric)
55
+ end
56
+
57
+ # Validates the value, ensure equality.
58
+ #
59
+ # validates_value_of :field, is: 'something'
60
+ #
61
+ def self.validates_value_of(obj, field, opts, validator)
62
+ obj.include?(field) && obj[field] == opts[:is]
63
+ end
64
+
65
+ # Validates a Hash field with its own set of validations.
66
+ #
67
+ # validates_child_hash :hash do
68
+ # validates_value_of :type, is: 'price'
69
+ # validates_numericality_of :amount
70
+ # end
71
+ #
72
+ def self.validates_child_hash(obj, field, opts, validator)
73
+ return false unless obj[field].respond_to?(:to_hash)
74
+ hash = obj[field].to_hash
75
+ validator.validates?(hash)
76
+ end
77
+
78
+ # Validates each element in an Array with a set of validations.
79
+ #
80
+ # *Note:* the children validations should look at the field `:self` to
81
+ # contain the value to be validated. ie. it validates {self: element}
82
+ #
83
+ # # ensures :elements is an array of strings
84
+ # validates_array :elements do
85
+ # validates_type_of :self, is: String
86
+ # end
87
+ #
88
+ def self.validates_array(obj, field, opts, validator)
89
+ return false unless obj[field].respond_to?(:to_a)
90
+ array = obj[field].to_a
91
+ array.map do |e|
92
+ validator.validates?({self: e})
93
+ end.reduce {|a,b| a && b }
94
+ end
95
+
96
+ # Validates a field against a regular expression.
97
+ #
98
+ # validates_regex :field, matches: /^hello/
99
+ #
100
+ def self.validates_regex(obj, field, opts, validator)
101
+ return false unless obj[field].respond_to?(:=~)
102
+ 0 == (obj[field] =~ opts[:matches])
103
+ end
104
+
105
+ end
106
+
107
+ end
@@ -0,0 +1,36 @@
1
+
2
+ module Validate
3
+
4
+ # Actual implementation
5
+ #
6
+ class Validator
7
+
8
+ def initialize(validations)
9
+ @validations = validations
10
+ end
11
+
12
+ def validates?(context)
13
+ bool = @validations
14
+ .select do |v|
15
+ # `:when` is a special case, this gets processed right away and
16
+ # filtered out...
17
+ !(v[:opts] || {})[:when].is_a?(Proc) || context.instance_exec(&v[:opts][:when])
18
+ end
19
+ .map do |v|
20
+ # destructure fields
21
+ v[:fields].map {|f| v.merge(fields: f) }
22
+ end.flatten(1)
23
+ .map do |v|
24
+ # lastly, execute validation
25
+ validator = if v[:validations]
26
+ Validator.new(v[:validations])
27
+ end
28
+ ValidationMethods.send(v[:name], context.to_hash, v[:fields], v[:opts], validator)
29
+ end
30
+ .reduce {|a,b| a && b }
31
+ # return the result as a boolean
32
+ bool.nil? ? true : bool
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,4 @@
1
+
2
+ module Validate
3
+ VERSION = '1.0.0'
4
+ end
data/lib/validate.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'validate/version'
2
+ require 'validate/validations'
3
+ require 'validate/parser'
4
+ require 'validate/validator'
5
+
6
+
7
+ module Validate
8
+
9
+ module ClassMethods
10
+ # Doubles as setter & getter for @validations
11
+ # This method is also the main interface to this lib.
12
+ #
13
+ def validations(&block)
14
+ return @validator unless block
15
+ validations = BlockParsingContext.parse(&block)
16
+ @validator = Validator.new(validations)
17
+ end
18
+ end
19
+
20
+ def self.included(klass)
21
+ klass.extend(ClassMethods)
22
+ end
23
+
24
+ # May throw a nil NoMethodError if validations are not defined properly.
25
+ #
26
+ def validates?
27
+ self.class.validations.validates?(self)
28
+ end
29
+
30
+ end
@@ -0,0 +1,445 @@
1
+
2
+ require 'rspec'
3
+
4
+ $: << File.dirname(__FILE__) + '/../lib'
5
+ require 'validate'
6
+
7
+
8
+
9
+ class BaseTestClass
10
+ def initialize(hash)
11
+ @hash = hash
12
+ end
13
+ def to_hash
14
+ @hash
15
+ end
16
+ include Validate
17
+ end
18
+
19
+ describe Validate do
20
+
21
+ context 'simple test' do
22
+
23
+ before do
24
+ class TestClass < BaseTestClass
25
+ validations do
26
+ validates_presence_of 'name', when: -> { true }
27
+ end
28
+ end
29
+ end
30
+
31
+ it 'should validate a valid object' do
32
+ test = TestClass.new({"name" => :hello})
33
+ test.validates?.should == true
34
+ end
35
+
36
+ it 'should fail to validate an invalid object' do
37
+ test = TestClass.new({"not_name" => :hello})
38
+ test.validates?.should == false
39
+ end
40
+
41
+ end
42
+
43
+ context 'multiple fields' do
44
+
45
+ before do
46
+ class TestClass < BaseTestClass
47
+ validations do
48
+ validates_presence_of :field1, :field2
49
+ end
50
+ end
51
+ end
52
+
53
+ it 'validate' do
54
+ test = TestClass.new(field1: true, field2: true)
55
+ test.validates?.should == true
56
+ end
57
+
58
+ it 'fail' do
59
+ test = TestClass.new(field1: true)
60
+ test.validates?.should == false
61
+ end
62
+ end
63
+
64
+ context 'when option' do
65
+ before do
66
+ class TestClass < BaseTestClass
67
+ validations do
68
+ validates_presence_of :name, when: -> { @hash[:something] == true }
69
+ end
70
+ end
71
+ end
72
+
73
+ it 'validates when when does not match' do
74
+ test = TestClass.new(something: false)
75
+ test.validates?.should == true
76
+ end
77
+
78
+ it 'validates when when does match' do
79
+ test = TestClass.new(something: true, name: 'me')
80
+ test.validates?.should == true
81
+ end
82
+
83
+ it 'fails' do
84
+ test = TestClass.new(something: true)
85
+ test.validates?.should == false
86
+ end
87
+ end
88
+
89
+ context 'run_when block' do
90
+ before do
91
+ class TestClass < BaseTestClass
92
+ validations do
93
+ run_when -> { @hash[:something] == true } do
94
+ validates_presence_of :name
95
+ validates_numericality_of :amount
96
+ end
97
+ end
98
+ end
99
+ end
100
+
101
+ it 'validates when when does not match' do
102
+ test = TestClass.new(something: false)
103
+ test.validates?.should == true
104
+ end
105
+
106
+ it 'validates when when does match' do
107
+ test = TestClass.new(something: true, name: 'me', amount: 1.3)
108
+ test.validates?.should == true
109
+ end
110
+
111
+ it 'fails when one validations fail' do
112
+ test = TestClass.new(something: true, name: 'me')
113
+ test.validates?.should == false
114
+ end
115
+
116
+ it 'fails when all validations fail' do
117
+ test = TestClass.new(something: true)
118
+ test.validates?.should == false
119
+ end
120
+ end
121
+
122
+ context 'validates_presence_of' do
123
+
124
+ before do
125
+ class TestClass < BaseTestClass
126
+ validations do
127
+ validates_presence_of :field
128
+ end
129
+ end
130
+ end
131
+
132
+ it 'validates' do
133
+ test = TestClass.new(field: :something)
134
+ test.validates?.should == true
135
+ end
136
+
137
+ it 'fails' do
138
+ test = TestClass.new(random: :field_name)
139
+ test.validates?.should == false
140
+ end
141
+ end
142
+
143
+ context 'validates_type_of' do
144
+
145
+ before do
146
+ class TestClass < BaseTestClass
147
+ validations do
148
+ validates_type_of :field, is: Symbol
149
+ end
150
+ end
151
+ end
152
+
153
+ it 'validates' do
154
+ test = TestClass.new(field: :symbol)
155
+ test.validates?.should == true
156
+ end
157
+
158
+ it 'fails' do
159
+ test = TestClass.new(field: 'symbol')
160
+ test.validates?.should == false
161
+ end
162
+ end
163
+
164
+ context 'validates' do
165
+
166
+ before do
167
+ class TestClass < BaseTestClass
168
+ validations do
169
+ validates :field, with: -> { self[:test] == :val }
170
+ end
171
+ end
172
+ end
173
+
174
+ it 'validates' do
175
+ test = TestClass.new(field: {test: :val})
176
+ test.validates?.should == true
177
+ end
178
+
179
+ it 'fails' do
180
+ test = TestClass.new(field: {test: nil})
181
+ test.validates?.should == false
182
+ end
183
+ end
184
+
185
+ context 'validates_inclusion_of' do
186
+
187
+ before do
188
+ class TestClass < BaseTestClass
189
+ validations do
190
+ validates_inclusion_of :field, in: %w(one two three)
191
+ end
192
+ end
193
+ end
194
+
195
+ it 'validates' do
196
+ test = TestClass.new(field: 'two')
197
+ test.validates?.should == true
198
+ end
199
+
200
+ it 'fails' do
201
+ test = TestClass.new(field: {test: nil})
202
+ test.validates?.should == false
203
+ end
204
+ end
205
+
206
+ context 'validates_numericality_of' do
207
+
208
+ before do
209
+ class TestClass < BaseTestClass
210
+ validations do
211
+ validates_numericality_of :field
212
+ end
213
+ end
214
+ end
215
+
216
+ it 'validates' do
217
+ test = TestClass.new(field: 1.3)
218
+ test.validates?.should == true
219
+ end
220
+
221
+ it 'fails' do
222
+ test = TestClass.new(field: {test: nil})
223
+ test.validates?.should == false
224
+ end
225
+ end
226
+
227
+ context 'validates_value_of' do
228
+
229
+ before do
230
+ class TestClass < BaseTestClass
231
+ validations do
232
+ validates_value_of :field, is: :something
233
+ end
234
+ end
235
+ end
236
+
237
+ it 'validates' do
238
+ test = TestClass.new(field: :something)
239
+ test.validates?.should == true
240
+ end
241
+
242
+ it 'fails' do
243
+ test = TestClass.new(field: :something_else)
244
+ test.validates?.should == false
245
+ end
246
+ end
247
+
248
+ context 'validates_regex' do
249
+
250
+ before do
251
+ class TestClass < BaseTestClass
252
+ validations do
253
+ validates_regex :field, matches: /^hello/
254
+ end
255
+ end
256
+ end
257
+
258
+ it 'validates' do
259
+ test = TestClass.new(field: 'hello world')
260
+ test.validates?.should == true
261
+ end
262
+
263
+ it 'fails' do
264
+ test = TestClass.new(field: 'bye world')
265
+ test.validates?.should == false
266
+ end
267
+ end
268
+
269
+ context 'validates_child_hash' do
270
+
271
+ before do
272
+ class TestClass < BaseTestClass
273
+ validations do
274
+ validates_child_hash :field do
275
+ validates_value_of :type, is: 'price'
276
+ validates_numericality_of :amount
277
+ end
278
+ end
279
+ end
280
+ end
281
+
282
+ it 'validates' do
283
+ test = TestClass.new(field: {type: 'price', amount: 1.3})
284
+ test.validates?.should == true
285
+ end
286
+
287
+ it 'fails when not a hash' do
288
+ test = TestClass.new(field: nil)
289
+ test.validates?.should == false
290
+ end
291
+
292
+ it 'fails when all validations fail' do
293
+ test = TestClass.new(field: {random: :stuff})
294
+ test.validates?.should == false
295
+ end
296
+
297
+ it 'fails when only one validation fails' do
298
+ test = TestClass.new(field: {type: :random, amount: 20})
299
+ test.validates?.should == false
300
+ end
301
+ end
302
+
303
+
304
+ context 'validates_array' do
305
+
306
+ before do
307
+ class TestClass < BaseTestClass
308
+ validations do
309
+ validates_array :field do
310
+ validates_type_of :self, is: String
311
+ end
312
+ end
313
+ end
314
+ end
315
+
316
+ it 'validates' do
317
+ test = TestClass.new(field: %w(one two three))
318
+ test.validates?.should == true
319
+ end
320
+
321
+ it 'fails when not a hash' do
322
+ test = TestClass.new(field: 'not an array')
323
+ test.validates?.should == false
324
+ end
325
+
326
+ it 'fails when all validations fail' do
327
+ test = TestClass.new(field: [1, 2, 3])
328
+ test.validates?.should == false
329
+ end
330
+
331
+ it 'fails when only one validation fails' do
332
+ test = TestClass.new(field: ['one', 'two', 3])
333
+ test.validates?.should == false
334
+ end
335
+ end
336
+
337
+
338
+ context 'complex example' do
339
+
340
+ before do
341
+
342
+ class TestClass < BaseTestClass
343
+
344
+ validations do
345
+ validates_type_of :id, is: Integer
346
+ validates_type_of :name, :description, is: String
347
+
348
+ validates_presence_of :secret
349
+
350
+ validates_inclusion_of :type, in: %w(paid free)
351
+
352
+ # validate a block in the data structure that must evaluate to true
353
+ validates :block, with: -> { self.call == true }
354
+
355
+ # number_or_symbols is an array that contains either numerics or
356
+ # symbols... only when it is set
357
+ validates_array :number_or_symbols, when: -> { @hash.include?(:number_or_symbols) } do
358
+
359
+ validates :self, with: -> { self.is_a?(String) || self.is_a?(Numeric) }
360
+
361
+ # when it is numeric, it must be greater than 0
362
+ validates :self,
363
+ when: -> { self[:self].is_a?(Numeric) },
364
+ with: -> { self > 0 }
365
+
366
+ # when it is a symbol, it start with `a` and is > 2 chars
367
+ run_when -> { self[:self].is_a?(String) } do
368
+ validates_regex :self, matches: /^a/
369
+ validates_regex :self, matches: /..+/
370
+ end
371
+ end
372
+
373
+ validates_child_hash :iap do
374
+ validates_type_of :id, is: Numeric
375
+ validates_type_of :bundle, is: String
376
+ validates_regex :bundle, matches: /(\w+\.){2}\w+/
377
+ end
378
+ validates :iap, with: -> { self.keys.count == 2 }
379
+ end
380
+ end
381
+
382
+ @valid_hash = {
383
+ id: 1,
384
+ name: 'item',
385
+ description: 'string',
386
+ secret: :anything,
387
+ type: 'paid',
388
+ block: -> { true },
389
+ number_or_symbols: [
390
+ 1, 2, 3,
391
+ 'awesome', 'awful'
392
+ ],
393
+ iap: {
394
+ id: 1,
395
+ bundle: 'com.chartboost.awesome'
396
+ }
397
+ }
398
+ end
399
+
400
+ it 'validates' do
401
+ test = TestClass.new(@valid_hash)
402
+ test.validates?.should == true
403
+ end
404
+
405
+ it 'fails when block is changed' do
406
+ hash = @valid_hash.dup
407
+ hash[:block] = -> { false }
408
+ test = TestClass.new(hash)
409
+ test.validates?.should == false
410
+ end
411
+
412
+ it 'fails when number_or_symbols contains invalid numbers' do
413
+ hash = @valid_hash.dup
414
+ hash[:number_or_symbols] = [0, -1, 'awesome']
415
+ test = TestClass.new(hash)
416
+ test.validates?.should == false
417
+ end
418
+
419
+ it 'fails when number_or_symbols contains invalid symbols' do
420
+ hash = @valid_hash.dup
421
+ hash[:number_or_symbols] = ['sick', 'awesome', 3, 'awful']
422
+ test = TestClass.new(hash)
423
+ test.validates?.should == false
424
+ end
425
+
426
+ it 'fails when secret does not exist' do
427
+ hash = @valid_hash.dup
428
+ hash.delete(:secret)
429
+ test = TestClass.new(hash)
430
+ test.validates?.should == false
431
+ end
432
+
433
+ it 'fails when number_or_symbols contains invalid numbers' do
434
+ hash = @valid_hash.dup
435
+ hash[:iap] = {
436
+ id: 1,
437
+ bundle: 'hello'
438
+ }
439
+ test = TestClass.new(hash)
440
+ test.validates?.should == false
441
+ end
442
+ end
443
+ end
444
+
445
+
data/validate.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'validate/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'validate'
8
+ gem.version = Validate::VERSION
9
+ gem.authors = ['Kenneth Ballenegger']
10
+ gem.email = ['kenneth@ballenegger.com']
11
+ gem.description = %q{Validations is a library for validating data structures.}
12
+ gem.summary = %q{Validations is a library for validating data structures.}
13
+ gem.homepage = ''
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ # dependencies
21
+
22
+ gem.add_development_dependency 'rspec'
23
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: validate
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kenneth Ballenegger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Validations is a library for validating data structures.
31
+ email:
32
+ - kenneth@ballenegger.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - LICENSE.txt
40
+ - README.md
41
+ - Rakefile
42
+ - lib/validate.rb
43
+ - lib/validate/parser.rb
44
+ - lib/validate/validations.rb
45
+ - lib/validate/validator.rb
46
+ - lib/validate/version.rb
47
+ - spec/validate_spec.rb
48
+ - validate.gemspec
49
+ homepage: ''
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.24
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Validations is a library for validating data structures.
73
+ test_files:
74
+ - spec/validate_spec.rb
75
+ has_rdoc: