aboutsummaryrefslogtreecommitdiffstats
path: root/railties/test/generators/create_migration_test.rb
blob: 2ae38045c56d29950d0d94af539d28daefc24732 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# frozen_string_literal: true

require "generators/generators_test_helper"
require "rails/generators/rails/migration/migration_generator"

class CreateMigrationTest < Rails::Generators::TestCase
  include GeneratorsTestHelper

  class Migrator < Rails::Generators::MigrationGenerator
    include Rails::Generators::Migration

    def self.next_migration_number(dirname)
      current_migration_number(dirname) + 1
    end
  end

  tests Migrator

  def default_destination_path
    "db/migrate/create_articles.rb"
  end

  def create_migration(destination_path = default_destination_path, config = {}, generator_options = {}, &block)
    migration_name = File.basename(destination_path, ".rb")
    generator([migration_name], generator_options)
    generator.set_migration_assigns!(destination_path)

    dir, base = File.split(destination_path)
    timestamped_destination_path = File.join(dir, ["%migration_number%", base].join("_"))

    @migration = Rails::Generators::Actions::CreateMigration.new(generator, timestamped_destination_path, block || "contents", config)
  end

  def migration_exists!(*args)
    @existing_migration = create_migration(*args)
    invoke!
    @generator = nil
  end

  def invoke!
    capture(:stdout) { @migration.invoke! }
  end

  def revoke!
    capture(:stdout) { @migration.revoke! }
  end

  def test_invoke
    create_migration

    assert_match(/create  db\/migrate\/1_create_articles\.rb\n/, invoke!)
    assert_file @migration.destination
  end

  def test_invoke_pretended
    create_migration(default_destination_path, {}, { pretend: true })

    assert_no_file @migration.destination
  end

  def test_invoke_when_exists
    migration_exists!
    create_migration

    assert_equal @existing_migration.destination, @migration.existing_migration
  end

  def test_invoke_when_exists_identical
    migration_exists!
    create_migration

    assert_match(/identical  db\/migrate\/1_create_articles\.rb\n/, invoke!)
    assert_predicate @migration, :identical?
  end

  def test_invoke_when_exists_not_identical
    migration_exists!
    create_migration { "different content" }

    assert_raise(Rails::Generators::Error) { invoke! }
  end

  def test_invoke_forced_when_exists_not_identical
    dest = "db/migrate/migration.rb"
    migration_exists!(dest)
    create_migration(dest, force: true) { "different content" }

    stdout = invoke!
    assert_match(/remove  db\/migrate\/1_migration\.rb\n/, stdout)
    assert_match(/create  db\/migrate\/2_migration\.rb\n/, stdout)
    assert_file @migration.destination
    assert_no_file @existing_migration.destination
  end

  def test_invoke_forced_pretended_when_exists_not_identical
    migration_exists!
    create_migration(default_destination_path, { force: true }, { pretend: true }) do
      "different content"
    end

    stdout = invoke!
    assert_match(/remove  db\/migrate\/1_create_articles\.rb\n/, stdout)
    assert_match(/create  db\/migrate\/2_create_articles\.rb\n/, stdout)
    assert_no_file @migration.destination
  end

  def test_invoke_skipped_when_exists_not_identical
    migration_exists!
    create_migration(default_destination_path, {}, { skip: true }) { "different content" }

    assert_match(/skip  db\/migrate\/2_create_articles\.rb\n/, invoke!)
    assert_no_file @migration.destination
  end

  def test_revoke
    migration_exists!
    create_migration

    assert_match(/remove  db\/migrate\/1_create_articles\.rb\n/, revoke!)
    assert_no_file @existing_migration.destination
  end

  def test_revoke_pretended
    migration_exists!
    create_migration(default_destination_path, {}, { pretend: true })

    assert_match(/remove  db\/migrate\/1_create_articles\.rb\n/, revoke!)
    assert_file @existing_migration.destination
  end

  def test_revoke_when_no_exists
    create_migration

    assert_match(/remove  db\/migrate\/1_create_articles\.rb\n/, revoke!)
  end
end