nested_validator 1.0.0 → 1.0.1

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.
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