shoulda-matchers 1.4.2 → 1.5.0

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