database_tasks_test.rb 33.6 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
      @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
18
          def structure_load(*); end
U
utilum 已提交
19 20
        end.new
      )
21 22 23 24 25 26 27

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

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

    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 已提交
39 40
  end

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

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

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

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

59 60 61 62 63 64 65 66
      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
67
      ActiveRecord::MigrationContext.any_instance.stubs(:current_version).returns(1)
68 69

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

      ActiveRecord::Base.protected_environments = [current_env.to_sym]
76 77 78 79 80 81 82 83
      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 已提交
84 85
      ActiveRecord::InternalMetadata.stub(:table_exists?, false) do
        ActiveRecord::MigrationContext.any_instance.stubs(:current_version).returns(1)
86

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

94 95 96 97 98 99 100 101
  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 已提交
102 103 104 105 106
      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 已提交
107
      end
108
    end
109 110 111

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

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

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

131 132 133 134 135 136
  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
137
      ActiveRecord::Base.clear_cache!
138 139 140 141
      FileUtils.rm_rf(path)
    end
  end

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

146 147 148 149 150 151
      $stdout, @original_stdout = StringIO.new, $stdout
      $stderr, @original_stderr = StringIO.new, $stderr
    end

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

154
    def test_ignores_configurations_without_databases
D
Dillon Welch 已提交
155
      @configurations["development"]["database"] = nil
156

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

164
    def test_ignores_remote_databases
D
Dillon Welch 已提交
165
      @configurations["development"]["host"] = "my.server.tld"
166

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

    def test_warning_for_remote_databases
D
Dillon Welch 已提交
175
      @configurations["development"]["host"] = "my.server.tld"
176

177
      with_stubbed_configurations_establish_connection do
178
        ActiveRecord::Tasks::DatabaseTasks.create_all
179

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

    def test_creates_configurations_with_local_ip
D
Dillon Welch 已提交
186
      @configurations["development"]["host"] = "127.0.0.1"
187

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

    def test_creates_configurations_with_local_host
D
Dillon Welch 已提交
196
      @configurations["development"]["host"] = "localhost"
197

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

    def test_creates_configurations_with_blank_hosts
D
Dillon Welch 已提交
206
      @configurations["development"]["host"] = nil
207

208
      with_stubbed_configurations_establish_connection do
209 210 211
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :create) do
          ActiveRecord::Tasks::DatabaseTasks.create_all
        end
U
utilum 已提交
212
      end
213
    end
214 215 216

    private

217
      def with_stubbed_configurations_establish_connection
218
        ActiveRecord::Base.stub(:configurations, @configurations) do
219 220 221 222 223 224 225 226
          # To refrain from connecting to a newly created empty DB in
          # sqlite3_mem tests
          ActiveRecord::Base.connection_handler.stub(
            :establish_connection,
            nil
          ) do
            yield
          end
227 228
        end
      end
229 230 231 232 233
  end

  class DatabaseTasksCreateCurrentTest < ActiveRecord::TestCase
    def setup
      @configurations = {
234 235
        "development" => { "database" => "dev-db" },
        "test"        => { "database" => "test-db" },
236
        "production"  => { "url" => "prod-db-url" }
237 238 239 240
      }
    end

    def test_creates_current_environment_database
U
utilum 已提交
241 242 243 244 245 246 247 248 249 250
      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 已提交
251
      end
252 253 254
    end

    def test_creates_current_environment_database_with_url
U
utilum 已提交
255 256 257 258 259 260 261 262 263 264
      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 已提交
265
      end
266 267
    end

268
    def test_creates_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
269 270 271 272 273 274 275 276 277 278 279 280 281 282
      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
283 284
    end

285
    def test_creates_test_and_development_databases_when_rails_env_is_development
286 287
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
288

U
utilum 已提交
289 290 291 292 293 294 295 296 297 298 299 300 301 302
      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
303
    ensure
304
      ENV["RAILS_ENV"] = old_env
305 306
    end

E
eileencodes 已提交
307
    def test_establishes_connection_for_the_given_environments
U
utilum 已提交
308 309 310 311 312 313 314 315
      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 已提交
316

U
utilum 已提交
317
    private
E
eileencodes 已提交
318

U
utilum 已提交
319 320 321 322 323 324 325
      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 已提交
326 327 328 329 330 331 332
  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" } },
333
        "production" => { "primary" => { "url" => "prod-db-url" }, "secondary" => { "url" => "secondary-prod-db-url" } }
E
eileencodes 已提交
334 335 336 337
      }
    end

    def test_creates_current_environment_database
U
utilum 已提交
338 339 340 341 342 343 344 345 346 347 348 349 350 351
      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
352 353 354
    end

    def test_creates_current_environment_database_with_url
U
utilum 已提交
355 356 357 358 359 360 361 362 363 364 365 366 367 368
      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 已提交
369 370 371
    end

    def test_creates_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387
      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 已提交
388 389 390 391 392
    end

    def test_creates_test_and_development_databases_when_rails_env_is_development
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
U
utilum 已提交
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409

      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 已提交
410 411 412 413 414
    ensure
      ENV["RAILS_ENV"] = old_env
    end

    def test_establishes_connection_for_the_given_environments_config
U
utilum 已提交
415
      ActiveRecord::Tasks::DatabaseTasks.stub(:create, nil) do
416 417 418 419 420 421 422 423 424
        assert_called_with(
          ActiveRecord::Base,
          :establish_connection,
          [:development]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.create_current(
            ActiveSupport::StringInquirer.new("development")
          )
        end
U
utilum 已提交
425
      end
426
    end
U
utilum 已提交
427 428 429 430 431 432 433 434 435 436

    private

      def with_stubbed_configurations_establish_connection
        ActiveRecord::Base.stub(:configurations, @configurations) do
          ActiveRecord::Base.stub(:establish_connection, nil) do
            yield
          end
        end
      end
437 438 439
  end

  class DatabaseTasksDropTest < ActiveRecord::TestCase
K
kennyj 已提交
440
    include DatabaseTasksSetupper
441

K
kennyj 已提交
442 443
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_drop") do
U
utilum 已提交
444
        with_stubbed_new do
445 446 447
          assert_called(eval("@#{v}"), :drop) do
            ActiveRecord::Tasks::DatabaseTasks.drop "adapter" => k
          end
U
utilum 已提交
448
        end
K
kennyj 已提交
449
      end
450 451 452 453 454
    end
  end

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

457 458 459 460 461 462
      $stdout, @original_stdout = StringIO.new, $stdout
      $stderr, @original_stderr = StringIO.new, $stderr
    end

    def teardown
      $stdout, $stderr = @original_stdout, @original_stderr
463 464
    end

465
    def test_ignores_configurations_without_databases
D
Dillon Welch 已提交
466
      @configurations[:development]["database"] = nil
467

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

475
    def test_ignores_remote_databases
D
Dillon Welch 已提交
476
      @configurations[:development]["host"] = "my.server.tld"
477

U
utilum 已提交
478 479 480 481
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_not_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
          ActiveRecord::Tasks::DatabaseTasks.drop_all
        end
U
utilum 已提交
482
      end
483 484 485
    end

    def test_warning_for_remote_databases
D
Dillon Welch 已提交
486
      @configurations[:development]["host"] = "my.server.tld"
487

U
utilum 已提交
488 489
      ActiveRecord::Base.stub(:configurations, @configurations) do
        ActiveRecord::Tasks::DatabaseTasks.drop_all
490

U
utilum 已提交
491 492 493
        assert_match "This task only modifies local databases. my-db is on a remote host.",
          $stderr.string
      end
494 495
    end

496
    def test_drops_configurations_with_local_ip
D
Dillon Welch 已提交
497
      @configurations[:development]["host"] = "127.0.0.1"
498

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

506
    def test_drops_configurations_with_local_host
D
Dillon Welch 已提交
507
      @configurations[:development]["host"] = "localhost"
508

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

516
    def test_drops_configurations_with_blank_hosts
D
Dillon Welch 已提交
517
      @configurations[:development]["host"] = nil
518

U
utilum 已提交
519 520 521 522
      ActiveRecord::Base.stub(:configurations, @configurations) do
        assert_called(ActiveRecord::Tasks::DatabaseTasks, :drop) do
          ActiveRecord::Tasks::DatabaseTasks.drop_all
        end
U
utilum 已提交
523
      end
524 525 526 527 528 529
    end
  end

  class DatabaseTasksDropCurrentTest < ActiveRecord::TestCase
    def setup
      @configurations = {
530 531
        "development" => { "database" => "dev-db" },
        "test"        => { "database" => "test-db" },
532
        "production"  => { "url" => "prod-db-url" }
533 534 535
      }
    end

536
    def test_drops_current_environment_database
U
utilum 已提交
537 538 539 540 541 542 543 544
      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
545 546 547
    end

    def test_drops_current_environment_database_with_url
U
utilum 已提交
548 549 550 551 552 553 554 555
      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
556 557
    end

558
    def test_drops_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
559 560 561 562 563 564 565 566 567 568 569 570 571 572
      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
573 574
    end

575
    def test_drops_testand_development_databases_when_rails_env_is_development
576 577
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
578

U
utilum 已提交
579 580 581 582 583 584 585 586 587 588 589 590 591 592
      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 已提交
593 594 595 596 597 598 599 600 601 602
    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" } },
603
        "production" => { "primary" => { "url" => "prod-db-url" }, "secondary" => { "url" => "secondary-prod-db-url" } }
E
eileencodes 已提交
604 605 606 607
      }
    end

    def test_drops_current_environment_database
U
utilum 已提交
608 609 610 611 612 613 614 615 616 617 618 619 620 621
      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
622 623 624
    end

    def test_drops_current_environment_database_with_url
U
utilum 已提交
625 626 627 628 629 630 631 632 633 634 635 636 637 638
      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 已提交
639 640 641
    end

    def test_drops_test_and_development_databases_when_env_was_not_specified
U
utilum 已提交
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657
      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 已提交
658 659 660 661 662
    end

    def test_drops_testand_development_databases_when_rails_env_is_development
      old_env = ENV["RAILS_ENV"]
      ENV["RAILS_ENV"] = "development"
U
utilum 已提交
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679

      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
680
    ensure
681
      ENV["RAILS_ENV"] = old_env
682 683 684
    end
  end

685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700
  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
701

702 703 704 705
      teardown do
        @conn.release_connection if @conn
        ActiveRecord::Base.establish_connection :arunit
      end
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 755 756 757 758 759 760 761 762 763 764 765
      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
766
    end
767 768 769 770
  end

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

772
    def test_migrate_raise_error_on_invalid_version_format
P
Philippe Guay 已提交
773
      version = ENV["VERSION"]
774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795

      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_"
796
      e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
797 798 799 800 801
      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 已提交
802 803 804 805
    ensure
      ENV["VERSION"] = version
    end

806
    def test_migrate_raise_error_on_failed_check_target_version
U
utilum 已提交
807 808 809 810
      ActiveRecord::Tasks::DatabaseTasks.stub(:check_target_version, -> { raise "foo" }) do
        e = assert_raise(RuntimeError) { ActiveRecord::Tasks::DatabaseTasks.migrate }
        assert_equal "foo", e.message
      end
811 812
    end

813
    def test_migrate_clears_schema_cache_afterward
U
utilum 已提交
814 815 816
      assert_called(ActiveRecord::Base, :clear_cache!) do
        ActiveRecord::Tasks::DatabaseTasks.migrate
      end
817
    end
818
  end
K
kennyj 已提交
819

820
  class DatabaseTasksPurgeTest < ActiveRecord::TestCase
K
kennyj 已提交
821
    include DatabaseTasksSetupper
822

K
kennyj 已提交
823 824
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_purge") do
U
utilum 已提交
825
        with_stubbed_new do
826 827 828
          assert_called(eval("@#{v}"), :purge) do
            ActiveRecord::Tasks::DatabaseTasks.purge "adapter" => k
          end
U
utilum 已提交
829
        end
K
kennyj 已提交
830
      end
831 832
    end
  end
S
Simon Jefford 已提交
833

834 835 836
  class DatabaseTasksPurgeCurrentTest < ActiveRecord::TestCase
    def test_purges_current_environment_database
      configurations = {
837 838 839
        "development" => { "database" => "dev-db" },
        "test"        => { "database" => "test-db" },
        "production"  => { "database" => "prod-db" }
840
      }
U
utilum 已提交
841
      ActiveRecord::Base.stub(:configurations, configurations) do
842 843 844 845 846 847 848 849
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :purge,
          ["database" => "prod-db"]
        ) do
          assert_called_with(ActiveRecord::Base, :establish_connection, [:production]) do
            ActiveRecord::Tasks::DatabaseTasks.purge_current("production")
          end
U
utilum 已提交
850
        end
U
utilum 已提交
851
      end
852 853 854 855 856
    end
  end

  class DatabaseTasksPurgeAllTest < ActiveRecord::TestCase
    def test_purge_all_local_configurations
857
      configurations = { development: { "database" => "my-db" } }
U
utilum 已提交
858
      ActiveRecord::Base.stub(:configurations, configurations) do
859 860 861 862 863 864 865
        assert_called_with(
          ActiveRecord::Tasks::DatabaseTasks,
          :purge,
          ["database" => "my-db"]
        ) do
          ActiveRecord::Tasks::DatabaseTasks.purge_all
        end
U
utilum 已提交
866
      end
867 868 869
    end
  end

S
Simon Jefford 已提交
870
  class DatabaseTasksCharsetTest < ActiveRecord::TestCase
K
kennyj 已提交
871
    include DatabaseTasksSetupper
872

K
kennyj 已提交
873 874
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_charset") do
U
utilum 已提交
875
        with_stubbed_new do
876 877 878
          assert_called(eval("@#{v}"), :charset) do
            ActiveRecord::Tasks::DatabaseTasks.charset "adapter" => k
          end
U
utilum 已提交
879
        end
K
kennyj 已提交
880
      end
S
Simon Jefford 已提交
881 882
    end
  end
K
kennyj 已提交
883

884 885
  class DatabaseTasksCollationTest < ActiveRecord::TestCase
    include DatabaseTasksSetupper
886

887 888
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_collation") do
U
utilum 已提交
889
        with_stubbed_new do
890 891 892
          assert_called(eval("@#{v}"), :collation) do
            ActiveRecord::Tasks::DatabaseTasks.collation "adapter" => k
          end
U
utilum 已提交
893
        end
894 895 896 897
      end
    end
  end

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 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
  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 已提交
1000
  class DatabaseTasksStructureDumpTest < ActiveRecord::TestCase
K
kennyj 已提交
1001
    include DatabaseTasksSetupper
K
kennyj 已提交
1002

K
kennyj 已提交
1003 1004
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_structure_dump") do
U
utilum 已提交
1005
        with_stubbed_new do
1006 1007 1008 1009 1010 1011
          assert_called_with(
            eval("@#{v}"), :structure_dump,
            ["awesome-file.sql", nil]
          ) do
            ActiveRecord::Tasks::DatabaseTasks.structure_dump({ "adapter" => k }, "awesome-file.sql")
          end
U
utilum 已提交
1012
        end
K
kennyj 已提交
1013
      end
K
kennyj 已提交
1014 1015
    end
  end
K
kennyj 已提交
1016 1017

  class DatabaseTasksStructureLoadTest < ActiveRecord::TestCase
K
kennyj 已提交
1018
    include DatabaseTasksSetupper
K
kennyj 已提交
1019

K
kennyj 已提交
1020 1021
    ADAPTERS_TASKS.each do |k, v|
      define_method("test_#{k}_structure_load") do
U
utilum 已提交
1022
        with_stubbed_new do
1023 1024 1025 1026 1027 1028 1029
          assert_called_with(
            eval("@#{v}"),
            :structure_load,
            ["awesome-file.sql", nil]
          ) do
            ActiveRecord::Tasks::DatabaseTasks.structure_load({ "adapter" => k }, "awesome-file.sql")
          end
U
utilum 已提交
1030
        end
K
kennyj 已提交
1031
      end
K
kennyj 已提交
1032 1033
    end
  end
1034 1035 1036

  class DatabaseTasksCheckSchemaFileTest < ActiveRecord::TestCase
    def test_check_schema_file
U
utilum 已提交
1037 1038 1039
      assert_called_with(Kernel, :abort, [/awesome-file.sql/]) do
        ActiveRecord::Tasks::DatabaseTasks.check_schema_file("awesome-file.sql")
      end
1040 1041
    end
  end
1042 1043 1044

  class DatabaseTasksCheckSchemaFileDefaultsTest < ActiveRecord::TestCase
    def test_check_schema_file_defaults
U
utilum 已提交
1045 1046 1047
      ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
        assert_equal "/tmp/schema.rb", ActiveRecord::Tasks::DatabaseTasks.schema_file
      end
1048 1049 1050 1051
    end
  end

  class DatabaseTasksCheckSchemaFileSpecifiedFormatsTest < ActiveRecord::TestCase
1052
    { ruby: "schema.rb", sql: "structure.sql" }.each_pair do |fmt, filename|
1053
      define_method("test_check_schema_file_for_#{fmt}_format") do
U
utilum 已提交
1054 1055 1056
        ActiveRecord::Tasks::DatabaseTasks.stub(:db_dir, "/tmp") do
          assert_equal "/tmp/#{filename}", ActiveRecord::Tasks::DatabaseTasks.schema_file(fmt)
        end
1057 1058 1059
      end
    end
  end
1060
end