Converted should_have_and_belong_to_many to use a matcher

This commit is contained in:
Joe Ferris 2008-12-15 15:31:44 -05:00
parent 1c7b67d9f4
commit 737f1f1f2f
3 changed files with 45 additions and 9 deletions

View File

@ -446,12 +446,9 @@ module Shoulda # :nodoc:
klass = model_class
associations.each do |association|
should "should have and belong to many #{association}" do
reflection = klass.reflect_on_association(association)
assert reflection, "#{klass.name} does not have any relationship to #{association}"
assert_equal :has_and_belongs_to_many, reflection.macro
table = reflection.options[:join_table]
assert ::ActiveRecord::Base.connection.tables.include?(table.to_s), "table #{table} doesn't exist"
matcher = have_and_belong_to_many(association)
should matcher.description do
assert_accepts(matcher, klass.new)
end
end
end

View File

@ -24,7 +24,8 @@ module Shoulda # :nodoc:
macro_correct? &&
foreign_key_exists? &&
through_association_valid? &&
dependent_correct?
dependent_correct? &&
join_table_exists?
end
def failure_message
@ -108,6 +109,16 @@ module Shoulda # :nodoc:
end
end
def join_table_exists?
if @macro != :has_and_belongs_to_many ||
::ActiveRecord::Base.connection.tables.include?(join_table.to_s)
true
else
@missing = "join table #{join_table} doesn't exist"
false
end
end
def class_has_foreign_key?(klass)
if klass.column_names.include?(foreign_key.to_s)
true
@ -121,6 +132,10 @@ module Shoulda # :nodoc:
@subject.class
end
def join_table
reflection.options[:join_table]
end
def associated_class
reflection.klass
end
@ -149,7 +164,9 @@ module Shoulda # :nodoc:
case @macro.to_s
when 'belongs_to' then 'belong to'
when 'has_many' then 'have many'
when 'has_one' then 'has one'
when 'has_one' then 'have one'
when 'has_and_belongs_to_many' then
'have and belong to many'
end
end
end
@ -166,6 +183,10 @@ module Shoulda # :nodoc:
AssociationMatcher.new(:has_one, name)
end
def have_and_belong_to_many(name)
AssociationMatcher.new(:has_and_belongs_to_many, name)
end
end
end
end

View File

@ -103,7 +103,7 @@ class ActiveRecordMatchersTest < Test::Unit::TestCase # :nodoc:
end
end
context "has_one" do
context "have_one" do
should "accept a valid association without any options" do
assert_accepts have_one(:friendship), User.new
end
@ -129,4 +129,22 @@ class ActiveRecordMatchersTest < Test::Unit::TestCase # :nodoc:
end
end
context "have_and_belong_to_many" do
should "accept a valid association" do
assert_accepts have_and_belong_to_many(:fleas), Dog.new
end
should "reject a nonexistent association" do
assert_rejects have_and_belong_to_many(:parties), User.new
end
should "reject an association with a nonexistent join table" do
assert_rejects have_and_belong_to_many(:stores), Product.new
end
should "reject an association of the wrong type" do
assert_rejects have_and_belong_to_many(:friends), User.new
end
end
end