database_tasks_test.rb 33.0 KB
Newer Older
1 2
# frozen_string_literal: true

3 4
require "cases/helper"
require "active_record/tasks/database_tasks"
5 6

module ActiveRecord
K
kennyj 已提交
7
  module DatabaseTasksSetupper
8
    def setup
U
utilum 已提交
9 10 11 12 13 14 15 16 17 18 19
      @mysql_tasks, @postgresql_tasks, @sqlite_tasks = Array.new(
        3,
        Class.new do
          def create; end
          def drop; end
          def purge; end
          def charset; end
          def collation; end
          def structure_dump(*); end
        end.new
      )
20 21 22 23 24 25 26

      $stdout, @original_stdout = StringIO.new, $stdout
      $stderr, @original_stderr = StringIO.new, $stderr
    end

    def teardown
      $stdout, $stderr = @original_stdout, @original_stderr
27
    end
U
utilum 已提交
28 29 30 31 32 33 34 35 36 37

    def with_stubbed_new
      ActiveRecord::Tasks::MySQLDatabaseTasks.stub(:new, @mysql_tasks) do
        ActiveRecord::Tasks::PostgreSQLDatabaseTasks.stub(:new, @postgresql_tasks) do
          ActiveRecord::Tasks::SQLiteDatabaseTasks.stub(:new, @sqlite_tasks) do
            yield
          end
        end
      end
    end
K
kennyj 已提交
38 39
  end

K
kennyj 已提交
40
  ADAPTERS_TASKS = {
41 42 43
    mysql2:     :mysql_tasks,
    postgresql: :postgresql_tasks,
    sqlite3:    :sqlite_tasks
K
kennyj 已提交
44
  }
45

46
  class DatabaseTasksUtilsTask < ActiveRecord::TestCase
47
    def test_raises_an_error_when_called_with_protected_environment
48
      ActiveRecord::MigrationContext.any_instance.stubs(:current_version).returns(1)
49

50
      protected_environments = ActiveRecord::Base.protected_environments
51
      current_env            = ActiveRecord::Base.connection.migration_context.current_environment
52
      assert_not_includes protected_environments, current_env
53 54 55
      # Assert no error
      ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!

56
      ActiveRecord::Base.protected_environments = [current_env]
U
utilum 已提交
57

58 59 60 61 62 63 64 65
      assert_raise(ActiveRecord::ProtectedEnvironmentError) do
        ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!
      end
    ensure
      ActiveRecord::Base.protected_environments = protected_environments
    end

    def test_raises_an_error_when_called_with_protected_environment_which_name_is_a_symbol
66
      ActiveRecord::MigrationContext.any_instance.stubs(:current_version).returns(1)
67 68

      protected_environments = ActiveRecord::Base.protected_environments
69
      current_env            = ActiveRecord::Base.connection.migration_context.current_environment
70 71 72 73 74
      assert_not_includes protected_environments, current_env
      # Assert no error
      ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!

      ActiveRecord::Base.protected_environments = [current_env.to_sym]
75 76 77 78 79 80 81 82
      assert_raise(ActiveRecord::ProtectedEnvironmentError) do
        ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!
      end
    ensure
      ActiveRecord::Base.protected_environments = protected_environments
    end

    def test_raises_an_error_if_no_migrations_have_been_made
U
utilum 已提交
83 84
      ActiveRecord::InternalMetadata.stub(:table_exists?, false) do
        ActiveRecord::MigrationContext.any_instance.stubs(:current_version).returns(1)
85

U
utilum 已提交
86 87 88
        assert_raise(ActiveRecord::NoEnvironmentInSchemaError) do
          ActiveRecord::Tasks::DatabaseTasks.check_protected_environments!
        end
89 90 91 92
      end
    end
  end

93 94 95 96 97 98 99 100
  class DatabaseTasksRegisterTask < ActiveRecord::TestCase
    def test_register_task
      klazz = Class.new do
        def initialize(*arguments); end
        def structure_dump(filename); end
      end
      instance = klazz.new

U
utilum 已提交
101 102 103 104 105
      klazz.stub(:new, instance) do
        assert_called_with(instance, :structure_dump, ["awesome-file.sql", nil]) do
          ActiveRecord::Tasks::DatabaseTasks.register_task(/foo/, klazz)
          ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :foo }, "awesome-file.sql")
        end
U
utilum 已提交
106
      end
107
    end
108 109 110

    def test_unregistered_task
      assert_raise(ActiveRecord::Tasks::DatabaseNotSupported) do
111
        ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => :bar }, "awesome-file.sql")
112 113
      end
    end
114
  end
115

K
kennyj 已提交
116 117
  class DatabaseTasksCreateTest < ActiveRecord::TestCase
    include DatabaseTasksSetupper
118

K
kennyj 已提交
119 120
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_create") do
U
utilum 已提交
121 122 123 124
        with_stubbed_new do
          eval("@#{v}").expects(:create)
          ActiveRecord::Tasks::DatabaseTasks.create "adapter" => k
        end
K
kennyj 已提交
125
      end
126 127 128
    end
  end

129 130 131 132 133 134
  class DatabaseTasksDumpSchemaCacheTest < ActiveRecord::TestCase
    def test_dump_schema_cache
      path = "/tmp/my_schema_cache.yml"
      ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.connection, path)
      assert File.file?(path)
    ensure
135
      ActiveRecord::Base.clear_cache!
136 137 138 139
      FileUtils.rm_rf(path)
    end
  end

140 141
  class DatabaseTasksCreateAllTest < ActiveRecord::TestCase
    def setup
142
      @configurations = { "development" => { "database" => "my-db" } }
143

144 145
      # To refrain from connecting to a newly created empty DB in sqlite3_mem tests
      ActiveRecord::Base.connection_handler.stubs(:establish_connection)
146 147 148 149 150 151 152

      $stdout, @original_stdout = StringIO.new, $stdout
      $stderr, @original_stderr = StringIO.new, $stderr
    end

    def teardown
      $stdout, $stderr = @original_stdout, @original_stderr
153 154
    end

155 156 157
    def test_ignores_configurations_without_databases
      @configurations["development"].merge!("database" => nil)

158 159 160 161
      with_stubbed_configurations do
        assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
          ActiveRecord::Tasks::DatabaseTasks.create_all
        end
U
utilum 已提交
162
      end
163 164
    end

165
    def test_ignores_remote_databases
166
      @configurations["development"].merge!("host" => "my.server.tld")
167

168 169 170 171
      with_stubbed_configurations do
        assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
          ActiveRecord::Tasks::DatabaseTasks.create_all
        end
U
utilum 已提交
172
      end
173 174 175
    end

    def test_warning_for_remote_databases
176
      @configurations["development"].merge!("host" => "my.server.tld")
177

178 179
      with_stubbed_configurations do
        ActiveRecord::Tasks::DatabaseTasks.create_all
180

181 182 183
        assert_match "This task only modifies local databases. my-db is on a remote host.",
          $stderr.string
      end
184 185 186
    end

    def test_creates_configurations_with_local_ip
187
      @configurations["development"].merge!("host" => "127.0.0.1")
188

189 190 191 192
      with_stubbed_configurations do
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
          ActiveRecord::Tasks::DatabaseTasks.create_all
        end
U
utilum 已提交
193
      end
194 195 196
    end

    def test_creates_configurations_with_local_host
197
      @configurations["development"].merge!("host" => "localhost")
198

199 200 201 202
      with_stubbed_configurations do
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
          ActiveRecord::Tasks::DatabaseTasks.create_all
        end
U
utilum 已提交
203
      end
204 205 206
    end

    def test_creates_configurations_with_blank_hosts
207
      @configurations["development"].merge!("host" => nil)
208

209 210 211 212
      with_stubbed_configurations do
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
          ActiveRecord::Tasks::DatabaseTasks.create_all
        end
U
utilum 已提交
213
      end
214
    end
215 216 217 218 219 220 221 222

    private

      def with_stubbed_configurations
        ActiveRecord::Base.stub(:configurations, @configurations) do
          yield
        end
      end
223 224 225 226 227
  end

  class DatabaseTasksCreateCurrentTest < ActiveRecord::TestCase
    def setup
      @configurations = {
228 229
        "development" => { "database" => "dev-db" },
        "test"        => { "database" => "test-db" },
230
        "production"  => { "url" => "prod-db-url" }
231 232 233 234
      }
    end

    def test_creates_current_environment_database
U
utilum 已提交
235 236 237 238 239 240 241 242 243 244
      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          ["database" => "test-db"],
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("test")
          )
        end
U
utilum 已提交
245
      end
246 247 248
    end

    def test_creates_current_environment_database_with_url
U
utilum 已提交
249 250 251 252 253 254 255 256 257 258
      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          ["url" => "prod-db-url"],
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("production")
          )
        end
U
utilum 已提交
259
      end
260 261
    end

262
    def test_creates_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
263 264 265 266 267 268 269 270 271 272 273 274 275 276
      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          [
            ["database" => "dev-db"],
            ["database" => "test-db"]
          ],
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
277 278
    end

279
    def test_creates_test_and_development_databases_when_rails_env_is_development
280 281
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
282

U
utilum 已提交
283 284 285 286 287 288 289 290 291 292 293 294 295 296
      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          [
            ["database" => "dev-db"],
            ["database" => "test-db"]
          ],
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
297
    ensure
298
      ENV["RAILS_ENV"] = old_env
299 300
    end

E
eileencodes 已提交
301
    def test_establishes_connection_for_the_given_environments
U
utilum 已提交
302 303 304 305 306 307 308 309
      ActiveRecord::Tasks::DatabaseTasks.stub(:create, nil) do
        assert_called_with(ActiveRecord::Base, :establish_connection, [:development]) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
    end
E
eileencodes 已提交
310

U
utilum 已提交
311
    private
E
eileencodes 已提交
312

U
utilum 已提交
313 314 315 316 317 318 319
      def with_stubbed_configurations_establish_connection
        ActiveRecord::Base.stub(:configurations, @configurations) do
          ActiveRecord::Base.stub(:establish_connection, nil) do
            yield
          end
        end
      end
E
eileencodes 已提交
320 321 322 323 324 325 326
  end

  class DatabaseTasksCreateCurrentThreeTierTest < ActiveRecord::TestCase
    def setup
      @configurations = {
        "development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
        "test" => { "primary" => { "database" => "test-db" }, "secondary" => { "database" => "secondary-test-db" } },
327
        "production" => { "primary" => { "url" => "prod-db-url" }, "secondary" => { "url" => "secondary-prod-db-url" } }
E
eileencodes 已提交
328 329 330 331
      }
    end

    def test_creates_current_environment_database
U
utilum 已提交
332 333 334 335 336 337 338 339 340 341 342 343 344 345
      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          [
            ["database" => "test-db"],
            ["database" => "secondary-test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("test")
          )
        end
      end
346 347 348
    end

    def test_creates_current_environment_database_with_url
U
utilum 已提交
349 350 351 352 353 354 355 356 357 358 359 360 361 362
      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          [
            ["url" => "prod-db-url"],
            ["url" => "secondary-prod-db-url"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("production")
          )
        end
      end
E
eileencodes 已提交
363 364 365
    end

    def test_creates_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381
      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          [
            ["database" => "dev-db"],
            ["database" => "secondary-dev-db"],
            ["database" => "test-db"],
            ["database" => "secondary-test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
E
eileencodes 已提交
382 383 384 385 386
    end

    def test_creates_test_and_development_databases_when_rails_env_is_development
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
U
utilum 已提交
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403

      with_stubbed_configurations_establish_connection do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :create,
          [
            ["database" => "dev-db"],
            ["database" => "secondary-dev-db"],
            ["database" => "test-db"],
            ["database" => "secondary-test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
E
eileencodes 已提交
404 405 406 407 408
    ensure
      ENV["RAILS_ENV"] = old_env
    end

    def test_establishes_connection_for_the_given_environments_config
U
utilum 已提交
409 410
      ActiveRecord::Tasks::DatabaseTasks.stub(:create, nil) do
        ActiveRecord::Base.expects(:establish_connection).with(:development)
411

U
utilum 已提交
412 413 414 415
        ActiveRecord::Tasks::DatabaseTasks.create_current(
          ActiveSupport::StringInquirer.new("development")
        )
      end
416
    end
U
utilum 已提交
417 418 419 420 421 422 423 424 425 426

    private

      def with_stubbed_configurations_establish_connection
        ActiveRecord::Base.stub(:configurations, @configurations) do
          ActiveRecord::Base.stub(:establish_connection, nil) do
            yield
          end
        end
      end
427 428 429
  end

  class DatabaseTasksDropTest < ActiveRecord::TestCase
K
kennyj 已提交
430
    include DatabaseTasksSetupper
431

K
kennyj 已提交
432 433
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_drop") do
U
utilum 已提交
434 435 436 437
        with_stubbed_new do
          eval("@#{v}").expects(:drop)
          ActiveRecord::Tasks::DatabaseTasks.drop "adapter" => k
        end
K
kennyj 已提交
438
      end
439 440 441 442 443
    end
  end

  class DatabaseTasksDropAllTest < ActiveRecord::TestCase
    def setup
444
      @configurations = { development: { "database" => "my-db" } }
445

446 447 448 449 450 451
      $stdout, @original_stdout = StringIO.new, $stdout
      $stderr, @original_stderr = StringIO.new, $stderr
    end

    def teardown
      $stdout, $stderr = @original_stdout, @original_stderr
452 453
    end

454 455 456
    def test_ignores_configurations_without_databases
      @configurations[:development].merge!("database" => nil)

U
utilum 已提交
457 458 459 460
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
          ActiveRecord::Tasks::DatabaseTasks.drop_all
        end
U
utilum 已提交
461
      end
462 463
    end

464
    def test_ignores_remote_databases
465
      @configurations[:development].merge!("host" => "my.server.tld")
466

U
utilum 已提交
467 468 469 470
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
          ActiveRecord::Tasks::DatabaseTasks.drop_all
        end
U
utilum 已提交
471
      end
472 473 474
    end

    def test_warning_for_remote_databases
475
      @configurations[:development].merge!("host" => "my.server.tld")
476

U
utilum 已提交
477 478
      ActiveRecord::Base.stub(:configurations, @configurations) do
        ActiveRecord::Tasks::DatabaseTasks.drop_all
479

U
utilum 已提交
480 481 482
        assert_match "This task only modifies local databases. my-db is on a remote host.",
          $stderr.string
      end
483 484
    end

485
    def test_drops_configurations_with_local_ip
486
      @configurations[:development].merge!("host" => "127.0.0.1")
487

U
utilum 已提交
488 489 490 491
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
          ActiveRecord::Tasks::DatabaseTasks.drop_all
        end
U
utilum 已提交
492
      end
493 494
    end

495
    def test_drops_configurations_with_local_host
496
      @configurations[:development].merge!("host" => "localhost")
497

U
utilum 已提交
498 499 500 501
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
          ActiveRecord::Tasks::DatabaseTasks.drop_all
        end
U
utilum 已提交
502
      end
503 504
    end

505
    def test_drops_configurations_with_blank_hosts
506
      @configurations[:development].merge!("host" => nil)
507

U
utilum 已提交
508 509 510 511
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
          ActiveRecord::Tasks::DatabaseTasks.drop_all
        end
U
utilum 已提交
512
      end
513 514 515 516 517 518
    end
  end

  class DatabaseTasksDropCurrentTest < ActiveRecord::TestCase
    def setup
      @configurations = {
519 520
        "development" => { "database" => "dev-db" },
        "test"        => { "database" => "test-db" },
521
        "production"  => { "url" => "prod-db-url" }
522 523 524
      }
    end

525
    def test_drops_current_environment_database
U
utilum 已提交
526 527 528 529 530 531 532 533
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(ActiveRecord::Tasks::DatabaseTasks, :drop,
          ["database" => "test-db"]) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("test")
          )
        end
      end
534 535 536
    end

    def test_drops_current_environment_database_with_url
U
utilum 已提交
537 538 539 540 541 542 543 544
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(ActiveRecord::Tasks::DatabaseTasks, :drop,
          ["url" => "prod-db-url"]) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("production")
          )
        end
      end
545 546
    end

547
    def test_drops_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
548 549 550 551 552 553 554 555 556 557 558 559 560 561
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :drop,
          [
            ["database" => "dev-db"],
            ["database" => "test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
562 563
    end

564
    def test_drops_testand_development_databases_when_rails_env_is_development
565 566
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
567

U
utilum 已提交
568 569 570 571 572 573 574 575 576 577 578 579 580 581
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :drop,
          [
            ["database" => "dev-db"],
            ["database" => "test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
E
eileencodes 已提交
582 583 584 585 586 587 588 589 590 591
    ensure
      ENV["RAILS_ENV"] = old_env
    end
  end

  class DatabaseTasksDropCurrentThreeTierTest < ActiveRecord::TestCase
    def setup
      @configurations = {
        "development" => { "primary" => { "database" => "dev-db" }, "secondary" => { "database" => "secondary-dev-db" } },
        "test" => { "primary" => { "database" => "test-db" }, "secondary" => { "database" => "secondary-test-db" } },
592
        "production" => { "primary" => { "url" => "prod-db-url" }, "secondary" => { "url" => "secondary-prod-db-url" } }
E
eileencodes 已提交
593 594 595 596
      }
    end

    def test_drops_current_environment_database
U
utilum 已提交
597 598 599 600 601 602 603 604 605 606 607 608 609 610
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :drop,
          [
            ["database" => "test-db"],
            ["database" => "secondary-test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("test")
          )
        end
      end
611 612 613
    end

    def test_drops_current_environment_database_with_url
U
utilum 已提交
614 615 616 617 618 619 620 621 622 623 624 625 626 627
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :drop,
          [
            ["url" => "prod-db-url"],
            ["url" => "secondary-prod-db-url"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("production")
          )
        end
      end
E
eileencodes 已提交
628 629 630
    end

    def test_drops_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :drop,
          [
            ["database" => "dev-db"],
            ["database" => "secondary-dev-db"],
            ["database" => "test-db"],
            ["database" => "secondary-test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
E
eileencodes 已提交
647 648 649 650 651
    end

    def test_drops_testand_development_databases_when_rails_env_is_development
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
U
utilum 已提交
652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668

      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :drop,
          [
            ["database" => "dev-db"],
            ["database" => "secondary-dev-db"],
            ["database" => "test-db"],
            ["database" => "secondary-test-db"]
          ]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.drop_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
      end
669
    ensure
670
      ENV["RAILS_ENV"] = old_env
671 672 673
    end
  end

674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
  if current_adapter?(:SQLite3Adapter) && !in_memory_db?
    class DatabaseTasksMigrateTest < ActiveRecord::TestCase
      self.use_transactional_tests = false

      # Use a memory db here to avoid having to rollback at the end
      setup do
        migrations_path = MIGRATIONS_ROOT + "/valid"
        file = ActiveRecord::Base.connection.raw_connection.filename
        @conn = ActiveRecord::Base.establish_connection adapter: "sqlite3",
          database: ":memory:", migrations_paths: migrations_path
        source_db = SQLite3::Database.new file
        dest_db = ActiveRecord::Base.connection.raw_connection
        backup = SQLite3::Backup.new(dest_db, "main", source_db, "main")
        backup.step(-1)
        backup.finish
      end
690

691 692 693 694
      teardown do
        @conn.release_connection if @conn
        ActiveRecord::Base.establish_connection :arunit
      end
695

696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
      def test_migrate_set_and_unset_verbose_and_version_env_vars
        verbose, version = ENV["VERBOSE"], ENV["VERSION"]
        ENV["VERSION"] = "2"
        ENV["VERBOSE"] = "false"

        # run down migration because it was already run on copied db
        assert_empty capture_migration_output

        ENV.delete("VERSION")
        ENV.delete("VERBOSE")

        # re-run up migration
        assert_includes capture_migration_output, "migrating"
      ensure
        ENV["VERBOSE"], ENV["VERSION"] = verbose, version
      end

      def test_migrate_set_and_unset_empty_values_for_verbose_and_version_env_vars
        verbose, version = ENV["VERBOSE"], ENV["VERSION"]

        ENV["VERSION"] = "2"
        ENV["VERBOSE"] = "false"

        # run down migration because it was already run on copied db
        assert_empty capture_migration_output

        ENV["VERBOSE"] = ""
        ENV["VERSION"] = ""

        # re-run up migration
        assert_includes capture_migration_output, "migrating"
      ensure
        ENV["VERBOSE"], ENV["VERSION"] = verbose, version
      end

      def test_migrate_set_and_unset_nonsense_values_for_verbose_and_version_env_vars
        verbose, version = ENV["VERBOSE"], ENV["VERSION"]

        # run down migration because it was already run on copied db
        ENV["VERSION"] = "2"
        ENV["VERBOSE"] = "false"

        assert_empty capture_migration_output

        ENV["VERBOSE"] = "yes"
        ENV["VERSION"] = "2"

        # run no migration because 2 was already run
        assert_empty capture_migration_output
      ensure
        ENV["VERBOSE"], ENV["VERSION"] = verbose, version
      end

      private
        def capture_migration_output
          capture(:stdout) do
            ActiveRecord::Tasks::DatabaseTasks.migrate
          end
        end
755
    end
756 757 758 759
  end

  class DatabaseTasksMigrateErrorTest < ActiveRecord::TestCase
    self.use_transactional_tests = false
760

761
    def test_migrate_raise_error_on_invalid_version_format
P
Philippe Guay 已提交
762
      version = ENV["VERSION"]
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784

      ENV["VERSION"] = "unknown"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "0.1.11"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1.1.11"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "0 "
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1."
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1_"
785
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
786 787 788 789 790
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1_name"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
      assert_match(/Invalid format of target version/, e.message)
P
Philippe Guay 已提交
791 792 793 794
    ensure
      ENV["VERSION"] = version
    end

795
    def test_migrate_raise_error_on_failed_check_target_version
U
utilum 已提交
796 797 798 799
      ActiveRecord::Tasks::DatabaseTasks.stub(:check_target_version, -> { raise "foo" }) do
        e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
        assert_equal "foo", e.message
      end
800 801
    end

802
    def test_migrate_clears_schema_cache_afterward
U
utilum 已提交
803 804 805
      assert_called(ActiveRecord::Base, :clear_cache!) do
        ActiveRecord::Tasks::DatabaseTasks.migrate
      end
806
    end
807
  end
K
kennyj 已提交
808

809
  class DatabaseTasksPurgeTest < ActiveRecord::TestCase
K
kennyj 已提交
810
    include DatabaseTasksSetupper
811

K
kennyj 已提交
812 813
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_purge") do
U
utilum 已提交
814 815 816 817
        with_stubbed_new do
          eval("@#{v}").expects(:purge)
          ActiveRecord::Tasks::DatabaseTasks.purge "adapter" => k
        end
K
kennyj 已提交
818
      end
819 820
    end
  end
S
Simon Jefford 已提交
821

822 823 824
  class DatabaseTasksPurgeCurrentTest < ActiveRecord::TestCase
    def test_purges_current_environment_database
      configurations = {
825 826 827
        "development" => { "database" => "dev-db" },
        "test"        => { "database" => "test-db" },
        "production"  => { "database" => "prod-db" }
828
      }
U
utilum 已提交
829 830 831
      ActiveRecord::Base.stub(:configurations, configurations) do
        ActiveRecord::Tasks::DatabaseTasks.expects(:purge).
          with("database" => "prod-db")
832

U
utilum 已提交
833 834 835
        assert_called_with(ActiveRecord::Base, :establish_connection, [:production]) do
          ActiveRecord::Tasks::DatabaseTasks.purge_current("production")
        end
U
utilum 已提交
836
      end
837 838 839 840 841
    end
  end

  class DatabaseTasksPurgeAllTest < ActiveRecord::TestCase
    def test_purge_all_local_configurations
842
      configurations = { development: { "database" => "my-db" } }
U
utilum 已提交
843 844 845
      ActiveRecord::Base.stub(:configurations, configurations) do
        ActiveRecord::Tasks::DatabaseTasks.expects(:purge).
          with("database" => "my-db")
846

U
utilum 已提交
847 848
        ActiveRecord::Tasks::DatabaseTasks.purge_all
      end
849 850 851
    end
  end

S
Simon Jefford 已提交
852
  class DatabaseTasksCharsetTest < ActiveRecord::TestCase
K
kennyj 已提交
853
    include DatabaseTasksSetupper
854

K
kennyj 已提交
855 856
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_charset") do
U
utilum 已提交
857 858 859 860
        with_stubbed_new do
          eval("@#{v}").expects(:charset)
          ActiveRecord::Tasks::DatabaseTasks.charset "adapter" => k
        end
K
kennyj 已提交
861
      end
S
Simon Jefford 已提交
862 863
    end
  end
K
kennyj 已提交
864

865 866
  class DatabaseTasksCollationTest < ActiveRecord::TestCase
    include DatabaseTasksSetupper
867

868 869
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_collation") do
U
utilum 已提交
870 871 872 873
        with_stubbed_new do
          eval("@#{v}").expects(:collation)
          ActiveRecord::Tasks::DatabaseTasks.collation "adapter" => k
        end
874 875 876 877
      end
    end
  end

878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979
  class DatabaseTaskTargetVersionTest < ActiveRecord::TestCase
    def test_target_version_returns_nil_if_version_does_not_exist
      version = ENV.delete("VERSION")
      assert_nil ActiveRecord::Tasks::DatabaseTasks.target_version
    ensure
      ENV["VERSION"] = version
    end

    def test_target_version_returns_nil_if_version_is_empty
      version = ENV["VERSION"]

      ENV["VERSION"] = ""
      assert_nil ActiveRecord::Tasks::DatabaseTasks.target_version
    ensure
      ENV["VERSION"] = version
    end

    def test_target_version_returns_converted_to_integer_env_version_if_version_exists
      version = ENV["VERSION"]

      ENV["VERSION"] = "0"
      assert_equal ENV["VERSION"].to_i, ActiveRecord::Tasks::DatabaseTasks.target_version

      ENV["VERSION"] = "42"
      assert_equal ENV["VERSION"].to_i, ActiveRecord::Tasks::DatabaseTasks.target_version

      ENV["VERSION"] = "042"
      assert_equal ENV["VERSION"].to_i, ActiveRecord::Tasks::DatabaseTasks.target_version
    ensure
      ENV["VERSION"] = version
    end
  end

  class DatabaseTaskCheckTargetVersionTest < ActiveRecord::TestCase
    def test_check_target_version_does_not_raise_error_on_empty_version
      version = ENV["VERSION"]
      ENV["VERSION"] = ""
      assert_nothing_raised { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
    ensure
      ENV["VERSION"] = version
    end

    def test_check_target_version_does_not_raise_error_if_version_is_not_setted
      version = ENV.delete("VERSION")
      assert_nothing_raised { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
    ensure
      ENV["VERSION"] = version
    end

    def test_check_target_version_raises_error_on_invalid_version_format
      version = ENV["VERSION"]

      ENV["VERSION"] = "unknown"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "0.1.11"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1.1.11"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "0 "
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1."
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1_"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
      assert_match(/Invalid format of target version/, e.message)

      ENV["VERSION"] = "1_name"
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
      assert_match(/Invalid format of target version/, e.message)
    ensure
      ENV["VERSION"] = version
    end

    def test_check_target_version_does_not_raise_error_on_valid_version_format
      version = ENV["VERSION"]

      ENV["VERSION"] = "0"
      assert_nothing_raised { ActiveRecord::Tasks::DatabaseTasks.check_target_version }

      ENV["VERSION"] = "1"
      assert_nothing_raised { ActiveRecord::Tasks::DatabaseTasks.check_target_version }

      ENV["VERSION"] = "001"
      assert_nothing_raised { ActiveRecord::Tasks::DatabaseTasks.check_target_version }

      ENV["VERSION"] = "001_name.rb"
      assert_nothing_raised { ActiveRecord::Tasks::DatabaseTasks.check_target_version }
    ensure
      ENV["VERSION"] = version
    end
  end

K
kennyj 已提交
980
  class DatabaseTasksStructureDumpTest < ActiveRecord::TestCase
K
kennyj 已提交
981
    include DatabaseTasksSetupper
K
kennyj 已提交
982

K
kennyj 已提交
983 984
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_structure_dump") do
U
utilum 已提交
985 986 987 988
        with_stubbed_new do
          eval("@#{v}").expects(:structure_dump).with("awesome-file.sql", nil)
          ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => k }, "awesome-file.sql")
        end
K
kennyj 已提交
989
      end
K
kennyj 已提交
990 991
    end
  end
K
kennyj 已提交
992 993

  class DatabaseTasksStructureLoadTest < ActiveRecord::TestCase
K
kennyj 已提交
994
    include DatabaseTasksSetupper
K
kennyj 已提交
995

K
kennyj 已提交
996 997
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_structure_load") do
U
utilum 已提交
998 999 1000 1001
        with_stubbed_new do
          eval("@#{v}").expects(:structure_load).with("awesome-file.sql", nil)
          ActiveRecord::Tasks::DatabaseTasks.structure_load({ "adapter" => k }, "awesome-file.sql")
        end
K
kennyj 已提交
1002
      end
K
kennyj 已提交
1003 1004
    end
  end
1005 1006 1007

  class DatabaseTasksCheckSchemaFileTest < ActiveRecord::TestCase
    def test_check_schema_file
U
utilum 已提交
1008 1009 1010
      assert_called_with(Kernel, :abort, [/awesome-file.sql/]) do
        ActiveRecord::Tasks::DatabaseTasks.check_schema_file("awesome-file.sql")
      end
1011 1012
    end
  end
1013 1014 1015

  class DatabaseTasksCheckSchemaFileDefaultsTest < ActiveRecord::TestCase
    def test_check_schema_file_defaults
U
utilum 已提交
1016 1017 1018
      ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
        assert_equal "/tmp/schema.rb", ActiveRecord::Tasks::DatabaseTasks.schema_file
      end
1019 1020 1021 1022
    end
  end

  class DatabaseTasksCheckSchemaFileSpecifiedFormatsTest < ActiveRecord::TestCase
1023
    { ruby: "schema.rb", sql: "structure.sql" }.each_pair do |fmt, filename|
1024
      define_method("test_check_schema_file_for_#{fmt}_format") do
U
utilum 已提交
1025 1026 1027
        ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
          assert_equal "/tmp/#{filename}", ActiveRecord::Tasks::DatabaseTasks.schema_file(fmt)
        end
1028 1029 1030
      end
    end
  end
1031
end