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
@@ -3,6 +3,9 @@ module Shoulda # :nodoc:
|
|
3
3
|
module ActiveRecord # :nodoc:
|
4
4
|
module AssociationMatchers
|
5
5
|
class ModelReflector
|
6
|
+
delegate :associated_class, :through?, :join_table,
|
7
|
+
:association_relation, to: :reflection
|
8
|
+
|
6
9
|
def initialize(subject, name)
|
7
10
|
@subject = subject
|
8
11
|
@name = name
|
@@ -13,55 +16,15 @@ module Shoulda # :nodoc:
|
|
13
16
|
end
|
14
17
|
|
15
18
|
def reflect_on_association(name)
|
16
|
-
model_class.reflect_on_association(name)
|
17
|
-
end
|
18
|
-
|
19
|
-
def model_class
|
20
|
-
subject.class
|
21
|
-
end
|
19
|
+
reflection = model_class.reflect_on_association(name)
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
def through?
|
28
|
-
reflection.options[:through]
|
29
|
-
end
|
30
|
-
|
31
|
-
def join_table
|
32
|
-
if reflection.respond_to? :join_table
|
33
|
-
reflection.join_table.to_s
|
34
|
-
else
|
35
|
-
reflection.options[:join_table].to_s
|
21
|
+
if reflection
|
22
|
+
ModelReflection.new(reflection)
|
36
23
|
end
|
37
24
|
end
|
38
25
|
|
39
|
-
def
|
40
|
-
|
41
|
-
relation_from_scope(reflection.scope)
|
42
|
-
else
|
43
|
-
options = reflection.options
|
44
|
-
relation = RailsShim.clean_scope(reflection.klass)
|
45
|
-
if options[:conditions]
|
46
|
-
relation = relation.where(options[:conditions])
|
47
|
-
end
|
48
|
-
if options[:include]
|
49
|
-
relation = relation.include(options[:include])
|
50
|
-
end
|
51
|
-
if options[:order]
|
52
|
-
relation = relation.order(options[:order])
|
53
|
-
end
|
54
|
-
if options[:group]
|
55
|
-
relation = relation.group(options[:group])
|
56
|
-
end
|
57
|
-
if options[:having]
|
58
|
-
relation = relation.having(options[:having])
|
59
|
-
end
|
60
|
-
if options[:limit]
|
61
|
-
relation = relation.limit(options[:limit])
|
62
|
-
end
|
63
|
-
relation
|
64
|
-
end
|
26
|
+
def model_class
|
27
|
+
subject.class
|
65
28
|
end
|
66
29
|
|
67
30
|
def build_relation_with_clause(name, value)
|
@@ -74,24 +37,26 @@ module Shoulda # :nodoc:
|
|
74
37
|
|
75
38
|
def extract_relation_clause_from(relation, name)
|
76
39
|
case name
|
77
|
-
|
78
|
-
|
79
|
-
|
40
|
+
when :conditions
|
41
|
+
relation.where_values_hash
|
42
|
+
when :order
|
43
|
+
relation.order_values.map { |value| value_as_sql(value) }.join(', ')
|
44
|
+
else
|
45
|
+
raise ArgumentError, "Unknown clause '#{name}'"
|
80
46
|
end
|
81
47
|
end
|
82
48
|
|
83
49
|
private
|
84
50
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
51
|
+
attr_reader :subject, :name
|
52
|
+
|
53
|
+
def value_as_sql(value)
|
54
|
+
if value.respond_to?(:to_sql)
|
55
|
+
value.to_sql
|
89
56
|
else
|
90
|
-
|
57
|
+
value
|
91
58
|
end
|
92
59
|
end
|
93
|
-
|
94
|
-
attr_reader :subject, :name
|
95
60
|
end
|
96
61
|
end
|
97
62
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Shoulda # :nodoc:
|
2
|
+
module Matchers
|
3
|
+
module ActiveRecord # :nodoc:
|
4
|
+
module AssociationMatchers
|
5
|
+
class SourceMatcher
|
6
|
+
attr_accessor :missing_option
|
7
|
+
|
8
|
+
def initialize(source, name)
|
9
|
+
@source = source
|
10
|
+
@name = name
|
11
|
+
@missing_option = ''
|
12
|
+
end
|
13
|
+
|
14
|
+
def description
|
15
|
+
"source => #{source}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def matches?(subject)
|
19
|
+
self.subject = ModelReflector.new(subject, name)
|
20
|
+
|
21
|
+
if option_verifier.correct_for_string?(:source, source)
|
22
|
+
true
|
23
|
+
else
|
24
|
+
self.missing_option = "#{name} should have #{source} as source option"
|
25
|
+
false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_accessor :subject, :source, :name
|
32
|
+
|
33
|
+
def option_verifier
|
34
|
+
@option_verifier ||= OptionVerifier.new(subject)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -51,13 +51,15 @@ module Shoulda # :nodoc:
|
|
51
51
|
correct_primary?
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def failure_message
|
55
55
|
"Expected #{expectation} (#{@missing})"
|
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
|
def description
|
63
65
|
desc = "have db column named #{@column}"
|
@@ -37,13 +37,15 @@ module Shoulda # :nodoc:
|
|
37
37
|
index_exists? && correct_unique?
|
38
38
|
end
|
39
39
|
|
40
|
-
def
|
40
|
+
def failure_message
|
41
41
|
"Expected #{expectation} (#{@missing})"
|
42
42
|
end
|
43
|
+
alias failure_message_for_should failure_message
|
43
44
|
|
44
|
-
def
|
45
|
+
def failure_message_when_negated
|
45
46
|
"Did not expect #{expectation}"
|
46
47
|
end
|
48
|
+
alias failure_message_for_should_not failure_message_when_negated
|
47
49
|
|
48
50
|
def description
|
49
51
|
if @options.key?(:unique)
|
@@ -16,19 +16,22 @@ module Shoulda # :nodoc:
|
|
16
16
|
@attribute = attribute.to_s
|
17
17
|
end
|
18
18
|
|
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 matches?(subject)
|
22
25
|
@subject = subject
|
23
26
|
if readonly_attributes.include?(@attribute)
|
24
|
-
@
|
27
|
+
@failure_message_when_negated = "Did not expect #{@attribute} to be read-only"
|
25
28
|
true
|
26
29
|
else
|
27
30
|
if readonly_attributes.empty?
|
28
|
-
@
|
31
|
+
@failure_message = "#{class_name} attribute #{@attribute} " <<
|
29
32
|
'is not read-only'
|
30
33
|
else
|
31
|
-
@
|
34
|
+
@failure_message = "#{class_name} is making " <<
|
32
35
|
"#{readonly_attributes.to_a.to_sentence} " <<
|
33
36
|
"read-only, but not #{@attribute}."
|
34
37
|
end
|
@@ -36,13 +36,15 @@ module Shoulda # :nodoc:
|
|
36
36
|
serialization_valid? && type_valid?
|
37
37
|
end
|
38
38
|
|
39
|
-
def
|
39
|
+
def failure_message
|
40
40
|
"Expected #{expectation} (#{@missing})"
|
41
41
|
end
|
42
|
+
alias failure_message_for_should failure_message
|
42
43
|
|
43
|
-
def
|
44
|
+
def failure_message_when_negated
|
44
45
|
"Did not expect #{expectation}"
|
45
46
|
end
|
47
|
+
alias failure_message_for_should_not failure_message_when_negated
|
46
48
|
|
47
49
|
def description
|
48
50
|
description = "serialize :#{@name}"
|
@@ -1,4 +1,4 @@
|
|
1
|
-
if defined?(ActionController)
|
1
|
+
if defined?(ActionController) && defined?(ActionController::TestCase)
|
2
2
|
require 'shoulda/matchers/action_controller'
|
3
3
|
|
4
4
|
ActionController::TestCase.class_eval do
|
@@ -11,7 +11,7 @@ if defined?(ActionController)
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
if defined?(ActiveRecord)
|
14
|
+
if defined?(ActiveRecord) && defined?(ActiveSupport::TestCase)
|
15
15
|
require 'shoulda/matchers/active_record'
|
16
16
|
|
17
17
|
ActiveSupport::TestCase.class_eval do
|
@@ -20,7 +20,7 @@ if defined?(ActiveRecord)
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
if defined?(ActiveModel)
|
23
|
+
if defined?(ActiveModel) && defined?(ActiveSupport::TestCase)
|
24
24
|
require 'shoulda/matchers/active_model'
|
25
25
|
|
26
26
|
ActiveSupport::TestCase.class_eval do
|
@@ -2,7 +2,7 @@ module Shoulda # :nodoc:
|
|
2
2
|
module Matchers
|
3
3
|
class RailsShim # :nodoc:
|
4
4
|
def self.layouts_ivar
|
5
|
-
if
|
5
|
+
if action_pack_major_version >= 4
|
6
6
|
'@_layouts'
|
7
7
|
else
|
8
8
|
'@layouts'
|
@@ -10,7 +10,7 @@ module Shoulda # :nodoc:
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def self.flashes_ivar
|
13
|
-
if
|
13
|
+
if action_pack_major_version >= 4
|
14
14
|
:@flashes
|
15
15
|
else
|
16
16
|
:@used
|
@@ -18,7 +18,7 @@ module Shoulda # :nodoc:
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.clean_scope(klass)
|
21
|
-
if
|
21
|
+
if active_record_major_version == 4
|
22
22
|
klass.all
|
23
23
|
else
|
24
24
|
klass.scoped
|
@@ -26,15 +26,23 @@ module Shoulda # :nodoc:
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.validates_confirmation_of_error_attribute(matcher)
|
29
|
-
if
|
29
|
+
if active_model_major_version == 4
|
30
30
|
matcher.confirmation_attribute
|
31
31
|
else
|
32
32
|
matcher.attribute
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def self.
|
37
|
-
|
36
|
+
def self.active_record_major_version
|
37
|
+
::ActiveRecord::VERSION::MAJOR
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.active_model_major_version
|
41
|
+
::ActiveModel::VERSION::MAJOR
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.action_pack_major_version
|
45
|
+
::ActionPack::VERSION::MAJOR
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
@@ -13,7 +13,7 @@ describe Shoulda::Matchers::ActionController::FilterParamMatcher do
|
|
13
13
|
|
14
14
|
matcher.matches?(nil).should be_false
|
15
15
|
|
16
|
-
matcher.
|
16
|
+
matcher.failure_message.should =~ /Expected other to be filtered.*secret/
|
17
17
|
end
|
18
18
|
|
19
19
|
def filter(param)
|
@@ -18,7 +18,7 @@ describe Shoulda::Matchers::ActionController::RescueFromMatcher do
|
|
18
18
|
it "asserts the controller responds to the handler method" do
|
19
19
|
matcher = rescue_from(RuntimeError).with(:error_method)
|
20
20
|
matcher.matches?(controller_with_rescue_from_and_invalid_method).should be_false
|
21
|
-
matcher.
|
21
|
+
matcher.failure_message.should =~ /does not respond to/
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -35,7 +35,7 @@ describe Shoulda::Matchers::ActionController::RescueFromMatcher do
|
|
35
35
|
it "asserts controller is not setup with rescue_from" do
|
36
36
|
matcher = rescue_from RuntimeError
|
37
37
|
define_controller("RandomController").should_not matcher
|
38
|
-
matcher.
|
38
|
+
matcher.failure_message_when_negated.should =~ /Did not expect \w+ to rescue from/
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -54,6 +54,11 @@ describe Shoulda::Matchers::ActionController::RouteMatcher, type: :controller do
|
|
54
54
|
to(:action => 'other', :id => '1')
|
55
55
|
end
|
56
56
|
|
57
|
+
it "accepts a string as first parameter" do
|
58
|
+
route_examples_to_examples.should route(:get, '/examples/1').
|
59
|
+
to("examples#example", id: '1')
|
60
|
+
end
|
61
|
+
|
57
62
|
def route_examples_to_examples
|
58
63
|
define_routes do
|
59
64
|
get 'examples/:id', :to => 'examples#example'
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoulda::Matchers::ActionController::RouteParams do
|
4
|
+
describe "#normalize" do
|
5
|
+
context "when the route parameters is a hash" do
|
6
|
+
it "stringifies the values in the hash" do
|
7
|
+
build_route_params(:controller => :examples, :action => 'example', :id => '1').normalize.
|
8
|
+
should eq({ :controller => "examples", :action => "example", :id => "1" })
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context "when the route parameters is a string and a hash" do
|
13
|
+
it "produces a hash of route parameters" do
|
14
|
+
build_route_params("examples#example", id: '1').normalize.
|
15
|
+
should eq({ :controller => "examples", :action => "example", :id => "1" })
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when the route params is a string" do
|
20
|
+
it "produces a hash of route params" do
|
21
|
+
build_route_params("examples#index").normalize.
|
22
|
+
should eq({ :controller => "examples", :action => "index"})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_route_params(*params)
|
28
|
+
Shoulda::Matchers::ActionController::RouteParams.new(params)
|
29
|
+
end
|
30
|
+
end
|
@@ -70,7 +70,7 @@ describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher do
|
|
70
70
|
|
71
71
|
matcher.matches?(no_protected_attributes).should be_true
|
72
72
|
|
73
|
-
matcher.
|
73
|
+
matcher.failure_message_when_negated.should_not be_nil
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -162,7 +162,7 @@ describe Shoulda::Matchers::ActiveModel::AllowValueMatcher do
|
|
162
162
|
|
163
163
|
matcher.matches?(validating_format(:with => /abc/, :strict => true))
|
164
164
|
|
165
|
-
matcher.
|
165
|
+
matcher.failure_message_when_negated.should eq 'Expected exception to include /abc/ ' +
|
166
166
|
'when attr is set to "xyz", got Attr is invalid'
|
167
167
|
end
|
168
168
|
end
|
@@ -40,13 +40,13 @@ describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "delegates its failure message to its allow matcher's negative failure message" do
|
43
|
-
allow_matcher = stub_everything(:
|
43
|
+
allow_matcher = stub_everything(:failure_message_when_negated => 'allow matcher failure')
|
44
44
|
Shoulda::Matchers::ActiveModel::AllowValueMatcher.stubs(:new).returns(allow_matcher)
|
45
45
|
|
46
46
|
matcher = matcher('abcde').for(:attr).with_message('good message')
|
47
47
|
matcher.matches?(validating_format(:with => /abc/, :message => 'good message'))
|
48
48
|
|
49
|
-
matcher.
|
49
|
+
matcher.failure_message.should eq 'allow matcher failure'
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'matches if the message is correct but the value is not' do
|
@@ -18,6 +18,16 @@ describe Shoulda::Matchers::ActiveModel::EnsureInclusionOfMatcher do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
context 'with an decimal column' do
|
22
|
+
it 'can verify decimal values' do
|
23
|
+
model = define_model(:example, :attr => :decimal) do
|
24
|
+
validates_inclusion_of :attr, :in => [0.0, 0.1]
|
25
|
+
end.new
|
26
|
+
|
27
|
+
model.should ensure_inclusion_of(:attr).in_array([0.0, 0.1])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
21
31
|
context 'with true/false values' do
|
22
32
|
it 'can verify outside values to ensure the negative case' do
|
23
33
|
define_model(:example, :attr => :string).new.
|