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
@@ -26,13 +26,15 @@ module Shoulda
|
|
26
26
|
description
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def failure_message
|
30
30
|
"Expected #{expectation}"
|
31
31
|
end
|
32
|
+
alias failure_message_for_should failure_message
|
32
33
|
|
33
|
-
def
|
34
|
+
def failure_message_when_negated
|
34
35
|
"Did not expect #{expectation}"
|
35
36
|
end
|
37
|
+
alias failure_message_for_should_not failure_message_when_negated
|
36
38
|
|
37
39
|
private
|
38
40
|
|
@@ -30,13 +30,15 @@ module Shoulda # :nodoc:
|
|
30
30
|
correct_status_code? || correct_status_code_range?
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
33
|
+
def failure_message
|
34
34
|
"Expected #{expectation}"
|
35
35
|
end
|
36
|
+
alias failure_message_for_should failure_message
|
36
37
|
|
37
|
-
def
|
38
|
+
def failure_message_when_negated
|
38
39
|
"Did not expect #{expectation}"
|
39
40
|
end
|
41
|
+
alias failure_message_for_should_not failure_message_when_negated
|
40
42
|
|
41
43
|
def description
|
42
44
|
"respond with #{@status}"
|
@@ -13,15 +13,19 @@ module Shoulda # :nodoc:
|
|
13
13
|
#
|
14
14
|
# it { should route(:get, '/posts').
|
15
15
|
# to(:controller => :posts, :action => :index) }
|
16
|
+
# it { should route(:get, '/posts').to('posts#index') }
|
16
17
|
# it { should route(:get, '/posts/new').to(:action => :new) }
|
17
18
|
# it { should route(:post, '/posts').to(:action => :create) }
|
18
19
|
# it { should route(:get, '/posts/1').to(:action => :show, :id => 1) }
|
20
|
+
# it { should route(:get, '/posts/1').to('posts#show', :id => 1) }
|
19
21
|
# it { should route(:get, '/posts/1/edit').to(:action => :edit, :id => 1) }
|
20
22
|
# it { should route(:put, '/posts/1').to(:action => :update, :id => 1) }
|
21
23
|
# it { should route(:delete, '/posts/1').
|
22
24
|
# to(:action => :destroy, :id => 1) }
|
23
25
|
# it { should route(:get, '/users/1/posts/1').
|
24
26
|
# to(:action => :show, :id => 1, :user_id => 1) }
|
27
|
+
# it { should route(:get, '/users/1/posts/1').
|
28
|
+
# to('posts#show', :id => 1, :user_id => 1) }
|
25
29
|
def route(method, path)
|
26
30
|
RouteMatcher.new(method, path, self)
|
27
31
|
end
|
@@ -33,10 +37,13 @@ module Shoulda # :nodoc:
|
|
33
37
|
@context = context
|
34
38
|
end
|
35
39
|
|
36
|
-
attr_reader :
|
40
|
+
attr_reader :failure_message, :failure_message_when_negated
|
41
|
+
|
42
|
+
alias failure_message_for_should failure_message
|
43
|
+
alias failure_message_for_should_not failure_message_when_negated
|
37
44
|
|
38
|
-
def to(
|
39
|
-
@params =
|
45
|
+
def to(*args)
|
46
|
+
@params = RouteParams.new(args).normalize
|
40
47
|
self
|
41
48
|
end
|
42
49
|
|
@@ -60,19 +67,6 @@ module Shoulda # :nodoc:
|
|
60
67
|
@params[:controller] ||= controller.controller_path
|
61
68
|
end
|
62
69
|
|
63
|
-
def stringify_params(params)
|
64
|
-
params.each do |key, value|
|
65
|
-
params[key] = stringify(value)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def stringify(value)
|
70
|
-
if value.is_a?(Array)
|
71
|
-
value.map(&:to_param)
|
72
|
-
else
|
73
|
-
value.to_param
|
74
|
-
end
|
75
|
-
end
|
76
70
|
|
77
71
|
def route_recognized?
|
78
72
|
begin
|
@@ -80,13 +74,13 @@ module Shoulda # :nodoc:
|
|
80
74
|
{ :method => @method, :path => @path },
|
81
75
|
@params)
|
82
76
|
|
83
|
-
@
|
77
|
+
@failure_message_when_negated = "Didn't expect to #{description}"
|
84
78
|
true
|
85
79
|
rescue ::ActionController::RoutingError => error
|
86
|
-
@
|
80
|
+
@failure_message = error.message
|
87
81
|
false
|
88
82
|
rescue Shoulda::Matchers::AssertionError => error
|
89
|
-
@
|
83
|
+
@failure_message = error.message
|
90
84
|
false
|
91
85
|
end
|
92
86
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module Matchers
|
3
|
+
module ActionController # :nodoc:
|
4
|
+
class RouteParams
|
5
|
+
def initialize(args)
|
6
|
+
@args = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def normalize
|
10
|
+
if controller_and_action_given_as_string?
|
11
|
+
extract_params_from_string
|
12
|
+
else
|
13
|
+
stringify_params
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :args
|
20
|
+
|
21
|
+
def controller_and_action_given_as_string?
|
22
|
+
args[0].is_a?(String)
|
23
|
+
end
|
24
|
+
|
25
|
+
def extract_params_from_string
|
26
|
+
params = args[1] || {}
|
27
|
+
controller, action = args[0].split('#')
|
28
|
+
params.merge!(:controller => controller, :action => action)
|
29
|
+
end
|
30
|
+
|
31
|
+
def stringify_params
|
32
|
+
args[0].each do |key, value|
|
33
|
+
args[0][key] = stringify(value)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def stringify(value)
|
38
|
+
if value.is_a?(Array)
|
39
|
+
value.map(&:to_param)
|
40
|
+
else
|
41
|
+
value.to_param
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -32,13 +32,15 @@ module Shoulda # :nodoc:
|
|
32
32
|
assigned_correct_value? || cleared_value?
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
35
|
+
def failure_message
|
36
36
|
"Expected #{expectation}, but #{result}"
|
37
37
|
end
|
38
|
+
alias failure_message_for_should failure_message
|
38
39
|
|
39
|
-
def
|
40
|
+
def failure_message_when_negated
|
40
41
|
"Didn't expect #{expectation}, but #{result}"
|
41
42
|
end
|
43
|
+
alias failure_message_for_should_not failure_message_when_negated
|
42
44
|
|
43
45
|
def description
|
44
46
|
description = "set session variable #{@key.inspect}"
|
@@ -51,13 +51,15 @@ module Shoulda # :nodoc:
|
|
51
51
|
description
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def failure_message
|
55
55
|
"Expected #{expectation}"
|
56
56
|
end
|
57
|
+
alias failure_message_for_should failure_message
|
57
58
|
|
58
|
-
def
|
59
|
+
def failure_message_when_negated
|
59
60
|
"Did not expect #{expectation}"
|
60
61
|
end
|
62
|
+
alias failure_message_for_should_not failure_message_when_negated
|
61
63
|
|
62
64
|
private
|
63
65
|
|
@@ -4,17 +4,18 @@ require 'shoulda/matchers/active_model/validation_message_finder'
|
|
4
4
|
require 'shoulda/matchers/active_model/exception_message_finder'
|
5
5
|
require 'shoulda/matchers/active_model/allow_value_matcher'
|
6
6
|
require 'shoulda/matchers/active_model/disallow_value_matcher'
|
7
|
-
require 'shoulda/matchers/active_model/only_integer_matcher'
|
8
|
-
require 'shoulda/matchers/active_model/odd_even_number_matcher'
|
9
|
-
require 'shoulda/matchers/active_model/comparison_matcher'
|
10
7
|
require 'shoulda/matchers/active_model/ensure_length_of_matcher'
|
11
8
|
require 'shoulda/matchers/active_model/ensure_inclusion_of_matcher'
|
12
9
|
require 'shoulda/matchers/active_model/ensure_exclusion_of_matcher'
|
10
|
+
require 'shoulda/matchers/active_model/validate_absence_of_matcher'
|
13
11
|
require 'shoulda/matchers/active_model/validate_presence_of_matcher'
|
14
12
|
require 'shoulda/matchers/active_model/validate_uniqueness_of_matcher'
|
15
13
|
require 'shoulda/matchers/active_model/validate_acceptance_of_matcher'
|
16
14
|
require 'shoulda/matchers/active_model/validate_confirmation_of_matcher'
|
17
15
|
require 'shoulda/matchers/active_model/validate_numericality_of_matcher'
|
16
|
+
require 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
|
17
|
+
require 'shoulda/matchers/active_model/numericality_matchers/odd_even_number_matcher'
|
18
|
+
require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
|
18
19
|
require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
|
19
20
|
require 'shoulda/matchers/active_model/errors'
|
20
21
|
require 'shoulda/matchers/active_model/have_secure_password_matcher'
|
@@ -16,7 +16,10 @@ module Shoulda # :nodoc:
|
|
16
16
|
end
|
17
17
|
|
18
18
|
class AllowMassAssignmentOfMatcher # :nodoc:
|
19
|
-
attr_reader :
|
19
|
+
attr_reader :failure_message, :failure_message_when_negated
|
20
|
+
|
21
|
+
alias failure_message_for_should failure_message
|
22
|
+
alias failure_message_for_should_not failure_message_when_negated
|
20
23
|
|
21
24
|
def initialize(attribute)
|
22
25
|
@attribute = attribute.to_s
|
@@ -35,12 +38,12 @@ module Shoulda # :nodoc:
|
|
35
38
|
@subject = subject
|
36
39
|
if attr_mass_assignable?
|
37
40
|
if whitelisting?
|
38
|
-
@
|
41
|
+
@failure_message_when_negated = "#{@attribute} was made accessible"
|
39
42
|
else
|
40
43
|
if protected_attributes.empty?
|
41
|
-
@
|
44
|
+
@failure_message_when_negated = 'no attributes were protected'
|
42
45
|
else
|
43
|
-
@
|
46
|
+
@failure_message_when_negated = "#{class_name} is protecting " <<
|
44
47
|
"#{protected_attributes.to_a.to_sentence}, " <<
|
45
48
|
"but not #{@attribute}."
|
46
49
|
end
|
@@ -48,9 +51,9 @@ module Shoulda # :nodoc:
|
|
48
51
|
true
|
49
52
|
else
|
50
53
|
if whitelisting?
|
51
|
-
@
|
54
|
+
@failure_message = "Expected #{@attribute} to be accessible"
|
52
55
|
else
|
53
|
-
@
|
56
|
+
@failure_message = "Did not expect #{@attribute} to be protected"
|
54
57
|
end
|
55
58
|
false
|
56
59
|
end
|
@@ -73,13 +73,15 @@ module Shoulda # :nodoc:
|
|
73
73
|
end
|
74
74
|
end
|
75
75
|
|
76
|
-
def
|
76
|
+
def failure_message
|
77
77
|
"Did not expect #{expectation}, got error: #{matched_error}"
|
78
78
|
end
|
79
|
+
alias failure_message_for_should failure_message
|
79
80
|
|
80
|
-
def
|
81
|
+
def failure_message_when_negated
|
81
82
|
"Expected #{expectation}, got #{error_description}"
|
82
83
|
end
|
84
|
+
alias failure_message_for_should_not failure_message_when_negated
|
83
85
|
|
84
86
|
def description
|
85
87
|
message_finder.allow_description(allowed_values)
|
@@ -25,13 +25,15 @@ module Shoulda # :nodoc:
|
|
25
25
|
self
|
26
26
|
end
|
27
27
|
|
28
|
-
def
|
29
|
-
@allow_matcher.
|
28
|
+
def failure_message
|
29
|
+
@allow_matcher.failure_message_when_negated
|
30
30
|
end
|
31
|
+
alias failure_message_for_should failure_message
|
31
32
|
|
32
|
-
def
|
33
|
-
@allow_matcher.
|
33
|
+
def failure_message_when_negated
|
34
|
+
@allow_matcher.failure_message
|
34
35
|
end
|
36
|
+
alias failure_message_for_should_not failure_message_when_negated
|
35
37
|
|
36
38
|
def allowed_types
|
37
39
|
''
|
@@ -24,6 +24,7 @@ module Shoulda # :nodoc:
|
|
24
24
|
class EnsureInclusionOfMatcher < ValidationMatcher # :nodoc:
|
25
25
|
ARBITRARY_OUTSIDE_STRING = 'shouldamatchersteststring'
|
26
26
|
ARBITRARY_OUTSIDE_FIXNUM = 123456789
|
27
|
+
ARBITRARY_OUTSIDE_DECIMAL = 0.123456789
|
27
28
|
|
28
29
|
def initialize(attribute)
|
29
30
|
super(attribute)
|
@@ -89,7 +90,7 @@ module Shoulda # :nodoc:
|
|
89
90
|
if allows_all_values_in_array? && allows_blank_value? && allows_nil_value? && disallows_value_outside_of_array?
|
90
91
|
true
|
91
92
|
else
|
92
|
-
@
|
93
|
+
@failure_message = "#{@array} doesn't match array in validation"
|
93
94
|
false
|
94
95
|
end
|
95
96
|
end
|
@@ -160,6 +161,8 @@ module Shoulda # :nodoc:
|
|
160
161
|
case @subject.send(@attribute.to_s)
|
161
162
|
when Fixnum
|
162
163
|
ARBITRARY_OUTSIDE_FIXNUM
|
164
|
+
when BigDecimal
|
165
|
+
ARBITRARY_OUTSIDE_DECIMAL
|
163
166
|
else
|
164
167
|
ARBITRARY_OUTSIDE_STRING
|
165
168
|
end
|
@@ -68,7 +68,6 @@ module Shoulda # :nodoc:
|
|
68
68
|
end
|
69
69
|
self
|
70
70
|
end
|
71
|
-
alias_method :with_message, :with_short_message
|
72
71
|
|
73
72
|
def with_long_message(message)
|
74
73
|
if message
|
@@ -77,6 +76,14 @@ module Shoulda # :nodoc:
|
|
77
76
|
self
|
78
77
|
end
|
79
78
|
|
79
|
+
def with_message(message)
|
80
|
+
if message
|
81
|
+
@short_message = message
|
82
|
+
@long_message = message
|
83
|
+
end
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
80
87
|
def description
|
81
88
|
description = "ensure #{@attribute} has a length "
|
82
89
|
if @options.key?(:minimum) && @options.key?(:maximum)
|
@@ -11,7 +11,9 @@ module Shoulda # :nodoc:
|
|
11
11
|
end
|
12
12
|
|
13
13
|
class HaveSecurePasswordMatcher # :nodoc:
|
14
|
-
attr_reader :
|
14
|
+
attr_reader :failure_message
|
15
|
+
|
16
|
+
alias failure_message_for_should failure_message
|
15
17
|
|
16
18
|
CORRECT_PASSWORD = "aBcDe12345"
|
17
19
|
INCORRECT_PASSWORD = "password"
|
@@ -39,7 +41,7 @@ module Shoulda # :nodoc:
|
|
39
41
|
|
40
42
|
if failure = validate
|
41
43
|
key, params = failure
|
42
|
-
@
|
44
|
+
@failure_message = MESSAGES[key] % { subject: subject.class }.merge(params)
|
43
45
|
end
|
44
46
|
|
45
47
|
failure.nil?
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel # :nodoc:
|
4
|
+
module NumericalityMatchers
|
5
|
+
# Examples:
|
6
|
+
# it { should validate_numericality_of(:attr).
|
7
|
+
# is_greater_than(6).
|
8
|
+
# less_than(20)...(and so on) }
|
9
|
+
class ComparisonMatcher < ValidationMatcher
|
10
|
+
def initialize(value, operator)
|
11
|
+
@value = value
|
12
|
+
@operator = operator
|
13
|
+
@message = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def for(attribute)
|
17
|
+
@attribute = attribute
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
def matches?(subject)
|
22
|
+
@subject = subject
|
23
|
+
disallows_value_of(value_to_compare, @message)
|
24
|
+
end
|
25
|
+
|
26
|
+
def allowed_types
|
27
|
+
'integer'
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_message(message)
|
31
|
+
@message = message
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def value_to_compare
|
37
|
+
case @operator
|
38
|
+
when :> then [@value, @value - 1].sample
|
39
|
+
when :>= then @value - 1
|
40
|
+
when :== then @value + 1
|
41
|
+
when :< then [@value, @value + 1].sample
|
42
|
+
when :<= then @value + 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def expectation
|
47
|
+
case @operator
|
48
|
+
when :> then "greater than"
|
49
|
+
when :>= then "greater than or equal to"
|
50
|
+
when :== then "equal to"
|
51
|
+
when :< then "less than"
|
52
|
+
when :<= then "less than or equal to"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module Matchers
|
3
|
+
module ActiveModel # :nodoc:
|
4
|
+
module NumericalityMatchers
|
5
|
+
class OddEvenNumberMatcher # :nodoc:
|
6
|
+
NON_EVEN_NUMBER_VALUE = 1
|
7
|
+
NON_ODD_NUMBER_VALUE = 2
|
8
|
+
|
9
|
+
def initialize(attribute, options = {})
|
10
|
+
@attribute = attribute
|
11
|
+
options[:odd] ||= true
|
12
|
+
options[:even] ||= false
|
13
|
+
|
14
|
+
if options[:odd] && !options[:even]
|
15
|
+
@disallow_value_matcher = DisallowValueMatcher.new(NON_ODD_NUMBER_VALUE).
|
16
|
+
for(@attribute).
|
17
|
+
with_message(:odd)
|
18
|
+
else
|
19
|
+
@disallow_value_matcher = DisallowValueMatcher.new(NON_EVEN_NUMBER_VALUE).
|
20
|
+
for(@attribute).
|
21
|
+
with_message(:even)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def matches?(subject)
|
26
|
+
@disallow_value_matcher.matches?(subject)
|
27
|
+
end
|
28
|
+
|
29
|
+
def with_message(message)
|
30
|
+
@disallow_value_matcher.with_message(message)
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def allowed_types
|
35
|
+
'integer'
|
36
|
+
end
|
37
|
+
|
38
|
+
def failure_message
|
39
|
+
@disallow_value_matcher.failure_message
|
40
|
+
end
|
41
|
+
alias failure_message_for_should failure_message
|
42
|
+
|
43
|
+
def failure_message_when_negated
|
44
|
+
@disallow_value_matcher.failure_message_when_negated
|
45
|
+
end
|
46
|
+
alias failure_message_for_should_not failure_message_when_negated
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|