mince_migrator 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +20 -58
- data/bin/mince_migrator +125 -0
- data/lib/mince_migrator/cli_helper.rb +72 -0
- data/lib/mince_migrator/config.rb +30 -0
- data/lib/mince_migrator/creator.rb +48 -0
- data/lib/mince_migrator/deleter.rb +42 -0
- data/lib/mince_migrator/list.rb +46 -0
- data/lib/mince_migrator/list_report.rb +67 -0
- data/lib/mince_migrator/migration.rb +66 -0
- data/lib/mince_migrator/migrations/file.rb +74 -0
- data/lib/mince_migrator/migrations/loader.rb +52 -0
- data/lib/mince_migrator/migrations/name.rb +48 -0
- data/lib/mince_migrator/migrations/runner.rb +39 -0
- data/lib/mince_migrator/migrations/runner_validator.rb +47 -0
- data/lib/mince_migrator/migrations/template.mustache +24 -0
- data/lib/mince_migrator/migrations/template.rb +16 -0
- data/lib/mince_migrator/migrations/versioned_file.rb +38 -0
- data/lib/mince_migrator/ran_migration.rb +27 -0
- data/lib/mince_migrator/reverter.rb +57 -0
- data/lib/mince_migrator/status_report.rb +41 -0
- data/lib/mince_migrator/version.rb +18 -1
- data/lib/mince_migrator.rb +5 -4
- data/spec/integration/create_a_migration_spec.rb +57 -0
- data/spec/integration/deleting_a_migration_spec.rb +40 -0
- data/spec/integration/list_all_migrations_spec.rb +57 -0
- data/spec/integration/reverting_a_migration_spec.rb +59 -0
- data/spec/integration/running_a_migration_spec.rb +66 -0
- data/spec/integration_helper.rb +17 -0
- data/spec/support/db/a_second_migration.rb +24 -0
- data/spec/support/db/a_second_migration_2.rb +24 -0
- data/spec/support/db/create_seeded_admin_users.rb +24 -0
- data/spec/support/db/first_migration.rb +24 -0
- data/spec/support/db/first_migration_2.rb +24 -0
- data/spec/support/db/first_migration_3.rb +24 -0
- data/spec/support/db/first_migration_4.rb +24 -0
- data/spec/support/db/name_of_migration.rb +24 -0
- data/spec/support/invalid_interface_migration.rb +7 -0
- data/spec/support/not_a_migration.rb +2 -0
- data/spec/support/test_migration.rb +30 -0
- data/spec/units/mince_migrator/cli_helper_spec.rb +147 -0
- data/spec/units/mince_migrator/creator_spec.rb +80 -0
- data/spec/units/mince_migrator/deleter_spec.rb +52 -0
- data/spec/units/mince_migrator/list_spec.rb +53 -0
- data/spec/units/mince_migrator/migration_spec.rb +119 -0
- data/spec/units/mince_migrator/migrations/file_spec.rb +85 -0
- data/spec/units/mince_migrator/migrations/loader_spec.rb +47 -0
- data/spec/units/mince_migrator/migrations/name_spec.rb +47 -0
- data/spec/units/mince_migrator/migrations/runner_spec.rb +70 -0
- data/spec/units/mince_migrator/migrations/runner_validator_spec.rb +46 -0
- data/spec/units/mince_migrator/migrations/template_spec.rb +42 -0
- data/spec/units/mince_migrator/migrations/versioned_file_spec.rb +48 -0
- data/spec/units/mince_migrator/ran_migration_spec.rb +60 -0
- data/spec/units/mince_migrator/reverter_spec.rb +78 -0
- metadata +298 -26
- data/.gitignore +0 -17
- data/Gemfile +0 -4
- data/Rakefile +0 -12
- data/mince_migrator.gemspec +0 -19
@@ -0,0 +1,66 @@
|
|
1
|
+
require_relative '../integration_helper'
|
2
|
+
|
3
|
+
describe 'Running a migration' do
|
4
|
+
subject { MinceMigrator::Migrations::Runner.new(name: name) }
|
5
|
+
|
6
|
+
context 'when the migration could not be found' do
|
7
|
+
let(:name) { 'migration that does not exist' }
|
8
|
+
|
9
|
+
before do
|
10
|
+
subject.can_run_migration?
|
11
|
+
end
|
12
|
+
|
13
|
+
its(:reasons_for_failure) { should == "Migration does not exist" }
|
14
|
+
its(:can_run_migration?) { should be_false }
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'when the migration exists' do
|
18
|
+
let(:name) { "test migration" }
|
19
|
+
let(:spec_migration) { File.expand_path('../../support/test_migration.rb', __FILE__) }
|
20
|
+
let(:db_dir) { MinceMigrator::Config.migration_dir }
|
21
|
+
let(:data_model) { MinceMigrator::Migrations::TestMigration::Temporary::UserDataModel }
|
22
|
+
|
23
|
+
its(:reasons_for_failure) { should be_empty }
|
24
|
+
its(:can_run_migration?) { should be_true }
|
25
|
+
|
26
|
+
before do
|
27
|
+
FileUtils.mkdir_p(db_dir)
|
28
|
+
FileUtils.cp(spec_migration, db_dir)
|
29
|
+
subject.can_run_migration?
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'can run the migration' do
|
33
|
+
subject.run_migration.should be_true
|
34
|
+
|
35
|
+
users = data_model.all
|
36
|
+
users.size.should == 1
|
37
|
+
users.first[:username].should == 'matt'
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'and the migration has already been ran' do
|
41
|
+
before do
|
42
|
+
subject.run_migration
|
43
|
+
subject.can_run_migration?
|
44
|
+
end
|
45
|
+
|
46
|
+
its(:reasons_for_failure) { should == "Migration has already ran" }
|
47
|
+
its(:can_run_migration?) { should be_false }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when Mince interface has not been set' do
|
52
|
+
let(:name) { 'name' }
|
53
|
+
|
54
|
+
before do
|
55
|
+
Mince::Config.interface = nil
|
56
|
+
subject.can_run_migration?
|
57
|
+
end
|
58
|
+
|
59
|
+
after do
|
60
|
+
Mince::Config.interface = Mince::HashyDb::Interface
|
61
|
+
end
|
62
|
+
|
63
|
+
its(:reasons_for_failure) { should == "Mince interface is not set" }
|
64
|
+
its(:can_run_migration?) { should be_false }
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../lib/mince_migrator'
|
2
|
+
require_relative '../lib/mince_migrator/config'
|
3
|
+
require 'mince'
|
4
|
+
require 'hashy_db'
|
5
|
+
|
6
|
+
Mince::Config.interface = Mince::HashyDb::Interface
|
7
|
+
MinceMigrator::Config.instance.migration_relative_dir = "tmp/db_for_integration_specs"
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.after(:each) do
|
11
|
+
if File.exists?(MinceMigrator::Config.migration_dir)
|
12
|
+
FileUtils.rm_r MinceMigrator::Config.migration_dir
|
13
|
+
end
|
14
|
+
|
15
|
+
Mince::Config.interface.clear
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module ASecondMigration
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module ASecondMigration2
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module CreateSeededAdminUsers
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module FirstMigration
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module FirstMigration2
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module FirstMigration3
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module FirstMigration4
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module NameOfMigration
|
6
|
+
def self.run
|
7
|
+
# Actual migration goes here
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
# In case you need to revert this one migration
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse "2013-03-28 05:03:26 UTC"
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
# Migration dependent classes go here
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MinceMigrator
|
2
|
+
module Migrations
|
3
|
+
require 'time'
|
4
|
+
|
5
|
+
module TestMigration
|
6
|
+
def self.run
|
7
|
+
Temporary::UserDataModel.add(username: 'matt')
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.revert
|
11
|
+
Temporary::UserDataModel.delete_by_params(username: 'matt')
|
12
|
+
end
|
13
|
+
|
14
|
+
# So you can change the order to run more easily
|
15
|
+
def self.time_created
|
16
|
+
Time.parse '2013-03-04 09:31:28 UTC'
|
17
|
+
end
|
18
|
+
|
19
|
+
module Temporary
|
20
|
+
class UserDataModel
|
21
|
+
include Mince::DataModel
|
22
|
+
|
23
|
+
data_collection :users
|
24
|
+
data_fields :username, :email, :first_name, :last_name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require_relative '../../../lib/mince_migrator/cli_helper'
|
2
|
+
|
3
|
+
module MinceMigrator
|
4
|
+
describe CliHelper do
|
5
|
+
subject { klass.new }
|
6
|
+
|
7
|
+
let(:klass) do
|
8
|
+
Class.new do
|
9
|
+
include CliHelper
|
10
|
+
end
|
11
|
+
end
|
12
|
+
let(:options) { mock }
|
13
|
+
let(:reasons_for_failure) { mock }
|
14
|
+
|
15
|
+
before do
|
16
|
+
subject.stub(:puts)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'deleting a migration' do
|
20
|
+
let(:deleter) { mock }
|
21
|
+
|
22
|
+
before do
|
23
|
+
Deleter.stub(:new).with(options).and_return(deleter)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when the migration can be deleted' do
|
27
|
+
before do
|
28
|
+
deleter.stub(can_delete_migration?: true, name: mock)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'deletes it' do
|
32
|
+
deleter.should_receive(:delete_migration)
|
33
|
+
|
34
|
+
subject.delete_migration(options)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'when the migration cannot be deleted' do
|
39
|
+
before do
|
40
|
+
deleter.stub(can_delete_migration?: false, reasons_for_failure: reasons_for_failure)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'fails with an error message' do
|
44
|
+
subject.should_receive(:help_now!).with(reasons_for_failure)
|
45
|
+
|
46
|
+
subject.delete_migration(options)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'running a migration' do
|
52
|
+
let(:runner) { mock }
|
53
|
+
|
54
|
+
before do
|
55
|
+
Migrations::Runner.stub(:new).with(options).and_return(runner)
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when the migration can be ran' do
|
59
|
+
before do
|
60
|
+
runner.stub(can_run_migration?: true, name: mock)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'runs it' do
|
64
|
+
runner.should_receive(:run_migration)
|
65
|
+
|
66
|
+
subject.run_migration(options)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when the migration cannot be ran' do
|
71
|
+
before do
|
72
|
+
runner.stub(can_run_migration?: false, reasons_for_failure: reasons_for_failure)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'fails with an error message' do
|
76
|
+
subject.should_receive(:help_now!).with(reasons_for_failure)
|
77
|
+
|
78
|
+
subject.run_migration(options)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'creating a migration' do
|
84
|
+
let(:creator) { mock migration_file_relative_path: mock }
|
85
|
+
|
86
|
+
before do
|
87
|
+
Creator.stub(:new).with(options).and_return(creator)
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when the migration can be created' do
|
91
|
+
before do
|
92
|
+
creator.stub(can_create_migration?: true, name: mock)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'creates it' do
|
96
|
+
creator.should_receive(:create_migration)
|
97
|
+
|
98
|
+
subject.create_migration(options)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when the migration cannot be created' do
|
103
|
+
before do
|
104
|
+
creator.stub(can_create_migration?: false, reasons_for_failure: reasons_for_failure)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'fails with an error message' do
|
108
|
+
subject.should_receive(:help_now!).with(reasons_for_failure)
|
109
|
+
|
110
|
+
subject.create_migration(options)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
describe 'reverting a migration' do
|
116
|
+
let(:reverter) { mock }
|
117
|
+
|
118
|
+
before do
|
119
|
+
Reverter.stub(:new).with(options).and_return(reverter)
|
120
|
+
end
|
121
|
+
|
122
|
+
context 'when the migration can be reverted' do
|
123
|
+
before do
|
124
|
+
reverter.stub(can_revert_migration?: true, name: mock)
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'reverts it' do
|
128
|
+
reverter.should_receive(:revert_migration)
|
129
|
+
|
130
|
+
subject.revert_migration(options)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'when the migration cannot be reverted' do
|
135
|
+
before do
|
136
|
+
reverter.stub(can_revert_migration?: false, reasons_for_failure: reasons_for_failure)
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'fails with an error message' do
|
140
|
+
subject.should_receive(:help_now!).with(reasons_for_failure)
|
141
|
+
|
142
|
+
subject.revert_migration(options)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative '../../../lib/mince_migrator/creator'
|
2
|
+
|
3
|
+
describe MinceMigrator::Creator do
|
4
|
+
context 'when a name is not provided' do
|
5
|
+
let(:migration_name) { mock valid?: false, reasons_for_failure: mock, value: mock }
|
6
|
+
|
7
|
+
before do
|
8
|
+
MinceMigrator::Migrations::Name.stub(:new).with(nil).and_return(migration_name)
|
9
|
+
end
|
10
|
+
|
11
|
+
its(:can_create_migration?) { should be_false }
|
12
|
+
its(:reasons_for_failure) { should == migration_name.reasons_for_failure }
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'when a name is provided' do
|
16
|
+
subject { described_class.new(name) }
|
17
|
+
|
18
|
+
let(:name) { mock }
|
19
|
+
let(:migration_name) { mock value: mock}
|
20
|
+
|
21
|
+
before do
|
22
|
+
MinceMigrator::Migrations::Name.stub(:new).with(name).and_return(migration_name)
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the name is invalid' do
|
26
|
+
let(:reasons_for_failure) { mock }
|
27
|
+
|
28
|
+
before do
|
29
|
+
migration_name.stub(valid?: false, reasons_for_failure: reasons_for_failure)
|
30
|
+
end
|
31
|
+
|
32
|
+
its(:can_create_migration?) { should be_false }
|
33
|
+
its(:reasons_for_failure) { should == reasons_for_failure }
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when the name is valid' do
|
37
|
+
let(:opened_file) { mock write: nil, close: nil }
|
38
|
+
let(:migration_file) { mock path: mock, full_path: mock, body: mock, full_relative_path: mock }
|
39
|
+
let(:versioned_file) { mock next_unused_version: migration_file }
|
40
|
+
|
41
|
+
before do
|
42
|
+
migration_name.stub(valid?: true, value: mock)
|
43
|
+
FileUtils.stub(:mkdir_p).with(MinceMigrator::Config.migration_dir)
|
44
|
+
MinceMigrator::Migrations::VersionedFile.stub(:new).with(migration_name.value).and_return(versioned_file)
|
45
|
+
::File.stub(:open).with(migration_file.full_path, 'w+').and_return(opened_file)
|
46
|
+
::File.stub(:exists?).with(migration_file.full_path).and_return(false)
|
47
|
+
end
|
48
|
+
|
49
|
+
its(:migration_file_relative_path){ should == migration_file.full_relative_path }
|
50
|
+
|
51
|
+
it 'insures the path to the migraiton file exists' do
|
52
|
+
FileUtils.should_receive(:mkdir_p).with(MinceMigrator::Config.migration_dir)
|
53
|
+
|
54
|
+
subject.create_migration
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'can create the migration' do
|
58
|
+
subject.can_create_migration?.should be_true
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'creates a migration file' do
|
62
|
+
opened_file.should_receive(:write).with(migration_file.body)
|
63
|
+
opened_file.should_receive(:close)
|
64
|
+
|
65
|
+
subject.create_migration
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe MinceMigrator::Creator, 'Class level methods' do
|
72
|
+
it 'can create a migration' do
|
73
|
+
name = mock
|
74
|
+
creator = mock can_create_migration?: true
|
75
|
+
described_class.should_receive(:new).with(name).and_return(creator)
|
76
|
+
creator.should_receive(:create_migration)
|
77
|
+
|
78
|
+
described_class.create(name)
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative '../../../lib/mince_migrator/deleter'
|
2
|
+
|
3
|
+
describe MinceMigrator::Deleter do
|
4
|
+
let(:name) { mock }
|
5
|
+
let(:migration_name) { mock filename: mock, value: mock }
|
6
|
+
let(:migration_path) { ::File.join(path, migration_name.filename) }
|
7
|
+
let(:path) { mock }
|
8
|
+
|
9
|
+
subject { described_class.new(name: name) }
|
10
|
+
|
11
|
+
before do
|
12
|
+
MinceMigrator::Config.stub(migration_dir: path)
|
13
|
+
MinceMigrator::Migrations::Name.stub(:new).with(name).and_return(migration_name)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'when the migration does not exist' do
|
17
|
+
before do
|
18
|
+
::File.stub(:exists?).with(migration_path).and_return(false)
|
19
|
+
end
|
20
|
+
|
21
|
+
its(:can_delete_migration?) { should be_false }
|
22
|
+
its(:reasons_for_failure) { should == "Migration does not exist with name '#{migration_name.value}'" }
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'when the migration exists' do
|
26
|
+
let(:ran_migration) { nil }
|
27
|
+
|
28
|
+
before do
|
29
|
+
::File.stub(:exists?).with(migration_path).and_return(true)
|
30
|
+
MinceMigrator::RanMigration.stub(:find_by_name).with(migration_name.value).and_return(ran_migration)
|
31
|
+
FileUtils.stub(:rm)
|
32
|
+
end
|
33
|
+
|
34
|
+
its(:can_delete_migration?) { should be_true }
|
35
|
+
|
36
|
+
it 'deletes the migration' do
|
37
|
+
FileUtils.should_receive(:rm).with(migration_path)
|
38
|
+
|
39
|
+
subject.delete_migration
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when it has been ran' do
|
43
|
+
let(:ran_migration) { mock }
|
44
|
+
|
45
|
+
it 'deletes the migration for the database' do
|
46
|
+
ran_migration.should_receive(:delete)
|
47
|
+
|
48
|
+
subject.delete_migration
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative '../../../lib/mince_migrator/list'
|
2
|
+
|
3
|
+
describe MinceMigrator::List do
|
4
|
+
let(:migration_dir) { mock }
|
5
|
+
|
6
|
+
before do
|
7
|
+
MinceMigrator::Config.stub(migration_dir: migration_dir)
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'getting all migrations' do
|
11
|
+
context 'when there are no migrations' do
|
12
|
+
before do
|
13
|
+
Dir.stub(:glob).with("#{migration_dir}/*").and_return([])
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'is empty' do
|
17
|
+
subject.all.should be_empty
|
18
|
+
end
|
19
|
+
|
20
|
+
its(:number_of_migrations) { should == 0 }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when some migrations exist' do
|
24
|
+
let(:migration_paths) { [migration_path1, migration_path2] }
|
25
|
+
let(:migration_path1) { mock }
|
26
|
+
let(:migration_path2) { mock }
|
27
|
+
let(:migration1) { mock time_created: Time.now.utc, status: 'ran' }
|
28
|
+
let(:migration2) { mock time_created: Time.now.utc - 500000, status: 'not ran' }
|
29
|
+
|
30
|
+
before do
|
31
|
+
Dir.stub(:glob).with("#{migration_dir}/*").and_return(migration_paths)
|
32
|
+
MinceMigrator::Migration.stub(:load_from_file).with(migration_path1).and_return(migration1)
|
33
|
+
MinceMigrator::Migration.stub(:load_from_file).with(migration_path2).and_return(migration2)
|
34
|
+
end
|
35
|
+
|
36
|
+
its(:number_of_migrations) { should == 2 }
|
37
|
+
|
38
|
+
it 'can load all migrations' do
|
39
|
+
subject.all.should == [migration2, migration1]
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'when only wanting a list of migrations that have not yet ran' do
|
43
|
+
subject { described_class.new 'not ran' }
|
44
|
+
|
45
|
+
its(:number_of_migrations) { should == 1 }
|
46
|
+
|
47
|
+
it 'can load those migrations' do
|
48
|
+
subject.all.should == [migration2]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|