hydra-validations 0.3.2 → 0.4.0

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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 14a1051a97f663c054e73db5a4f50c90a45a447a
4
- data.tar.gz: d7ffb762b468269fc1275604c50bacdabb05f83b
3
+ metadata.gz: 6cd9dc181595609320187b6967b7419c584e5592
4
+ data.tar.gz: e87ae57ed9847709bccd5979eee498381707cc13
5
5
  SHA512:
6
- metadata.gz: ceca377220db7fc7391c1d8bc2cc4729579b74c8fc9508cc11f60a98f3a79aff6d08c7480f4218e8e6f39811a1ba06f7b39fd83255ce8e72cd249865a7b69d05
7
- data.tar.gz: 4c24af4ec23bfddbb3635486be91d310d2acd4c8225bdc17166b06be0f90ea1ef57e59105dcedba9f6106f53e60e53d0f1820d1db149d867a25bf187d7500f46
6
+ metadata.gz: 45b9a25dd9f59461d336b8877e14371f67ef764ed0b879960f375f97e60236a646c29cef36660703598a2fe3ac46f6f7a7a0ea2ee1be020ea6552e94c914bfa7
7
+ data.tar.gz: 0212d9e7f159ddbacf0a291b4a80a91f95659aa95474c7cff67e337e57132fb37d2f39e2be660c4cfaaa0f856d51d62884c715196ca6b061522645e8c154aa23
data/README.md CHANGED
@@ -25,13 +25,15 @@ and
25
25
  bundle install
26
26
  ```
27
27
 
28
+ ## EnumerableBehavior Mixin
29
+
28
30
  ## Validators
29
31
 
30
32
  See also the source code and spec tests.
31
33
 
32
34
  ### FormatValidator
33
35
 
34
- Extends the ActiveModel version to validate the format of *each member* of an enumerable attribute value.
36
+ Extends the ActiveModel::Validations::FormatValidator, adding EnumerableBehavior.
35
37
 
36
38
  See documentation for ActiveModel::Validations::FormatValidator for usage and options.
37
39
 
@@ -63,7 +65,7 @@ end
63
65
 
64
66
  ### InclusionValidator
65
67
 
66
- Extends the ActiveModel version to validate inclusion of *each member* of an enumerable attribute value.
68
+ Extends ActiveModel::Validations::InclusionValidator, adding EnumerableBehavior.
67
69
 
68
70
  See documentation for ActiveModel::Validations::InclusionValidator for usage and options.
69
71
 
@@ -73,6 +75,8 @@ class InclusionValidatable
73
75
  include Hydra::Validations
74
76
  attr_accessor :field
75
77
  validates :field, inclusion: { in: ["foo", "bar", "baz"] }
78
+ # or using helper method ...
79
+ # validates_inclusion_of :field, in: ["foo", "bar", "baz"]
76
80
  end
77
81
 
78
82
  > v = InclusionValidatable.new
@@ -103,7 +107,6 @@ class UniquenessValidatable < ActiveFedora::Base
103
107
  has_metadata name: 'descMetadata', type: ActiveFedora::QualifiedDublinCoreDatastream
104
108
  has_attributes :title, datastream: 'descMetadata', multiple: false
105
109
  # Can use with multi-value attributes, but single cardinality is required.
106
- # See SingleCardinalityValidator below.
107
110
  has_attributes :source, datastream: 'descMetadata', multiple: true
108
111
  validates :source, uniqueness: { solr_name: "source_ssim" }
109
112
  # ... or using helper method
@@ -111,20 +114,35 @@ class UniquenessValidatable < ActiveFedora::Base
111
114
  end
112
115
  ```
113
116
 
114
- ### SingleCardinalityValidator
117
+ ### CardinalityValidator
118
+
119
+ Validates the cardinality of the attribute value.
120
+
121
+ CardinalityValidator is a subclass of ActiveModel::Validations::LengthValidator which
122
+ "tokenizes" values with `Array.wrap(value)`. The "cardinality" of the value
123
+ is the length the array. Hence,
124
+
125
+ - `nil` and empty enumerables have cardinality 0
126
+ - scalar values (including empty string) have cardinality 1.
115
127
 
116
- Validates that the attribute value is a scalar or single-member enumerable.
128
+ CardinalityValidator customizes the `:wrong_length`, `:too_short` and `:too_long` messages
129
+ of LengthValidator to use language appropriate to cardinality. You can also override these
130
+ options.
117
131
 
118
132
  ```ruby
119
- class Validatable
133
+ class CardinalityValidatable
120
134
  include ActiveModel::Validations # required if not already included in class
121
135
  include Hydra::Validations
122
136
  attr_accessor :field
123
- validates :field, single_cardinality: true
137
+ validates :field, cardinality: { is: 1 }
138
+ # or with helper method ...
139
+ # validates_cardinality_of :field, is: 1
140
+ # or, for single cardinality (same as above) ...
141
+ # validates_single_cardinality_of :field
124
142
  end
125
143
 
126
- > Validatable.validators
127
- => [#<Hydra::Validations::SingleCardinalityValidator:0x007fb91d1e9460 @attributes=[:field], @options={}>]
144
+ > CardinalityValidatable.validators
145
+ => [#<Hydra::Validations::CardinalityValidator:0x007fb91d1e9460 @attributes=[:field], @options={:is=>1}>]
128
146
  > v = Validatable.new
129
147
  => #<Validatable:0x007fb91d1c9188>
130
148
  > v.field = "foo"
@@ -14,7 +14,7 @@ module Hydra
14
14
  protected
15
15
  # Overwrites ActiveModel::Validations::ClassMethods, adding :allow_empty
16
16
  def _validates_default_keys
17
- [:if, :unless, :on, :allow_blank, :allow_nil , :strict, :allow_empty]
17
+ [:if, :unless, :on, :allow_blank, :allow_nil, :strict, :allow_empty]
18
18
  end
19
19
  end
20
20
 
@@ -1,20 +1,57 @@
1
+ require 'active_support/core_ext/array/wrap'
2
+
1
3
  module Hydra
2
4
  module Validations
3
5
  #
4
- # Cardinality - a mixin adding cardinality validation methods.
6
+ # CardinalityValidator - A cardinality validator for enumerable values based on
7
+ # ActiveModel's LengthValidator.
8
+ #
9
+ # validates :field, cardinality: { minimum: 1, maximum: 5 }
10
+ # validates :field, cardinality: { in: 1..5 }
11
+ # validates :field, cardinality: { within: 1..5 }
12
+ # validates :field, cardinality: { is: 1 }
5
13
  #
6
- module Cardinality
14
+ # See ActiveModel::Validations::LengthValidator for options.
15
+ #
16
+ class CardinalityValidator < ActiveModel::Validations::LengthValidator
17
+
18
+ def initialize(options = {})
19
+ super(default_options.merge(options))
20
+ end
7
21
 
8
- def validate_cardinality(cardinality, record, attribute, value)
9
- return validate_single_cardinality(record, attribute, value) if cardinality == :single
10
- raise ArgumentError, "Cardinality validation not supported: #{cardinality.inspect}"
22
+ def validate_each(record, attribute, value)
23
+ return if options[:allow_empty] && value.respond_to?(:empty?) && value.empty?
24
+ super
11
25
  end
12
26
 
13
- def validate_single_cardinality(record, attribute, value)
14
- # TODO i18n message
15
- record.errors.add(attribute, "can't have more than one value") if value.respond_to?(:each) && value.size > 1
27
+ protected
28
+
29
+ def default_options
30
+ { wrong_length: "has the wrong cardinality (should have %{count} value(s))",
31
+ too_short: "has too few values (minimum cardinality is %{count})",
32
+ too_long: "has too many values (maximum cardinality is %{count})"
33
+ }
34
+ end
35
+
36
+ private
37
+
38
+ # Override
39
+ def tokenize(value)
40
+ Array.wrap(value)
16
41
  end
17
42
 
18
43
  end
44
+
45
+ module HelperMethods
46
+ def validates_cardinality_of *attr_names
47
+ validates_with CardinalityValidator, _merge_attributes(attr_names)
48
+ end
49
+
50
+ def validates_single_cardinality_of *attr_names
51
+ options = _merge_attributes(attr_names).merge(is: 1)
52
+ validates_with CardinalityValidator, options
53
+ end
54
+ end
55
+
19
56
  end
20
57
  end
@@ -7,10 +7,15 @@ module Hydra
7
7
  # Behavior includes 'fixing' each error message to include the specific value
8
8
  # which was invalid.
9
9
  #
10
- # `allow_empty` option can be used instead of `allow_blank` for greater
10
+ # The `allow_empty` option can be used instead of `allow_blank` for greater
11
11
  # clarity and precision with enumerable values. If a validator includes
12
- # this mixin, then an empty enumerable value will always be invalid if
13
- # `allow_empty` is false or nil.
12
+ # this mixin, an empty enumerable value will *always* be invalid unless
13
+ # `allow_empty` is true.
14
+ #
15
+ # Note that `allow_nil` and `allow_blank` options apply to the enumerable
16
+ # value, not to its members. Thus, for example, `allow_blank: true` will
17
+ # not bypass validation of the value `[""]` even though its member `""`
18
+ # is blank.
14
19
  #
15
20
  module EnumerableBehavior
16
21
 
@@ -1,5 +1,4 @@
1
- require 'hydra/validations'
2
- require 'hydra/validations/cardinality'
1
+ require 'active_support/core_ext/array/wrap'
3
2
 
4
3
  module Hydra
5
4
  module Validations
@@ -25,22 +24,26 @@ module Hydra
25
24
  #
26
25
  class UniquenessValidator < ActiveModel::EachValidator
27
26
 
28
- include Cardinality
29
-
30
27
  def check_validity!
31
- raise ArgumentError, "UniquenessValidator accepts only a single attribute: #{attribues}" if attributes.length > 1
32
- raise ArgumentError, "UniquenessValidator requires the :solr_name option be present." unless options[:solr_name].present?
28
+ if attributes.length > 1
29
+ raise ArgumentError, "UniquenessValidator accepts only a single attribute: #{attributes}"
30
+ end
31
+ unless options[:solr_name].present?
32
+ raise ArgumentError, "UniquenessValidator requires the :solr_name option be present."
33
+ end
33
34
  end
34
35
 
35
36
  def validate_each(record, attribute, value)
36
- # TODO: i18n messages
37
- validate_cardinality(:single, record, attribute, value)
38
- # Validate uniqueness proper only if value is of single cardinality
39
- return if record.errors.added?(attribute, "can't have more than one value")
40
- value = value.first if value.respond_to?(:each)
41
- conditions = {options[:solr_name] => value}
42
- conditions.merge!("-id" => record.id) if record.persisted?
43
- record.errors.add attribute, "has already been taken" if record.class.exists?(conditions)
37
+ wrapped_value = Array.wrap(value)
38
+ if wrapped_value.length > 1
39
+ record.errors.add(attribute, "can't have more than one value")
40
+ elsif wrapped_value.empty?
41
+ record.errors.add(attribute, "can't be empty") unless options[:allow_empty]
42
+ else
43
+ conditions = {options[:solr_name] => wrapped_value.first}
44
+ conditions.merge!("-id" => record.id) if record.persisted?
45
+ record.errors.add attribute, "has already been taken" if record.class.exists?(conditions)
46
+ end
44
47
  end
45
48
 
46
49
  end
@@ -1,5 +1,5 @@
1
1
  module Hydra
2
2
  module Validations
3
- VERSION = "0.3.2"
3
+ VERSION = "0.4.0"
4
4
  end
5
5
  end
@@ -0,0 +1,199 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hydra::Validations::CardinalityValidator do
4
+
5
+ before(:all) do
6
+ class Validatable
7
+ include ActiveModel::Validations
8
+ include Hydra::Validations
9
+ attr_accessor :field
10
+ end
11
+ end
12
+
13
+ before(:each) do
14
+ Validatable.clear_validators!
15
+ Validatable.validates :field, options
16
+ allow(record).to receive(:field) { value }
17
+ end
18
+
19
+ after(:all) { Object.send(:remove_const, :Validatable) }
20
+
21
+ let(:record) { Validatable.new }
22
+
23
+ let(:opts) { { cardinality: cardinality } }
24
+
25
+ shared_examples "it has cardinality 0" do
26
+ let(:options) { opts }
27
+ describe "and :is == 0" do
28
+ let(:cardinality) { { is: 0 } }
29
+ it "should be valid" do
30
+ expect(record).to be_valid
31
+ end
32
+ end
33
+ describe "and :is > 0" do
34
+ let(:cardinality) { { is: 1 } }
35
+ it "should be invalid" do
36
+ expect(record).to be_invalid
37
+ end
38
+ end
39
+ describe "and :minimum == 0" do
40
+ let(:cardinality) { { minimum: 0 } }
41
+ it "should be valid" do
42
+ expect(record).to be_valid
43
+ end
44
+ end
45
+ describe "and :minimum > 0" do
46
+ let(:cardinality) { { minimum: 1 } }
47
+ it "should be invalid" do
48
+ expect(record).to be_invalid
49
+ end
50
+ end
51
+ end
52
+
53
+ shared_examples "it has cardinality 1" do
54
+ let(:options) { opts }
55
+ describe "and is == 0" do
56
+ let(:cardinality) { { is: 0 } }
57
+ it "should be invalid" do
58
+ expect(record).to be_invalid
59
+ end
60
+ end
61
+ describe "and :is == 1" do
62
+ let(:cardinality) { { is: 1 } }
63
+ it "should be valid" do
64
+ expect(record).to be_valid
65
+ end
66
+ end
67
+ describe "and :is > 1" do
68
+ let(:cardinality) { { is: 2 } }
69
+ it "should be invalid" do
70
+ expect(record).to be_invalid
71
+ end
72
+ end
73
+ describe "and :minimum == 0" do
74
+ let(:cardinality) { { minimum: 0 } }
75
+ it "should be valid" do
76
+ expect(record).to be_valid
77
+ end
78
+ end
79
+ describe "and :minimum == 1" do
80
+ let(:cardinality) { { minimum: 1 } }
81
+ it "should be valid" do
82
+ expect(record).to be_valid
83
+ end
84
+ end
85
+ describe "and :minimum > 1" do
86
+ let(:cardinality) { { minimum: 2 } }
87
+ it "should be invalid" do
88
+ expect(record).to be_invalid
89
+ end
90
+ end
91
+ describe "and :maximum == 0" do
92
+ let(:cardinality) { { maximum: 0 } }
93
+ it "should be invalid" do
94
+ expect(record).to be_invalid
95
+ end
96
+ end
97
+ describe "and :maximum == 1" do
98
+ let(:cardinality) { { maximum: 1 } }
99
+ it "should be valid" do
100
+ expect(record).to be_valid
101
+ end
102
+ end
103
+ describe "and :maximum > 1" do
104
+ let(:cardinality) { { maximum: 2 } }
105
+ it "should be valid" do
106
+ expect(record).to be_valid
107
+ end
108
+ end
109
+ end
110
+
111
+ describe "when value is nil" do
112
+ let(:value) { nil }
113
+ it_behaves_like "it has cardinality 0"
114
+ end
115
+
116
+ describe "when value is an empty string" do
117
+ let(:value) { "" }
118
+ it_behaves_like "it has cardinality 1"
119
+ end
120
+
121
+ describe "when value is a non-empty string" do
122
+ let(:value) { "foo" }
123
+ it_behaves_like "it has cardinality 1"
124
+ end
125
+
126
+ describe "when value is an empty enumerable" do
127
+ let(:value) { [] }
128
+ it_behaves_like "it has cardinality 0"
129
+ describe "and `allow_empty: true`" do
130
+ let(:options) { opts.merge(allow_empty: true) }
131
+ describe "and :is != 0" do
132
+ let(:cardinality) { { is: 1 } }
133
+ it "should be valid" do
134
+ expect(record).to be_valid
135
+ end
136
+ end
137
+ describe "and :minimum > 0" do
138
+ let(:cardinality) { { minimum: 1 } }
139
+ it "should be valid" do
140
+ expect(record).to be_valid
141
+ end
142
+ end
143
+ end
144
+ end
145
+
146
+ describe "when value is a non-empty enumerable" do
147
+ let(:value) { ["foo", "bar"] }
148
+ let(:options) { opts }
149
+ describe "and :is != length" do
150
+ let(:cardinality) { { is: 1 } }
151
+ it "should be invalid" do
152
+ expect(record).to be_invalid
153
+ end
154
+ end
155
+ describe "and :is == length" do
156
+ let(:cardinality) { { is: 2 } }
157
+ it "should be valid" do
158
+ expect(record).to be_valid
159
+ end
160
+ end
161
+ describe "and :minimum < length" do
162
+ let(:cardinality) { { minimum: 1 } }
163
+ it "should be valid" do
164
+ expect(record).to be_valid
165
+ end
166
+ end
167
+ describe "and :minimum == length" do
168
+ let(:cardinality) { { minimum: 2 } }
169
+ it "should be valid" do
170
+ expect(record).to be_valid
171
+ end
172
+ end
173
+ describe "and :minimum > length" do
174
+ let(:cardinality) { { minimum: 3 } }
175
+ it "should be invalid" do
176
+ expect(record).to be_invalid
177
+ end
178
+ end
179
+ describe "and :maximum < length" do
180
+ let(:cardinality) { { maximum: 1 } }
181
+ it "should be invalid" do
182
+ expect(record).to be_invalid
183
+ end
184
+ end
185
+ describe "and :maximum == length" do
186
+ let(:cardinality) { { maximum: 2 } }
187
+ it "should be valid" do
188
+ expect(record).to be_valid
189
+ end
190
+ end
191
+ describe "and :maximum > length" do
192
+ let(:cardinality) { { maximum: 3 } }
193
+ it "should be valid" do
194
+ expect(record).to be_valid
195
+ end
196
+ end
197
+ end
198
+
199
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hydra::Validations::FormatValidator do
4
+
5
+ before(:all) do
6
+ class Validatable
7
+ include ActiveModel::Validations
8
+ include Hydra::Validations
9
+ attr_accessor :field
10
+ validates :field, format: { with: /\A[[:alpha:]]+\Z/ }
11
+ end
12
+ end
13
+
14
+ after(:all) { Object.send(:remove_const, :Validatable) }
15
+
16
+ before(:each) { allow(record).to receive(:field) { value } }
17
+
18
+ let(:record) { Validatable.new }
19
+
20
+ describe "when the value is a scalar" do
21
+ describe "which matches the format" do
22
+ let(:value) { "foo" }
23
+ it "should be valid" do
24
+ expect(record).to be_valid
25
+ end
26
+ end
27
+ describe "which does not match the format" do
28
+ let(:value) { "foo1" }
29
+ it "should be invalid" do
30
+ expect(record).to be_invalid
31
+ end
32
+ it "should have the standard error message" do
33
+ record.valid?
34
+ # TODO i18n
35
+ expect(record.errors[:field]).to eq ["is invalid"]
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "when the value is an enumerable" do
41
+ describe "and all value members match the format" do
42
+ let(:value) { ["foo", "bar"] }
43
+ it "should be valid" do
44
+ expect(record).to be_valid
45
+ end
46
+ end
47
+ describe "and one value member does not match the format" do
48
+ let(:value) { ["foo1", "bar"] }
49
+ it "should be invalid" do
50
+ expect(record).to be_invalid
51
+ end
52
+ it "should 'fix' the error message to include the value" do
53
+ record.valid?
54
+ # TODO i18n
55
+ expect(record.errors[:field]).to eq ["value \"foo1\" is invalid"]
56
+ end
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hydra::Validations::HelperMethods do
4
+
5
+ before(:all) do
6
+ class Validatable
7
+ include ActiveModel::Validations
8
+ include Hydra::Validations
9
+ attr_accessor :field
10
+ end
11
+ end
12
+
13
+ before(:each) { Validatable.clear_validators! }
14
+
15
+ after(:all) { Object.send(:remove_const, :Validatable) }
16
+
17
+ subject { Validatable.validators.first }
18
+
19
+ describe ".validates_cardinality_of" do
20
+ before { Validatable.validates_cardinality_of :field, is: 1 }
21
+ it "should add a cardinality validator" do
22
+ expect(subject).to be_a Hydra::Validations::CardinalityValidator
23
+ expect(subject.options).to include({ is: 1 })
24
+ end
25
+ end
26
+
27
+ describe ".validates_single_cardinality_of" do
28
+ before { Validatable.validates_single_cardinality_of :field }
29
+ it "should add a cardinality validator having :is=>1" do
30
+ expect(subject).to be_a Hydra::Validations::CardinalityValidator
31
+ expect(subject.attributes).to eq [:field]
32
+ expect(subject.options).to include({ is: 1 })
33
+ end
34
+ end
35
+
36
+ describe ".validates_format_of" do
37
+ before { Validatable.validates_format_of :field, with: /\A[[:alpha:]]+\Z/ }
38
+ it "should add a format validator" do
39
+ expect(subject).to be_a Hydra::Validations::FormatValidator
40
+ expect(subject.attributes).to eq [:field]
41
+ expect(subject.options).to include({ with: /\A[[:alpha:]]+\Z/ })
42
+ end
43
+ end
44
+
45
+ describe ".validates_inclusion_of" do
46
+ before { Validatable.validates_inclusion_of :field, in: ["foo", "bar", "baz"] }
47
+ it "should add an inclusion validator" do
48
+ expect(subject).to be_a Hydra::Validations::InclusionValidator
49
+ expect(subject.attributes).to eq [:field]
50
+ expect(subject.options).to include({ in: ["foo", "bar", "baz"] })
51
+ end
52
+ end
53
+
54
+ describe ".validates_uniqueness_of" do
55
+ before { Validatable.validates_uniqueness_of :title, solr_name: "title_ssi" }
56
+ it "should add a uniqueness validator" do
57
+ expect(subject).to be_a Hydra::Validations::UniquenessValidator
58
+ expect(subject.attributes).to eq [:title]
59
+ expect(subject.options).to include({ solr_name: "title_ssi" })
60
+ end
61
+ end
62
+
63
+ end
@@ -1,21 +1,6 @@
1
1
  require 'spec_helper'
2
2
  require 'support/shared_examples_for_validators'
3
3
 
4
- shared_examples "it validates the uniqueness of the attribute value" do
5
- context "when the value is not taken" do
6
- before { allow(Validatable).to receive(:exists?).with(conditions) { false } }
7
- it "should be valid" do
8
- expect(subject).to be_valid
9
- end
10
- end
11
- context "when the value is taken" do
12
- before { allow(Validatable).to receive(:exists?).with(conditions) { true } }
13
- it "should not be valid" do
14
- expect(subject).not_to be_valid
15
- end
16
- end
17
- end
18
-
19
4
  describe Hydra::Validations::UniquenessValidator do
20
5
 
21
6
  before(:all) do
@@ -41,8 +26,9 @@ describe Hydra::Validations::UniquenessValidator do
41
26
 
42
27
  after(:all) { Object.send(:remove_const, :Validatable) }
43
28
 
29
+ before(:each) { Validatable.clear_validators! }
30
+
44
31
  describe "exceptions" do
45
- before { Validatable.clear_validators! }
46
32
  it "cannot be used on more than one attribute at a time" do
47
33
  expect { Validatable.validates :title, :source, uniqueness: { solr_name: "snafu_ssim" } }.to raise_error
48
34
  end
@@ -52,18 +38,26 @@ describe Hydra::Validations::UniquenessValidator do
52
38
  end
53
39
 
54
40
  describe "validation" do
41
+
55
42
  subject { Validatable.new(pid: "foobar:1", title: "I am Unique!", source: ["Outer Space"]) }
56
- context "with a scalar attribute (:multiple=>false)" do
57
- before(:all) do
58
- Validatable.clear_validators!
59
- Validatable.validates_uniqueness_of :title, solr_name: "title_ssi"
43
+
44
+ shared_examples "it validates the uniqueness of the attribute value" do
45
+ context "when the value is not taken" do
46
+ before { allow(Validatable).to receive(:exists?).with(conditions) { false } }
47
+ it "should be valid" do
48
+ expect(subject).to be_valid
49
+ end
60
50
  end
61
- context "cardinality validation" do
62
- before { allow(Validatable).to receive(:exists?) { false } }
63
- it_behaves_like "it validates the single cardinality of a scalar attribute" do
64
- let(:attribute) { :title }
51
+ context "when the value is taken" do
52
+ before { allow(Validatable).to receive(:exists?).with(conditions) { true } }
53
+ it "should not be valid" do
54
+ expect(subject).not_to be_valid
65
55
  end
66
56
  end
57
+ end
58
+
59
+ context "with a scalar attribute (:multiple=>false)" do
60
+ before { Validatable.validates :title, uniqueness: { solr_name: "title_ssi" } }
67
61
  context "when the record is new" do
68
62
  before { allow(subject).to receive(:persisted?) { false } }
69
63
  it_behaves_like "it validates the uniqueness of the attribute value" do
@@ -77,17 +71,9 @@ describe Hydra::Validations::UniquenessValidator do
77
71
  end
78
72
  end
79
73
  end
74
+
80
75
  context "with an enumerable attribute (:multiple=>true)" do
81
- before(:all) do
82
- Validatable.clear_validators!
83
- Validatable.validates_uniqueness_of :source, solr_name: "source_ssim"
84
- end
85
- context "cardinality validation" do
86
- before { allow(Validatable).to receive(:exists?) { false } }
87
- it_behaves_like "it validates the single cardinality of an enumerable attribute" do
88
- let(:attribute) { :source }
89
- end
90
- end
76
+ before { Validatable.validates :source, uniqueness: { solr_name: "source_ssim" } }
91
77
  context "when the record is new" do
92
78
  before { allow(subject).to receive(:persisted?) { false } }
93
79
  it_behaves_like "it validates the uniqueness of the attribute value" do
@@ -101,5 +87,6 @@ describe Hydra::Validations::UniquenessValidator do
101
87
  end
102
88
  end
103
89
  end
90
+
104
91
  end
105
92
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hydra-validations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dchandekstark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-08 00:00:00.000000000 Z
11
+ date: 2014-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -88,15 +88,15 @@ files:
88
88
  - lib/hydra/validations/enumerable_behavior.rb
89
89
  - lib/hydra/validations/format.rb
90
90
  - lib/hydra/validations/inclusion.rb
91
- - lib/hydra/validations/single_cardinality.rb
92
91
  - lib/hydra/validations/uniqueness.rb
93
92
  - lib/hydra/validations/version.rb
94
93
  - spec/spec_helper.rb
95
94
  - spec/support/shared_examples_for_validators.rb
96
- - spec/validators/format_validator_spec.rb
97
- - spec/validators/inclusion_validator_spec.rb
98
- - spec/validators/single_cardinality_validator_spec.rb
99
- - spec/validators/uniqueness_validator_spec.rb
95
+ - spec/validations/cardinality_validator_spec.rb
96
+ - spec/validations/format_validator_spec.rb
97
+ - spec/validations/helper_methods_spec.rb
98
+ - spec/validations/inclusion_validator_spec.rb
99
+ - spec/validations/uniqueness_validator_spec.rb
100
100
  homepage: https://github.com/duke-libraries/hydra-validations
101
101
  licenses:
102
102
  - APACHE2
@@ -125,7 +125,8 @@ summary: Validations for Hydra applications, based on ActiveModel::Validations
125
125
  test_files:
126
126
  - spec/spec_helper.rb
127
127
  - spec/support/shared_examples_for_validators.rb
128
- - spec/validators/format_validator_spec.rb
129
- - spec/validators/inclusion_validator_spec.rb
130
- - spec/validators/single_cardinality_validator_spec.rb
131
- - spec/validators/uniqueness_validator_spec.rb
128
+ - spec/validations/cardinality_validator_spec.rb
129
+ - spec/validations/format_validator_spec.rb
130
+ - spec/validations/helper_methods_spec.rb
131
+ - spec/validations/inclusion_validator_spec.rb
132
+ - spec/validations/uniqueness_validator_spec.rb
@@ -1,32 +0,0 @@
1
- require 'hydra/validations/cardinality'
2
-
3
- module Hydra
4
- module Validations
5
- #
6
- # SingleCardinalityValidator - validates that an enumerator value has size 0 or 1
7
- #
8
- # validates :myattr, single_cardinality: true
9
- # validates_single_cardinality_of :myattr
10
- #
11
- # Blank and nil values are considered valid (even without :allow_blank or :allow_nil
12
- # validator options).
13
- #
14
- class SingleCardinalityValidator < ActiveModel::EachValidator
15
-
16
- include Cardinality
17
-
18
- def validate_each(record, attribute, value)
19
- validate_cardinality(:single, record, attribute, value)
20
- end
21
-
22
- end
23
-
24
- module HelperMethods
25
- def validates_single_cardinality_of *attr_names
26
- validates_with SingleCardinalityValidator, _merge_attributes(attr_names)
27
- end
28
- end
29
-
30
- end
31
- end
32
-
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/shared_examples_for_validators'
3
-
4
- shared_examples "it validates the format of each member of the attribute value" do
5
- context "all attribute value members are valid" do
6
- before { record.field = ["foo", "bar"] }
7
- it "should be valid" do
8
- expect(record).to be_valid
9
- end
10
- end
11
-
12
- context "one of the attribute value members is invalid" do
13
- before { record.field = ["foo1", "bar"] }
14
- it "should be invalid" do
15
- expect(record).to be_invalid
16
- end
17
- it "should 'fix' the error message to include the value" do
18
- record.valid?
19
- expect(record.errors[:field]).to eq ["value \"foo1\" is invalid"]
20
- end
21
- end
22
- end
23
-
24
- describe Hydra::Validations::FormatValidator do
25
-
26
- before(:all) do
27
- class Validatable
28
- include ActiveModel::Validations
29
- include Hydra::Validations
30
- attr_accessor :field
31
- end
32
- end
33
-
34
- before(:each) { Validatable.clear_validators! }
35
-
36
- after(:all) { Object.send(:remove_const, :Validatable) }
37
-
38
- describe "class methods" do
39
- describe ".validates" do
40
- before { Validatable.validates :field, format: { with: /\A[[:alpha:]]+\Z/ } }
41
- it_behaves_like "it validates the format of each member of the attribute value" do
42
- let(:record) { Validatable.new }
43
- end
44
- end
45
- end
46
- describe "helper methods" do
47
- describe ".validates_format_of" do
48
- before { Validatable.validates_format_of :field, with: /\A[[:alpha:]]+\Z/ }
49
- it_behaves_like "it validates the format of each member of the attribute value" do
50
- let(:record) { Validatable.new }
51
- end
52
- end
53
- end
54
-
55
- it_behaves_like "an enumerable validator" do
56
- let(:options) { { format: { with: /\A[[:alpha:]]+\Z/ } } }
57
- let(:record_class) { Validatable }
58
- let(:attribute) { :field }
59
- end
60
-
61
- end
@@ -1,33 +0,0 @@
1
- require 'spec_helper'
2
- require 'support/shared_examples_for_validators'
3
-
4
- shared_examples "it validates the single cardinality of the attribute" do
5
- it_behaves_like "it validates the single cardinality of a scalar attribute"
6
- it_behaves_like "it validates the single cardinality of an enumerable attribute"
7
- end
8
-
9
- describe Hydra::Validations::SingleCardinalityValidator do
10
- before(:all) do
11
- class Validatable
12
- include ActiveModel::Validations
13
- include Hydra::Validations
14
- attr_accessor :field
15
- end
16
- end
17
- before(:each) { Validatable.clear_validators! }
18
- after(:all) { Object.send(:remove_const, :Validatable) }
19
- subject { Validatable.new }
20
- describe ".validates" do
21
- before { Validatable.validates :field, single_cardinality: true }
22
- it_behaves_like "it validates the single cardinality of the attribute" do
23
- let(:attribute) { :field }
24
- end
25
- end
26
- describe ".validates_single_cardinality_of" do
27
- before { Validatable.validates_single_cardinality_of :field }
28
- it_behaves_like "it validates the single cardinality of the attribute" do
29
- let(:attribute) { :field }
30
- end
31
- end
32
- end
33
-