diff --git a/lib/shoulda/matchers/active_record/association_matcher.rb b/lib/shoulda/matchers/active_record/association_matcher.rb
index 15ccd7f6..911d8e27 100644
--- a/lib/shoulda/matchers/active_record/association_matcher.rb
+++ b/lib/shoulda/matchers/active_record/association_matcher.rb
@@ -18,6 +18,7 @@ module Shoulda # :nodoc:
# * through - association name for has_many :through
# * dependent - tests that the association makes use of the
# dependent option.
+ # * :class_name - tests that the association makes use of the class_name option.
#
# Example:
# it { should have_many(:friends) }
@@ -35,6 +36,7 @@ module Shoulda # :nodoc:
# Options:
# * :dependent - tests that the association makes use of the
# dependent option.
+ # * :class_name - tests that the association makes use of the class_name option.
#
# Example:
# it { should have_one(:god) } # unless hindu
@@ -72,12 +74,17 @@ module Shoulda # :nodoc:
@order = order
self
end
-
+
def conditions(conditions)
@conditions = conditions
self
end
+ def class_name(class_name)
+ @class_name = class_name
+ self
+ end
+
def matches?(subject)
@subject = subject
association_exists? &&
@@ -85,6 +92,7 @@ module Shoulda # :nodoc:
foreign_key_exists? &&
through_association_valid? &&
dependent_correct? &&
+ class_name_correct? &&
order_correct? &&
conditions_correct? &&
join_table_exists?
@@ -102,6 +110,7 @@ module Shoulda # :nodoc:
description = "#{macro_description} #{@name}"
description += " through #{@through}" if @through
description += " dependent => #{@dependent}" if @dependent
+ description += " class_name => #{@class_name}" if @class_name
description += " order => #{@order}" if @order
description
end
@@ -172,6 +181,15 @@ module Shoulda # :nodoc:
end
end
+ def class_name_correct?
+ if @class_name.nil? || @class_name.to_s == reflection.options[:class_name].to_s
+ true
+ else
+ @missing = "#{@name} should have #{@class_name} as class_name"
+ false
+ end
+ end
+
def order_correct?
if @order.nil? || @order.to_s == reflection.options[:order].to_s
true
diff --git a/spec/shoulda/active_record/association_matcher_spec.rb b/spec/shoulda/active_record/association_matcher_spec.rb
index ca3ed6ff..e9aea3e7 100644
--- a/spec/shoulda/active_record/association_matcher_spec.rb
+++ b/spec/shoulda/active_record/association_matcher_spec.rb
@@ -83,6 +83,22 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
end
Child.new.should_not @matcher.conditions(:adopter => true)
end
+
+ it "should accept an association with a valid :class_name option" do
+ define_model :tree_parent, :adopter => :boolean
+ define_model :child, :parent_id => :integer do
+ belongs_to :parent, :class_name => 'TreeParent'
+ end
+ Child.new.should @matcher.class_name('TreeParent')
+ end
+
+ it "should reject an association with a bad :class_name option" do
+ define_model :parent, :adopter => :boolean
+ define_model :child, :parent_id => :integer do
+ belongs_to :parent
+ end
+ Child.new.should_not @matcher.class_name('TreeChild')
+ end
end
context "have_many" do
@@ -208,6 +224,22 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
end
Parent.new.should_not @matcher.conditions({ :adopted => true })
end
+
+ it "should accept an association with a valid :class_name option" do
+ define_model :node, :parent_id => :integer, :adopted => :boolean
+ define_model :parent do
+ has_many :children, :class_name => 'Node'
+ end
+ Parent.new.should @matcher.class_name('Node')
+ end
+
+ it "should reject an association with a bad :class_name option" do
+ define_model :child, :parent_id => :integer, :adopted => :boolean
+ define_model :parent do
+ has_many :children
+ end
+ Parent.new.should_not @matcher.class_name('Node')
+ end
end
@@ -297,7 +329,23 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
end
Person.new.should_not @matcher.conditions(:disabled => true)
end
-
+
+ it "should accept an association with a valid :class_name option" do
+ define_model :person_detail, :person_id => :integer, :disabled => :boolean
+ define_model :person do
+ has_one :detail, :class_name => 'PersonDetail'
+ end
+ Person.new.should @matcher.class_name('PersonDetail')
+ end
+
+ it "should reject an association with a bad :class_name option" do
+ define_model :detail, :person_id => :integer, :disabled => :boolean
+ define_model :person do
+ has_one :detail
+ end
+ Person.new.should_not @matcher.class_name('PersonDetail')
+ end
+
end
context "have_and_belong_to_many" do
@@ -359,6 +407,26 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatcher do
Person.new.should_not @matcher.conditions(:adopted => true)
end
+ it "should accept an association with a valid :class_name option" do
+ define_model :person_relatives, :adopted => :boolean
+ define_model :person do
+ has_and_belongs_to_many :relatives, :class_name => 'PersonRelatives'
+ end
+ define_model :people_person_relative, :person_id => :integer,
+ :person_relative_id => :integer
+ Person.new.should @matcher.class_name('PersonRelatives')
+ end
+
+ it "should reject an association with a bad :class_name option" do
+ define_model :relatives, :adopted => :boolean
+ define_model :person do
+ has_and_belongs_to_many :relatives
+ end
+ define_model :people_relative, :person_id => :integer,
+ :relative_id => :integer
+ Person.new.should_not @matcher.class_name('PersonRelatives')
+ end
+
end
end