nested_validator 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MDVlMmQxNWU4MjFkZjYxMmZkY2I2OGVlNzM0YzE4NzcwMGMwMjExYw==
4
+ YWYzM2NmNDIzYTkxOTM5NDc1ZGMyNGFlODA4Y2M2NGI2NGQxNTRiMw==
5
5
  data.tar.gz: !binary |-
6
- MTk5MmQ5MmRmMWE4NGZjMzQxOGU2ZWUwNWRiMWMyMDI3NTAwNWZmMA==
6
+ ODRmZTNjYTcyY2VhODI5ODY3YjlmOTMwMzk5M2VmODY2MmNhNDk5Yw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YjNiNDNhNjc0YTBkYzQzN2ViMzViNDY4M2YzODZmYWMyYzQ2ZTY2NWI2M2Yy
10
- YTQ3NWE3OGRmNjA4YmIzNGNlMTY5NDgyMzJiYWQyNDQwYzE1MTIyMmY3MmM5
11
- NzA3M2E0YjczMDk5N2Y2NzA1Mjg1OGU0MDE2M2NhODVjMDkxM2U=
9
+ MTRhMjg2NTgyMGQ2MDEyMjY4NzM3NjQ0NjdkYzIxOTlmOTk5M2JmNGRiNjhk
10
+ NTgwYmU1NDg5M2M1YzczNGE3MTcwODZjZjYzOWU0MzA5ZDkyNDEyYzkzNmFh
11
+ ZjlkZTZjMjAyMWUxMWQ1ZThkM2IzM2ExMWVlYTBiOTRhNDM4MmM=
12
12
  data.tar.gz: !binary |-
13
- OGJjZDAyOTMzYWNjNzgwZmY2YzYzMWNkYTA3OTIxNWVhNDM0MDVhNjk0OGVk
14
- MDU0YWJmY2FkMGI5MTdlZTcyM2ExMjBlNWQ1NjllYTI3MmQyN2IxZjc0OWM5
15
- OTE2MGI3ZWU0MjkyNzAyZTQ0Y2M0ZWYyMzQzOWMyYWE0MjJlZWI=
13
+ NGM2YzJhN2I5MmM2NmNmMjkwZmU1NDg3NzBhOWYyZWZlMWY3NzE2MjAzOTg0
14
+ Y2QxYTlkMGM2YzRmMTUxNzZlNWM3YzNhZjBlZmFmNTUzY2QzODVjMGM2YzYz
15
+ YzY0NjE1MWY5ZmI1ZWNmYjFiNjI5ODhkZTgxZTM0ODU5M2EzM2E=
data/.gitignore CHANGED
@@ -0,0 +1,4 @@
1
+ .yardoc
2
+ coverage
3
+ doc
4
+ pkg
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nested_validator (1.0.0)
4
+ nested_validator (1.0.1)
5
5
  activemodel
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- [![Gem Version](https://badge.fury.io/rb/percentable.png)](http://badge.fury.io/rb/percentable)
2
- [![Build Status](https://travis-ci.org/ericroberts/percentable.png?branch=master)](https://travis-ci.org/ericroberts/percentable)
3
- [![Code Climate](https://codeclimate.com/github/ericroberts/percentable.png)](https://codeclimate.com/github/ericroberts/percentable)
4
- [![Coverage Status](https://coveralls.io/repos/ericroberts/percentable/badge.png?branch=master)](https://coveralls.io/r/ericroberts/percentable?branch=master)
1
+ [![Gem Version](https://badge.fury.io/rb/nested_validator.png)](https://badge.fury.io/rb/nested_validator.png)
2
+ [![Build Status](https://travis-ci.org/dwhelan/nested_validator.png?branch=master)](https://travis-ci.org/dwhelan/nested_validator)
3
+ [![Code Climate](https://codeclimate.com/github/dwhelan/nested_validator.png)](https://codeclimate.com/github/dwhelan/nested_validator)
4
+ [![Coverage Status](https://coveralls.io/repos/dwhelan/nested_validator/badge.png)](https://coveralls.io/r/dwhelan/nested_validator)
5
5
 
6
6
  # Nested Validator
7
7
 
@@ -3,6 +3,7 @@ require 'active_support/core_ext/array'
3
3
 
4
4
  module ActiveModel
5
5
  module Validations
6
+
6
7
  class NestedValidator < EachValidator
7
8
 
8
9
  private
@@ -63,8 +64,54 @@ module ActiveModel
63
64
  end
64
65
 
65
66
  module HelperMethods
66
- def validates_nested(*attributes)
67
- validates_with NestedValidator, _merge_attributes(attributes)
67
+ # Bases an object's validity on nested attr_names.
68
+ #
69
+ # class Parent < ActiveRecord::Base
70
+ # has_one :child
71
+ #
72
+ # validates_nested :child
73
+ # end
74
+ #
75
+ # class Child < ActiveRecord::Base
76
+ # has_one :child
77
+ #
78
+ # validates_presence_of :attribute
79
+ # end
80
+ #
81
+ # Any errors in the child will be copied to the parent using the child's name as
82
+ # a prefix for the error:
83
+ #
84
+ # puts parent.errors.messages #=> { :'child attribute' => ["can't be blank"] }
85
+ #
86
+ # @param attr_names attribute names followed with options
87
+ #
88
+ # @option attr_names [String] :prefix The prefix to use instead of the attribute name
89
+ #
90
+ # @option attr_names [String, Array] :only The name(s) of attr_names to include
91
+ # when validating. Default is <tt>all</tt>
92
+ #
93
+ # @option attr_names [String, Array] :except The name(s) of attr_names to exclude
94
+ # when validating. Default is <tt>none</tt>
95
+ #
96
+ # @option attr_names [Symbol] :on Specifies when this validation is active. Runs in all
97
+ # validation contexts by default (+nil+), other options are <tt>:create</tt>
98
+ # and <tt>:update</tt>.
99
+ #
100
+ # @option attr_names [Symbol, String or Proc] :if a method, proc or string to call to determine
101
+ # if the validation should occur (e.g. <tt>if: :allow_validation</tt>,
102
+ # or <tt>if: Proc.new { |user| user.signup_step > 2 }</tt>). The method,
103
+ # proc or string should return or evaluate to a true or false value.
104
+ #
105
+ # @option attr_names [[Symbol, String or Proc]] :unless a method, proc or string to call to determine
106
+ # if the validation should not occur (e.g. <tt>unless: :skip_validation</tt>,
107
+ # or <tt>unless: Proc.new { |user| user.signup_step <= 2 }</tt>). The method,
108
+ # proc or string should return or evaluate to a true or false value.
109
+ #
110
+ # @option attr_names [boolean] :strict Specifies whether validation should be strict.
111
+ # See <tt>ActiveModel::Validation#validates!</tt> for more information.
112
+ #
113
+ def validates_nested(*attr_names)
114
+ validates_with NestedValidator, _merge_attributes(attr_names)
68
115
  end
69
116
  end
70
117
  end
@@ -28,8 +28,9 @@ RSpec::Matchers.define :validate_nested do |child_name|
28
28
  self.parent = parent
29
29
 
30
30
  return false unless parent.respond_to? child_name
31
-
32
31
  self.actual_keys = (error_keys_when_child_validity_is(false) - error_keys_when_child_validity_is(true))
32
+ return false if invalid_child_keys.present?
33
+
33
34
 
34
35
  actual_keys == expected_keys
35
36
  end
@@ -89,10 +90,8 @@ RSpec::Matchers.define :validate_nested do |child_name|
89
90
 
90
91
  failure_message do
91
92
  case
92
- when !parent.respond_to?(child_name)
93
- "#{parent} doesn't respond to #{show child_name}"
94
- when invalid_child_keys.present?
95
- "#{child_name} doesn't respond to #{show invalid_child_keys}"
93
+ when common_failure_message
94
+ common_failure_message
96
95
  when (missing_child_keys = expected_child_keys - actual_child_keys - invalid_child_keys - [TEST_KEY]).present?
97
96
  "#{parent} doesn't nest validations for: #{show missing_child_keys}"
98
97
  when actual_keys.empty?
@@ -110,12 +109,10 @@ RSpec::Matchers.define :validate_nested do |child_name|
110
109
 
111
110
  failure_message_when_negated do
112
111
  case
113
- when !parent.respond_to?(child_name)
114
- "#{parent} doesn't respond to #{show child_name}"
112
+ when common_failure_message
113
+ common_failure_message
115
114
  when (extras = only_keys & actual_child_keys).present?
116
- "#{parent} does nest #{show child_name} validations for: #{show extras}"
117
- when invalid_child_keys.present?
118
- "#{child_name} doesn't respond to #{show invalid_child_keys}"
115
+ "#{parent} does nest #{show child_name} validations for: #{show extras}"
119
116
  when except_keys.present?
120
117
  "#{parent} doesn't nest #{show child_name} validations for: #{show except_keys - actual_child_keys}"
121
118
  when prefix.present?
@@ -125,6 +122,11 @@ RSpec::Matchers.define :validate_nested do |child_name|
125
122
  end
126
123
  end
127
124
 
125
+ def common_failure_message
126
+ return "#{parent} doesn't respond to #{show child_name}" unless parent.respond_to?(child_name)
127
+ "#{child_name} doesn't respond to #{show invalid_child_keys}" if invalid_child_keys.present?
128
+ end
129
+
128
130
  def show(value)
129
131
  Array.wrap(value).map{|key| key.is_a?(Symbol) ? ":#{key}" : key.to_s}.join(', ')
130
132
  end
@@ -1,3 +1,3 @@
1
1
  module NestedValidator
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
@@ -86,10 +86,16 @@ describe NestedValidator do
86
86
  its('errors.messages') { should eq :'child1 attribute1' => ["can't be blank"] }
87
87
  end
88
88
 
89
- describe 'with "prefix: "OMG""' do
89
+ describe 'with "prefix: "OMG"', :focus do
90
90
  subject { with_nested_options prefix: 'OMG' }
91
91
 
92
- its('errors.messages') { should eq :'OMG attribute1' => ["can't be blank"] }
92
+ its('errors.messages') { puts subject.errors.messages; should eq :'OMG attribute1' => ["can't be blank"] }
93
+ end
94
+
95
+ describe 'with "prefix: ""' do
96
+ subject { with_nested_options prefix: '' }
97
+
98
+ its('errors.messages') { should eq :'attribute1' => ["can't be blank"] }
93
99
  end
94
100
  end
95
101
 
@@ -38,8 +38,9 @@ describe 'validates_nested with [parent class with "validates, child1]"' do
38
38
  }
39
39
  end
40
40
 
41
- let(:parent) { parent_class.new child_class.new, child_class.new }
42
- let(:options) { { presence: true } }
41
+ let(:parent) { parent_class.new child_class.new, child_class.new }
42
+ let(:options) { { nested: true } }
43
+ let(:validator) { instance_eval self.class.description }
43
44
 
44
45
  before { parent_class.class_eval "validates :child1, #{options}" }
45
46
 
@@ -57,7 +58,6 @@ describe 'validates_nested with [parent class with "validates, child1]"' do
57
58
  end
58
59
 
59
60
  context 'nested: {prefix: "OMG"}' do
60
-
61
61
  it { should validate_nested(:child1).with_prefix('OMG') }
62
62
  it { should validate_nested(:child1).with_prefix(:OMG) }
63
63
 
@@ -99,8 +99,6 @@ describe 'validates_nested with [parent class with "validates, child1]"' do
99
99
  end
100
100
 
101
101
  describe 'its description for:' do
102
- let(:validator) { instance_eval self.class.description }
103
-
104
102
  subject { validator.description }
105
103
 
106
104
  context('validate_nested(:child1)') { it { should eq 'validate nested :child1' } }
@@ -110,17 +108,28 @@ describe 'validates_nested with [parent class with "validates, child1]"' do
110
108
  end
111
109
 
112
110
  describe 'its error messages:' do
113
- let(:options) { self.class.parent.description }
114
- let(:validator) { instance_eval self.class.description }
111
+ let(:options) { self.class.parent.description }
112
+ let(:expect_match) { false }
115
113
 
116
- describe 'should failure messages for' do
117
- before { expect(validator.matches? parent).to be false }
114
+ before { expect(validator.matches? parent).to be expect_match }
115
+
116
+ describe 'failures for should and should_not' do
117
+ [:failure_message, :failure_message_when_negated].each do |message|
118
+ subject { validator.send message }
118
119
 
120
+ context 'nested: true' do
121
+ describe('validate_nested(:invalid_child_name)') { it { should eq "parent doesn't respond to :invalid_child_name" } }
122
+ describe('validate_nested(:child1).only(:invalid_attribute_name)') { it { should eq "child1 doesn't respond to :invalid_attribute_name" } }
123
+ describe('validate_nested(:child1).except(:invalid_attribute_name)') { it { should eq "child1 doesn't respond to :invalid_attribute_name" } }
124
+ end
125
+ end
126
+ end
127
+
128
+ describe 'should failure messages for' do
119
129
  subject { validator.failure_message }
120
130
 
121
131
  context 'nested: true' do
122
- describe('validate_nested(:child2)') { it { should eq "parent doesn't nest validations for :child2" } }
123
- describe('validate_nested(:invalid_child_name)') { it { should eq "parent doesn't respond to :invalid_child_name" } }
132
+ describe('validate_nested(:child2)') { it { should eq "parent doesn't nest validations for :child2" } }
124
133
  end
125
134
 
126
135
  context 'nested: {prefix: :OMG}' do
@@ -129,20 +138,18 @@ describe 'validates_nested with [parent class with "validates, child1]"' do
129
138
  end
130
139
 
131
140
  context 'nested: {only: :attribute1}' do
132
- describe('validate_nested(:child1).only(:invalid_attribute_name)') { it { should eq "child1 doesn't respond to :invalid_attribute_name" } }
133
141
  describe('validate_nested(:child1).only(:attribute2)') { it { should eq "parent doesn't nest validations for: :attribute2" } }
134
142
  describe('validate_nested(:child1).only(:attribute1, :attribute2)') { it { should eq "parent doesn't nest validations for: :attribute2" } }
135
143
  end
136
144
 
137
145
  context 'nested: {except: :attribute1}' do
138
- describe('validate_nested(:child1).except(:invalid_attribute_name)') { it { should eq "child1 doesn't respond to :invalid_attribute_name" } }
139
146
  describe('validate_nested(:child1).except(:attribute2)') { it { should eq 'parent does nest validations for: :attribute2' } }
140
147
  describe('validate_nested(:child1).except(:attribute1, :attribute2)') { it { should eq 'parent does nest validations for: :attribute2' } }
141
148
  end
142
149
  end
143
150
 
144
151
  describe 'should_not failure messages for' do
145
- before { expect(validator.matches? parent).to be true }
152
+ let(:expect_match) { true }
146
153
 
147
154
  subject { validator.failure_message_when_negated }
148
155
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nested_validator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Declan Whelan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-23 00:00:00.000000000 Z
11
+ date: 2014-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel