fixtures_test.rb 27.0 KB
Newer Older
1 2 3
require 'cases/helper'
require 'models/admin'
require 'models/admin/account'
4
require 'models/admin/randomly_named_c1'
5
require 'models/admin/user'
J
Jeremy Kemper 已提交
6
require 'models/binary'
7 8 9
require 'models/book'
require 'models/category'
require 'models/company'
J
Jeremy Kemper 已提交
10
require 'models/computer'
11
require 'models/course'
J
Jeremy Kemper 已提交
12 13
require 'models/developer'
require 'models/joke'
14
require 'models/matey'
J
Jeremy Kemper 已提交
15 16
require 'models/parrot'
require 'models/pirate'
17
require 'models/post'
18
require 'models/randomly_named_c1'
19
require 'models/reply'
20
require 'models/ship'
21 22 23 24
require 'models/task'
require 'models/topic'
require 'models/traffic_light'
require 'models/treasure'
25
require 'tempfile'
D
Initial  
David Heinemeier Hansson 已提交
26

27
class FixturesTest < ActiveRecord::TestCase
28 29 30
  self.use_instantiated_fixtures = true
  self.use_transactional_fixtures = false

31
  # other_topics fixture should not be included here
P
Pratik Naik 已提交
32
  fixtures :topics, :developers, :accounts, :tasks, :categories, :funny_jokes, :binaries, :traffic_lights
33

34
  FIXTURES = %w( accounts binaries companies customers
D
Initial  
David Heinemeier Hansson 已提交
35
                 developers developers_projects entrants
36
                 movies projects subscribers topics tasks )
37
  MATCH_ATTRIBUTE_NAME = /[a-zA-Z][-\w]*/
D
Initial  
David Heinemeier Hansson 已提交
38 39 40 41

  def test_clean_fixtures
    FIXTURES.each do |name|
      fixtures = nil
42
      assert_nothing_raised { fixtures = create_fixtures(name).first }
43
      assert_kind_of(ActiveRecord::FixtureSet, fixtures)
44
      fixtures.each { |_name, fixture|
D
Initial  
David Heinemeier Hansson 已提交
45 46 47 48 49 50 51
        fixture.each { |key, value|
          assert_match(MATCH_ATTRIBUTE_NAME, key)
        }
      }
    end
  end

52 53
  def test_broken_yaml_exception
    badyaml = Tempfile.new ['foo', '.yml']
54
    badyaml.write 'a: : '
55 56 57
    badyaml.flush

    dir  = File.dirname badyaml.path
58
    name = File.basename badyaml.path, '.yml'
59
    assert_raises(ActiveRecord::Fixture::FormatError) do
60
      ActiveRecord::FixtureSet.create_fixtures(dir, name)
61 62 63 64 65 66
    end
  ensure
    badyaml.close
    badyaml.unlink
  end

67
  def test_create_fixtures
68
    fixtures = ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT, "parrots")
69
    assert Parrot.find_by_name('Curious George'), 'George is not in the database'
70
    assert fixtures.detect { |f| f.name == 'parrots' }, "no fixtures named 'parrots' in #{fixtures.map(&:name).inspect}"
71 72
  end

D
Initial  
David Heinemeier Hansson 已提交
73 74 75 76
  def test_multiple_clean_fixtures
    fixtures_array = nil
    assert_nothing_raised { fixtures_array = create_fixtures(*FIXTURES) }
    assert_kind_of(Array, fixtures_array)
77
    fixtures_array.each { |fixtures| assert_kind_of(ActiveRecord::FixtureSet, fixtures) }
D
Initial  
David Heinemeier Hansson 已提交
78 79
  end

80
  def test_create_symbol_fixtures
81
    fixtures = ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT, :collections, :collections => Course) { Course.connection }
82

83
    assert Course.find_by_name('Collection'), 'course is not in the database'
84 85 86
    assert fixtures.detect { |f| f.name == 'collections' }, "no fixtures named 'collections' in #{fixtures.map(&:name).inspect}"
  end

A
Aaron Patterson 已提交
87 88 89 90 91 92
  def test_create_symbol_fixtures_is_deprecated
    assert_deprecated do
      ActiveRecord::FixtureSet.create_fixtures(FIXTURES_ROOT, :collections, :collections => 'Course') { Course.connection }
    end
  end

D
Initial  
David Heinemeier Hansson 已提交
93
  def test_attributes
94
    topics = create_fixtures("topics").first
D
Initial  
David Heinemeier Hansson 已提交
95 96 97 98 99
    assert_equal("The First Topic", topics["first"]["title"])
    assert_nil(topics["second"]["author_email_address"])
  end

  def test_inserts
A
Aaron Patterson 已提交
100
    create_fixtures("topics")
101 102
    first_row = ActiveRecord::Base.connection.select_one("SELECT * FROM topics WHERE author_name = 'David'")
    assert_equal("The First Topic", first_row["title"])
D
Initial  
David Heinemeier Hansson 已提交
103

104 105
    second_row = ActiveRecord::Base.connection.select_one("SELECT * FROM topics WHERE author_name = 'Mary'")
    assert_nil(second_row["author_email_address"])
D
Initial  
David Heinemeier Hansson 已提交
106 107
  end

108 109
  if ActiveRecord::Base.connection.supports_migrations?
    def test_inserts_with_pre_and_suffix
110
      # Reset cache to make finds on the new table work
111
      ActiveRecord::FixtureSet.reset_cache
112

113
      ActiveRecord::Base.connection.create_table :prefix_other_topics_suffix do |t|
114 115 116 117 118 119
        t.column :title, :string
        t.column :author_name, :string
        t.column :author_email_address, :string
        t.column :written_on, :datetime
        t.column :bonus_time, :time
        t.column :last_read, :date
120
        t.column :content, :string
121 122 123 124 125 126 127 128 129 130 131 132 133 134
        t.column :approved, :boolean, :default => true
        t.column :replies_count, :integer, :default => 0
        t.column :parent_id, :integer
        t.column :type, :string, :limit => 50
      end

      # Store existing prefix/suffix
      old_prefix = ActiveRecord::Base.table_name_prefix
      old_suffix = ActiveRecord::Base.table_name_suffix

      # Set a prefix/suffix we can test against
      ActiveRecord::Base.table_name_prefix = 'prefix_'
      ActiveRecord::Base.table_name_suffix = '_suffix'

135 136 137 138 139
      other_topic_klass = Class.new(ActiveRecord::Base) do
        def self.name
          "OtherTopic"
        end
      end
140

141
      topics = [create_fixtures("other_topics")].flatten.first
142

143 144 145
      # This checks for a caching problem which causes a bug in the fixtures
      # class-level configuration helper.
      assert_not_nil topics, "Fixture data inserted, but fixture objects not returned from create"
146 147 148 149 150 151 152 153 154 155 156 157 158

      first_row = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_other_topics_suffix WHERE author_name = 'David'")
      assert_not_nil first_row, "The prefix_other_topics_suffix table appears to be empty despite create_fixtures: the row with author_name = 'David' was not found"
      assert_equal("The First Topic", first_row["title"])

      second_row = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_other_topics_suffix WHERE author_name = 'Mary'")
      assert_nil(second_row["author_email_address"])

      assert_equal :prefix_other_topics_suffix, topics.table_name.to_sym
      # This assertion should preferably be the last in the list, because calling
      # other_topic_klass.table_name sets a class-level instance variable
      assert_equal :prefix_other_topics_suffix, other_topic_klass.table_name.to_sym

159
    ensure
160
      # Restore prefix/suffix to its previous values
161 162
      ActiveRecord::Base.table_name_prefix = old_prefix
      ActiveRecord::Base.table_name_suffix = old_suffix
163

164
      ActiveRecord::Base.connection.drop_table :prefix_other_topics_suffix rescue nil
165 166 167
    end
  end

168
  def test_insert_with_datetime
A
Aaron Patterson 已提交
169
    create_fixtures("tasks")
170 171 172 173
    first = Task.find(1)
    assert first
  end

D
Initial  
David Heinemeier Hansson 已提交
174 175 176 177 178
  def test_logger_level_invariant
    level = ActiveRecord::Base.logger.level
    create_fixtures('topics')
    assert_equal level, ActiveRecord::Base.logger.level
  end
179

D
Initial  
David Heinemeier Hansson 已提交
180
  def test_instantiation
181
    topics = create_fixtures("topics").first
D
Initial  
David Heinemeier Hansson 已提交
182 183
    assert_kind_of Topic, topics["first"].find
  end
184

D
Initial  
David Heinemeier Hansson 已提交
185 186 187
  def test_complete_instantiation
    assert_equal "The First Topic", @first.title
  end
188

D
Initial  
David Heinemeier Hansson 已提交
189 190 191 192
  def test_fixtures_from_root_yml_with_instantiation
    # assert_equal 2, @accounts.size
    assert_equal 50, @unknown.credit_limit
  end
193

D
Initial  
David Heinemeier Hansson 已提交
194 195 196
  def test_erb_in_fixtures
    assert_equal "fixture_5", @dev_5.name
  end
197 198

  def test_empty_yaml_fixture
199
    assert_not_nil ActiveRecord::FixtureSet.new( Account.connection, "accounts", Account, FIXTURES_ROOT + "/naked/yml/accounts")
200 201 202
  end

  def test_empty_yaml_fixture_with_a_comment_in_it
203
    assert_not_nil ActiveRecord::FixtureSet.new( Account.connection, "companies", Company, FIXTURES_ROOT + "/naked/yml/companies")
204 205
  end

206 207 208 209 210 211
  def test_nonexistent_fixture_file
    nonexistent_fixture_path = FIXTURES_ROOT + "/imnothere"

    #sanity check to make sure that this file never exists
    assert Dir[nonexistent_fixture_path+"*"].empty?

212
    assert_raise(Errno::ENOENT) do
213
      ActiveRecord::FixtureSet.new( Account.connection, "companies", Company, nonexistent_fixture_path)
214 215 216
    end
  end

217
  def test_dirty_dirty_yaml_file
J
Jason Noble 已提交
218
    assert_raise(ActiveRecord::Fixture::FormatError) do
219
      ActiveRecord::FixtureSet.new( Account.connection, "courses", Course, FIXTURES_ROOT + "/naked/yml/courses")
220 221 222
    end
  end

223 224
  def test_omap_fixtures
    assert_nothing_raised do
225
      fixtures = ActiveRecord::FixtureSet.new(Account.connection, 'categories', Category, FIXTURES_ROOT + "/categories_ordered")
226

227
      fixtures.each.with_index do |(name, fixture), i|
228 229 230 231
        assert_equal "fixture_no_#{i}", name
        assert_equal "Category #{i}", fixture['name']
      end
    end
232
  end
233 234

  def test_yml_file_in_subdirectory
D
David Heinemeier Hansson 已提交
235 236
    assert_equal(categories(:sub_special_1).name, "A special category in a subdir file")
    assert_equal(categories(:sub_special_1).class, SpecialCategory)
237 238 239
  end

  def test_subsubdir_file_with_arbitrary_name
D
David Heinemeier Hansson 已提交
240 241
    assert_equal(categories(:sub_special_3).name, "A special category in an arbitrarily named subsubdir file")
    assert_equal(categories(:sub_special_3).class, SpecialCategory)
242 243
  end

244
  def test_binary_in_fixtures
R
Rob 已提交
245
    data = File.open(ASSETS_ROOT + "/flowers.jpg", 'rb') { |f| f.read }
246
    data.force_encoding('ASCII-8BIT')
247
    data.freeze
248 249
    assert_equal data, @flowers.data
  end
P
Pratik Naik 已提交
250 251 252 253

  def test_serialized_fixtures
    assert_equal ["Green", "Red", "Orange"], traffic_lights(:uk).state
  end
254 255

  def test_fixtures_are_set_up_with_database_env_variable
256 257
    db_url_tmp = ENV['DATABASE_URL']
    ENV['DATABASE_URL'] = "sqlite3:///:memory:"
258 259 260 261 262 263 264 265 266 267 268 269
    ActiveRecord::Base.stubs(:configurations).returns({})
    test_case = Class.new(ActiveRecord::TestCase) do
      fixtures :accounts

      def test_fixtures
        assert accounts(:signals37)
      end
    end

    result = test_case.new(:test_fixtures).run

    assert result.passed?, "Expected #{result.name} to pass:\n#{result}"
270 271
  ensure
    ENV['DATABASE_URL'] = db_url_tmp
272
  end
J
Jeremy Kemper 已提交
273 274
end

275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
class HasManyThroughFixture < ActiveSupport::TestCase
  def make_model(name)
    Class.new(ActiveRecord::Base) { define_singleton_method(:name) { name } }
  end

  def test_has_many_through
    pt = make_model "ParrotTreasure"
    parrot = make_model "Parrot"
    treasure = make_model "Treasure"

    pt.table_name = "parrots_treasures"
    pt.belongs_to :parrot, :class => parrot
    pt.belongs_to :treasure, :class => treasure

    parrot.has_many :parrot_treasures, :class => pt
    parrot.has_many :treasures, :through => :parrot_treasures

    parrots = File.join FIXTURES_ROOT, 'parrots'

    fs = ActiveRecord::FixtureSet.new parrot.connection, "parrots", parrot, parrots
    rows = fs.table_rows
    assert_equal load_has_and_belongs_to_many['parrots_treasures'], rows['parrots_treasures']
  end

  def load_has_and_belongs_to_many
    parrot = make_model "Parrot"
    parrot.has_and_belongs_to_many :treasures

    parrots = File.join FIXTURES_ROOT, 'parrots'

    fs = ActiveRecord::FixtureSet.new parrot.connection, "parrots", parrot, parrots
    fs.table_rows
  end
end

J
Jeremy Kemper 已提交
310
if Account.connection.respond_to?(:reset_pk_sequence!)
311
  class FixturesResetPkSequenceTest < ActiveRecord::TestCase
J
Jeremy Kemper 已提交
312
    fixtures :accounts
313
    fixtures :companies
314

315 316
    def setup
      @instances = [Account.new(:credit_limit => 50), Company.new(:name => 'RoR Consulting')]
317
      ActiveRecord::FixtureSet.reset_cache # make sure tables get reinitialized
318 319 320 321 322 323 324
    end

    def test_resets_to_min_pk_with_specified_pk_and_sequence
      @instances.each do |instance|
        model = instance.class
        model.delete_all
        model.connection.reset_pk_sequence!(model.table_name, model.primary_key, model.sequence_name)
325

326 327 328
        instance.save!
        assert_equal 1, instance.id, "Sequence reset for #{model.table_name} failed."
      end
329 330
    end

331 332 333 334 335 336 337 338
    def test_resets_to_min_pk_with_default_pk_and_sequence
      @instances.each do |instance|
        model = instance.class
        model.delete_all
        model.connection.reset_pk_sequence!(model.table_name)

        instance.save!
        assert_equal 1, instance.id, "Sequence reset for #{model.table_name} failed."
339
      end
340
    end
341

342
    def test_create_fixtures_resets_sequences_when_not_cached
343
      @instances.each do |instance|
344
        max_id = create_fixtures(instance.class.table_name).first.fixtures.inject(0) do |_max_id, (_, fixture)|
345
          fixture_id = fixture['id'].to_i
346
          fixture_id > _max_id ? fixture_id : _max_id
347 348 349 350 351 352
        end

        # Clone the last fixture to check that it gets the next greatest id.
        instance.save!
        assert_equal max_id + 1, instance.id, "Sequence reset for #{instance.class.table_name} failed."
      end
353
    end
354
  end
355 356
end

357
class FixturesWithoutInstantiationTest < ActiveRecord::TestCase
358 359 360 361
  self.use_instantiated_fixtures = false
  fixtures :topics, :developers, :accounts

  def test_without_complete_instantiation
362 363 364 365
    assert !defined?(@first)
    assert !defined?(@topics)
    assert !defined?(@developers)
    assert !defined?(@accounts)
366 367 368
  end

  def test_fixtures_from_root_yml_without_instantiation
369
    assert !defined?(@unknown), "@unknown is not defined"
370
  end
371

372 373 374 375
  def test_visibility_of_accessor_method
    assert_equal false, respond_to?(:topics, false), "should be private method"
    assert_equal true, respond_to?(:topics, true), "confirm to respond surely"
  end
376 377 378 379 380 381

  def test_accessor_methods
    assert_equal "The First Topic", topics(:first).title
    assert_equal "Jamis", developers(:jamis).name
    assert_equal 50, accounts(:signals37).credit_limit
  end
382 383 384 385 386 387

  def test_accessor_methods_with_multiple_args
    assert_equal 2, topics(:first, :second).size
    assert_raise(StandardError) { topics([:first, :second]) }
  end

388 389 390 391
  def test_reloading_fixtures_through_accessor_methods
    assert_equal "The First Topic", topics(:first).title
    @loaded_fixtures['topics']['first'].expects(:find).returns(stub(:title => "Fresh Topic!"))
    assert_equal "Fresh Topic!", topics(:first, true).title
392
  end
393 394
end

395
class FixturesWithoutInstanceInstantiationTest < ActiveRecord::TestCase
396
  self.use_instantiated_fixtures = true
397
  self.use_instantiated_fixtures = :no_instances
398

399 400 401
  fixtures :topics, :developers, :accounts

  def test_without_instance_instantiation
402
    assert !defined?(@first), "@first is not defined"
403 404 405
  end
end

406
class TransactionalFixturesTest < ActiveRecord::TestCase
407
  self.use_instantiated_fixtures = true
408
  self.use_transactional_fixtures = true
409

410 411 412 413 414 415 416 417 418 419
  fixtures :topics

  def test_destroy
    assert_not_nil @first
    @first.destroy
  end

  def test_destroy_just_kidding
    assert_not_nil @first
  end
420
end
421

422
class MultipleFixturesTest < ActiveRecord::TestCase
423 424 425 426
  fixtures :topics
  fixtures :developers, :accounts

  def test_fixture_table_names
427
    assert_equal %w(topics developers accounts), fixture_table_names
428 429 430
  end
end

431
class SetupTest < ActiveRecord::TestCase
432
  # fixtures :topics
J
Jeremy Kemper 已提交
433

434 435 436
  def setup
    @first = true
  end
J
Jeremy Kemper 已提交
437

438 439 440 441 442 443 444 445 446
  def test_nothing
  end
end

class SetupSubclassTest < SetupTest
  def setup
    super
    @second = true
  end
J
Jeremy Kemper 已提交
447

448 449 450 451 452 453 454
  def test_subclassing_should_preserve_setups
    assert @first
    assert @second
  end
end


455
class OverlappingFixturesTest < ActiveRecord::TestCase
456 457 458 459
  fixtures :topics, :developers
  fixtures :developers, :accounts

  def test_fixture_table_names
460
    assert_equal %w(topics developers accounts), fixture_table_names
461 462
  end
end
463

464
class ForeignKeyFixturesTest < ActiveRecord::TestCase
465 466 467 468 469 470 471 472 473 474 475 476 477 478
  fixtures :fk_test_has_pk, :fk_test_has_fk

  # if foreign keys are implemented and fixtures
  # are not deleted in reverse order then this test
  # case will raise StatementInvalid

  def test_number1
    assert true
  end

  def test_number2
    assert true
  end
end
479

480 481 482 483 484 485 486 487 488 489 490 491 492 493 494
class OverRideFixtureMethodTest < ActiveRecord::TestCase
  fixtures :topics

  def topics(name)
    topic = super
    topic.title = 'omg'
    topic
  end

  def test_fixture_methods_can_be_overridden
    x = topics :first
    assert_equal 'omg', x.title
  end
end

495
class CheckSetTableNameFixturesTest < ActiveRecord::TestCase
496
  set_fixture_class :funny_jokes => Joke
497
  fixtures :funny_jokes
498
  # Set to false to blow away fixtures cache and ensure our fixtures are loaded
499 500
  # and thus takes into account our set_fixture_class
  self.use_transactional_fixtures = false
501

502 503 504 505
  def test_table_method
    assert_kind_of Joke, funny_jokes(:a_joke)
  end
end
506

507 508 509
class FixtureNameIsNotTableNameFixturesTest < ActiveRecord::TestCase
  set_fixture_class :items => Book
  fixtures :items
510
  # Set to false to blow away fixtures cache and ensure our fixtures are loaded
511 512 513 514 515 516 517 518 519 520 521
  # and thus takes into account our set_fixture_class
  self.use_transactional_fixtures = false

  def test_named_accessor
    assert_kind_of Book, items(:dvd)
  end
end

class FixtureNameIsNotTableNameMultipleFixturesTest < ActiveRecord::TestCase
  set_fixture_class :items => Book, :funny_jokes => Joke
  fixtures :items, :funny_jokes
522
  # Set to false to blow away fixtures cache and ensure our fixtures are loaded
523 524 525 526 527 528 529 530 531 532 533 534
  # and thus takes into account our set_fixture_class
  self.use_transactional_fixtures = false

  def test_named_accessor_of_differently_named_fixture
    assert_kind_of Book, items(:dvd)
  end

  def test_named_accessor_of_same_named_fixture
    assert_kind_of Joke, funny_jokes(:a_joke)
  end
end

535
class CustomConnectionFixturesTest < ActiveRecord::TestCase
536 537
  set_fixture_class :courses => Course
  fixtures :courses
538
  self.use_transactional_fixtures = false
539

540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
  def test_leaky_destroy
    assert_nothing_raised { courses(:ruby) }
    courses(:ruby).destroy
  end

  def test_it_twice_in_whatever_order_to_check_for_fixture_leakage
    test_leaky_destroy
  end
end

class TransactionalFixturesOnCustomConnectionTest < ActiveRecord::TestCase
  set_fixture_class :courses => Course
  fixtures :courses
  self.use_transactional_fixtures = true

  def test_leaky_destroy
    assert_nothing_raised { courses(:ruby) }
    courses(:ruby).destroy
  end

  def test_it_twice_in_whatever_order_to_check_for_fixture_leakage
    test_leaky_destroy
  end
563 564
end

565
class InvalidTableNameFixturesTest < ActiveRecord::TestCase
566
  fixtures :funny_jokes
567
  # Set to false to blow away fixtures cache and ensure our fixtures are loaded
568 569
  # and thus takes into account our lack of set_fixture_class
  self.use_transactional_fixtures = false
570 571

  def test_raises_error
572
    assert_raise ActiveRecord::FixtureClassNotFound do
573 574 575 576
      funny_jokes(:a_joke)
    end
  end
end
577

578
class CheckEscapedYamlFixturesTest < ActiveRecord::TestCase
579
  set_fixture_class :funny_jokes => Joke
580
  fixtures :funny_jokes
581
  # Set to false to blow away fixtures cache and ensure our fixtures are loaded
582 583
  # and thus takes into account our set_fixture_class
  self.use_transactional_fixtures = false
584 585 586 587 588 589

  def test_proper_escaped_fixture
    assert_equal "The \\n Aristocrats\nAte the candy\n", funny_jokes(:another_joke).name
  end
end

590
class DevelopersProject; end
591
class ManyToManyFixturesWithClassDefined < ActiveRecord::TestCase
592
  fixtures :developers_projects
593

594 595 596
  def test_this_should_run_cleanly
    assert true
  end
597 598
end

599
class FixturesBrokenRollbackTest < ActiveRecord::TestCase
600 601 602
  def blank_setup
    @fixture_connections = [ActiveRecord::Base.connection]
  end
603 604
  alias_method :ar_setup_fixtures, :setup_fixtures
  alias_method :setup_fixtures, :blank_setup
605 606 607
  alias_method :setup, :blank_setup

  def blank_teardown; end
608 609
  alias_method :ar_teardown_fixtures, :teardown_fixtures
  alias_method :teardown_fixtures, :blank_teardown
610 611 612
  alias_method :teardown, :blank_teardown

  def test_no_rollback_in_teardown_unless_transaction_active
613
    assert_equal 0, ActiveRecord::Base.connection.open_transactions
614
    assert_raise(RuntimeError) { ar_setup_fixtures }
615
    assert_equal 0, ActiveRecord::Base.connection.open_transactions
616
    assert_nothing_raised { ar_teardown_fixtures }
617
    assert_equal 0, ActiveRecord::Base.connection.open_transactions
618 619 620
  end

  private
621
    def load_fixtures(config)
622 623 624
      raise 'argh'
    end
end
625

626
class LoadAllFixturesTest < ActiveRecord::TestCase
627
  def test_all_there
628 629 630
    self.class.fixture_path = FIXTURES_ROOT + "/all"
    self.class.fixtures :all

631 632 633
    if File.symlink? FIXTURES_ROOT + "/all/admin"
      assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort
    end
634 635
  ensure
    ActiveRecord::FixtureSet.reset_cache
636 637
  end
end
638

639 640
class LoadAllFixturesWithPathnameTest < ActiveRecord::TestCase
  def test_all_there
641 642 643
    self.class.fixture_path = Pathname.new(FIXTURES_ROOT).join('all')
    self.class.fixtures :all

644 645 646
    if File.symlink? FIXTURES_ROOT + "/all/admin"
      assert_equal %w(admin/accounts admin/users developers people tasks), fixture_table_names.sort
    end
647 648
  ensure
    ActiveRecord::FixtureSet.reset_cache
649 650 651
  end
end

652
class FasterFixturesTest < ActiveRecord::TestCase
653
  fixtures :categories, :authors
654

655
  def load_extra_fixture(name)
656
    fixture = create_fixtures(name).first
657
    assert fixture.is_a?(ActiveRecord::FixtureSet)
658 659
    @loaded_fixtures[fixture.table_name] = fixture
  end
660

661
  def test_cache
662 663
    assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, 'categories')
    assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, 'authors')
664

665 666 667 668
    assert_no_queries do
      create_fixtures('categories')
      create_fixtures('authors')
    end
669

670
    load_extra_fixture('posts')
671
    assert ActiveRecord::FixtureSet.fixture_is_cached?(ActiveRecord::Base.connection, 'posts')
672
    self.class.setup_fixture_accessors :posts
673 674 675
    assert_equal 'Welcome to the weblog', posts(:welcome).title
  end
end
676

677
class FoxyFixturesTest < ActiveRecord::TestCase
678
  fixtures :parrots, :parrots_pirates, :pirates, :treasures, :mateys, :ships, :computers, :developers, :"admin/accounts", :"admin/users"
679 680

  def test_identifies_strings
681 682
    assert_equal(ActiveRecord::FixtureSet.identify("foo"), ActiveRecord::FixtureSet.identify("foo"))
    assert_not_equal(ActiveRecord::FixtureSet.identify("foo"), ActiveRecord::FixtureSet.identify("FOO"))
683 684 685
  end

  def test_identifies_symbols
686
    assert_equal(ActiveRecord::FixtureSet.identify(:foo), ActiveRecord::FixtureSet.identify(:foo))
687 688
  end

689
  def test_identifies_consistently
690 691
    assert_equal 207281424, ActiveRecord::FixtureSet.identify(:ruby)
    assert_equal 1066363776, ActiveRecord::FixtureSet.identify(:sapphire_2)
692 693
  end

694 695 696 697 698 699 700 701
  TIMESTAMP_COLUMNS = %w(created_at created_on updated_at updated_on)

  def test_populates_timestamp_columns
    TIMESTAMP_COLUMNS.each do |property|
      assert_not_nil(parrots(:george).send(property), "should set #{property}")
    end
  end

702 703 704 705 706 707
  def test_does_not_populate_timestamp_columns_if_model_has_set_record_timestamps_to_false
    TIMESTAMP_COLUMNS.each do |property|
      assert_nil(ships(:black_pearl).send(property), "should not set #{property}")
    end
  end

708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
  def test_populates_all_columns_with_the_same_time
    last = nil

    TIMESTAMP_COLUMNS.each do |property|
      current = parrots(:george).send(property)
      last ||= current

      assert_equal(last, current)
      last = current
    end
  end

  def test_only_populates_columns_that_exist
    assert_not_nil(pirates(:blackbeard).created_on)
    assert_not_nil(pirates(:blackbeard).updated_on)
  end

  def test_preserves_existing_fixture_data
726 727
    assert_equal(2.weeks.ago.to_date, pirates(:redbeard).created_on.to_date)
    assert_equal(2.weeks.ago.to_date, pirates(:redbeard).updated_on.to_date)
728 729 730 731 732 733 734
  end

  def test_generates_unique_ids
    assert_not_nil(parrots(:george).id)
    assert_not_equal(parrots(:george).id, parrots(:louis).id)
  end

735 736 737 738 739 740 741 742
  def test_automatically_sets_primary_key
    assert_not_nil(ships(:black_pearl))
  end

  def test_preserves_existing_primary_key
    assert_equal(2, ships(:interceptor).id)
  end

743 744 745 746
  def test_resolves_belongs_to_symbols
    assert_equal(parrots(:george), pirates(:blackbeard).parrot)
  end

747 748 749 750
  def test_ignores_belongs_to_symbols_if_association_and_foreign_key_are_named_the_same
    assert_equal(developers(:david), computers(:workstation).developer)
  end

751 752 753 754 755 756 757 758 759 760 761 762
  def test_supports_join_tables
    assert(pirates(:blackbeard).parrots.include?(parrots(:george)))
    assert(pirates(:blackbeard).parrots.include?(parrots(:louis)))
    assert(parrots(:george).pirates.include?(pirates(:blackbeard)))
  end

  def test_supports_inline_habtm
    assert(parrots(:george).treasures.include?(treasures(:diamond)))
    assert(parrots(:george).treasures.include?(treasures(:sapphire)))
    assert(!parrots(:george).treasures.include?(treasures(:ruby)))
  end

763 764 765 766 767 768
  def test_supports_inline_habtm_with_specified_id
    assert(parrots(:polly).treasures.include?(treasures(:ruby)))
    assert(parrots(:polly).treasures.include?(treasures(:sapphire)))
    assert(!parrots(:polly).treasures.include?(treasures(:diamond)))
  end

769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
  def test_supports_yaml_arrays
    assert(parrots(:louis).treasures.include?(treasures(:diamond)))
    assert(parrots(:louis).treasures.include?(treasures(:sapphire)))
  end

  def test_strips_DEFAULTS_key
    assert_raise(StandardError) { parrots(:DEFAULTS) }

    # this lets us do YAML defaults and not have an extra fixture entry
    %w(sapphire ruby).each { |t| assert(parrots(:davey).treasures.include?(treasures(t))) }
  end

  def test_supports_label_interpolation
    assert_equal("frederick", parrots(:frederick).name)
  end
784 785 786 787 788

  def test_supports_polymorphic_belongs_to
    assert_equal(pirates(:redbeard), treasures(:sapphire).looter)
    assert_equal(parrots(:louis), treasures(:ruby).looter)
  end
789

790
  def test_only_generates_a_pk_if_necessary
791
    m = Matey.first
792 793 794
    m.pirate = pirates(:blackbeard)
    m.target = pirates(:redbeard)
  end
795 796 797 798 799

  def test_supports_sti
    assert_kind_of DeadParrot, parrots(:polly)
    assert_equal pirates(:blackbeard), parrots(:polly).killer
  end
800 801 802 803 804

  def test_namespaced_models
    assert admin_accounts(:signals37).users.include?(admin_users(:david))
    assert_equal 2, admin_accounts(:signals37).users.size
  end
805
end
806

807
class ActiveSupportSubclassWithFixturesTest < ActiveRecord::TestCase
808 809 810 811 812
  fixtures :parrots

  # This seemingly useless assertion catches a bug that caused the fixtures
  # setup code call nil[]
  def test_foo
813
    assert_equal parrots(:louis), Parrot.find_by_name("King Louis")
814
  end
815
end
816 817

class FixtureLoadingTest < ActiveRecord::TestCase
818 819 820 821 822
  def test_logs_message_for_failed_dependency_load
    ActiveRecord::TestCase.expects(:require_dependency).with(:does_not_exist).raises(LoadError)
    ActiveRecord::Base.logger.expects(:warn)
    ActiveRecord::TestCase.try_to_load_dependency(:does_not_exist)
  end
823

824 825 826 827
  def test_does_not_logs_message_for_successful_dependency_load
    ActiveRecord::TestCase.expects(:require_dependency).with(:works_out_fine)
    ActiveRecord::Base.logger.expects(:warn).never
    ActiveRecord::TestCase.try_to_load_dependency(:works_out_fine)
828 829
  end
end
830 831

class CustomNameForFixtureOrModelTest < ActiveRecord::TestCase
832
  ActiveRecord::FixtureSet.reset_cache
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854

  set_fixture_class :randomly_named_a9         =>
                        ClassNameThatDoesNotFollowCONVENTIONS,
                    :'admin/randomly_named_a9' =>
                        Admin::ClassNameThatDoesNotFollowCONVENTIONS,
                    'admin/randomly_named_b0'  =>
                        Admin::ClassNameThatDoesNotFollowCONVENTIONS

  fixtures :randomly_named_a9, 'admin/randomly_named_a9',
           :'admin/randomly_named_b0'

  def test_named_accessor_for_randomly_named_fixture_and_class
    assert_kind_of ClassNameThatDoesNotFollowCONVENTIONS,
                   randomly_named_a9(:first_instance)
  end

  def test_named_accessor_for_randomly_named_namespaced_fixture_and_class
    assert_kind_of Admin::ClassNameThatDoesNotFollowCONVENTIONS,
                   admin_randomly_named_a9(:first_instance)
    assert_kind_of Admin::ClassNameThatDoesNotFollowCONVENTIONS,
                   admin_randomly_named_b0(:second_instance)
  end
855 856

  def test_table_name_is_defined_in_the_model
857
    assert_equal 'randomly_named_table', ActiveRecord::FixtureSet::all_loaded_fixtures["admin/randomly_named_a9"].table_name
858
    assert_equal 'randomly_named_table', Admin::ClassNameThatDoesNotFollowCONVENTIONS.table_name
859
  end
860
end