shoulda-matchers 2.4.0 → 2.5.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 +4 -4
- data/.travis.yml +7 -4
- data/Appraisals +19 -7
- data/Gemfile.lock +1 -1
- data/NEWS.md +35 -0
- data/README.md +1204 -46
- data/features/step_definitions/rails_steps.rb +1 -1
- data/gemfiles/3.0.gemfile.lock +1 -1
- data/gemfiles/3.1.gemfile.lock +1 -1
- data/gemfiles/3.2.gemfile.lock +1 -1
- data/gemfiles/{4.0.gemfile → 4.0.0.gemfile} +4 -4
- data/gemfiles/{4.0.gemfile.lock → 4.0.0.gemfile.lock} +24 -24
- data/gemfiles/4.0.1.gemfile +19 -0
- data/gemfiles/4.0.1.gemfile.lock +161 -0
- data/lib/shoulda/matchers/action_controller.rb +1 -0
- data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +4 -2
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +6 -3
- data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +6 -3
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +4 -2
- data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +4 -2
- data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +4 -2
- data/lib/shoulda/matchers/action_controller/route_matcher.rb +13 -19
- data/lib/shoulda/matchers/action_controller/route_params.rb +47 -0
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +4 -2
- data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +4 -2
- data/lib/shoulda/matchers/active_model.rb +4 -3
- data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +9 -6
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +4 -2
- data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +6 -4
- data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +4 -1
- data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +8 -1
- data/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +4 -2
- data/lib/shoulda/matchers/active_model/numericality_matchers/comparison_matcher.rb +59 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/odd_even_number_matcher.rb +51 -0
- data/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +41 -0
- data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +77 -0
- data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +14 -12
- data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +6 -6
- data/lib/shoulda/matchers/active_model/validation_matcher.rb +10 -7
- data/lib/shoulda/matchers/active_record.rb +2 -0
- data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +4 -2
- data/lib/shoulda/matchers/active_record/association_matcher.rb +11 -3
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +80 -0
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +20 -55
- data/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +40 -0
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +4 -2
- data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +4 -2
- data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +7 -4
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +4 -2
- data/lib/shoulda/matchers/integrations/test_unit.rb +3 -3
- data/lib/shoulda/matchers/rails_shim.rb +14 -6
- data/lib/shoulda/matchers/version.rb +1 -1
- data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +1 -1
- data/spec/shoulda/matchers/action_controller/rescue_from_matcher_spec.rb +2 -2
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +5 -0
- data/spec/shoulda/matchers/action_controller/route_params_spec.rb +30 -0
- data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +1 -1
- data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +1 -1
- data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +2 -2
- data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +10 -0
- data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +7 -0
- data/spec/shoulda/matchers/active_model/{comparison_matcher_spec.rb → numericality_matchers/comparison_matcher_spec.rb} +2 -2
- data/spec/shoulda/matchers/active_model/{odd_even_number_matcher_spec.rb → numericality_matchers/odd_even_number_matcher_spec.rb} +4 -4
- data/spec/shoulda/matchers/active_model/{only_integer_matcher_spec.rb → numericality_matchers/only_integer_matcher_spec.rb} +3 -3
- data/spec/shoulda/matchers/active_model/validate_absence_of_matcher_spec.rb +139 -0
- data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +7 -7
- data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +48 -38
- data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +6 -6
- data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +21 -8
- data/spec/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +247 -0
- data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +1 -1
- data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +3 -3
- data/spec/spec_helper.rb +9 -15
- data/spec/support/active_resource_builder.rb +2 -0
- data/spec/support/controller_builder.rb +4 -10
- data/spec/support/model_builder.rb +6 -2
- data/spec/support/rails_versions.rb +18 -0
- data/spec/support/shared_examples/numerical_submatcher_spec.rb +4 -4
- data/spec/support/test_application.rb +97 -0
- metadata +30 -14
- data/lib/shoulda/matchers/active_model/comparison_matcher.rb +0 -57
- data/lib/shoulda/matchers/active_model/odd_even_number_matcher.rb +0 -47
- data/lib/shoulda/matchers/active_model/only_integer_matcher.rb +0 -37
@@ -98,6 +98,13 @@ describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
+
context 'an attribute with a custom equal validation' do
|
102
|
+
it 'accepts ensuring the correct exact length' do
|
103
|
+
validating_length(:is => 4, :message => 'foobar').
|
104
|
+
should ensure_length_of(:attr).is_equal_to(4).with_message(/foo/)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
101
108
|
context 'an attribute without a length validation' do
|
102
109
|
it 'rejects ensuring a minimum length' do
|
103
110
|
define_model(:example, :attr => :string).new.
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveModel::ComparisonMatcher do
|
3
|
+
describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::ComparisonMatcher do
|
4
4
|
it_behaves_like 'a numerical submatcher' do
|
5
|
-
subject {
|
5
|
+
subject { described_class.new(0, :>) }
|
6
6
|
end
|
7
7
|
|
8
8
|
context 'is_greater_than' do
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveModel::OddEvenNumberMatcher do
|
3
|
+
describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::OddEvenNumberMatcher do
|
4
4
|
it_behaves_like 'a numerical submatcher' do
|
5
|
-
subject {
|
5
|
+
subject { described_class.new(:attr) }
|
6
6
|
end
|
7
7
|
|
8
8
|
context 'given an attribute that only allows odd number values' do
|
@@ -57,7 +57,7 @@ describe Shoulda::Matchers::ActiveModel::OddEvenNumberMatcher do
|
|
57
57
|
|
58
58
|
matcher.matches?(define_model(:example, :attr => :string).new)
|
59
59
|
|
60
|
-
matcher.
|
60
|
+
matcher.failure_message.should include 'Expected errors to include "must be odd"'
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
@@ -71,7 +71,7 @@ describe Shoulda::Matchers::ActiveModel::OddEvenNumberMatcher do
|
|
71
71
|
|
72
72
|
matcher.matches?(define_model(:example, :attr => :string).new)
|
73
73
|
|
74
|
-
matcher.
|
74
|
+
matcher.failure_message.should include 'Expected errors to include "must be even"'
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
@@ -1,8 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
3
|
+
describe Shoulda::Matchers::ActiveModel::NumericalityMatchers::OnlyIntegerMatcher do
|
4
4
|
it_behaves_like 'a numerical submatcher' do
|
5
|
-
subject {
|
5
|
+
subject { described_class.new(:attr) }
|
6
6
|
end
|
7
7
|
|
8
8
|
context 'given an attribute that only allows integer values' do
|
@@ -40,7 +40,7 @@ describe Shoulda::Matchers::ActiveModel::OnlyIntegerMatcher do
|
|
40
40
|
|
41
41
|
matcher.matches?(define_model(:example, :attr => :string).new)
|
42
42
|
|
43
|
-
matcher.
|
43
|
+
matcher.failure_message.should include 'Expected errors to include "must be an integer"'
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoulda::Matchers::ActiveModel::ValidateAbsenceOfMatcher do
|
4
|
+
if active_model_4_0?
|
5
|
+
context 'a model with an absence validation' do
|
6
|
+
it 'accepts' do
|
7
|
+
validating_absence_of(:attr).should validate_absence_of(:attr)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'does not override the default message with a present' do
|
11
|
+
validating_absence_of(:attr).should validate_absence_of(:attr).with_message(nil)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'a model without an absence validation' do
|
16
|
+
it 'rejects' do
|
17
|
+
model = define_model(:example, attr: :string).new
|
18
|
+
model.should_not validate_absence_of(:attr)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'an ActiveModel class with an absence validation' do
|
23
|
+
it 'accepts' do
|
24
|
+
active_model_validating_absence_of(:attr).should validate_absence_of(:attr)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'does not override the default message with a blank' do
|
28
|
+
active_model_validating_absence_of(:attr).should validate_absence_of(:attr).with_message(nil)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'an ActiveModel class without an absence validation' do
|
33
|
+
it 'rejects' do
|
34
|
+
active_model_with(:attr).should_not validate_absence_of(:attr)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'provides the correct failure message' do
|
38
|
+
message = %{Expected errors to include "must be blank" when attr is set to "an arbitrary value", got no errors}
|
39
|
+
|
40
|
+
expect { active_model_with(:attr).should validate_absence_of(:attr) }.to fail_with_message(message)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'a has_many association with an absence validation' do
|
45
|
+
it 'requires the attribute to not be set' do
|
46
|
+
having_many(:children, absence: true).should validate_absence_of(:children)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'a has_many association without an absence validation' do
|
51
|
+
it 'does not require the attribute to not be set' do
|
52
|
+
having_many(:children, absence: false).
|
53
|
+
should_not validate_absence_of(:children)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'an absent has_and_belongs_to_many association' do
|
58
|
+
it 'accepts' do
|
59
|
+
model = having_and_belonging_to_many(:children, absence: true)
|
60
|
+
model.should validate_absence_of(:children)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'a non-absent has_and_belongs_to_many association' do
|
65
|
+
it 'rejects' do
|
66
|
+
model = having_and_belonging_to_many(:children, absence: false)
|
67
|
+
model.should_not validate_absence_of(:children)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "an i18n translation containing %{attribute} and %{model}" do
|
72
|
+
after { I18n.backend.reload! }
|
73
|
+
|
74
|
+
it "does not raise an exception" do
|
75
|
+
stub_translation("activerecord.errors.messages.present",
|
76
|
+
"%{attribute} must be blank in a %{model}")
|
77
|
+
|
78
|
+
expect {
|
79
|
+
validating_absence_of(:attr).should validate_absence_of(:attr)
|
80
|
+
}.to_not raise_exception
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "an attribute with a context-dependent validation" do
|
85
|
+
context "without the validation context" do
|
86
|
+
it "does not match" do
|
87
|
+
validating_absence_of(:attr, on: :customisable).should_not validate_absence_of(:attr)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "with the validation context" do
|
92
|
+
it "matches" do
|
93
|
+
validating_absence_of(:attr, on: :customisable).should validate_absence_of(:attr).on(:customisable)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def validating_absence_of(attr, options = {})
|
99
|
+
define_model :example, attr => :string do
|
100
|
+
validates_absence_of attr, options
|
101
|
+
end.new
|
102
|
+
end
|
103
|
+
|
104
|
+
def active_model_with(attr, &block)
|
105
|
+
define_active_model_class('Example', accessors: [attr], &block).new
|
106
|
+
end
|
107
|
+
|
108
|
+
def active_model_validating_absence_of(attr)
|
109
|
+
active_model_with(attr) do
|
110
|
+
validates_absence_of attr
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def having_many(plural_name, options = {})
|
115
|
+
define_model plural_name.to_s.singularize
|
116
|
+
define_model :parent do
|
117
|
+
has_many plural_name
|
118
|
+
if options[:absence]
|
119
|
+
validates_absence_of plural_name
|
120
|
+
end
|
121
|
+
end.new
|
122
|
+
end
|
123
|
+
|
124
|
+
def having_and_belonging_to_many(plural_name, options = {})
|
125
|
+
create_table 'children_parents', id: false do |t|
|
126
|
+
t.integer "#{plural_name.to_s.singularize}_id"
|
127
|
+
t.integer :parent_id
|
128
|
+
end
|
129
|
+
|
130
|
+
define_model plural_name.to_s.singularize
|
131
|
+
define_model :parent do
|
132
|
+
has_and_belongs_to_many plural_name
|
133
|
+
if options[:absence]
|
134
|
+
validates_absence_of plural_name
|
135
|
+
end
|
136
|
+
end.new
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -27,7 +27,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
27
27
|
|
28
28
|
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
29
29
|
|
30
|
-
the_matcher.
|
30
|
+
the_matcher.failure_message_when_negated.should include 'Did not expect errors to include "is not a number"'
|
31
31
|
end
|
32
32
|
|
33
33
|
it 'rejects with the ActiveRecord :not_an_integer message' do
|
@@ -35,7 +35,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
35
35
|
|
36
36
|
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
37
37
|
|
38
|
-
the_matcher.
|
38
|
+
the_matcher.failure_message.should include 'Expected errors to include "must be an integer"'
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'rejects with the ActiveRecord :odd message' do
|
@@ -43,7 +43,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
43
43
|
|
44
44
|
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
45
45
|
|
46
|
-
the_matcher.
|
46
|
+
the_matcher.failure_message.should include 'Expected errors to include "must be odd"'
|
47
47
|
end
|
48
48
|
|
49
49
|
it 'rejects with the ActiveRecord :even message' do
|
@@ -51,7 +51,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
51
51
|
|
52
52
|
the_matcher.matches?(define_model(:example, :attr => :string).new)
|
53
53
|
|
54
|
-
the_matcher.
|
54
|
+
the_matcher.failure_message.should include 'Expected errors to include "must be even"'
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -69,7 +69,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
69
69
|
|
70
70
|
the_matcher.matches?(validating_numericality)
|
71
71
|
|
72
|
-
the_matcher.
|
72
|
+
the_matcher.failure_message.should include 'Expected errors to include "must be an integer"'
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
@@ -87,7 +87,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
87
87
|
|
88
88
|
the_matcher.matches?(validating_numericality)
|
89
89
|
|
90
|
-
the_matcher.
|
90
|
+
the_matcher.failure_message.should include 'Expected errors to include "must be odd"'
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
@@ -105,7 +105,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
105
105
|
|
106
106
|
the_matcher.matches?(validating_numericality)
|
107
107
|
|
108
|
-
the_matcher.
|
108
|
+
the_matcher.failure_message.should include 'Expected errors to include "must be even"'
|
109
109
|
end
|
110
110
|
end
|
111
111
|
|
@@ -3,13 +3,23 @@ require 'spec_helper'
|
|
3
3
|
describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
4
4
|
context 'a model without a a uniqueness validation' do
|
5
5
|
it 'rejects' do
|
6
|
-
model = define_model(:example, :
|
7
|
-
Example.create!(:
|
6
|
+
model = define_model(:example, attr: :string) { attr_accessible :attr } .new
|
7
|
+
Example.create!(attr: 'value')
|
8
8
|
model.should_not matcher
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
context 'a model with a uniqueness validation' do
|
13
|
+
context 'where the subject has a character limit' do
|
14
|
+
it 'tests with values within the character limit' do
|
15
|
+
model = define_model(:example, attr: { type: :string, options: { limit: 1 } }) do
|
16
|
+
attr_accessible :attr
|
17
|
+
validates_uniqueness_of :attr
|
18
|
+
end.new
|
19
|
+
model.should matcher
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
13
23
|
context 'with an existing record' do
|
14
24
|
it 'requires a unique value for that attribute' do
|
15
25
|
create_existing
|
@@ -27,7 +37,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
27
37
|
|
28
38
|
def create_existing
|
29
39
|
define_model_with_other
|
30
|
-
Example.create!(:
|
40
|
+
Example.create!(attr: 'value', other: 1)
|
31
41
|
end
|
32
42
|
end
|
33
43
|
|
@@ -40,7 +50,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
40
50
|
end
|
41
51
|
|
42
52
|
def define_model_with_other(options = {})
|
43
|
-
@model ||= define_model(:example, :
|
53
|
+
@model ||= define_model(:example, attr: :string, other: :integer) do
|
44
54
|
attr_accessible :attr, :other
|
45
55
|
validates_uniqueness_of :attr, options
|
46
56
|
end
|
@@ -53,26 +63,26 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
53
63
|
|
54
64
|
context 'a model with a uniqueness validation, a custom error, and an existing record' do
|
55
65
|
it 'rejects when the actual message does not match the default message' do
|
56
|
-
validating_uniqueness_with_existing_record(:
|
66
|
+
validating_uniqueness_with_existing_record(message: 'Bad value').
|
57
67
|
should_not matcher
|
58
68
|
end
|
59
69
|
|
60
70
|
it 'rejects when the messages do not match' do
|
61
|
-
validating_uniqueness_with_existing_record(:
|
71
|
+
validating_uniqueness_with_existing_record(message: 'Bad value').
|
62
72
|
should_not matcher.with_message(/abc/)
|
63
73
|
end
|
64
74
|
|
65
75
|
it 'accepts when the messages match' do
|
66
|
-
validating_uniqueness_with_existing_record(:
|
76
|
+
validating_uniqueness_with_existing_record(message: 'Bad value').
|
67
77
|
should matcher.with_message(/Bad/)
|
68
78
|
end
|
69
79
|
|
70
80
|
def validating_uniqueness_with_existing_record(options = {})
|
71
|
-
model = define_model(:example, :
|
81
|
+
model = define_model(:example, attr: :string) do
|
72
82
|
attr_accessible :attr
|
73
83
|
validates_uniqueness_of :attr, options
|
74
84
|
end.new
|
75
|
-
Example.create!(:
|
85
|
+
Example.create!(attr: 'value')
|
76
86
|
model
|
77
87
|
end
|
78
88
|
end
|
@@ -114,27 +124,27 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
114
124
|
|
115
125
|
context 'when the scoped attribute is a date' do
|
116
126
|
it "accepts" do
|
117
|
-
validating_scoped_uniqueness([:scope1], :date, :
|
127
|
+
validating_scoped_uniqueness([:scope1], :date, scope1: Date.today).
|
118
128
|
should matcher.scoped_to(:scope1)
|
119
129
|
end
|
120
130
|
|
121
131
|
context 'with an existing record that conflicts with scope.next' do
|
122
132
|
it 'accepts' do
|
123
|
-
validating_scoped_uniqueness_with_conflicting_next(:scope1, :date, :
|
133
|
+
validating_scoped_uniqueness_with_conflicting_next(:scope1, :date, scope1: Date.today).
|
124
134
|
should matcher.scoped_to(:scope1)
|
125
135
|
end
|
126
136
|
end
|
127
137
|
|
128
138
|
context 'when too narrow of a scope is specified' do
|
129
139
|
it 'rejects' do
|
130
|
-
validating_scoped_uniqueness([:scope1, :scope2], :date, :
|
140
|
+
validating_scoped_uniqueness([:scope1, :scope2], :date, scope1: Date.today, scope2: Date.today).
|
131
141
|
should_not matcher.scoped_to(:scope1, :scope2, :other)
|
132
142
|
end
|
133
143
|
end
|
134
144
|
|
135
145
|
context 'when too broad of a scope is specified' do
|
136
146
|
it 'rejects' do
|
137
|
-
validating_scoped_uniqueness([:scope1, :scope2], :date, :
|
147
|
+
validating_scoped_uniqueness([:scope1, :scope2], :date, scope1: Date.today, scope2: Date.today).
|
138
148
|
should_not matcher.scoped_to(:scope1)
|
139
149
|
end
|
140
150
|
end
|
@@ -142,34 +152,34 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
142
152
|
|
143
153
|
context 'when the scoped attribute is a datetime' do
|
144
154
|
it 'accepts' do
|
145
|
-
validating_scoped_uniqueness([:scope1], :datetime, :
|
155
|
+
validating_scoped_uniqueness([:scope1], :datetime, scope1: DateTime.now).
|
146
156
|
should matcher.scoped_to(:scope1)
|
147
157
|
end
|
148
158
|
|
149
159
|
context 'with an existing record that conflicts with scope.next' do
|
150
160
|
it 'accepts' do
|
151
|
-
validating_scoped_uniqueness_with_conflicting_next(:scope1, :datetime, :
|
161
|
+
validating_scoped_uniqueness_with_conflicting_next(:scope1, :datetime, scope1: DateTime.now).
|
152
162
|
should matcher.scoped_to(:scope1)
|
153
163
|
end
|
154
164
|
end
|
155
165
|
|
156
166
|
context 'with a nil value' do
|
157
167
|
it 'accepts' do
|
158
|
-
validating_scoped_uniqueness([:scope1], :datetime, :
|
168
|
+
validating_scoped_uniqueness([:scope1], :datetime, scope1: nil).
|
159
169
|
should matcher.scoped_to(:scope1)
|
160
170
|
end
|
161
171
|
end
|
162
172
|
|
163
173
|
context 'when too narrow of a scope is specified' do
|
164
174
|
it 'rejects' do
|
165
|
-
validating_scoped_uniqueness([:scope1, :scope2], :datetime, :
|
175
|
+
validating_scoped_uniqueness([:scope1, :scope2], :datetime, scope1: DateTime.now, scope2: DateTime.now).
|
166
176
|
should_not matcher.scoped_to(:scope1, :scope2, :other)
|
167
177
|
end
|
168
178
|
end
|
169
179
|
|
170
180
|
context 'when too broad of a scope is specified' do
|
171
181
|
it 'rejects' do
|
172
|
-
validating_scoped_uniqueness([:scope1, :scope2], :datetime, :
|
182
|
+
validating_scoped_uniqueness([:scope1, :scope2], :datetime, scope1: DateTime.now, scope2: DateTime.now).
|
173
183
|
should_not matcher.scoped_to(:scope1)
|
174
184
|
end
|
175
185
|
end
|
@@ -177,20 +187,20 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
177
187
|
|
178
188
|
context 'when the scoped attribute is a uuid' do
|
179
189
|
it 'accepts' do
|
180
|
-
validating_scoped_uniqueness([:scope1], :uuid, :
|
190
|
+
validating_scoped_uniqueness([:scope1], :uuid, scope1: SecureRandom.uuid).
|
181
191
|
should matcher.scoped_to(:scope1)
|
182
192
|
end
|
183
193
|
|
184
194
|
context 'with an existing record that conflicts with scope.next' do
|
185
195
|
it 'accepts' do
|
186
|
-
validating_scoped_uniqueness_with_conflicting_next(:scope1, :uuid, :
|
196
|
+
validating_scoped_uniqueness_with_conflicting_next(:scope1, :uuid, scope1: SecureRandom.uuid).
|
187
197
|
should matcher.scoped_to(:scope1)
|
188
198
|
end
|
189
199
|
end
|
190
200
|
|
191
201
|
context 'with a nil value' do
|
192
202
|
it 'accepts' do
|
193
|
-
validating_scoped_uniqueness([:scope1], :uuid, :
|
203
|
+
validating_scoped_uniqueness([:scope1], :uuid, scope1: nil).
|
194
204
|
should matcher.scoped_to(:scope1)
|
195
205
|
end
|
196
206
|
end
|
@@ -198,8 +208,8 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
198
208
|
context 'when too narrow of a scope is specified' do
|
199
209
|
it 'rejects' do
|
200
210
|
record = validating_scoped_uniqueness([:scope1, :scope2], :uuid,
|
201
|
-
:
|
202
|
-
:
|
211
|
+
scope1: SecureRandom.uuid,
|
212
|
+
scope2: SecureRandom.uuid
|
203
213
|
)
|
204
214
|
record.should_not matcher.scoped_to(:scope1, :scope2, :other)
|
205
215
|
end
|
@@ -208,8 +218,8 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
208
218
|
context 'when too broad of a scope is specified' do
|
209
219
|
it 'rejects' do
|
210
220
|
record = validating_scoped_uniqueness([:scope1, :scope2], :uuid,
|
211
|
-
:
|
212
|
-
:
|
221
|
+
scope1: SecureRandom.uuid,
|
222
|
+
scope2: SecureRandom.uuid
|
213
223
|
)
|
214
224
|
record.should_not matcher.scoped_to(:scope1)
|
215
225
|
end
|
@@ -221,15 +231,15 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
221
231
|
end
|
222
232
|
|
223
233
|
def create_record(attributes = {})
|
224
|
-
default_attributes = {:
|
234
|
+
default_attributes = {attr: 'value', scope1: 1, scope2: 2, other: 3}
|
225
235
|
Example.create!(default_attributes.merge(attributes))
|
226
236
|
end
|
227
237
|
|
228
238
|
def define_scoped_model(scope, scope_attr_type = :integer)
|
229
|
-
define_model(:example, :
|
230
|
-
:
|
239
|
+
define_model(:example, attr: :string, scope1: scope_attr_type,
|
240
|
+
scope2: scope_attr_type, other: :integer) do
|
231
241
|
attr_accessible :attr, :scope1, :scope2, :other
|
232
|
-
validates_uniqueness_of :attr, :
|
242
|
+
validates_uniqueness_of :attr, scope: scope
|
233
243
|
end
|
234
244
|
end
|
235
245
|
|
@@ -278,7 +288,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
278
288
|
context "when there is an existing entry with a nil" do
|
279
289
|
it "should allow_nil" do
|
280
290
|
model = define_model_with_allow_nil
|
281
|
-
Example.create!(:
|
291
|
+
Example.create!(attr: nil)
|
282
292
|
model.should matcher.allow_nil
|
283
293
|
end
|
284
294
|
end
|
@@ -290,9 +300,9 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
290
300
|
end
|
291
301
|
|
292
302
|
def define_model_with_allow_nil
|
293
|
-
define_model(:example, :
|
303
|
+
define_model(:example, attr: :integer) do
|
294
304
|
attr_accessible :attr
|
295
|
-
validates_uniqueness_of :attr, :
|
305
|
+
validates_uniqueness_of :attr, allow_nil: true
|
296
306
|
end.new
|
297
307
|
end
|
298
308
|
end
|
@@ -301,7 +311,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
301
311
|
context "when there is an existing entry with a nil" do
|
302
312
|
it "should not allow_nil" do
|
303
313
|
model = define_model_without_allow_nil
|
304
|
-
Example.create!(:
|
314
|
+
Example.create!(attr: nil)
|
305
315
|
model.should_not matcher.allow_nil
|
306
316
|
end
|
307
317
|
end
|
@@ -312,7 +322,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
312
322
|
end
|
313
323
|
|
314
324
|
def define_model_without_allow_nil
|
315
|
-
define_model(:example, :
|
325
|
+
define_model(:example, attr: :integer) do
|
316
326
|
attr_accessible :attr
|
317
327
|
validates_uniqueness_of :attr
|
318
328
|
end.new
|
@@ -320,14 +330,14 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
320
330
|
end
|
321
331
|
|
322
332
|
def case_sensitive_validation_with_existing_value(attr_type)
|
323
|
-
model = define_model(:example, :
|
333
|
+
model = define_model(:example, attr: attr_type) do
|
324
334
|
attr_accessible :attr
|
325
|
-
validates_uniqueness_of :attr, :
|
335
|
+
validates_uniqueness_of :attr, case_sensitive: true
|
326
336
|
end.new
|
327
337
|
if attr_type == :string
|
328
|
-
Example.create!(:
|
338
|
+
Example.create!(attr: 'value')
|
329
339
|
elsif attr_type == :integer
|
330
|
-
Example.create!(:
|
340
|
+
Example.create!(attr: 1)
|
331
341
|
else
|
332
342
|
raise 'Must be :string or :integer'
|
333
343
|
end
|