shoulda-matchers 1.4.2 → 1.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.
Files changed (135) hide show
  1. data/.travis.yml +11 -3
  2. data/Appraisals +3 -3
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +69 -70
  5. data/MIT-LICENSE +1 -1
  6. data/NEWS.md +22 -4
  7. data/README.md +3 -1
  8. data/Rakefile +9 -5
  9. data/features/step_definitions/rails_steps.rb +7 -7
  10. data/features/support/env.rb +1 -1
  11. data/gemfiles/3.0.gemfile +1 -1
  12. data/gemfiles/3.0.gemfile.lock +25 -22
  13. data/gemfiles/3.1.gemfile +1 -1
  14. data/gemfiles/3.1.gemfile.lock +27 -24
  15. data/gemfiles/3.2.gemfile +1 -1
  16. data/gemfiles/3.2.gemfile.lock +56 -52
  17. data/lib/shoulda/matchers/action_controller.rb +3 -2
  18. data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +10 -8
  19. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +2 -4
  20. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +3 -4
  21. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +3 -4
  22. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +6 -6
  23. data/lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb +5 -2
  24. data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +2 -2
  25. data/lib/shoulda/matchers/action_controller/route_matcher.rb +12 -12
  26. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +3 -4
  27. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +10 -11
  28. data/lib/shoulda/matchers/action_controller/strong_parameters_matcher.rb +121 -0
  29. data/lib/shoulda/matchers/action_mailer/have_sent_email_matcher.rb +7 -4
  30. data/lib/shoulda/matchers/active_model.rb +1 -1
  31. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +8 -8
  32. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +5 -4
  33. data/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +3 -3
  34. data/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb +2 -2
  35. data/lib/shoulda/matchers/active_model/exception_message_finder.rb +0 -1
  36. data/lib/shoulda/matchers/active_model/helpers.rb +16 -7
  37. data/lib/shoulda/matchers/active_model/only_integer_matcher.rb +3 -3
  38. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +8 -6
  39. data/lib/shoulda/matchers/active_model/validate_format_of_matcher.rb +19 -10
  40. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +4 -4
  41. data/lib/shoulda/matchers/active_model/validate_uniqueness_of_matcher.rb +19 -21
  42. data/lib/shoulda/matchers/active_model/validation_matcher.rb +7 -7
  43. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +1 -1
  44. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +5 -5
  45. data/lib/shoulda/matchers/active_record/association_matcher.rb +3 -3
  46. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +11 -7
  47. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +2 -2
  48. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +5 -5
  49. data/lib/shoulda/matchers/active_record/query_the_database_matcher.rb +5 -2
  50. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +3 -3
  51. data/lib/shoulda/matchers/assertion_error.rb +4 -1
  52. data/lib/shoulda/matchers/independent/delegate_matcher.rb +17 -7
  53. data/lib/shoulda/matchers/integrations/rspec.rb +19 -33
  54. data/lib/shoulda/matchers/version.rb +1 -1
  55. data/shoulda-matchers.gemspec +6 -4
  56. data/spec/shoulda/matchers/action_controller/assign_to_matcher_spec.rb +66 -0
  57. data/spec/shoulda/matchers/action_controller/filter_param_matcher_spec.rb +22 -0
  58. data/spec/shoulda/matchers/action_controller/redirect_to_matcher_spec.rb +42 -0
  59. data/spec/shoulda/matchers/action_controller/render_template_matcher_spec.rb +78 -0
  60. data/spec/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +58 -0
  61. data/spec/shoulda/matchers/action_controller/respond_with_content_type_matcher_spec.rb +31 -0
  62. data/spec/shoulda/matchers/action_controller/respond_with_matcher_spec.rb +31 -0
  63. data/spec/shoulda/matchers/action_controller/route_matcher_spec.rb +65 -0
  64. data/spec/shoulda/matchers/action_controller/set_session_matcher_spec.rb +51 -0
  65. data/spec/shoulda/matchers/action_controller/set_the_flash_matcher_spec.rb +153 -0
  66. data/spec/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +142 -0
  67. data/spec/shoulda/matchers/action_mailer/have_sent_email_spec.rb +324 -0
  68. data/spec/shoulda/matchers/active_model/allow_mass_assignment_of_matcher_spec.rb +111 -0
  69. data/spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb +124 -0
  70. data/spec/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +43 -0
  71. data/spec/shoulda/matchers/active_model/ensure_exclusion_of_matcher_spec.rb +74 -0
  72. data/spec/shoulda/matchers/active_model/ensure_inclusion_of_matcher_spec.rb +171 -0
  73. data/spec/shoulda/matchers/active_model/ensure_length_of_matcher_spec.rb +113 -0
  74. data/spec/shoulda/{active_model → matchers/active_model}/exception_message_finder_spec.rb +2 -2
  75. data/spec/shoulda/matchers/active_model/helpers_spec.rb +158 -0
  76. data/spec/shoulda/matchers/active_model/only_integer_matcher_spec.rb +52 -0
  77. data/spec/shoulda/matchers/active_model/validate_acceptance_of_matcher_spec.rb +41 -0
  78. data/spec/shoulda/matchers/active_model/validate_confirmation_of_matcher_spec.rb +41 -0
  79. data/spec/shoulda/matchers/active_model/validate_format_of_matcher_spec.rb +75 -0
  80. data/spec/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +73 -0
  81. data/spec/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +127 -0
  82. data/spec/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +175 -0
  83. data/spec/shoulda/{active_model → matchers/active_model}/validation_message_finder_spec.rb +0 -1
  84. data/spec/shoulda/matchers/active_record/accept_nested_attributes_for_matcher_spec.rb +106 -0
  85. data/spec/shoulda/matchers/active_record/association_matcher_spec.rb +534 -0
  86. data/spec/shoulda/matchers/active_record/have_db_column_matcher_spec.rb +111 -0
  87. data/spec/shoulda/matchers/active_record/have_db_index_matcher_spec.rb +78 -0
  88. data/spec/shoulda/matchers/active_record/have_readonly_attributes_matcher_spec.rb +41 -0
  89. data/spec/shoulda/{active_record → matchers/active_record}/query_the_database_matcher_spec.rb +10 -10
  90. data/spec/shoulda/matchers/active_record/serialize_matcher_spec.rb +86 -0
  91. data/spec/shoulda/{independent → matchers/independent}/delegate_matcher_spec.rb +55 -34
  92. data/spec/spec_helper.rb +1 -2
  93. data/spec/support/active_model_versions.rb +4 -0
  94. data/spec/support/activemodel_helpers.rb +19 -0
  95. data/spec/support/controller_builder.rb +38 -12
  96. data/spec/support/model_builder.rb +8 -2
  97. metadata +106 -98
  98. data/spec/fixtures/addresses.yml +0 -3
  99. data/spec/fixtures/friendships.yml +0 -0
  100. data/spec/fixtures/posts.yml +0 -5
  101. data/spec/fixtures/products.yml +0 -0
  102. data/spec/fixtures/taggings.yml +0 -0
  103. data/spec/fixtures/tags.yml +0 -9
  104. data/spec/fixtures/users.yml +0 -6
  105. data/spec/shoulda/action_controller/assign_to_matcher_spec.rb +0 -63
  106. data/spec/shoulda/action_controller/filter_param_matcher_spec.rb +0 -20
  107. data/spec/shoulda/action_controller/redirect_to_matcher_spec.rb +0 -40
  108. data/spec/shoulda/action_controller/render_template_matcher_spec.rb +0 -69
  109. data/spec/shoulda/action_controller/render_with_layout_matcher_spec.rb +0 -55
  110. data/spec/shoulda/action_controller/respond_with_content_type_matcher_spec.rb +0 -28
  111. data/spec/shoulda/action_controller/respond_with_matcher_spec.rb +0 -83
  112. data/spec/shoulda/action_controller/route_matcher_spec.rb +0 -65
  113. data/spec/shoulda/action_controller/set_session_matcher_spec.rb +0 -46
  114. data/spec/shoulda/action_controller/set_the_flash_matcher_spec.rb +0 -130
  115. data/spec/shoulda/action_mailer/have_sent_email_spec.rb +0 -333
  116. data/spec/shoulda/active_model/allow_mass_assignment_of_matcher_spec.rb +0 -115
  117. data/spec/shoulda/active_model/allow_value_matcher_spec.rb +0 -131
  118. data/spec/shoulda/active_model/disallow_value_matcher_spec.rb +0 -65
  119. data/spec/shoulda/active_model/ensure_exclusion_of_matcher_spec.rb +0 -79
  120. data/spec/shoulda/active_model/ensure_inclusion_of_matcher_spec.rb +0 -181
  121. data/spec/shoulda/active_model/ensure_length_of_matcher_spec.rb +0 -138
  122. data/spec/shoulda/active_model/helpers_spec.rb +0 -129
  123. data/spec/shoulda/active_model/only_integer_matcher_spec.rb +0 -69
  124. data/spec/shoulda/active_model/validate_acceptance_of_matcher_spec.rb +0 -43
  125. data/spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb +0 -48
  126. data/spec/shoulda/active_model/validate_format_of_matcher_spec.rb +0 -79
  127. data/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb +0 -112
  128. data/spec/shoulda/active_model/validate_presence_of_matcher_spec.rb +0 -135
  129. data/spec/shoulda/active_model/validate_uniqueness_of_matcher_spec.rb +0 -154
  130. data/spec/shoulda/active_record/accept_nested_attributes_for_matcher_spec.rb +0 -84
  131. data/spec/shoulda/active_record/association_matcher_spec.rb +0 -642
  132. data/spec/shoulda/active_record/have_db_column_matcher_spec.rb +0 -185
  133. data/spec/shoulda/active_record/have_db_index_matcher_spec.rb +0 -105
  134. data/spec/shoulda/active_record/have_readonly_attributes_matcher_spec.rb +0 -46
  135. data/spec/shoulda/active_record/serialize_matcher_spec.rb +0 -81
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
4
+ context '#description' do
5
+ it 'states that it allows only numeric values' do
6
+ matcher.description.should == 'only allow numeric values for attr'
7
+ end
8
+ end
9
+
10
+ context 'with a model with a numericality validation' do
11
+ it 'accepts' do
12
+ validating_numericality.should matcher
13
+ end
14
+
15
+ it 'does not override the default message with a blank' do
16
+ validating_numericality.should matcher.with_message(nil)
17
+ end
18
+ end
19
+
20
+ context 'with a model without a numericality validation' do
21
+ it 'rejects' do
22
+ define_model(:example, :attr => :string).new.should_not matcher
23
+ end
24
+
25
+ it 'rejects with the ActiveRecord :not_an_integer message' do
26
+ the_matcher = matcher.only_integer
27
+
28
+ the_matcher.matches?(define_model(:example, :attr => :string).new)
29
+
30
+ the_matcher.failure_message_for_should.should include 'Expected errors to include "must be an integer"'
31
+ end
32
+ end
33
+
34
+ context 'with the only_integer option' do
35
+ it 'allows integer values for that attribute' do
36
+ validating_numericality(:only_integer => true).should matcher.only_integer
37
+ end
38
+
39
+ it 'rejects when the model does not enforce integer values' do
40
+ validating_numericality.should_not matcher.only_integer
41
+ end
42
+
43
+ it 'rejects with the ActiveRecord :not_an_integer message' do
44
+ the_matcher = matcher.only_integer
45
+
46
+ the_matcher.matches?(validating_numericality)
47
+
48
+ the_matcher.failure_message_for_should.should include 'Expected errors to include "must be an integer"'
49
+ end
50
+ end
51
+
52
+ context 'with a custom validation message' do
53
+ it 'accepts when the messages match' do
54
+ validating_numericality(:message => 'custom').
55
+ should matcher.with_message(/custom/)
56
+ end
57
+
58
+ it 'rejects when the messages do not match' do
59
+ validating_numericality(:message => 'custom').
60
+ should_not matcher.with_message(/wrong/)
61
+ end
62
+ end
63
+
64
+ def validating_numericality(options = {})
65
+ define_model :example, :attr => :string do
66
+ validates_numericality_of :attr, options
67
+ end.new
68
+ end
69
+
70
+ def matcher
71
+ validate_numericality_of(:attr)
72
+ end
73
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveModel::ValidatePresenceOfMatcher do
4
+ context 'a model with a presence validation' do
5
+ it 'accepts' do
6
+ validating_presence.should matcher
7
+ end
8
+
9
+ it 'does not override the default message with a blank' do
10
+ validating_presence.should matcher.with_message(nil)
11
+ end
12
+ end
13
+
14
+ context 'a model without a presence validation' do
15
+ it 'rejects' do
16
+ define_model(:example, :attr => :string).new.should_not matcher
17
+ end
18
+ end
19
+
20
+ context 'an ActiveModel class with a presence validation' do
21
+ it 'accepts' do
22
+ active_model_validating_presence.should matcher
23
+ end
24
+
25
+ it 'does not override the default message with a blank' do
26
+ active_model_validating_presence.should matcher.with_message(nil)
27
+ end
28
+ end
29
+
30
+ context 'an ActiveModel class without a presence validation' do
31
+ it 'rejects' do
32
+ define_active_model_class('Example', :accessors => [:attr]).new.
33
+ should_not matcher
34
+ end
35
+ end
36
+
37
+ context 'a has_many association with a presence validation' do
38
+ it 'requires the attribute to be set' do
39
+ has_many_children(:presence => true).should validate_presence_of(:children)
40
+ end
41
+ end
42
+
43
+ context 'a has_many association without a presence validation' do
44
+ it 'does not require the attribute to be set' do
45
+ has_many_children(:presence => false).
46
+ should_not validate_presence_of(:children)
47
+ end
48
+ end
49
+
50
+ context 'a required has_and_belongs_to_many association' do
51
+ before do
52
+ define_model :child
53
+ @model = define_model :parent do
54
+ has_and_belongs_to_many :children
55
+ validates_presence_of :children
56
+ end.new
57
+ create_table 'children_parents', :id => false do |t|
58
+ t.integer :child_id
59
+ t.integer :parent_id
60
+ end
61
+ end
62
+
63
+ it 'accepts' do
64
+ @model.should validate_presence_of(:children)
65
+ end
66
+ end
67
+
68
+ context 'an optional has_and_belongs_to_many association' do
69
+ before do
70
+ define_model :child
71
+ @model = define_model :parent do
72
+ has_and_belongs_to_many :children
73
+ end.new
74
+ create_table 'children_parents', :id => false do |t|
75
+ t.integer :child_id
76
+ t.integer :parent_id
77
+ end
78
+ end
79
+
80
+ it 'rejects' do
81
+ @model.should_not validate_presence_of(:children)
82
+ end
83
+ end
84
+
85
+ if active_model_3_2?
86
+ context 'a strictly required attribute' do
87
+ it 'accepts when the :strict options match' do
88
+ validating_presence(:strict => true).should matcher.strict
89
+ end
90
+
91
+ it 'rejects when the :strict options do not match' do
92
+ validating_presence(:strict => false).should_not matcher.strict
93
+ end
94
+ end
95
+
96
+ it 'does not override the default message with a blank' do
97
+ validating_presence(:strict => true).
98
+ should matcher.strict.with_message(nil)
99
+ end
100
+ end
101
+
102
+ def matcher
103
+ validate_presence_of(:attr)
104
+ end
105
+
106
+ def validating_presence(options = {})
107
+ define_model :example, :attr => :string do
108
+ validates_presence_of :attr, options
109
+ end.new
110
+ end
111
+
112
+ def active_model_validating_presence
113
+ define_active_model_class('Example', :accessors => [:attr]) do
114
+ validates_presence_of :attr
115
+ end.new
116
+ end
117
+
118
+ def has_many_children(options = {})
119
+ define_model :child
120
+ define_model :parent do
121
+ has_many :children
122
+ if options[:presence]
123
+ validates_presence_of :children
124
+ end
125
+ end.new
126
+ end
127
+ end
@@ -0,0 +1,175 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveModel::ValidateUniquenessOfMatcher do
4
+ context 'a model without a a uniqueness validation' do
5
+ it 'rejects' do
6
+ model = define_model(:example, :attr => :string) { attr_accessible :attr } .new
7
+ Example.create!(:attr => 'value')
8
+ model.should_not matcher
9
+ end
10
+ end
11
+
12
+ context 'a model with a uniqueness validation' do
13
+ context 'with an existing record' do
14
+ it 'requires a unique value for that attribute' do
15
+ create_existing
16
+ validating_uniqueness_with_other.should matcher
17
+ end
18
+
19
+ it 'accepts when the subject is an existing record' do
20
+ create_existing.should matcher
21
+ end
22
+
23
+ it 'rejects when a scope is specified' do
24
+ create_existing
25
+ validating_uniqueness_with_other.should_not matcher.scoped_to(:other)
26
+ end
27
+
28
+ def create_existing
29
+ define_model_with_other
30
+ Example.create!(:attr => 'value', :other => 1)
31
+ end
32
+ end
33
+
34
+ context 'without an existing record' do
35
+ it 'does not require a created instance' do
36
+ define_model_with_other
37
+ Example.count.should == 0
38
+ validating_uniqueness_with_other.should matcher
39
+ end
40
+ end
41
+
42
+ def define_model_with_other(options = {})
43
+ @model ||= define_model(:example, :attr => :string, :other => :integer) do
44
+ attr_accessible :attr, :other
45
+ validates_uniqueness_of :attr, options
46
+ end
47
+ end
48
+
49
+ def validating_uniqueness_with_other(options = {})
50
+ define_model_with_other.new
51
+ end
52
+ end
53
+
54
+ context 'a model with a uniqueness validation, a custom error, and an existing record' do
55
+ it 'rejects when the actual message does not match the default message' do
56
+ validating_uniqueness_with_existing_record(:message => 'Bad value').
57
+ should_not matcher
58
+ end
59
+
60
+ it 'rejects when the messages do not match' do
61
+ validating_uniqueness_with_existing_record(:message => 'Bad value').
62
+ should_not matcher.with_message(/abc/)
63
+ end
64
+
65
+ it 'accepts when the messages match' do
66
+ validating_uniqueness_with_existing_record(:message => 'Bad value').
67
+ should matcher.with_message(/Bad/)
68
+ end
69
+
70
+ def validating_uniqueness_with_existing_record(options = {})
71
+ model = define_model(:example, :attr => :string) do
72
+ attr_accessible :attr
73
+ validates_uniqueness_of :attr, options
74
+ end.new
75
+ Example.create!(:attr => 'value')
76
+ model
77
+ end
78
+ end
79
+
80
+ context 'a model with a scoped uniqueness validation with an existing value' do
81
+ it 'accepts when the correct scope is specified' do
82
+ validating_scoped_uniqueness([:scope1, :scope2]).
83
+ should matcher.scoped_to(:scope1, :scope2)
84
+ end
85
+
86
+ it 'accepts when the subject is an existing record' do
87
+ define_scoped_model([:scope1, :scope2])
88
+ create_existing_record.should matcher.scoped_to(:scope1, :scope2)
89
+ end
90
+
91
+ it 'rejects when too narrow of a scope is specified' do
92
+ validating_scoped_uniqueness([:scope1, :scope2]).
93
+ should_not matcher.scoped_to(:scope1, :scope2, :other)
94
+ end
95
+
96
+ it 'rejects when too broad of a scope is specified' do
97
+ validating_scoped_uniqueness([:scope1, :scope2]).
98
+ should_not matcher.scoped_to(:scope1)
99
+ end
100
+
101
+ it 'rejects when a different scope is specified' do
102
+ validating_scoped_uniqueness([:scope1]).
103
+ should_not matcher.scoped_to(:other)
104
+ end
105
+
106
+ it 'rejects when no scope is specified' do
107
+ validating_scoped_uniqueness([:scope1]).should_not matcher
108
+ end
109
+
110
+ it 'rejects when a non-existent attribute is specified as a scope' do
111
+ validating_scoped_uniqueness([:scope1]).
112
+ should_not matcher.scoped_to(:fake)
113
+ end
114
+
115
+ def create_existing_record
116
+ @existing ||= Example.create!(:attr => 'value', :scope1 => 1, :scope2 => 2, :other => 3)
117
+ end
118
+
119
+ def define_scoped_model(scope)
120
+ define_model(:example, :attr => :string, :scope1 => :integer,
121
+ :scope2 => :integer, :other => :integer) do
122
+ attr_accessible :attr, :scope1, :scope2, :other
123
+ validates_uniqueness_of :attr, :scope => scope
124
+ end
125
+ end
126
+
127
+ def validating_scoped_uniqueness(scope)
128
+ model = define_scoped_model(scope).new
129
+ create_existing_record
130
+ model
131
+ end
132
+ end
133
+
134
+ context 'a model with a case-sensitive uniqueness validation on a string attribute and an existing record' do
135
+ it 'accepts a case-sensitive value for that attribute' do
136
+ case_sensitive_validation_with_existing_value(:string).
137
+ should matcher
138
+ end
139
+
140
+ it 'rejects a case-insensitive value for that attribute' do
141
+ case_sensitive_validation_with_existing_value(:string).
142
+ should_not matcher.case_insensitive
143
+ end
144
+ end
145
+
146
+ context 'a model with a case-sensitive uniqueness validation on an integer attribute with an existing value' do
147
+ it 'accepts a case-insensitive value for that attribute' do
148
+ case_sensitive_validation_with_existing_value(:integer).
149
+ should matcher.case_insensitive
150
+ end
151
+
152
+ it 'accepts a case-sensitive value for that attribute' do
153
+ case_sensitive_validation_with_existing_value(:integer).should matcher
154
+ end
155
+ end
156
+
157
+ def case_sensitive_validation_with_existing_value(attr_type)
158
+ model = define_model(:example, :attr => attr_type) do
159
+ attr_accessible :attr
160
+ validates_uniqueness_of :attr, :case_sensitive => true
161
+ end.new
162
+ if attr_type == :string
163
+ Example.create!(:attr => 'value')
164
+ elsif attr_type == :integer
165
+ Example.create!(:attr => 1)
166
+ else
167
+ raise 'Must be :string or :integer'
168
+ end
169
+ model
170
+ end
171
+
172
+ def matcher
173
+ validate_uniqueness_of(:attr)
174
+ end
175
+ end
@@ -51,7 +51,6 @@ describe Shoulda::Matchers::ActiveModel::ValidationMessageFinder do
51
51
 
52
52
  context '#messages_description' do
53
53
  it 'describes errors for the given attribute' do
54
- value = 'xyz'
55
54
  finder = build_finder(
56
55
  :attribute => :attr,
57
56
  :format => /abc/,
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveRecord::AcceptNestedAttributesForMatcher do
4
+ it 'accepts an existing declaration' do
5
+ accepting_children.should accept_nested_attributes_for(:children)
6
+ end
7
+
8
+ it 'rejects a missing declaration' do
9
+ matcher = children_matcher
10
+
11
+ matcher.matches?(rejecting_children).should be_false
12
+
13
+ matcher.failure_message_for_should.should == 'Expected Parent to accept nested attributes for children (is not declared)'
14
+ end
15
+
16
+ context 'allow_destroy' do
17
+ it 'accepts a valid truthy value' do
18
+ matching = accepting_children(:allow_destroy => true)
19
+
20
+ matching.should children_matcher.allow_destroy(true)
21
+ end
22
+
23
+ it 'accepts a valid falsey value' do
24
+ matching = accepting_children(:allow_destroy => false)
25
+
26
+ matching.should children_matcher.allow_destroy(false)
27
+ end
28
+
29
+ it 'rejects an invalid truthy value' do
30
+ matcher = children_matcher
31
+ matching = accepting_children(:allow_destroy => true)
32
+
33
+ matcher.allow_destroy(false).matches?(matching).should be_false
34
+ matcher.failure_message_for_should.should =~ /should not allow destroy/
35
+ end
36
+
37
+ it 'rejects an invalid falsey value' do
38
+ matcher = children_matcher
39
+ matching = accepting_children(:allow_destroy => false)
40
+
41
+ matcher.allow_destroy(true).matches?(matching).should be_false
42
+ matcher.failure_message_for_should.should =~ /should allow destroy/
43
+ end
44
+ end
45
+
46
+ context 'limit' do
47
+ it 'accepts a correct value' do
48
+ accepting_children(:limit => 3).should children_matcher.limit(3)
49
+ end
50
+
51
+ it 'rejects a false value' do
52
+ matcher = children_matcher
53
+ rejecting = accepting_children(:limit => 3)
54
+
55
+ matcher.limit(2).matches?(rejecting).should be_false
56
+ matcher.failure_message_for_should.should =~ /limit should be 2, got 3/
57
+ end
58
+ end
59
+
60
+ context 'update_only' do
61
+ it 'accepts a valid truthy value' do
62
+ accepting_children(:update_only => true).
63
+ should children_matcher.update_only(true)
64
+ end
65
+
66
+ it 'accepts a valid falsey value' do
67
+ accepting_children(:update_only => false).
68
+ should children_matcher.update_only(false)
69
+ end
70
+
71
+ it 'rejects an invalid truthy value' do
72
+ matcher = children_matcher.update_only(false)
73
+ rejecting = accepting_children(:update_only => true)
74
+
75
+ matcher.matches?(rejecting).should be_false
76
+ matcher.failure_message_for_should.should =~ /should not be update only/
77
+ end
78
+
79
+ it 'rejects an invalid falsey value' do
80
+ matcher = children_matcher.update_only(true)
81
+ rejecting = accepting_children(:update_only => false)
82
+
83
+ matcher.matches?(rejecting).should be_false
84
+ matcher.failure_message_for_should.should =~ /should be update only/
85
+ end
86
+ end
87
+
88
+ def accepting_children(options = {})
89
+ define_model :child, :parent_id => :integer
90
+ define_model :parent do
91
+ has_many :children
92
+ accepts_nested_attributes_for :children, options
93
+ end.new
94
+ end
95
+
96
+ def children_matcher
97
+ accept_nested_attributes_for(:children)
98
+ end
99
+
100
+ def rejecting_children
101
+ define_model :child, :parent_id => :integer
102
+ define_model :parent do
103
+ has_many :children
104
+ end.new
105
+ end
106
+ end