mince_migrator 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|