validate 1.2.1 → 1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -26,13 +26,24 @@ module Validate
26
26
  end
27
27
 
28
28
 
29
+ # CompiledValidations is a struct that represents a set of compiled
30
+ # validations + options, eg. whether to allow extra keys.
31
+ #
32
+ class CompiledValidations < Struct.new(:validations, :allow_keys); end
33
+
34
+
29
35
  class BlockParsingContext
30
36
 
31
37
  def initialize
38
+ @allow_keys = :any
32
39
  @validations = []
33
40
  end
34
41
 
35
- attr_reader :validations
42
+ # Returns a CompiledValidations struct.
43
+ #
44
+ def validations
45
+ CompiledValidations.new(@validations, @allow_keys)
46
+ end
36
47
 
37
48
  def method_missing(method, *args, &block)
38
49
  raise NoMethodError.new("No method #{method} to call in the context of a validation block.") unless method.to_s =~ /^validates/
@@ -51,12 +62,12 @@ module Validate
51
62
 
52
63
  # `when` is a special case, its syntax is as follows:
53
64
  #
54
- # when -> { ... } do
65
+ # run_when -> { ... } do
55
66
  # # validations go here
56
67
  # end
57
68
  #
58
69
  def run_when(condition, &block)
59
- validations = Parser.parse(&block)
70
+ validations = Parser.parse(&block).validations
60
71
  validations.map do |v|
61
72
  v[:opts] ||= {}
62
73
  v[:opts][:when] = condition
@@ -64,6 +75,19 @@ module Validate
64
75
  end
65
76
  @validations += validations
66
77
  end
78
+
79
+ # `allow_keys` is another special case, which can be used like this:
80
+ #
81
+ # allow_keys :any
82
+ # allow_keys :valid
83
+ # allow_keys %w(one two three)
84
+ #
85
+ # Defaults to :any, if not specified.
86
+ #
87
+ def allow_keys(keys)
88
+ @allow_keys = keys
89
+ end
90
+
67
91
  end
68
92
  end
69
93
 
@@ -19,7 +19,8 @@ module Validate
19
19
  #
20
20
  fails_because_key 'failed to match a custom validation.'
21
21
  def validates(obj, field, opts, validator)
22
- true == obj[field].instance_exec(&opts[:with])
22
+ args = [obj, field].first(opts[:with].arity)
23
+ true == obj[field].instance_exec(*args, &opts[:with])
23
24
  end
24
25
 
25
26
  # Validates that a field exists.
@@ -64,7 +65,7 @@ module Validate
64
65
  #
65
66
  # validates_value_of :field, is: 'something'
66
67
  #
67
- fails_because_key { "was not of in #{opts[:is].inspect}." }
68
+ fails_because_key { "was not #{opts[:is].inspect}." }
68
69
  def validates_value_of(obj, field, opts, validator)
69
70
  obj.include?(field) && obj[field] == opts[:is]
70
71
  end
@@ -5,11 +5,16 @@ module Validate
5
5
  #
6
6
  class Validator
7
7
 
8
- def initialize(validations)
9
- @validations = validations
8
+ def initialize(compiled_validations)
9
+ @validations = compiled_validations.validations
10
+ @allow_keys = compiled_validations.allow_keys
10
11
  end
11
12
 
13
+ # TODO: this method could use some cleaning up...
14
+ #
12
15
  def validates?(context)
16
+ context_hash = context.to_hash
17
+
13
18
  @failures = @validations
14
19
  .map do |v|
15
20
  # destructure fields
@@ -32,14 +37,24 @@ module Validate
32
37
  validator = if v[:validations]
33
38
  Validator.new(v[:validations])
34
39
  end
35
- success = ValidationMethods.new.send(v[:name], context.to_hash, v[:fields], v[:opts], validator)
40
+ success = ValidationMethods.new.send(v[:name], context_hash, v[:fields], v[:opts], validator)
36
41
  unless success
37
42
  reason = v[:reason].is_a?(Proc) ?
38
- ValidationMethods::ArgumentFailureBlockScope.new(context.to_hash, v[:fields], v[:opts], validator).instance_exec(&v[:reason]) :
43
+ ValidationMethods::ArgumentFailureBlockScope.new(context_hash, v[:fields], v[:opts], validator).instance_exec(&v[:reason]) :
39
44
  v[:reason]
40
45
  {v[:fields] => reason}
41
46
  end
42
47
  end.select {|v| !v.nil? } # discard successes
48
+
49
+ if @allow_keys != :any
50
+ allow_keys = if @allow_keys == :valid
51
+ @validations.map {|v| v[:fields]}.flatten
52
+ else
53
+ @allow_keys
54
+ end
55
+ @failures.push(*(context_hash.keys - allow_keys).map {|k| {k => 'is not a valid key.'} })
56
+ end
57
+
43
58
  @failures.count == 0
44
59
  end
45
60
 
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Validate
3
- VERSION = '1.2.1'
3
+ VERSION = '1.3'
4
4
  end
@@ -248,11 +248,21 @@ describe Validate do
248
248
  test = TestClass.new(field: {test: :val})
249
249
  test.validates?.should == true
250
250
  end
251
-
251
+
252
252
  it 'fails' do
253
253
  test = TestClass.new(field: {test: nil})
254
254
  test.validates?.should == false
255
255
  end
256
+
257
+ it 'passes arguments' do
258
+ class TestClass < BaseTestClass
259
+ validations do
260
+ validates :field, with: ->(o,k) { o[k] == :val }
261
+ end
262
+ end
263
+ test = TestClass.new(field: :val)
264
+ test.validates?.should == true
265
+ end
256
266
  end
257
267
 
258
268
  context 'validates_inclusion_of' do
@@ -544,6 +554,57 @@ describe Validate do
544
554
  hash.failures.should == []
545
555
  end
546
556
  end
547
- end
548
557
 
549
558
 
559
+ context 'when allow_keys' do
560
+
561
+ context 'is `:valid`' do
562
+
563
+ before do
564
+ class TestClass < BaseTestClass
565
+ validations do
566
+ allow_keys :valid
567
+ validates_type_of 'one', 'two', when: :is_set, is: Symbol
568
+ end
569
+ end
570
+ end
571
+
572
+ it 'should validate an object' do
573
+ test = TestClass.new({'one' => :hello})
574
+ test.validates?.should == true
575
+ end
576
+
577
+ it 'should not validate an invalid object' do
578
+ test = TestClass.new({'one' => :hello, 'three' => :hello})
579
+ test.validates?.should == false
580
+ test.failures.should == [{'three' => 'is not a valid key.'}]
581
+ end
582
+
583
+ end
584
+
585
+ context 'is an array' do
586
+
587
+ before do
588
+ class TestClass < BaseTestClass
589
+ validations do
590
+ allow_keys %w(one two)
591
+ end
592
+ end
593
+ end
594
+
595
+ it 'should validate an object' do
596
+ test = TestClass.new({'two' => :hello})
597
+ test.validates?.should == true
598
+ end
599
+
600
+ it 'should not validate an invalid object' do
601
+ test = TestClass.new({'one' => :hello, 'three' => :hello})
602
+ test.validates?.should == false
603
+ test.failures.should == [{'three' => 'is not a valid key.'}]
604
+ end
605
+
606
+ end
607
+ end
608
+
609
+ end
610
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validate
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: '1.3'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-02 00:00:00.000000000 Z
12
+ date: 2013-05-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec