nested_validator 1.0.5 → 1.0.6

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
- OTc4N2MxNWMwNGRjZGRlNjA0MzBkNzZlZjRlZjczMGU5M2I4YjE3OQ==
4
+ OTAwNDBjOGJmNDEzM2I0MjYwOTczMmMwNzUxNTRjMTc2NDAzMTM1Yg==
5
5
  data.tar.gz: !binary |-
6
- YmNhNWI2YzdjYmE1YjNhNGE0ZDdiMzY4Yzg0YWYwZmRiODUzNjk2Yg==
6
+ ZjM4OGNjMmZkNzc2MmY0OGJhMTdjNGE2NDM2M2M0ZjJmMTY5YTY3OQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NWY5NmU2ZjA4NmY4OWI3ZGMwMjI0NzU0ZDM4YWVjZjRlNzYzZDc5MTE4ZDM4
10
- NjgxZWQyNTc3ODZhMDhlYzc4OGQyYTk4MTI1Y2Q1N2NhYmFiNmMxMTgwYzBl
11
- NTEzYjhhMDM2MjMzMTI0MzQ3ZGZkY2EyNmRiNzAxZDJjZThhMTE=
9
+ MDFhY2E0ZDlmY2E3Mzk0MzVmNWY5NzFkNGE3ZjVmNjEwNzZlNTE0MjQzOTI5
10
+ ZjZmZGU3NWRmYjUxNTlmMjdmNTY3YTRiYjZiM2VlMjY0ODU0MTFkOTBkZjgy
11
+ OGM5NDRjY2NjYzg1NWM5YTcwMjAzMjA0ODNlNTQ0NTcwOGY0NzI=
12
12
  data.tar.gz: !binary |-
13
- YzkyZmRiNGJiYjFkZTRhMWIxODY0ZmFiNGZkN2Y5Mjk5ZjYyMTU5YzJkODFi
14
- ODEzMWRmZDg2NjdhNjNhYzdjNTUxZWEwODY1ZjcwNTE2N2YyMjQxMjM1ZmNj
15
- MzczMjU5ZmQ3MmY1ZDlmYTBiYzA1ZjYwNGUxNGM1NjA0Mzg5ODM=
13
+ MTM1ZDY2NmNhMjgzN2E3YjIxNjIyNzllMzM4NzJhNzM3NTg5NGE0OTU2NzQ2
14
+ OGM5OTJlY2JiNTQyMzU5YTYwZGE4M2M2NWM3YThlOGQ2YjcxYmYxZjljNTU3
15
+ NjU1YTQ5NmEzYTIyODJhYzBkNGUxYmM4Mjg2MTk1MzZmNTQyOTU=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nested_validator (1.0.5)
4
+ nested_validator (1.0.6)
5
5
  activemodel
6
6
  activesupport
7
7
 
@@ -41,9 +41,9 @@ module ActiveModel
41
41
  valid_keys = any - value.errors.keys.map{|k| k.to_s.split.first}
42
42
  return if valid_keys.present?
43
43
  end
44
- value.errors.each do |key, error|
45
- key = key.to_s.split.first
46
- record.errors.add(nested_key(prefix, key), error) if include?(key)
44
+ value.errors.select{|key, _| include?(key)}.each do |key, error|
45
+ message = [key.to_s, error].join(' ').strip
46
+ record.errors.add(prefix, message) unless record.errors[prefix].include?(message)
47
47
  end
48
48
  end
49
49
 
@@ -16,8 +16,15 @@ require 'rspec/expectations'
16
16
  # end
17
17
  RSpec::Matchers.define :validate_nested do |child_name|
18
18
 
19
- attr_accessor :child_name, :prefix, :only_keys, :except_keys, :any_keys
20
- attr_accessor :parent, :actual_keys
19
+ [:child_name, :prefix, :only_keys, :except_keys, :any_keys, :parent, :child_attributes, :child_error_key].each do |attr|
20
+ define_method(attr) do
21
+ instance_variable_get "@#{attr}"
22
+ end
23
+
24
+ define_method("#{attr}=") do |value|
25
+ instance_variable_set "@#{attr}", value
26
+ end
27
+ end
21
28
 
22
29
  TEST_KEY ||= :__test_key__
23
30
 
@@ -27,14 +34,16 @@ RSpec::Matchers.define :validate_nested do |child_name|
27
34
  self.except_keys ||= []
28
35
  self.any_keys ||= []
29
36
 
30
- self.child_name = child_name
37
+ self.child_name = child_name.to_sym
31
38
  self.parent = parent
32
39
 
33
40
  return false unless parent.respond_to? child_name
34
- self.actual_keys = (error_keys_when_child_validity_is(false) - error_keys_when_child_validity_is(true))
35
41
  return false if invalid_child_keys.present?
36
42
 
37
- actual_keys == expected_keys
43
+ self.child_attributes = child_attributes_when_validity_is(false) - child_attributes_when_validity_is(true)
44
+ self.child_error_key = (child_error_keys_when_validity_is(false) - child_error_keys_when_validity_is(true)).first
45
+
46
+ child_attributes == expected_child_attributes && child_error_key == expected_child_error_key
38
47
  end
39
48
 
40
49
  def prepare_keys(keys)
@@ -45,38 +54,42 @@ RSpec::Matchers.define :validate_nested do |child_name|
45
54
  end
46
55
  end
47
56
 
48
- chain(:with_prefix) { |prefix| self.prefix = prefix }
57
+ chain(:with_prefix) { |prefix| self.prefix = prefix.to_sym }
49
58
  chain(:only) { |*only| self.only_keys = prepare_keys(only) }
50
59
  chain(:except) { |*except| self.except_keys = prepare_keys(except) }
51
60
  chain(:any) { |*any| self.any_keys = prepare_keys(any) }
52
61
 
53
62
  def child
54
- parent.public_send child_name
63
+ parent.public_send(child_name)
55
64
  end
56
65
 
57
- def error_keys_when_child_validity_is(valid)
66
+ def child_attributes_when_validity_is(valid)
67
+ errors_when_child_validity_is(valid).map{|k, msg| msg.split.first.to_sym}
68
+ end
69
+
70
+ def child_error_keys_when_validity_is(valid)
71
+ errors_when_child_validity_is(valid).keys
72
+ end
73
+
74
+ def errors_when_child_validity_is(valid)
58
75
  child_error_keys = combine TEST_KEY, only_keys, except_keys, any_keys
59
- child_errors = child_error_keys.inject({}){|result, key| result[key] = ['error message'];result }
76
+ child_errors = child_error_keys.inject({}) { |result, key| result[key] = ['error message']; result }
60
77
 
61
78
  allow(child).to receive(:valid?) { valid }
62
79
  allow(child).to receive(:errors) { valid ? [] : child_errors }
63
80
 
64
81
  parent.valid?
65
- parent.errors.keys
82
+ parent.errors
66
83
  end
67
84
 
68
- def expected_keys
69
- expected_child_keys.map{|key| :"#{expected_prefix} #{key}"}
85
+ def expected_child_attributes
86
+ expected_child_keys.map{|k| k.to_sym}
70
87
  end
71
88
 
72
- def expected_prefix
89
+ def expected_child_error_key
73
90
  prefix.present? ? prefix : child_name
74
91
  end
75
92
 
76
- def actual_prefix
77
- :"#{actual_keys.first.to_s.split.first}"
78
- end
79
-
80
93
  def expected_child_keys
81
94
  expected_keys = case
82
95
  when only_keys.present?
@@ -91,11 +104,10 @@ RSpec::Matchers.define :validate_nested do |child_name|
91
104
  end
92
105
 
93
106
  def actual_child_keys
94
- actual_keys.map{|key| key.to_s.sub(/^.*\s+/, '').to_sym }
107
+ child_attributes.map{|key| key.to_s.sub(/^.*\s+/, '').to_sym }
95
108
  end
96
109
 
97
110
  def invalid_child_keys
98
- #binding.pry
99
111
  (only_keys + except_keys).reject{|key| child.respond_to? key}
100
112
  end
101
113
 
@@ -114,13 +126,13 @@ RSpec::Matchers.define :validate_nested do |child_name|
114
126
  common_failure_message
115
127
  when (missing_child_keys = expected_child_keys - actual_child_keys - invalid_child_keys - [TEST_KEY]).present?
116
128
  "#{parent} doesn't nest validations for: #{show missing_child_keys}"
117
- when actual_keys.empty?
129
+ when child_attributes.empty?
118
130
  "parent doesn't nest validations for #{show child_name}"
119
- when actual_prefix != expected_prefix
131
+ when child_error_key != expected_child_error_key
120
132
  if prefix.present?
121
- "parent uses a prefix of #{show actual_prefix} rather than #{show expected_prefix}"
133
+ "parent uses a prefix of #{show child_error_key} rather than #{show expected_child_error_key}"
122
134
  else
123
- "parent has a prefix of #{show actual_prefix}. Are you missing '.with_prefix(#{show actual_prefix})'?"
135
+ "parent has a prefix of #{show child_error_key}. Are you missing '.with_prefix(#{show child_error_key})'?"
124
136
  end
125
137
  else
126
138
  "parent does nest validations for: #{show except_keys & actual_child_keys}"
@@ -1,3 +1,3 @@
1
1
  module NestedValidator
2
- VERSION = '1.0.5'
2
+ VERSION = '1.0.6'
3
3
  end
@@ -7,19 +7,19 @@ RSpec::Matchers.define :detect_nested_error_for do
7
7
  end
8
8
 
9
9
  def description
10
- "detect an error for '#{child_attribute}'"
10
+ "detect an error for child '#{child_attribute}'"
11
11
  end
12
12
 
13
13
  failure_message do
14
- "has no error for '#{child_attribute}'"
14
+ "has no error for child '#{child_attribute}'"
15
15
  end
16
16
 
17
17
  failure_message_when_negated do
18
- "has an error '#{child_attribute}' => '#{error}'"
18
+ "has an error child '#{child_attribute}' => '#{error}'"
19
19
  end
20
20
 
21
21
  def error
22
- subject.errors[child_attribute].first
22
+ subject.errors[:child].find{|e| e =~ /^#{expected} /}
23
23
  end
24
24
 
25
25
  def attribute
@@ -31,7 +31,7 @@ RSpec::Matchers.define :detect_nested_error_for do
31
31
  end
32
32
 
33
33
  def child_attribute
34
- :"child #{attribute}"
34
+ :"#{attribute}"
35
35
  end
36
36
  end
37
37
 
@@ -193,31 +193,42 @@ describe 'nested validation' do
193
193
  end
194
194
  end
195
195
 
196
- describe 'error message keys' do
196
+ describe 'error keys' do
197
197
  before { parent.valid? }
198
198
  subject { parent.errors.messages.keys.first }
199
199
 
200
- context('true') { it { should eq :'child attribute' } }
201
- context('{prefix: ""}') { it { should eq :'attribute' } }
202
- context('{prefix: nil}') { it { should eq :'attribute' } }
203
- context('{prefix: "OMG"}') { it { should eq :'OMG attribute' } }
200
+ context('true') { it { should eq :'child' } }
201
+ context('{prefix: ""}') { it { should eq :'' } }
202
+ context('{prefix: nil}') { it { should eq :'' } }
203
+ context('{prefix: "OMG"}') { it { should eq :'OMG' } }
204
204
 
205
205
  context 'with arrays' do
206
206
  let(:child) { [child_class.new] }
207
207
 
208
- context('true') { it { should eq :'child[0] attribute' } }
209
- context('{prefix: ""}') { it { should eq :'[0] attribute' } }
210
- context('{prefix: nil}') { it { should eq :'[0] attribute' } }
211
- context('{prefix: "OMG"}') { it { should eq :'OMG[0] attribute' } }
208
+ context('true') { it { should eq :'child[0]' } }
209
+ context('{prefix: ""}') { it { should eq :'[0]' } }
210
+ context('{prefix: nil}') { it { should eq :'[0]' } }
211
+ context('{prefix: "OMG"}') { it { should eq :'OMG[0]' } }
212
212
  end
213
213
 
214
214
  context('with hashes') do
215
215
  let(:child) { {key: child_class.new} }
216
216
 
217
- context('true') { it { should eq :'child[key] attribute' } }
218
- context('{prefix: ""}') { it { should eq :'[key] attribute' } }
219
- context('{prefix: nil}') { it { should eq :'[key] attribute' } }
220
- context('{prefix: "OMG"}') { it { should eq :'OMG[key] attribute' } }
217
+ context('true') { it { should eq :'child[key]' } }
218
+ context('{prefix: ""}') { it { should eq :'[key]' } }
219
+ context('{prefix: nil}') { it { should eq :'[key]' } }
220
+ context('{prefix: "OMG"}') { it { should eq :'OMG[key]' } }
221
+ end
222
+ end
223
+
224
+ describe 'error messages' do
225
+ before { parent.valid? }
226
+ subject { parent.errors.messages.values.first }
227
+
228
+ context('true') do
229
+ it { should include "attribute can't be blank" }
230
+ it { should include "attribute2 can't be blank" }
231
+ it { should include "attribute3 can't be blank" }
221
232
  end
222
233
  end
223
234
 
@@ -265,5 +276,16 @@ describe 'nested validation' do
265
276
  it { expect(grand_parent).to_not be_valid }
266
277
  end
267
278
  end
279
+
280
+ describe 'errors[:parent]' do
281
+ let(:parent_options) { true}
282
+
283
+ before { grand_parent.valid? }
284
+ subject { grand_parent.errors[:parent] }
285
+
286
+ it { should include "child attribute can't be blank" }
287
+ it { should include "child attribute2 can't be blank" }
288
+ it { should include "child attribute3 can't be blank" }
289
+ end
268
290
  end
269
291
  end
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.5
4
+ version: 1.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Declan Whelan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-28 00:00:00.000000000 Z
11
+ date: 2015-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel