nested_validator 1.0.5 → 1.0.6

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