shoulda-matchers 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/.gitignore +11 -0
  2. data/.travis.yml +13 -0
  3. data/Appraisals +4 -6
  4. data/CONTRIBUTING.md +38 -0
  5. data/Gemfile +8 -5
  6. data/Gemfile.lock +77 -41
  7. data/NEWS.md +32 -0
  8. data/README.md +84 -0
  9. data/Rakefile +5 -36
  10. data/features/rails_integration.feature +88 -0
  11. data/features/step_definitions/rails_steps.rb +111 -0
  12. data/features/support/env.rb +5 -0
  13. data/gemfiles/3.0.gemfile +14 -0
  14. data/gemfiles/3.0.gemfile.lock +142 -0
  15. data/gemfiles/3.1.gemfile +16 -0
  16. data/gemfiles/3.1.gemfile.lock +164 -0
  17. data/lib/shoulda/matchers/action_controller/assign_to_matcher.rb +6 -9
  18. data/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +1 -3
  19. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +10 -6
  20. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +1 -4
  21. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +6 -6
  22. data/lib/shoulda/matchers/action_controller/respond_with_content_type_matcher.rb +11 -10
  23. data/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +0 -2
  24. data/lib/shoulda/matchers/action_controller/route_matcher.rb +17 -14
  25. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +24 -16
  26. data/lib/shoulda/matchers/action_controller/set_the_flash_matcher.rb +52 -15
  27. data/lib/shoulda/matchers/action_mailer.rb +1 -1
  28. data/lib/shoulda/matchers/action_mailer/{have_sent_email.rb → have_sent_email_matcher.rb} +37 -21
  29. data/lib/shoulda/matchers/active_model.rb +1 -0
  30. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +9 -10
  31. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +60 -33
  32. data/lib/shoulda/matchers/active_model/ensure_length_of_matcher.rb +0 -1
  33. data/lib/shoulda/matchers/active_model/helpers.rb +13 -9
  34. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +63 -0
  35. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +38 -8
  36. data/lib/shoulda/matchers/active_model/validation_matcher.rb +1 -5
  37. data/lib/shoulda/matchers/active_record.rb +3 -1
  38. data/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +127 -0
  39. data/lib/shoulda/matchers/active_record/association_matcher.rb +19 -7
  40. data/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +20 -5
  41. data/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +4 -10
  42. data/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +3 -7
  43. data/lib/shoulda/matchers/active_record/query_the_database_matcher.rb +107 -0
  44. data/lib/shoulda/matchers/active_record/serialize_matcher.rb +111 -0
  45. data/lib/shoulda/matchers/integrations/rspec.rb +0 -1
  46. data/lib/shoulda/matchers/version.rb +1 -1
  47. data/shoulda-matchers.gemspec +30 -0
  48. data/spec/fixtures/addresses.yml +3 -0
  49. data/spec/fixtures/friendships.yml +0 -0
  50. data/spec/fixtures/posts.yml +5 -0
  51. data/spec/fixtures/products.yml +0 -0
  52. data/spec/fixtures/taggings.yml +0 -0
  53. data/spec/fixtures/tags.yml +9 -0
  54. data/spec/fixtures/users.yml +6 -0
  55. data/spec/shoulda/action_controller/assign_to_matcher_spec.rb +61 -0
  56. data/spec/shoulda/action_controller/filter_param_matcher_spec.rb +20 -0
  57. data/spec/shoulda/action_controller/redirect_to_matcher_spec.rb +40 -0
  58. data/spec/shoulda/action_controller/render_template_matcher_spec.rb +69 -0
  59. data/spec/shoulda/action_controller/render_with_layout_matcher_spec.rb +47 -0
  60. data/spec/shoulda/action_controller/respond_with_content_type_matcher_spec.rb +28 -0
  61. data/spec/shoulda/action_controller/respond_with_matcher_spec.rb +83 -0
  62. data/spec/shoulda/action_controller/route_matcher_spec.rb +65 -0
  63. data/spec/shoulda/action_controller/set_session_matcher_spec.rb +46 -0
  64. data/spec/shoulda/action_controller/set_the_flash_matcher_spec.rb +124 -0
  65. data/spec/shoulda/action_mailer/have_sent_email_spec.rb +293 -0
  66. data/spec/shoulda/active_model/allow_mass_assignment_of_matcher_spec.rb +95 -0
  67. data/spec/shoulda/active_model/allow_value_matcher_spec.rb +91 -0
  68. data/spec/shoulda/active_model/ensure_exclusion_of_matcher_spec.rb +57 -0
  69. data/spec/shoulda/active_model/ensure_inclusion_of_matcher_spec.rb +71 -0
  70. data/spec/shoulda/active_model/ensure_length_of_matcher_spec.rb +125 -0
  71. data/spec/shoulda/active_model/helpers_spec.rb +100 -0
  72. data/spec/shoulda/active_model/validate_acceptance_of_matcher_spec.rb +43 -0
  73. data/spec/shoulda/active_model/validate_confirmation_of_matcher_spec.rb +48 -0
  74. data/spec/shoulda/active_model/validate_format_of_matcher_spec.rb +38 -0
  75. data/spec/shoulda/active_model/validate_numericality_of_matcher_spec.rb +62 -0
  76. data/spec/shoulda/active_model/validate_presence_of_matcher_spec.rb +121 -0
  77. data/spec/shoulda/active_model/validate_uniqueness_of_matcher_spec.rb +143 -0
  78. data/spec/shoulda/active_record/accept_nested_attributes_for_matcher_spec.rb +84 -0
  79. data/spec/shoulda/active_record/association_matcher_spec.rb +449 -0
  80. data/spec/shoulda/active_record/have_db_column_matcher_spec.rb +185 -0
  81. data/spec/shoulda/active_record/have_db_index_matcher_spec.rb +88 -0
  82. data/spec/shoulda/active_record/have_readonly_attributes_matcher_spec.rb +46 -0
  83. data/spec/shoulda/active_record/query_the_database_matcher_spec.rb +45 -0
  84. data/spec/shoulda/active_record/serialize_matcher_spec.rb +81 -0
  85. data/spec/spec_helper.rb +31 -0
  86. data/spec/support/model_builder.rb +149 -0
  87. metadata +211 -60
  88. data/CONTRIBUTION_GUIDELINES.rdoc +0 -10
  89. data/README.rdoc +0 -80
@@ -0,0 +1,84 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveRecord::AcceptNestedAttributesForMatcher do
4
+ before do
5
+ define_model :child, :parent_id => :integer
6
+ define_model :parent do
7
+ has_many :children
8
+ end
9
+ end
10
+
11
+ let(:parent) { Parent.new }
12
+ let(:matcher) { accept_nested_attributes_for(:children) }
13
+
14
+ it "should accept an existing declaration" do
15
+ Parent.accepts_nested_attributes_for :children
16
+ matcher.matches?(parent).should be_true
17
+ end
18
+
19
+ it "should reject a missing declaration" do
20
+ matcher.matches?(parent).should be_false
21
+ matcher.failure_message.should == "Expected Parent to accept nested attributes for children (is not declared)"
22
+ end
23
+
24
+ context "allow_destroy" do
25
+ it "should accept a valid truthy value" do
26
+ Parent.accepts_nested_attributes_for :children, :allow_destroy => true
27
+ matcher.allow_destroy(true).matches?(parent).should be_true
28
+ end
29
+
30
+ it "should accept a valid falsey value" do
31
+ Parent.accepts_nested_attributes_for :children, :allow_destroy => false
32
+ matcher.allow_destroy(false).matches?(parent).should be_true
33
+ end
34
+
35
+ it "should reject an invalid truthy value" do
36
+ Parent.accepts_nested_attributes_for :children, :allow_destroy => true
37
+ matcher.allow_destroy(false).matches?(parent).should be_false
38
+ matcher.failure_message.should =~ /should not allow destroy/
39
+ end
40
+
41
+ it "should reject an invalid falsey value" do
42
+ Parent.accepts_nested_attributes_for :children, :allow_destroy => false
43
+ matcher.allow_destroy(true).matches?(parent).should be_false
44
+ matcher.failure_message.should =~ /should allow destroy/
45
+ end
46
+ end
47
+
48
+ context "limit" do
49
+ it "should accept a correct value" do
50
+ Parent.accepts_nested_attributes_for :children, :limit => 3
51
+ matcher.limit(3).matches?(parent).should be_true
52
+ end
53
+
54
+ it "should reject a false value" do
55
+ Parent.accepts_nested_attributes_for :children, :limit => 3
56
+ matcher.limit(2).matches?(parent).should be_false
57
+ matcher.failure_message.should =~ /limit should be 2, got 3/
58
+ end
59
+ end
60
+
61
+ context "update_only" do
62
+ it "should accept a valid truthy value" do
63
+ Parent.accepts_nested_attributes_for :children, :update_only => true
64
+ matcher.update_only(true).matches?(parent).should be_true
65
+ end
66
+
67
+ it "should accept a valid falsey value" do
68
+ Parent.accepts_nested_attributes_for :children, :update_only => false
69
+ matcher.update_only(false).matches?(parent).should be_true
70
+ end
71
+
72
+ it "should reject an invalid truthy value" do
73
+ Parent.accepts_nested_attributes_for :children, :update_only => true
74
+ matcher.update_only(false).matches?(parent).should be_false
75
+ matcher.failure_message.should =~ /should not be update only/
76
+ end
77
+
78
+ it "should reject an invalid falsey value" do
79
+ Parent.accepts_nested_attributes_for :children, :update_only => false
80
+ matcher.update_only(true).matches?(parent).should be_false
81
+ matcher.failure_message.should =~ /should be update only/
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,449 @@
1
+ require 'spec_helper'
2
+
3
+ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
4
+ context "belong_to" do
5
+ before do
6
+ @matcher = belong_to(:parent)
7
+ end
8
+
9
+ it "should accept a good association with the default foreign key" do
10
+ define_model :parent
11
+ define_model :child, :parent_id => :integer do
12
+ belongs_to :parent
13
+ end
14
+ Child.new.should @matcher
15
+ end
16
+
17
+ it "should reject a nonexistent association" do
18
+ define_model :child
19
+ Child.new.should_not @matcher
20
+ end
21
+
22
+ it "should reject an association of the wrong type" do
23
+ define_model :parent, :child_id => :integer
24
+ child_class = define_model :child do
25
+ has_one :parent
26
+ end
27
+ Child.new.should_not @matcher
28
+ end
29
+
30
+ it "should reject an association that has a nonexistent foreign key" do
31
+ define_model :parent
32
+ define_model :child do
33
+ belongs_to :parent
34
+ end
35
+ Child.new.should_not @matcher
36
+ end
37
+
38
+ it "should accept an association with an existing custom foreign key" do
39
+ define_model :parent
40
+ define_model :child, :guardian_id => :integer do
41
+ belongs_to :parent, :foreign_key => 'guardian_id'
42
+ end
43
+ Child.new.should @matcher
44
+ end
45
+
46
+ it "should accept a polymorphic association" do
47
+ define_model :child, :parent_type => :string,
48
+ :parent_id => :integer do
49
+ belongs_to :parent, :polymorphic => true
50
+ end
51
+ Child.new.should @matcher
52
+ end
53
+
54
+ it "should accept an association with a valid :dependent option" do
55
+ define_model :parent
56
+ define_model :child, :parent_id => :integer do
57
+ belongs_to :parent, :dependent => :destroy
58
+ end
59
+ Child.new.should @matcher.dependent(:destroy)
60
+ end
61
+
62
+ it "should reject an association with a bad :dependent option" do
63
+ define_model :parent
64
+ define_model :child, :parent_id => :integer do
65
+ belongs_to :parent
66
+ end
67
+ Child.new.should_not @matcher.dependent(:destroy)
68
+ end
69
+
70
+ it "should accept an association with a valid :conditions option" do
71
+ define_model :parent, :adopter => :boolean
72
+ define_model :child, :parent_id => :integer do
73
+ belongs_to :parent, :conditions => { :adopter => true }
74
+ end
75
+ Child.new.should @matcher.conditions(:adopter => true)
76
+ end
77
+
78
+ it "should reject an association with a bad :conditions option" do
79
+ define_model :parent, :adopter => :boolean
80
+ define_model :child, :parent_id => :integer do
81
+ belongs_to :parent
82
+ end
83
+ Child.new.should_not @matcher.conditions(:adopter => true)
84
+ end
85
+
86
+ it "should accept an association with a valid :class_name option" do
87
+ define_model :tree_parent, :adopter => :boolean
88
+ define_model :child, :parent_id => :integer do
89
+ belongs_to :parent, :class_name => 'TreeParent'
90
+ end
91
+ Child.new.should @matcher.class_name('TreeParent')
92
+ end
93
+
94
+ it "should reject an association with a bad :class_name option" do
95
+ define_model :parent, :adopter => :boolean
96
+ define_model :child, :parent_id => :integer do
97
+ belongs_to :parent
98
+ end
99
+ Child.new.should_not @matcher.class_name('TreeChild')
100
+ end
101
+ end
102
+
103
+ context "have_many" do
104
+ before do
105
+ @matcher = have_many(:children)
106
+ end
107
+
108
+ it "should accept a valid association without any options" do
109
+ define_model :child, :parent_id => :integer
110
+ define_model :parent do
111
+ has_many :children
112
+ end
113
+ Parent.new.should @matcher
114
+ end
115
+
116
+ it "should accept a valid association with a :through option" do
117
+ define_model :child
118
+ define_model :conception, :child_id => :integer,
119
+ :parent_id => :integer do
120
+ belongs_to :child
121
+ end
122
+ define_model :parent do
123
+ has_many :conceptions
124
+ has_many :children, :through => :conceptions
125
+ end
126
+ Parent.new.should @matcher
127
+ end
128
+
129
+ it "should accept a valid association with an :as option" do
130
+ define_model :child, :guardian_type => :string,
131
+ :guardian_id => :integer
132
+ define_model :parent do
133
+ has_many :children, :as => :guardian
134
+ end
135
+ Parent.new.should @matcher
136
+ end
137
+
138
+ it "should reject an association that has a nonexistent foreign key" do
139
+ define_model :child
140
+ define_model :parent do
141
+ has_many :children
142
+ end
143
+ Parent.new.should_not @matcher
144
+ end
145
+
146
+ it "should reject an association with a bad :as option" do
147
+ define_model :child, :caretaker_type => :string,
148
+ :caretaker_id => :integer
149
+ define_model :parent do
150
+ has_many :children, :as => :guardian
151
+ end
152
+ Parent.new.should_not @matcher
153
+ end
154
+
155
+ it "should reject an association that has a bad :through option" do
156
+ define_model :child, :parent_id => :integer
157
+ define_model :parent do
158
+ has_many :children
159
+ end
160
+ @matcher.through(:conceptions).matches?(Parent.new).should be_false
161
+ @matcher.failure_message.should =~ /does not have any relationship to conceptions/
162
+ end
163
+
164
+ it "should reject an association that has the wrong :through option" do
165
+ define_model :child
166
+ define_model :conception, :child_id => :integer,
167
+ :parent_id => :integer do
168
+ belongs_to :child
169
+ end
170
+ define_model :parent do
171
+ has_many :conceptions
172
+ has_many :relationships
173
+ has_many :children, :through => :conceptions
174
+ end
175
+ @matcher.through(:relationships).matches?(Parent.new).should be_false
176
+ @matcher.failure_message.should =~ /through relationships, but got it through conceptions/
177
+ end
178
+
179
+ it "should accept an association with a valid :dependent option" do
180
+ define_model :child, :parent_id => :integer
181
+ define_model :parent do
182
+ has_many :children, :dependent => :destroy
183
+ end
184
+ Parent.new.should @matcher.dependent(:destroy)
185
+ end
186
+
187
+ it "should reject an association with a bad :dependent option" do
188
+ define_model :child, :parent_id => :integer
189
+ define_model :parent do
190
+ has_many :children
191
+ end
192
+ Parent.new.should_not @matcher.dependent(:destroy)
193
+ end
194
+
195
+ it "should accept an association with a valid :order option" do
196
+ define_model :child, :parent_id => :integer
197
+ define_model :parent do
198
+ has_many :children, :order => :id
199
+ end
200
+ Parent.new.should @matcher.order(:id)
201
+ end
202
+
203
+ it "should reject an association with a bad :order option" do
204
+ define_model :child, :parent_id => :integer
205
+ define_model :parent do
206
+ has_many :children
207
+ end
208
+ Parent.new.should_not @matcher.order(:id)
209
+ end
210
+
211
+ it "should accept an association with a valid :conditions option" do
212
+ define_model :child, :parent_id => :integer, :adopted => :boolean
213
+ define_model :parent do
214
+ has_many :children, :conditions => { :adopted => true }
215
+ end
216
+ Parent.new.should @matcher.conditions({ :adopted => true })
217
+ end
218
+
219
+ it "should reject an association with a bad :conditions option" do
220
+ define_model :child, :parent_id => :integer, :adopted => :boolean
221
+ define_model :parent do
222
+ has_many :children
223
+ end
224
+ Parent.new.should_not @matcher.conditions({ :adopted => true })
225
+ end
226
+
227
+ it "should accept an association with a valid :class_name option" do
228
+ define_model :node, :parent_id => :integer, :adopted => :boolean
229
+ define_model :parent do
230
+ has_many :children, :class_name => 'Node'
231
+ end
232
+ Parent.new.should @matcher.class_name('Node')
233
+ end
234
+
235
+ it "should reject an association with a bad :class_name option" do
236
+ define_model :child, :parent_id => :integer, :adopted => :boolean
237
+ define_model :parent do
238
+ has_many :children
239
+ end
240
+ Parent.new.should_not @matcher.class_name('Node')
241
+ end
242
+
243
+ it "should accept an association with a nonstandard reverse foreign key, using :inverse_of" do
244
+ define_model :child, :ancestor_id => :integer do
245
+ belongs_to :ancestor, :inverse_of => :children, :class_name => :Parent
246
+ end
247
+ define_model :parent do
248
+ has_many :children, :inverse_of => :ancestor
249
+ end
250
+ Parent.new.should @matcher
251
+ end
252
+
253
+ it "should reject an association with a nonstandard reverse foreign key, if :inverse_of is not correct" do
254
+ define_model :child, :mother_id => :integer do
255
+ belongs_to :mother, :inverse_of => :children, :class_name => :Parent
256
+ end
257
+ define_model :parent do
258
+ has_many :children, :inverse_of => :ancestor
259
+ end
260
+ Parent.new.should_not @matcher
261
+ end
262
+ end
263
+
264
+ context "have_one" do
265
+ before do
266
+ @matcher = have_one(:detail)
267
+ end
268
+
269
+ it "should accept a valid association without any options" do
270
+ define_model :detail, :person_id => :integer
271
+ define_model :person do
272
+ has_one :detail
273
+ end
274
+ Person.new.should @matcher
275
+ end
276
+
277
+ it "should accept a valid association with an :as option" do
278
+ define_model :detail, :detailable_id => :integer,
279
+ :detailable_type => :string
280
+ define_model :person do
281
+ has_one :detail, :as => :detailable
282
+ end
283
+ Person.new.should @matcher
284
+ end
285
+
286
+ it "should reject an association that has a nonexistent foreign key" do
287
+ define_model :detail
288
+ define_model :person do
289
+ has_one :detail
290
+ end
291
+ Person.new.should_not @matcher
292
+ end
293
+
294
+ it "should reject an association with a bad :as option" do
295
+ define_model :detail, :detailable_id => :integer,
296
+ :detailable_type => :string
297
+ define_model :person do
298
+ has_one :detail, :as => :describable
299
+ end
300
+ Person.new.should_not @matcher
301
+ end
302
+
303
+ it "should accept an association with a valid :dependent option" do
304
+ define_model :detail, :person_id => :integer
305
+ define_model :person do
306
+ has_one :detail, :dependent => :destroy
307
+ end
308
+ Person.new.should @matcher.dependent(:destroy)
309
+ end
310
+
311
+ it "should reject an association with a bad :dependent option" do
312
+ define_model :detail, :person_id => :integer
313
+ define_model :person do
314
+ has_one :detail
315
+ end
316
+ Person.new.should_not @matcher.dependent(:destroy)
317
+ end
318
+
319
+ it "should accept an association with a valid :order option" do
320
+ define_model :detail, :person_id => :integer
321
+ define_model :person do
322
+ has_one :detail, :order => :id
323
+ end
324
+ Person.new.should @matcher.order(:id)
325
+ end
326
+
327
+ it "should reject an association with a bad :order option" do
328
+ define_model :detail, :person_id => :integer
329
+ define_model :person do
330
+ has_one :detail
331
+ end
332
+ Person.new.should_not @matcher.order(:id)
333
+ end
334
+
335
+ it "should accept an association with a valid :conditions option" do
336
+ define_model :detail, :person_id => :integer, :disabled => :boolean
337
+ define_model :person do
338
+ has_one :detail, :conditions => { :disabled => true}
339
+ end
340
+ Person.new.should @matcher.conditions(:disabled => true)
341
+ end
342
+
343
+ it "should reject an association with a bad :conditions option" do
344
+ define_model :detail, :person_id => :integer, :disabled => :boolean
345
+ define_model :person do
346
+ has_one :detail
347
+ end
348
+ Person.new.should_not @matcher.conditions(:disabled => true)
349
+ end
350
+
351
+ it "should accept an association with a valid :class_name option" do
352
+ define_model :person_detail, :person_id => :integer, :disabled => :boolean
353
+ define_model :person do
354
+ has_one :detail, :class_name => 'PersonDetail'
355
+ end
356
+ Person.new.should @matcher.class_name('PersonDetail')
357
+ end
358
+
359
+ it "should reject an association with a bad :class_name option" do
360
+ define_model :detail, :person_id => :integer, :disabled => :boolean
361
+ define_model :person do
362
+ has_one :detail
363
+ end
364
+ Person.new.should_not @matcher.class_name('PersonDetail')
365
+ end
366
+
367
+ end
368
+
369
+ context "have_and_belong_to_many" do
370
+ before do
371
+ @matcher = have_and_belong_to_many(:relatives)
372
+ end
373
+
374
+ it "should accept a valid association" do
375
+ define_model :relatives
376
+ define_model :person do
377
+ has_and_belongs_to_many :relatives
378
+ end
379
+ define_model :people_relative, :person_id => :integer,
380
+ :relative_id => :integer
381
+ Person.new.should @matcher
382
+ end
383
+
384
+ it "should reject a nonexistent association" do
385
+ define_model :relatives
386
+ define_model :person
387
+ define_model :people_relative, :person_id => :integer,
388
+ :relative_id => :integer
389
+ Person.new.should_not @matcher
390
+ end
391
+
392
+ it "should reject an association with a nonexistent join table" do
393
+ define_model :relatives
394
+ define_model :person do
395
+ has_and_belongs_to_many :relatives
396
+ end
397
+ Person.new.should_not @matcher
398
+ end
399
+
400
+ it "should reject an association of the wrong type" do
401
+ define_model :relatives, :person_id => :integer
402
+ define_model :person do
403
+ has_many :relatives
404
+ end
405
+ Person.new.should_not @matcher
406
+ end
407
+
408
+ it "should accept an association with a valid :conditions option" do
409
+ define_model :relatives, :adopted => :boolean
410
+ define_model :person do
411
+ has_and_belongs_to_many :relatives, :conditions => { :adopted => true }
412
+ end
413
+ define_model :people_relative, :person_id => :integer,
414
+ :relative_id => :integer
415
+ Person.new.should @matcher.conditions(:adopted => true)
416
+ end
417
+
418
+ it "should reject an association with a bad :conditions option" do
419
+ define_model :relatives, :adopted => :boolean
420
+ define_model :person do
421
+ has_and_belongs_to_many :relatives
422
+ end
423
+ define_model :people_relative, :person_id => :integer,
424
+ :relative_id => :integer
425
+ Person.new.should_not @matcher.conditions(:adopted => true)
426
+ end
427
+
428
+ it "should accept an association with a valid :class_name option" do
429
+ define_model :person_relatives, :adopted => :boolean
430
+ define_model :person do
431
+ has_and_belongs_to_many :relatives, :class_name => 'PersonRelatives'
432
+ end
433
+ define_model :people_person_relative, :person_id => :integer,
434
+ :person_relative_id => :integer
435
+ Person.new.should @matcher.class_name('PersonRelatives')
436
+ end
437
+
438
+ it "should reject an association with a bad :class_name option" do
439
+ define_model :relatives, :adopted => :boolean
440
+ define_model :person do
441
+ has_and_belongs_to_many :relatives
442
+ end
443
+ define_model :people_relative, :person_id => :integer,
444
+ :relative_id => :integer
445
+ Person.new.should_not @matcher.class_name('PersonRelatives')
446
+ end
447
+
448
+ end
449
+ end