shoulda-matchers 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|