validate 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: