shoulda-matchers 2.7.0 → 2.8.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +13 -3
- data/Appraisals +18 -0
- data/CONTRIBUTING.md +13 -29
- data/Gemfile +1 -4
- data/Gemfile.lock +2 -10
- data/NEWS.md +100 -14
- data/README.md +62 -58
- data/Rakefile +9 -16
- data/gemfiles/3.0.gemfile +11 -12
- data/gemfiles/3.0.gemfile.lock +15 -10
- data/gemfiles/3.1.gemfile +11 -12
- data/gemfiles/3.1.gemfile.lock +14 -10
- data/gemfiles/3.1_1.9.2.gemfile +12 -11
- data/gemfiles/3.1_1.9.2.gemfile.lock +14 -3
- data/gemfiles/3.2.gemfile +11 -12
- data/gemfiles/3.2.gemfile.lock +15 -10
- data/gemfiles/3.2_1.9.2.gemfile +12 -11
- data/gemfiles/3.2_1.9.2.gemfile.lock +14 -2
- data/gemfiles/4.0.0.gemfile +10 -12
- data/gemfiles/4.0.0.gemfile.lock +13 -10
- data/gemfiles/4.0.1.gemfile +10 -12
- data/gemfiles/4.0.1.gemfile.lock +13 -10
- data/gemfiles/4.1.gemfile +13 -15
- data/gemfiles/4.1.gemfile.lock +45 -50
- data/gemfiles/4.2.gemfile +36 -0
- data/gemfiles/4.2.gemfile.lock +245 -0
- data/lib/shoulda/matchers.rb +3 -1
- data/lib/shoulda/matchers/action_controller.rb +1 -1
- data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
- data/lib/shoulda/matchers/action_controller/route_params.rb +9 -4
- data/lib/shoulda/matchers/action_controller/{set_the_flash_matcher.rb → set_flash_matcher.rb} +34 -26
- data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +125 -69
- data/lib/shoulda/matchers/active_model.rb +1 -2
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +18 -5
- data/lib/shoulda/matchers/active_model/exception_message_finder.rb +2 -2
- data/lib/shoulda/matchers/active_model/helpers.rb +4 -4
- data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +10 -3
- data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +3 -1
- data/lib/shoulda/matchers/active_model/{ensure_length_of_matcher.rb → validate_length_of_matcher.rb} +30 -20
- data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +21 -0
- data/lib/shoulda/matchers/active_model/validation_message_finder.rb +2 -2
- data/lib/shoulda/matchers/active_record.rb +2 -0
- data/lib/shoulda/matchers/active_record/association_matcher.rb +96 -2
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +3 -3
- data/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +22 -2
- data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +30 -4
- data/lib/shoulda/matchers/active_record/serialize_matcher.rb +19 -3
- data/lib/shoulda/matchers/active_record/uniqueness.rb +14 -0
- data/lib/shoulda/matchers/active_record/uniqueness/model.rb +45 -0
- data/lib/shoulda/matchers/active_record/uniqueness/namespace.rb +36 -0
- data/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +50 -0
- data/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +24 -0
- data/lib/shoulda/matchers/{active_model → active_record}/validate_uniqueness_of_matcher.rb +76 -16
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +117 -51
- data/lib/shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error.rb +1 -1
- data/lib/shoulda/matchers/matcher_context.rb +35 -0
- data/lib/shoulda/matchers/rails_shim.rb +23 -0
- data/lib/shoulda/matchers/util.rb +28 -0
- data/lib/shoulda/matchers/version.rb +1 -1
- data/script/SUPPORTED_VERSIONS +1 -1
- data/spec/acceptance/active_model_integration_spec.rb +20 -0
- data/spec/acceptance/independent_matchers_spec.rb +64 -0
- data/spec/acceptance/rails_integration_spec.rb +142 -0
- data/spec/acceptance_spec_helper.rb +23 -0
- data/spec/support/acceptance/helpers.rb +29 -0
- data/spec/support/acceptance/helpers/active_model_helpers.rb +11 -0
- data/spec/support/acceptance/helpers/array_helpers.rb +13 -0
- data/spec/support/acceptance/helpers/base_helpers.rb +14 -0
- data/spec/support/acceptance/helpers/command_helpers.rb +51 -0
- data/spec/support/acceptance/helpers/file_helpers.rb +19 -0
- data/spec/support/acceptance/helpers/gem_helpers.rb +31 -0
- data/spec/support/acceptance/helpers/minitest_helpers.rb +19 -0
- data/spec/support/acceptance/helpers/pluralization_helpers.rb +13 -0
- data/spec/support/acceptance/helpers/rails_version_helpers.rb +11 -0
- data/spec/support/acceptance/helpers/rspec_helpers.rb +26 -0
- data/spec/support/acceptance/helpers/ruby_version_helpers.rb +9 -0
- data/spec/support/acceptance/helpers/step_helpers.rb +117 -0
- data/spec/support/acceptance/matchers/have_output.rb +31 -0
- data/spec/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +55 -0
- data/spec/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +103 -0
- data/spec/support/tests/bundle.rb +94 -0
- data/spec/support/tests/command_runner.rb +214 -0
- data/spec/support/tests/filesystem.rb +77 -0
- data/spec/support/tests/version.rb +45 -0
- data/spec/support/unit/capture.rb +34 -0
- data/spec/support/unit/helpers/active_model_helpers.rb +25 -0
- data/spec/support/unit/helpers/active_model_versions.rb +20 -0
- data/spec/support/unit/helpers/active_resource_builder.rb +27 -0
- data/spec/support/unit/helpers/allow_value_matcher_helpers.rb +15 -0
- data/spec/support/unit/helpers/class_builder.rb +72 -0
- data/spec/support/unit/helpers/confirmation_matcher_helpers.rb +17 -0
- data/spec/support/unit/helpers/controller_builder.rb +91 -0
- data/spec/support/unit/helpers/i18n_faker.rb +15 -0
- data/spec/support/unit/helpers/mailer_builder.rb +12 -0
- data/spec/support/unit/helpers/model_builder.rb +102 -0
- data/spec/support/unit/helpers/rails_versions.rb +28 -0
- data/spec/support/unit/i18n.rb +7 -0
- data/spec/support/unit/matchers/deprecate.rb +60 -0
- data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +50 -0
- data/spec/support/unit/matchers/fail_with_message_matcher.rb +50 -0
- data/spec/support/unit/matchers/print_warning_including.rb +59 -0
- data/spec/support/unit/rails_application.rb +110 -0
- data/spec/support/unit/record_builder_with_i18n_validation_message.rb +69 -0
- data/spec/support/unit/record_validating_confirmation_builder.rb +56 -0
- data/spec/support/unit/record_with_different_error_attribute_builder.rb +92 -0
- data/spec/support/{shared_examples → unit/shared_examples}/numerical_submatcher.rb +0 -2
- data/spec/support/{shared_examples → unit/shared_examples}/numerical_type_submatcher.rb +0 -2
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/callback_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/filter_param_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/redirect_to_matcher_spec.rb +3 -3
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/render_template_matcher_spec.rb +2 -4
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/render_with_layout_matcher_spec.rb +9 -6
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/rescue_from_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/respond_with_matcher_spec.rb +2 -2
- data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +126 -0
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/route_params_spec.rb +2 -2
- data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +167 -0
- data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +294 -0
- data/spec/{shoulda → unit/shoulda}/matchers/action_controller/strong_parameters_matcher_spec.rb +19 -11
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/allow_value_matcher_spec.rb +49 -21
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/disallow_value_matcher_spec.rb +8 -4
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/exception_message_finder_spec.rb +4 -4
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/have_secure_password_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/helpers_spec.rb +7 -3
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +1 -1
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +1 -1
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +1 -1
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +1 -1
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_absence_of_matcher_spec.rb +3 -3
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_acceptance_of_matcher_spec.rb +2 -2
- data/spec/unit/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +63 -0
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_exclusion_of_matcher_spec.rb +5 -4
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_inclusion_of_matcher_spec.rb +7 -14
- data/spec/{shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb → unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb} +43 -23
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_numericality_of_matcher_spec.rb +3 -4
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_presence_of_matcher_spec.rb +3 -3
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +127 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_model/validation_message_finder_spec.rb +8 -6
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/association_matcher_spec.rb +217 -26
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/association_matchers/model_reflection_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/define_enum_for_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_db_column_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_db_index_matcher_spec.rb +8 -5
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/have_readonly_attributes_matcher_spec.rb +2 -2
- data/spec/{shoulda → unit/shoulda}/matchers/active_record/serialize_matcher_spec.rb +3 -3
- data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_collection_spec.rb +29 -7
- data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_implementation_registry_spec.rb +1 -1
- data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/double_spec.rb +20 -10
- data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/object_double_spec.rb +1 -1
- data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/proxy_implementation_spec.rb +13 -6
- data/spec/{shoulda → unit/shoulda}/matchers/doublespeak/stub_implementation_spec.rb +2 -2
- data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +77 -0
- data/spec/{shoulda → unit/shoulda}/matchers/doublespeak_spec.rb +11 -3
- data/spec/{shoulda → unit/shoulda}/matchers/independent/delegate_method_matcher/stubbed_target_spec.rb +1 -1
- data/spec/unit/shoulda/matchers/independent/delegate_method_matcher_spec.rb +517 -0
- data/spec/unit_spec_helper.rb +66 -0
- data/spec/warnings_spy/partitioner.rb +10 -3
- data/spec/warnings_spy/reader.rb +9 -20
- data/spec/warnings_spy/reporter.rb +2 -1
- metadata +212 -149
- data/features/activemodel_integration.feature +0 -15
- data/features/rails_integration.feature +0 -160
- data/features/step_definitions/activemodel_steps.rb +0 -21
- data/features/step_definitions/rails_steps.rb +0 -227
- data/features/support/env.rb +0 -6
- data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +0 -70
- data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +0 -113
- data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +0 -153
- data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +0 -47
- data/spec/shoulda/matchers/doublespeak/world_spec.rb +0 -70
- data/spec/shoulda/matchers/independent/delegate_method_matcher_spec.rb +0 -309
- data/spec/spec_helper.rb +0 -42
- data/spec/support/active_model_versions.rb +0 -13
- data/spec/support/active_resource_builder.rb +0 -29
- data/spec/support/activemodel_helpers.rb +0 -23
- data/spec/support/capture_helpers.rb +0 -19
- data/spec/support/class_builder.rb +0 -46
- data/spec/support/controller_builder.rb +0 -102
- data/spec/support/fail_with_message_including_matcher.rb +0 -44
- data/spec/support/fail_with_message_matcher.rb +0 -44
- data/spec/support/i18n_faker.rb +0 -10
- data/spec/support/mailer_builder.rb +0 -10
- data/spec/support/model_builder.rb +0 -81
- data/spec/support/rails_versions.rb +0 -26
- data/spec/support/test_application.rb +0 -120
@@ -1,75 +1,93 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveModel
|
3
|
+
describe Shoulda::Matchers::ActiveModel, type: :model do
|
4
|
+
describe '#ensure_length_of' do
|
5
|
+
it 'is aliased to #validate_length_of' do
|
6
|
+
allow(matchers).to receive(:validate_length_of)
|
7
|
+
|
8
|
+
silence_warnings do
|
9
|
+
matchers.ensure_length_of(:attr)
|
10
|
+
expect(matchers).to have_received(:validate_length_of).with(:attr)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def matchers
|
16
|
+
@_matchers ||= Object.new.extend(described_class)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Shoulda::Matchers::ActiveModel::ValidateLengthOfMatcher, type: :model do
|
4
21
|
context 'an attribute with a non-zero minimum length validation' do
|
5
22
|
it 'accepts ensuring the correct minimum length' do
|
6
23
|
expect(validating_length(minimum: 4)).
|
7
|
-
to
|
24
|
+
to validate_length_of(:attr).is_at_least(4)
|
8
25
|
end
|
9
26
|
|
10
27
|
it 'rejects ensuring a lower minimum length with any message' do
|
11
28
|
expect(validating_length(minimum: 4)).
|
12
|
-
not_to
|
29
|
+
not_to validate_length_of(:attr).is_at_least(3).with_short_message(/.*/)
|
13
30
|
end
|
14
31
|
|
15
32
|
it 'rejects ensuring a higher minimum length with any message' do
|
16
33
|
expect(validating_length(minimum: 4)).
|
17
|
-
not_to
|
34
|
+
not_to validate_length_of(:attr).is_at_least(5).with_short_message(/.*/)
|
18
35
|
end
|
19
36
|
|
20
37
|
it 'does not override the default message with a blank' do
|
21
38
|
expect(validating_length(minimum: 4)).
|
22
|
-
to
|
39
|
+
to validate_length_of(:attr).is_at_least(4).with_short_message(nil)
|
23
40
|
end
|
24
41
|
end
|
25
42
|
|
26
43
|
context 'an attribute with a minimum length validation of 0' do
|
27
44
|
it 'accepts ensuring the correct minimum length' do
|
28
45
|
expect(validating_length(minimum: 0)).
|
29
|
-
to
|
46
|
+
to validate_length_of(:attr).is_at_least(0)
|
30
47
|
end
|
31
48
|
end
|
32
49
|
|
33
50
|
context 'an attribute with a maximum length' do
|
34
51
|
it 'accepts ensuring the correct maximum length' do
|
35
52
|
expect(validating_length(maximum: 4)).
|
36
|
-
to
|
53
|
+
to validate_length_of(:attr).is_at_most(4)
|
37
54
|
end
|
38
55
|
|
39
56
|
it 'rejects ensuring a lower maximum length with any message' do
|
40
57
|
expect(validating_length(maximum: 4)).
|
41
|
-
not_to
|
58
|
+
not_to validate_length_of(:attr).is_at_most(3).with_long_message(/.*/)
|
42
59
|
end
|
43
60
|
|
44
61
|
it 'rejects ensuring a higher maximum length with any message' do
|
45
62
|
expect(validating_length(maximum: 4)).
|
46
|
-
not_to
|
63
|
+
not_to validate_length_of(:attr).is_at_most(5).with_long_message(/.*/)
|
47
64
|
end
|
48
65
|
|
49
66
|
it 'does not override the default message with a blank' do
|
50
67
|
expect(validating_length(maximum: 4)).
|
51
|
-
to
|
68
|
+
to validate_length_of(:attr).is_at_most(4).with_long_message(nil)
|
52
69
|
end
|
53
70
|
end
|
54
71
|
|
55
72
|
context 'an attribute with a required exact length' do
|
56
73
|
it 'accepts ensuring the correct length' do
|
57
|
-
expect(validating_length(is: 4)).
|
74
|
+
expect(validating_length(is: 4)).
|
75
|
+
to validate_length_of(:attr).is_equal_to(4)
|
58
76
|
end
|
59
77
|
|
60
78
|
it 'rejects ensuring a lower maximum length with any message' do
|
61
79
|
expect(validating_length(is: 4)).
|
62
|
-
not_to
|
80
|
+
not_to validate_length_of(:attr).is_equal_to(3).with_message(/.*/)
|
63
81
|
end
|
64
82
|
|
65
83
|
it 'rejects ensuring a higher maximum length with any message' do
|
66
84
|
expect(validating_length(is: 4)).
|
67
|
-
not_to
|
85
|
+
not_to validate_length_of(:attr).is_equal_to(5).with_message(/.*/)
|
68
86
|
end
|
69
87
|
|
70
88
|
it 'does not override the default message with a blank' do
|
71
89
|
expect(validating_length(is: 4)).
|
72
|
-
to
|
90
|
+
to validate_length_of(:attr).is_equal_to(4).with_message(nil)
|
73
91
|
end
|
74
92
|
end
|
75
93
|
|
@@ -80,35 +98,35 @@ describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
|
80
98
|
validates_numericality_of :attr
|
81
99
|
end.new
|
82
100
|
|
83
|
-
expect(model).to
|
101
|
+
expect(model).to validate_length_of(:attr).is_equal_to(4)
|
84
102
|
end
|
85
103
|
end
|
86
104
|
|
87
105
|
context 'an attribute with a custom minimum length validation' do
|
88
106
|
it 'accepts ensuring the correct minimum length' do
|
89
107
|
expect(validating_length(minimum: 4, too_short: 'foobar')).
|
90
|
-
to
|
108
|
+
to validate_length_of(:attr).is_at_least(4).with_short_message(/foo/)
|
91
109
|
end
|
92
110
|
end
|
93
111
|
|
94
112
|
context 'an attribute with a custom maximum length validation' do
|
95
113
|
it 'accepts ensuring the correct minimum length' do
|
96
114
|
expect(validating_length(maximum: 4, too_long: 'foobar')).
|
97
|
-
to
|
115
|
+
to validate_length_of(:attr).is_at_most(4).with_long_message(/foo/)
|
98
116
|
end
|
99
117
|
end
|
100
118
|
|
101
119
|
context 'an attribute with a custom equal validation' do
|
102
120
|
it 'accepts ensuring the correct exact length' do
|
103
121
|
expect(validating_length(is: 4, message: 'foobar')).
|
104
|
-
to
|
122
|
+
to validate_length_of(:attr).is_equal_to(4).with_message(/foo/)
|
105
123
|
end
|
106
124
|
end
|
107
125
|
|
108
126
|
context 'an attribute without a length validation' do
|
109
127
|
it 'rejects ensuring a minimum length' do
|
110
128
|
expect(define_model(:example, attr: :string).new).
|
111
|
-
not_to
|
129
|
+
not_to validate_length_of(:attr).is_at_least(1)
|
112
130
|
end
|
113
131
|
end
|
114
132
|
|
@@ -124,7 +142,8 @@ describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
|
124
142
|
|
125
143
|
it "does not raise an exception" do
|
126
144
|
expect {
|
127
|
-
expect(validating_length(maximum: 4)).
|
145
|
+
expect(validating_length(maximum: 4)).
|
146
|
+
to validate_length_of(:attr).is_at_most(4)
|
128
147
|
}.to_not raise_exception
|
129
148
|
end
|
130
149
|
end
|
@@ -138,7 +157,7 @@ describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
|
138
157
|
|
139
158
|
it "does not raise an exception" do
|
140
159
|
expect {
|
141
|
-
expect(validating_length(minimum: 4)).to
|
160
|
+
expect(validating_length(minimum: 4)).to validate_length_of(:attr).is_at_least(4)
|
142
161
|
}.to_not raise_exception
|
143
162
|
end
|
144
163
|
end
|
@@ -152,7 +171,8 @@ describe Shoulda::Matchers::ActiveModel::EnsureLengthOfMatcher do
|
|
152
171
|
|
153
172
|
it "does not raise an exception" do
|
154
173
|
expect {
|
155
|
-
expect(validating_length(is: 4)).
|
174
|
+
expect(validating_length(is: 4)).
|
175
|
+
to validate_length_of(:attr).is_equal_to(4)
|
156
176
|
}.to_not raise_exception
|
157
177
|
end
|
158
178
|
end
|
data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_numericality_of_matcher_spec.rb
RENAMED
@@ -1,7 +1,6 @@
|
|
1
|
-
require '
|
2
|
-
|
3
|
-
describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
1
|
+
require 'unit_spec_helper'
|
4
2
|
|
3
|
+
describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher, type: :model do
|
5
4
|
context 'with a model with a numericality validation' do
|
6
5
|
it 'accepts' do
|
7
6
|
expect(validating_numericality).to matcher
|
@@ -278,7 +277,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
|
|
278
277
|
def set_attr!; self.attr = 5 end
|
279
278
|
end.new
|
280
279
|
|
281
|
-
subject.
|
280
|
+
allow(subject).to receive(:set_attr!)
|
282
281
|
expect(subject).to matcher.odd
|
283
282
|
end
|
284
283
|
end
|
data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_presence_of_matcher_spec.rb
RENAMED
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher do
|
3
|
+
describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher, type: :model do
|
4
4
|
context 'a model with a presence validation' do
|
5
5
|
it 'accepts' do
|
6
6
|
expect(validating_presence).to matcher
|
@@ -33,7 +33,7 @@ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'provides the correct failure message' do
|
36
|
-
message = %{Expected errors to include "can't be blank" when attr is set to nil
|
36
|
+
message = %{Expected errors to include "can't be blank" when attr is set to nil,\ngot no errors}
|
37
37
|
|
38
38
|
expect { expect(active_model).to matcher }.to fail_with_message(message)
|
39
39
|
end
|
data/spec/{shoulda → unit/shoulda}/matchers/active_model/validate_uniqueness_of_matcher_spec.rb
RENAMED
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::
|
3
|
+
describe Shoulda::Matchers::ActiveRecord::ValidateUniquenessOfMatcher, type: :model do
|
4
4
|
context 'a model without a a uniqueness validation' do
|
5
5
|
it 'rejects' do
|
6
6
|
model = define_model(:example, attr: :string) { attr_accessible :attr } .new
|
@@ -418,6 +418,131 @@ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
|
|
418
418
|
end
|
419
419
|
end
|
420
420
|
|
421
|
+
context 'when the validation allows blank' do
|
422
|
+
context 'when there is an existing record with a blank value' do
|
423
|
+
it 'accepts' do
|
424
|
+
model = model_allowing_blank
|
425
|
+
model.create!(attribute_name => '')
|
426
|
+
expect(model.new).to matcher.allow_blank
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
context 'when there is not an an existing record with a blank value' do
|
431
|
+
it 'still accepts' do
|
432
|
+
expect(record_allowing_blank).to matcher.allow_blank
|
433
|
+
end
|
434
|
+
|
435
|
+
it 'automatically creates a record' do
|
436
|
+
model = model_allowing_blank
|
437
|
+
matcher.allow_blank.matches?(model.new)
|
438
|
+
|
439
|
+
record_created = model.all.any? do |instance|
|
440
|
+
instance.__send__(attribute_name).blank?
|
441
|
+
end
|
442
|
+
|
443
|
+
expect(record_created).to be true
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
def attribute_name
|
448
|
+
:attr
|
449
|
+
end
|
450
|
+
|
451
|
+
def model_allowing_blank
|
452
|
+
_attribute_name = attribute_name
|
453
|
+
|
454
|
+
define_model(:example, attribute_name => :string) do
|
455
|
+
attr_accessible _attribute_name
|
456
|
+
validates_uniqueness_of _attribute_name, allow_blank: true
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
def record_allowing_blank
|
461
|
+
model_allowing_blank.new
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
context 'when the validation does not allow blank' do
|
466
|
+
context 'when there is an existing entry with a blank value' do
|
467
|
+
it 'rejects' do
|
468
|
+
model = model_disallowing_blank
|
469
|
+
model.create!(attribute_name => '')
|
470
|
+
expect(model.new).not_to matcher.allow_blank
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
it 'should not allow_blank' do
|
475
|
+
expect(record_disallowing_blank).not_to matcher.allow_blank
|
476
|
+
end
|
477
|
+
|
478
|
+
def attribute_name
|
479
|
+
:attr
|
480
|
+
end
|
481
|
+
|
482
|
+
def model_disallowing_blank
|
483
|
+
_attribute_name = attribute_name
|
484
|
+
|
485
|
+
define_model(:example, attribute_name => :string) do
|
486
|
+
attr_accessible _attribute_name
|
487
|
+
validates_uniqueness_of _attribute_name, allow_blank: false
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
def record_disallowing_blank
|
492
|
+
model_disallowing_blank.new
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
context "when testing that a polymorphic *_type column is one of the validation scopes" do
|
497
|
+
it "sets that column to a meaningful value that works with other validations on the same column" do
|
498
|
+
user_model = define_model :user
|
499
|
+
favorite_columns = {
|
500
|
+
favoriteable_id: { type: :integer, options: { null: false } },
|
501
|
+
favoriteable_type: { type: :string, options: { null: false } }
|
502
|
+
}
|
503
|
+
favorite_model = define_model :favorite, favorite_columns do
|
504
|
+
attr_accessible :favoriteable
|
505
|
+
belongs_to :favoriteable, polymorphic: true
|
506
|
+
validates :favoriteable, presence: true
|
507
|
+
validates :favoriteable_id, uniqueness: { scope: :favoriteable_type }
|
508
|
+
end
|
509
|
+
|
510
|
+
user = user_model.create!
|
511
|
+
favorite_model.create!(favoriteable: user)
|
512
|
+
new_favorite = favorite_model.new
|
513
|
+
|
514
|
+
expect(new_favorite).
|
515
|
+
to validate_uniqueness_of(:favoriteable_id).
|
516
|
+
scoped_to(:favoriteable_type)
|
517
|
+
end
|
518
|
+
|
519
|
+
context "if the model the *_type column refers to is namespaced, and shares the last part of its name with an existing model" do
|
520
|
+
it "still works" do
|
521
|
+
define_class 'User'
|
522
|
+
define_module 'Models'
|
523
|
+
user_model = define_model 'Models::User'
|
524
|
+
favorite_columns = {
|
525
|
+
favoriteable_id: { type: :integer, options: { null: false } },
|
526
|
+
favoriteable_type: { type: :string, options: { null: false } }
|
527
|
+
}
|
528
|
+
favorite_model = define_model 'Models::Favorite', favorite_columns do
|
529
|
+
attr_accessible :favoriteable
|
530
|
+
belongs_to :favoriteable, polymorphic: true
|
531
|
+
validates :favoriteable, presence: true
|
532
|
+
validates :favoriteable_id, uniqueness: { scope: :favoriteable_type }
|
533
|
+
end
|
534
|
+
|
535
|
+
user = user_model.create!
|
536
|
+
favorite_model.create!(favoriteable: user)
|
537
|
+
new_favorite = favorite_model.new
|
538
|
+
|
539
|
+
expect(new_favorite).
|
540
|
+
to validate_uniqueness_of(:favoriteable_id).
|
541
|
+
scoped_to(:favoriteable_type)
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
421
546
|
def case_sensitive_validation_with_existing_value(attr_type)
|
422
547
|
model = define_model(:example, attr: attr_type) do
|
423
548
|
attr_accessible :attr
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_spec_helper'
|
2
2
|
|
3
3
|
describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
|
4
4
|
context '#allow_description' do
|
@@ -67,8 +67,9 @@ describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
|
|
67
67
|
|
68
68
|
description = finder.messages_description
|
69
69
|
|
70
|
-
|
71
|
-
|
70
|
+
expect(description).to eq(
|
71
|
+
%{ errors:\n* "is invalid" (attribute: attr, value: "xyz")}
|
72
|
+
)
|
72
73
|
end
|
73
74
|
|
74
75
|
it 'describes errors when there are none' do
|
@@ -76,7 +77,7 @@ describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
|
|
76
77
|
|
77
78
|
description = finder.messages_description
|
78
79
|
|
79
|
-
expect(description).to eq 'no errors'
|
80
|
+
expect(description).to eq ' no errors'
|
80
81
|
end
|
81
82
|
|
82
83
|
it 'should not fetch attribute values for errors that were copied from an autosaved belongs_to association' do
|
@@ -87,8 +88,9 @@ describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
|
|
87
88
|
end.new
|
88
89
|
finder = Shoulda::Matchers::ActiveModel::ValidationMessageFinder.new(instance, :attribute)
|
89
90
|
|
90
|
-
|
91
|
-
|
91
|
+
expect(finder.messages_description).to eq(
|
92
|
+
%{ errors:\n* "is invalid" (attribute: association.association_attribute)}
|
93
|
+
)
|
92
94
|
end
|
93
95
|
|
94
96
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveRecord::AcceptNestedAttributesForMatcher do
|
3
|
+
describe Shoulda::Matchers::ActiveRecord::AcceptNestedAttributesForMatcher, type: :model do
|
4
4
|
it 'accepts an existing declaration' do
|
5
5
|
expect(accepting_children).to accept_nested_attributes_for(:children)
|
6
6
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require '
|
1
|
+
require 'unit_spec_helper'
|
2
2
|
|
3
|
-
describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
3
|
+
describe Shoulda::Matchers::ActiveRecord::AssociationMatcher, type: :model do
|
4
4
|
context 'belong_to' do
|
5
5
|
it 'accepts a good association with the default foreign key' do
|
6
6
|
expect(belonging_to_parent).to belong_to(:parent)
|
@@ -29,6 +29,22 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
29
29
|
expect(Child.new).to belong_to(:parent)
|
30
30
|
end
|
31
31
|
|
32
|
+
it 'accepts an association using an existing custom primary key' do
|
33
|
+
define_model :parent
|
34
|
+
define_model :child, parent_id: :integer, custom_primary_key: :integer do
|
35
|
+
belongs_to :parent, primary_key: :custom_primary_key
|
36
|
+
end
|
37
|
+
expect(Child.new).to belong_to(:parent).with_primary_key(:custom_primary_key)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'rejects an association with a bad :primary_key option' do
|
41
|
+
matcher = belong_to(:parent).with_primary_key(:custom_primary_key)
|
42
|
+
|
43
|
+
expect(belonging_to_parent).not_to matcher
|
44
|
+
|
45
|
+
expect(matcher.failure_message).to match(/Child does not have a custom_primary_key primary key/)
|
46
|
+
end
|
47
|
+
|
32
48
|
it 'accepts a polymorphic association' do
|
33
49
|
define_model :child, parent_type: :string, parent_id: :integer do
|
34
50
|
belongs_to :parent, polymorphic: true
|
@@ -130,6 +146,31 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
130
146
|
}.to fail_with_message(message)
|
131
147
|
end
|
132
148
|
|
149
|
+
it 'accepts an association with a namespaced class name' do
|
150
|
+
define_module 'Models'
|
151
|
+
define_model 'Models::Organization'
|
152
|
+
user_model = define_model 'Models::User', organization_id: :integer do
|
153
|
+
belongs_to :organization, class_name: 'Organization'
|
154
|
+
end
|
155
|
+
|
156
|
+
expect(user_model.new).
|
157
|
+
to belong_to(:organization).
|
158
|
+
class_name('Organization')
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'resolves class_name within the context of the namespace before the global namespace' do
|
162
|
+
define_module 'Models'
|
163
|
+
define_model 'Organization'
|
164
|
+
define_model 'Models::Organization'
|
165
|
+
user_model = define_model 'Models::User', organization_id: :integer do
|
166
|
+
belongs_to :organization, class_name: 'Organization'
|
167
|
+
end
|
168
|
+
|
169
|
+
expect(user_model.new).
|
170
|
+
to belong_to(:organization).
|
171
|
+
class_name('Organization')
|
172
|
+
end
|
173
|
+
|
133
174
|
it 'accepts an association with a matching :autosave option' do
|
134
175
|
define_model :parent, adopter: :boolean
|
135
176
|
define_model :child, parent_id: :integer do
|
@@ -288,6 +329,22 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
288
329
|
expect(Parent.new).not_to have_many(:children)
|
289
330
|
end
|
290
331
|
|
332
|
+
it 'accepts an association using an existing custom primary key' do
|
333
|
+
define_model :child, parent_id: :integer
|
334
|
+
define_model :parent, custom_primary_key: :integer do
|
335
|
+
has_many :children, primary_key: :custom_primary_key
|
336
|
+
end
|
337
|
+
expect(Parent.new).to have_many(:children).with_primary_key(:custom_primary_key)
|
338
|
+
end
|
339
|
+
|
340
|
+
it 'rejects an association with a bad :primary_key option' do
|
341
|
+
matcher = have_many(:children).with_primary_key(:custom_primary_key)
|
342
|
+
|
343
|
+
expect(having_many_children).not_to matcher
|
344
|
+
|
345
|
+
expect(matcher.failure_message).to match(/Parent does not have a custom_primary_key primary key/)
|
346
|
+
end
|
347
|
+
|
291
348
|
it 'rejects an association with a bad :as option' do
|
292
349
|
define_model :child, caretaker_type: :string,
|
293
350
|
caretaker_id: :integer
|
@@ -325,6 +382,16 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
325
382
|
expect(matcher.failure_message).to match(/through relationships, but got it through conceptions/)
|
326
383
|
end
|
327
384
|
|
385
|
+
it 'produces a failure message without exception when association is missing :through option' do
|
386
|
+
define_model :child
|
387
|
+
define_model :parent
|
388
|
+
matcher = have_many(:children).through(:relationships).source(:child)
|
389
|
+
failure_message = 'Expected Parent to have a has_many association called children (no association called children)'
|
390
|
+
|
391
|
+
matcher.matches?(Parent.new)
|
392
|
+
expect(matcher.failure_message).to eq failure_message
|
393
|
+
end
|
394
|
+
|
328
395
|
it 'accepts an association with a valid :dependent option' do
|
329
396
|
expect(having_many_children(dependent: :destroy)).
|
330
397
|
to have_many(:children).dependent(:destroy)
|
@@ -414,6 +481,31 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
414
481
|
}.to fail_with_message(message)
|
415
482
|
end
|
416
483
|
|
484
|
+
it 'accepts an association with a namespaced class name' do
|
485
|
+
define_module 'Models'
|
486
|
+
define_model 'Models::Friend', user_id: :integer
|
487
|
+
friend_model = define_model 'Models::User' do
|
488
|
+
has_many :friends, class_name: 'Friend'
|
489
|
+
end
|
490
|
+
|
491
|
+
expect(friend_model.new).
|
492
|
+
to have_many(:friends).
|
493
|
+
class_name('Friend')
|
494
|
+
end
|
495
|
+
|
496
|
+
it 'resolves class_name within the context of the namespace before the global namespace' do
|
497
|
+
define_module 'Models'
|
498
|
+
define_model 'Friend'
|
499
|
+
define_model 'Models::Friend', user_id: :integer
|
500
|
+
friend_model = define_model 'Models::User' do
|
501
|
+
has_many :friends, class_name: 'Friend'
|
502
|
+
end
|
503
|
+
|
504
|
+
expect(friend_model.new).
|
505
|
+
to have_many(:friends).
|
506
|
+
class_name('Friend')
|
507
|
+
end
|
508
|
+
|
417
509
|
it 'accepts an association with a matching :autosave option' do
|
418
510
|
define_model :child, parent_id: :integer
|
419
511
|
define_model :parent do
|
@@ -527,6 +619,22 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
527
619
|
expect(Person.new).to have_one(:detail).with_foreign_key(:detailed_person_id)
|
528
620
|
end
|
529
621
|
|
622
|
+
it 'accepts an association using an existing custom primary key' do
|
623
|
+
define_model :detail, person_id: :integer
|
624
|
+
define_model :person, custom_primary_key: :integer do
|
625
|
+
has_one :detail, primary_key: :custom_primary_key
|
626
|
+
end
|
627
|
+
expect(Person.new).to have_one(:detail).with_primary_key(:custom_primary_key)
|
628
|
+
end
|
629
|
+
|
630
|
+
it 'rejects an association with a bad :primary_key option' do
|
631
|
+
matcher = have_one(:detail).with_primary_key(:custom_primary_key)
|
632
|
+
|
633
|
+
expect(having_one_detail).not_to matcher
|
634
|
+
|
635
|
+
expect(matcher.failure_message).to match(/Person does not have a custom_primary_key primary key/)
|
636
|
+
end
|
637
|
+
|
530
638
|
it 'rejects an association with a bad :as option' do
|
531
639
|
define_model :detail, detailable_id: :integer,
|
532
640
|
detailable_type: :string
|
@@ -584,26 +692,6 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
584
692
|
expect(having_one_detail).to have_one(:detail).class_name('Detail')
|
585
693
|
end
|
586
694
|
|
587
|
-
it 'accepts an association with a matching :autosave option' do
|
588
|
-
define_model :detail, person_id: :integer, disabled: :boolean
|
589
|
-
define_model :person do
|
590
|
-
has_one :detail, autosave: true
|
591
|
-
end
|
592
|
-
expect(Person.new).to have_one(:detail).autosave(true)
|
593
|
-
end
|
594
|
-
|
595
|
-
it 'rejects an association with a non-matching :autosave option with the correct message' do
|
596
|
-
define_model :detail, person_id: :integer, disabled: :boolean
|
597
|
-
define_model :person do
|
598
|
-
has_one :detail, autosave: false
|
599
|
-
end
|
600
|
-
|
601
|
-
message = 'Expected Person to have a has_one association called detail (detail should have autosave set to true)'
|
602
|
-
expect {
|
603
|
-
expect(Person.new).to have_one(:detail).autosave(true)
|
604
|
-
}.to fail_with_message(message)
|
605
|
-
end
|
606
|
-
|
607
695
|
it 'accepts an association with a valid :class_name option' do
|
608
696
|
define_model :person_detail, person_id: :integer
|
609
697
|
define_model :person do
|
@@ -632,6 +720,52 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
632
720
|
}.to fail_with_message(message)
|
633
721
|
end
|
634
722
|
|
723
|
+
it 'accepts an association with a namespaced class name' do
|
724
|
+
define_module 'Models'
|
725
|
+
define_model 'Models::Account', user_id: :integer
|
726
|
+
user_model = define_model 'Models::User' do
|
727
|
+
has_one :account, class_name: 'Account'
|
728
|
+
end
|
729
|
+
|
730
|
+
expect(user_model.new).
|
731
|
+
to have_one(:account).
|
732
|
+
class_name('Account')
|
733
|
+
end
|
734
|
+
|
735
|
+
it 'resolves class_name within the context of the namespace before the global namespace' do
|
736
|
+
define_module 'Models'
|
737
|
+
define_model 'Account'
|
738
|
+
define_model 'Models::Account', user_id: :integer
|
739
|
+
user_model = define_model 'Models::User' do
|
740
|
+
has_one :account, class_name: 'Account'
|
741
|
+
end
|
742
|
+
|
743
|
+
expect(user_model.new).
|
744
|
+
to have_one(:account).
|
745
|
+
class_name('Account')
|
746
|
+
end
|
747
|
+
|
748
|
+
it 'accepts an association with a matching :autosave option' do
|
749
|
+
define_model :detail, person_id: :integer, disabled: :boolean
|
750
|
+
define_model :person do
|
751
|
+
has_one :detail, autosave: true
|
752
|
+
end
|
753
|
+
expect(Person.new).to have_one(:detail).autosave(true)
|
754
|
+
end
|
755
|
+
|
756
|
+
it 'rejects an association with a non-matching :autosave option with the correct message' do
|
757
|
+
define_model :detail, person_id: :integer, disabled: :boolean
|
758
|
+
define_model :person do
|
759
|
+
has_one :detail, autosave: false
|
760
|
+
end
|
761
|
+
|
762
|
+
message = 'Expected Person to have a has_one association called detail (detail should have autosave set to true)'
|
763
|
+
expect {
|
764
|
+
expect(Person.new).to have_one(:detail).autosave(true)
|
765
|
+
}.to fail_with_message(message)
|
766
|
+
end
|
767
|
+
|
768
|
+
|
635
769
|
it 'accepts an association with a through' do
|
636
770
|
define_model :detail
|
637
771
|
|
@@ -747,7 +881,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
747
881
|
|
748
882
|
expect do
|
749
883
|
expect(Person.new).to have_and_belong_to_many(:relatives)
|
750
|
-
end.to fail_with_message_including('missing
|
884
|
+
end.to fail_with_message_including('missing column: relative_id')
|
751
885
|
end
|
752
886
|
end
|
753
887
|
|
@@ -766,8 +900,26 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
766
900
|
|
767
901
|
expect do
|
768
902
|
expect(Person.new).to have_and_belong_to_many(:relatives)
|
769
|
-
end.to fail_with_message_including('missing
|
903
|
+
end.to fail_with_message_including('missing column: person_id')
|
904
|
+
end
|
905
|
+
|
906
|
+
it 'accepts foreign keys when they are symbols' do
|
907
|
+
define_model :relative
|
908
|
+
define_model :person do
|
909
|
+
has_and_belongs_to_many :relatives,
|
910
|
+
foreign_key: :some_foreign_key_id,
|
911
|
+
association_foreign_key: :custom_association_foreign_key_id
|
912
|
+
end
|
913
|
+
|
914
|
+
define_model :people_relative,
|
915
|
+
id: false,
|
916
|
+
custom_association_foreign_key_id: :integer,
|
917
|
+
some_foreign_key_id: :integer
|
918
|
+
|
919
|
+
expect(Person.new).to have_and_belong_to_many(:relatives)
|
920
|
+
|
770
921
|
end
|
922
|
+
|
771
923
|
end
|
772
924
|
|
773
925
|
it 'rejects an association of the wrong type' do
|
@@ -841,6 +993,45 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
841
993
|
}.to fail_with_message(message)
|
842
994
|
end
|
843
995
|
|
996
|
+
it 'accepts an association with a namespaced class name' do
|
997
|
+
possible_join_table_names = [:groups_users, :models_groups_users, :groups_models_users]
|
998
|
+
possible_join_table_names.each do |join_table_name|
|
999
|
+
create_table join_table_name, id: false do |t|
|
1000
|
+
t.integer :group_id
|
1001
|
+
t.integer :user_id
|
1002
|
+
end
|
1003
|
+
end
|
1004
|
+
define_module 'Models'
|
1005
|
+
define_model 'Models::Group'
|
1006
|
+
user_model = define_model 'Models::User' do
|
1007
|
+
has_and_belongs_to_many :groups, class_name: 'Group'
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
expect(user_model.new).
|
1011
|
+
to have_and_belong_to_many(:groups).
|
1012
|
+
class_name('Group')
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
it 'resolves class_name within the context of the namespace before the global namespace' do
|
1016
|
+
possible_join_table_names = [:groups_users, :models_groups_users, :groups_models_users]
|
1017
|
+
possible_join_table_names.each do |join_table_name|
|
1018
|
+
create_table join_table_name, id: false do |t|
|
1019
|
+
t.integer :group_id
|
1020
|
+
t.integer :user_id
|
1021
|
+
end
|
1022
|
+
end
|
1023
|
+
define_module 'Models'
|
1024
|
+
define_model 'Group'
|
1025
|
+
define_model 'Models::Group'
|
1026
|
+
user_model = define_model 'Models::User' do
|
1027
|
+
has_and_belongs_to_many :groups, class_name: 'Group'
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
expect(user_model.new).
|
1031
|
+
to have_and_belong_to_many(:groups).
|
1032
|
+
class_name('Group')
|
1033
|
+
end
|
1034
|
+
|
844
1035
|
it 'accepts an association with a matching :autosave option' do
|
845
1036
|
define_model :relatives, adopted: :boolean
|
846
1037
|
define_model :person do
|
@@ -907,7 +1098,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
907
1098
|
args = []
|
908
1099
|
options = {}
|
909
1100
|
if Shoulda::Matchers::RailsShim.active_record_major_version == 4
|
910
|
-
args <<
|
1101
|
+
args << proc { where(conditions) }
|
911
1102
|
else
|
912
1103
|
options[:conditions] = conditions
|
913
1104
|
end
|
@@ -919,7 +1110,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
|
|
919
1110
|
args = []
|
920
1111
|
options = {}
|
921
1112
|
if Shoulda::Matchers::RailsShim.active_record_major_version == 4
|
922
|
-
args <<
|
1113
|
+
args << proc { order(order) }
|
923
1114
|
else
|
924
1115
|
options[:order] = order
|
925
1116
|
end
|