reflection_test.rb 9.7 KB
Newer Older
1
require "cases/helper"
J
Jeremy Kemper 已提交
2 3 4 5 6
require 'models/topic'
require 'models/customer'
require 'models/company'
require 'models/company_in_module'
require 'models/subscriber'
7
require 'models/ship'
8
require 'models/pirate'
9
require 'models/price_estimate'
D
Initial  
David Heinemeier Hansson 已提交
10

11
class ReflectionTest < ActiveRecord::TestCase
12 13
  include ActiveRecord::Reflection

14
  fixtures :topics, :customers, :companies, :subscribers, :price_estimates
15

D
Initial  
David Heinemeier Hansson 已提交
16 17 18 19
  def setup
    @first = Topic.find(1)
  end

20
  def test_human_name
21 22
    assert_equal "Price estimate", PriceEstimate.model_name.human
    assert_equal "Subscriber", Subscriber.model_name.human
23 24
  end

25 26 27 28 29 30
  def test_column_null_not_null
    subscriber = Subscriber.find(:first)
    assert subscriber.column_for_attribute("name").null
    assert !subscriber.column_for_attribute("nick").null
  end

D
Initial  
David Heinemeier Hansson 已提交
31 32
  def test_read_attribute_names
    assert_equal(
33
      %w( id title author_name author_email_address bonus_time written_on last_read content approved replies_count parent_id parent_title type ).sort,
D
Initial  
David Heinemeier Hansson 已提交
34 35 36
      @first.attribute_names
    )
  end
37

D
Initial  
David Heinemeier Hansson 已提交
38
  def test_columns
39
    assert_equal 13, Topic.columns.length
D
Initial  
David Heinemeier Hansson 已提交
40 41
  end

42 43
  def test_columns_are_returned_in_the_order_they_were_declared
    column_names = Topic.columns.map { |column| column.name }
44
    assert_equal %w(id title author_name author_email_address written_on bonus_time last_read content approved replies_count parent_id parent_title type), column_names
45 46
  end

D
Initial  
David Heinemeier Hansson 已提交
47
  def test_content_columns
48 49
    content_columns        = Topic.content_columns
    content_column_names   = content_columns.map {|column| column.name}
50 51
    assert_equal 9, content_columns.length
    assert_equal %w(title author_name author_email_address written_on bonus_time last_read content approved parent_title).sort, content_column_names.sort
D
Initial  
David Heinemeier Hansson 已提交
52
  end
53

D
Initial  
David Heinemeier Hansson 已提交
54 55 56 57
  def test_column_string_type_and_limit
    assert_equal :string, @first.column_for_attribute("title").type
    assert_equal 255, @first.column_for_attribute("title").limit
  end
J
Jeremy Kemper 已提交
58

59 60 61 62 63
  def test_column_null_not_null
    subscriber = Subscriber.find(:first)
    assert subscriber.column_for_attribute("name").null
    assert !subscriber.column_for_attribute("nick").null
  end
D
Initial  
David Heinemeier Hansson 已提交
64 65 66 67

  def test_human_name_for_column
    assert_equal "Author name", @first.column_for_attribute("author_name").human_name
  end
68

D
Initial  
David Heinemeier Hansson 已提交
69 70
  def test_integer_columns
    assert_equal :integer, @first.column_for_attribute("id").type
71
  end
D
Initial  
David Heinemeier Hansson 已提交
72

73
  def test_reflection_klass_for_nested_class_name
74
    reflection = MacroReflection.new(nil, nil, { :class_name => 'MyApplication::Business::Company' }, nil)
75 76 77 78 79
    assert_nothing_raised do
      assert_equal MyApplication::Business::Company, reflection.klass
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
80
  def test_aggregation_reflection
81
    reflection_for_address = AggregateReflection.new(
82
      :composed_of, :address, { :mapping => [ %w(address_street street), %w(address_city city), %w(address_country country) ] }, Customer
D
Initial  
David Heinemeier Hansson 已提交
83 84
    )

85
    reflection_for_balance = AggregateReflection.new(
86
      :composed_of, :balance, { :class_name => "Money", :mapping => %w(balance amount) }, Customer
D
Initial  
David Heinemeier Hansson 已提交
87 88
    )

89
    reflection_for_gps_location = AggregateReflection.new(
90 91 92
      :composed_of, :gps_location, { }, Customer
    )

93 94 95
    assert Customer.reflect_on_all_aggregations.include?(reflection_for_gps_location)
    assert Customer.reflect_on_all_aggregations.include?(reflection_for_balance)
    assert Customer.reflect_on_all_aggregations.include?(reflection_for_address)
96

D
Initial  
David Heinemeier Hansson 已提交
97
    assert_equal reflection_for_address, Customer.reflect_on_aggregation(:address)
98

D
Initial  
David Heinemeier Hansson 已提交
99
    assert_equal Address, Customer.reflect_on_aggregation(:address).klass
J
Jeremy Kemper 已提交
100

101
    assert_equal Money, Customer.reflect_on_aggregation(:balance).klass
D
Initial  
David Heinemeier Hansson 已提交
102
  end
103

104 105 106 107 108 109 110 111 112
  def test_reflect_on_all_autosave_associations
    expected = Pirate.reflect_on_all_associations.select { |r| r.options[:autosave] }
    received = Pirate.reflect_on_all_autosave_associations

    assert !received.empty?
    assert_not_equal Pirate.reflect_on_all_associations.length, received.length
    assert_equal expected, received
  end

113
  def test_has_many_reflection
114
    reflection_for_clients = AssociationReflection.new(:has_many, :clients, { :order => "id", :dependent => :destroy }, Firm)
D
Initial  
David Heinemeier Hansson 已提交
115 116 117 118

    assert_equal reflection_for_clients, Firm.reflect_on_association(:clients)

    assert_equal Client, Firm.reflect_on_association(:clients).klass
119 120
    assert_equal 'companies', Firm.reflect_on_association(:clients).table_name

D
Initial  
David Heinemeier Hansson 已提交
121
    assert_equal Client, Firm.reflect_on_association(:clients_of_firm).klass
122 123 124 125
    assert_equal 'companies', Firm.reflect_on_association(:clients_of_firm).table_name
  end

  def test_has_one_reflection
126
    reflection_for_account = AssociationReflection.new(:has_one, :account, { :foreign_key => "firm_id", :dependent => :destroy }, Firm)
127 128 129 130
    assert_equal reflection_for_account, Firm.reflect_on_association(:account)

    assert_equal Account, Firm.reflect_on_association(:account).klass
    assert_equal 'accounts', Firm.reflect_on_association(:account).table_name
D
Initial  
David Heinemeier Hansson 已提交
131
  end
132

133 134 135 136 137 138 139 140 141
  def test_belongs_to_inferred_foreign_key_from_assoc_name
    Company.belongs_to :foo
    assert_equal "foo_id", Company.reflect_on_association(:foo).primary_key_name
    Company.belongs_to :bar, :class_name => "Xyzzy"
    assert_equal "bar_id", Company.reflect_on_association(:bar).primary_key_name
    Company.belongs_to :baz, :class_name => "Xyzzy", :foreign_key => "xyzzy_id"
    assert_equal "xyzzy_id", Company.reflect_on_association(:baz).primary_key_name
  end

D
Initial  
David Heinemeier Hansson 已提交
142
  def test_association_reflection_in_modules
143 144
    ActiveRecord::Base.store_full_sti_class = false
    
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
    assert_reflection MyApplication::Business::Firm,
      :clients_of_firm,
      :klass      => MyApplication::Business::Client,
      :class_name => 'Client',
      :table_name => 'companies'

    assert_reflection MyApplication::Billing::Account,
      :firm,
      :klass      => MyApplication::Business::Firm,
      :class_name => 'MyApplication::Business::Firm',
      :table_name => 'companies'

    assert_reflection MyApplication::Billing::Account,
      :qualified_billing_firm,
      :klass      => MyApplication::Billing::Firm,
      :class_name => 'MyApplication::Billing::Firm',
      :table_name => 'companies'

    assert_reflection MyApplication::Billing::Account,
      :unqualified_billing_firm,
      :klass      => MyApplication::Billing::Firm,
      :class_name => 'Firm',
      :table_name => 'companies'

    assert_reflection MyApplication::Billing::Account,
      :nested_qualified_billing_firm,
      :klass      => MyApplication::Billing::Nested::Firm,
      :class_name => 'MyApplication::Billing::Nested::Firm',
      :table_name => 'companies'

    assert_reflection MyApplication::Billing::Account,
      :nested_unqualified_billing_firm,
      :klass      => MyApplication::Billing::Nested::Firm,
      :class_name => 'Nested::Firm',
      :table_name => 'companies'
180 181
  ensure
    ActiveRecord::Base.store_full_sti_class = true
D
Initial  
David Heinemeier Hansson 已提交
182
  end
J
Jeremy Kemper 已提交
183

184
  def test_reflection_of_all_associations
185
    # FIXME these assertions bust a lot
186 187
    assert_equal 37, Firm.reflect_on_all_associations.size
    assert_equal 27, Firm.reflect_on_all_associations(:has_many).size
188
    assert_equal 10, Firm.reflect_on_all_associations(:has_one).size
189
    assert_equal 0, Firm.reflect_on_all_associations(:belongs_to).size
190
  end
191

192 193 194 195
  def test_reflection_should_not_raise_error_when_compared_to_other_object
    assert_nothing_raised { Firm.reflections[:clients] == Object.new }
  end

196
  def test_has_many_through_reflection
197
    assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books)
198 199
  end

200
  def test_collection_association
201 202 203 204 205 206 207
    assert Pirate.reflect_on_association(:birds).collection_association?
    assert Pirate.reflect_on_association(:parrots).collection_association?

    assert !Pirate.reflect_on_association(:ship).collection_association?
    assert !Ship.reflect_on_association(:pirate).collection_association?
  end

208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
  def test_default_association_validation
    assert AssociationReflection.new(:has_many, :clients, {}, Firm).validate?

    assert !AssociationReflection.new(:has_one, :client, {}, Firm).validate?
    assert !AssociationReflection.new(:belongs_to, :client, {}, Firm).validate?
    assert !AssociationReflection.new(:has_and_belongs_to_many, :clients, {}, Firm).validate?
  end

  def test_always_validate_association_if_explicit
    assert AssociationReflection.new(:has_one, :client, { :validate => true }, Firm).validate?
    assert AssociationReflection.new(:belongs_to, :client, { :validate => true }, Firm).validate?
    assert AssociationReflection.new(:has_many, :clients, { :validate => true }, Firm).validate?
    assert AssociationReflection.new(:has_and_belongs_to_many, :clients, { :validate => true }, Firm).validate?
  end

  def test_validate_association_if_autosave
    assert AssociationReflection.new(:has_one, :client, { :autosave => true }, Firm).validate?
    assert AssociationReflection.new(:belongs_to, :client, { :autosave => true }, Firm).validate?
    assert AssociationReflection.new(:has_many, :clients, { :autosave => true }, Firm).validate?
    assert AssociationReflection.new(:has_and_belongs_to_many, :clients, { :autosave => true }, Firm).validate?
  end

  def test_never_validate_association_if_explicit
    assert !AssociationReflection.new(:has_one, :client, { :autosave => true, :validate => false }, Firm).validate?
    assert !AssociationReflection.new(:belongs_to, :client, { :autosave => true, :validate => false }, Firm).validate?
    assert !AssociationReflection.new(:has_many, :clients, { :autosave => true, :validate => false }, Firm).validate?
    assert !AssociationReflection.new(:has_and_belongs_to_many, :clients, { :autosave => true, :validate => false }, Firm).validate?
  end

237 238 239 240 241 242 243
  private
    def assert_reflection(klass, association, options)
      assert reflection = klass.reflect_on_association(association)
      options.each do |method, value|
        assert_equal(value, reflection.send(method))
      end
    end
244
end