hummingbird 0.0.1
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.
- data/.gitignore +16 -0
- data/.travis.yml +4 -0
- data/CONTRIBUTING.md +7 -0
- data/Gemfile +15 -0
- data/Guardfile +9 -0
- data/LICENSE +20 -0
- data/README.md +134 -0
- data/Rakefile +10 -0
- data/hummingbird.gemspec +31 -0
- data/lib/hummingbird/configuration.rb +35 -0
- data/lib/hummingbird/database.rb +31 -0
- data/lib/hummingbird/plan.rb +75 -0
- data/lib/hummingbird/plan_error.rb +11 -0
- data/lib/hummingbird/version.rb +3 -0
- data/lib/hummingbird.rb +7 -0
- data/test/fixtures/basic_config.yml +6 -0
- data/test/fixtures/no_basedir_config.yml +3 -0
- data/test/fixtures/no_basedir_user_config.yml +3 -0
- data/test/fixtures/no_connection_string_config.yml +5 -0
- data/test/fixtures/no_migrations_dir_config.yml +3 -0
- data/test/fixtures/no_migrations_dir_user_config.yml +3 -0
- data/test/fixtures/no_migrations_table_config.yml +4 -0
- data/test/fixtures/no_planfile_config.yml +3 -0
- data/test/fixtures/no_planfile_user_config.yml +3 -0
- data/test/fixtures/plan/basic.plan +4 -0
- data/test/fixtures/sql/migrations/basic/file1.sql +1 -0
- data/test/fixtures/sql/migrations/basic/file2.sql +1 -0
- data/test/fixtures/sql/migrations/basic/file3.sql +1 -0
- data/test/fixtures/sql/migrations/basic/file4.sql +1 -0
- data/test/fixtures/sql/migrations_table.sql +4 -0
- data/test/fixtures/user_config.yml +4 -0
- data/test/lib/hummingbird/configuration_test.rb +153 -0
- data/test/lib/hummingbird/database_test.rb +100 -0
- data/test/lib/hummingbird/plan_test.rb +230 -0
- data/test/lib/hummingbird/version_test.rb +7 -0
- data/test/test_helper.rb +66 -0
- data/test/test_helper_test.rb +41 -0
- metadata +237 -0
@@ -0,0 +1 @@
|
|
1
|
+
CREATE TABLE table1 (name text);
|
@@ -0,0 +1 @@
|
|
1
|
+
CREATE TABLE table2 (name text);
|
@@ -0,0 +1 @@
|
|
1
|
+
CREATE TABLE table3 (name text);
|
@@ -0,0 +1 @@
|
|
1
|
+
CREATE TABLE table4 (name text);
|
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Hummingbird::Configuration do
|
4
|
+
before do
|
5
|
+
@tempdir = tempdir
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'defines the CONFIG_FILE basename constant' do
|
9
|
+
assert_equal 'hummingbird.yml', Hummingbird::Configuration::CONFIG_FILE
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'defines the USER_CONFIG_FILE basename constant' do
|
13
|
+
assert_equal '.hummingbird.yml', Hummingbird::Configuration::USER_CONFIG_FILE
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'loads the hummingbird.yml file from the specified config_dir' do
|
17
|
+
copy_fixture_to(
|
18
|
+
'basic_config.yml',
|
19
|
+
File.join(@tempdir, Hummingbird::Configuration::CONFIG_FILE)
|
20
|
+
)
|
21
|
+
|
22
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
23
|
+
|
24
|
+
assert_equal 'sql', config.basedir
|
25
|
+
assert_equal _with_basedir(config, 'application.plan'), config.planfile
|
26
|
+
assert_equal _with_basedir(config, 'migrations-dir'), config.migrations_dir
|
27
|
+
assert_equal :application_migrations, config.migrations_table
|
28
|
+
assert_equal 'sequel connection string', config.connection_string
|
29
|
+
end
|
30
|
+
|
31
|
+
it "defaults #basedir to be '.'" do
|
32
|
+
copy_fixture_to(
|
33
|
+
'no_basedir_config.yml',
|
34
|
+
File.join(@tempdir, Hummingbird::Configuration::CONFIG_FILE)
|
35
|
+
)
|
36
|
+
|
37
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
38
|
+
|
39
|
+
assert_equal '.', config.basedir
|
40
|
+
end
|
41
|
+
|
42
|
+
it "defaults #planfile to be basedir + 'hummingbird.plan'" do
|
43
|
+
copy_fixture_to(
|
44
|
+
'no_planfile_config.yml',
|
45
|
+
File.join(@tempdir, Hummingbird::Configuration::CONFIG_FILE)
|
46
|
+
)
|
47
|
+
|
48
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
49
|
+
|
50
|
+
assert_equal _with_basedir(config,'hummingbird.plan'), config.planfile
|
51
|
+
end
|
52
|
+
|
53
|
+
it "defaults #migrations_dir to be basedir + 'migrations'" do
|
54
|
+
copy_fixture_to(
|
55
|
+
'no_migrations_dir_config.yml',
|
56
|
+
File.join(@tempdir, Hummingbird::Configuration::CONFIG_FILE)
|
57
|
+
)
|
58
|
+
|
59
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
60
|
+
|
61
|
+
assert_equal _with_basedir(config,'migrations'), config.migrations_dir
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'defaults #migrations_table to be :hummingbird_migrations' do
|
65
|
+
copy_fixture_to(
|
66
|
+
'no_migrations_table_config.yml',
|
67
|
+
File.join(@tempdir, Hummingbird::Configuration::CONFIG_FILE)
|
68
|
+
)
|
69
|
+
|
70
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
71
|
+
|
72
|
+
assert_equal :hummingbird_migrations, config.migrations_table
|
73
|
+
end
|
74
|
+
|
75
|
+
it "does not have a default #connection_string" do
|
76
|
+
copy_fixture_to(
|
77
|
+
'no_connection_string_config.yml',
|
78
|
+
File.join(@tempdir, Hummingbird::Configuration::CONFIG_FILE)
|
79
|
+
)
|
80
|
+
|
81
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
82
|
+
|
83
|
+
assert_equal nil, config.connection_string
|
84
|
+
end
|
85
|
+
|
86
|
+
it "prefers the user's configuration file if one is present" do
|
87
|
+
[['basic_config.yml', Hummingbird::Configuration::CONFIG_FILE],
|
88
|
+
['user_config.yml', Hummingbird::Configuration::USER_CONFIG_FILE]].each do |s,d|
|
89
|
+
copy_fixture_to(s, File.join(@tempdir, d))
|
90
|
+
end
|
91
|
+
|
92
|
+
config = nil
|
93
|
+
FileUtils.stub :pwd, @tempdir do
|
94
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
95
|
+
end
|
96
|
+
|
97
|
+
assert_equal 'user-sql', config.basedir
|
98
|
+
assert_equal _with_basedir(config,'user-application.plan'), config.planfile
|
99
|
+
assert_equal _with_basedir(config,'user-migrations-dir'), config.migrations_dir
|
100
|
+
end
|
101
|
+
|
102
|
+
it "uses non-user basedir if not present for user" do
|
103
|
+
[['basic_config.yml', Hummingbird::Configuration::CONFIG_FILE],
|
104
|
+
['no_basedir_user_config.yml', Hummingbird::Configuration::USER_CONFIG_FILE]].each do |s,d|
|
105
|
+
copy_fixture_to(s, File.join(@tempdir, d))
|
106
|
+
end
|
107
|
+
|
108
|
+
config = nil
|
109
|
+
FileUtils.stub :pwd, @tempdir do
|
110
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
111
|
+
end
|
112
|
+
|
113
|
+
assert_equal 'sql', config.basedir
|
114
|
+
assert_equal _with_basedir(config, 'user-application.plan'), config.planfile
|
115
|
+
assert_equal _with_basedir(config, 'user-migrations-dir'), config.migrations_dir
|
116
|
+
end
|
117
|
+
|
118
|
+
it "uses non-user planfile if not present for user" do
|
119
|
+
[['basic_config.yml', Hummingbird::Configuration::CONFIG_FILE],
|
120
|
+
['no_planfile_user_config.yml', Hummingbird::Configuration::USER_CONFIG_FILE]].each do |s,d|
|
121
|
+
copy_fixture_to(s, File.join(@tempdir, d))
|
122
|
+
end
|
123
|
+
|
124
|
+
config = nil
|
125
|
+
FileUtils.stub :pwd, @tempdir do
|
126
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
127
|
+
end
|
128
|
+
|
129
|
+
assert_equal 'user-sql', config.basedir
|
130
|
+
assert_equal _with_basedir(config, 'application.plan'), config.planfile
|
131
|
+
assert_equal _with_basedir(config, 'user-migrations-dir'), config.migrations_dir
|
132
|
+
end
|
133
|
+
|
134
|
+
it "uses non-user migrations_dir if not present for user" do
|
135
|
+
[['basic_config.yml', Hummingbird::Configuration::CONFIG_FILE],
|
136
|
+
['no_migrations_dir_user_config.yml', Hummingbird::Configuration::USER_CONFIG_FILE]].each do |s,d|
|
137
|
+
copy_fixture_to(s, File.join(@tempdir, d))
|
138
|
+
end
|
139
|
+
|
140
|
+
config = nil
|
141
|
+
FileUtils.stub :pwd, @tempdir do
|
142
|
+
config = Hummingbird::Configuration.new(@tempdir)
|
143
|
+
end
|
144
|
+
|
145
|
+
assert_equal 'user-sql', config.basedir
|
146
|
+
assert_equal _with_basedir(config, 'user-application.plan'), config.planfile
|
147
|
+
assert_equal _with_basedir(config, 'migrations-dir'), config.migrations_dir
|
148
|
+
end
|
149
|
+
|
150
|
+
def _with_basedir(config,path)
|
151
|
+
File.expand_path(File.join(config.basedir,path))
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'sqlite3'
|
3
|
+
|
4
|
+
describe Hummingbird::Database do
|
5
|
+
describe 'with an sqlite3 database' do
|
6
|
+
it 'reports the database as uninitialized if the migrations table is not found' do
|
7
|
+
sqlite_db = tempfile
|
8
|
+
sqlite_db.close
|
9
|
+
|
10
|
+
db = Hummingbird::Database.new("sqlite://#{sqlite_db.path}", :hummingbird_migrations)
|
11
|
+
|
12
|
+
assert_equal false, db.initialized?, 'DB should not be initialized'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'reports the database as initialized if the migrations table exists' do
|
16
|
+
sqlite_db_path = tempfile.path
|
17
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
18
|
+
|
19
|
+
sqlite_db.execute "create table hummingbird_migrations (migration_name text);"
|
20
|
+
|
21
|
+
db = Hummingbird::Database.new("sqlite://#{sqlite_db_path}", :hummingbird_migrations)
|
22
|
+
|
23
|
+
assert_equal true, db.initialized?, 'DB should be initialized'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns an empty list of already run migrations if the database has not already been initialized' do
|
27
|
+
sqlite_db_path = tempfile.path
|
28
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
29
|
+
|
30
|
+
db = Hummingbird::Database.new("sqlite://#{sqlite_db_path}", :hummingbird_migrations)
|
31
|
+
|
32
|
+
assert_set_equal [], db.already_run_migrations
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'returns a list of the migrations that have already been run, in ascending run order of run date' do
|
36
|
+
sqlite_db_path = tempfile.path
|
37
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
38
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
39
|
+
stmt = sqlite_db.prepare('INSERT INTO hummingbird_migrations (migration_name, run_on) VALUES (?,?);')
|
40
|
+
[ ['third_migration.sql', DateTime.new(2012,10,11,12,0,0,'-7').strftime('%s')],
|
41
|
+
['first_migration.sql', DateTime.new(2012,10, 1,13,0,0,'-7').strftime('%s')],
|
42
|
+
['second_migration.sql', DateTime.new(2012,10, 8, 8,0,0,'-7').strftime('%s')]].each {|data| stmt.execute(*data)}
|
43
|
+
|
44
|
+
db = Hummingbird::Database.new("sqlite://#{sqlite_db_path}", :hummingbird_migrations)
|
45
|
+
|
46
|
+
assert_equal(
|
47
|
+
[ { migration_name: 'first_migration.sql', run_on: DateTime.new(2012,10, 1,13,0,0,'-7').strftime('%s').to_i },
|
48
|
+
{ migration_name: 'second_migration.sql', run_on: DateTime.new(2012,10, 8, 8,0,0,'-7').strftime('%s').to_i },
|
49
|
+
{ migration_name: 'third_migration.sql', run_on: DateTime.new(2012,10,11,12,0,0,'-7').strftime('%s').to_i }
|
50
|
+
],
|
51
|
+
db.already_run_migrations
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'records and runs migrations specified via #run_migration' do
|
56
|
+
sqlite_db_path = tempfile.path
|
57
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
58
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
59
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
60
|
+
|
61
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
62
|
+
|
63
|
+
migration_time = DateTime.new(2012,10,15,14,03,40,'-7')
|
64
|
+
DateTime.stub :now, migration_time do
|
65
|
+
db.run_migration('test_migration.sql', 'CREATE TABLE test_table (col1 text);')
|
66
|
+
end
|
67
|
+
|
68
|
+
assert_equal(
|
69
|
+
[{migration_name: 'test_migration.sql', run_on: migration_time.strftime('%s').to_i}],
|
70
|
+
db.already_run_migrations
|
71
|
+
)
|
72
|
+
|
73
|
+
assert_includes Sequel.connect(connect_string).tables, :test_table
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'allows bootstrapping the DB via #run_migration' do
|
77
|
+
sqlite_db_path = tempfile.path
|
78
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
79
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
80
|
+
|
81
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
82
|
+
|
83
|
+
seconds = 40
|
84
|
+
DateTime.stub :now, lambda { DateTime.new(2012,10,15,14,03,seconds+=1,'-7') } do
|
85
|
+
db.run_migration('bootstrap_hummingbird.sql', read_fixture('sql', 'migrations_table.sql'))
|
86
|
+
db.run_migration('test_migration.sql', 'CREATE TABLE test_table (col1 text);')
|
87
|
+
end
|
88
|
+
|
89
|
+
assert_equal(
|
90
|
+
[
|
91
|
+
{migration_name: 'bootstrap_hummingbird.sql', run_on: DateTime.new(2012,10,15,14,03,41,'-7').strftime('%s').to_i},
|
92
|
+
{migration_name: 'test_migration.sql', run_on: DateTime.new(2012,10,15,14,03,42,'-7').strftime('%s').to_i}
|
93
|
+
],
|
94
|
+
db.already_run_migrations
|
95
|
+
)
|
96
|
+
|
97
|
+
assert_includes Sequel.connect(connect_string).tables, :test_table
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'sqlite3'
|
3
|
+
|
4
|
+
describe Hummingbird::Plan do
|
5
|
+
it 'reads the planned file list from the planfile' do
|
6
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), tempdir)
|
7
|
+
|
8
|
+
assert_equal(
|
9
|
+
['file1.sql','file2.sql','file3.sql','file4.sql'],
|
10
|
+
plan.planned_files
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'gets the list of migration files from examining config.migration_dir' do
|
15
|
+
migration_dir = tempdir
|
16
|
+
migration_files = ['migration1.sql','migration2.sql','migration3.sql']
|
17
|
+
FileUtils.touch migration_files.map {|f| File.join(migration_dir,f)}
|
18
|
+
|
19
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), migration_dir)
|
20
|
+
|
21
|
+
assert_equal(
|
22
|
+
migration_files.sort,
|
23
|
+
plan.migration_files.sort
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'recurses into config.migration_dir to get the list of migration files' do
|
28
|
+
migration_dir = tempdir
|
29
|
+
migration_files = [['a','b','migration1.sql'],['a','migration2.sql'],['migration3.sql']].map {|f| File.join(*f)}
|
30
|
+
FileUtils.mkdir_p(File.join(migration_dir, 'a', 'b'))
|
31
|
+
FileUtils.touch migration_files.map {|f| File.join(migration_dir, f)}
|
32
|
+
|
33
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), migration_dir)
|
34
|
+
|
35
|
+
assert_equal(
|
36
|
+
migration_files.sort,
|
37
|
+
plan.migration_files.sort
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'returns the list of files missing from the plan' do
|
42
|
+
migration_dir = tempdir
|
43
|
+
migration_files = (0..6).map {|n| "file#{n}.sql"}
|
44
|
+
FileUtils.touch migration_files.map {|f| File.join(migration_dir,f)}
|
45
|
+
|
46
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), migration_dir)
|
47
|
+
|
48
|
+
assert_set_equal [migration_files[0],*migration_files[-2,2]], plan.files_missing_from_plan, 'Wrong files missing from plan'
|
49
|
+
assert_set_equal [], plan.files_missing_from_migration_dir, 'Wrong files missing from migration_dir'
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'returns the list of extra files in the plan' do
|
53
|
+
migration_dir = tempdir
|
54
|
+
migration_files = (2..3).map {|n| "file#{n}.sql"}
|
55
|
+
FileUtils.touch migration_files.map {|f| File.join(migration_dir,f)}
|
56
|
+
|
57
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), migration_dir)
|
58
|
+
|
59
|
+
assert_set_equal ['file1.sql','file4.sql'], plan.files_missing_from_migration_dir, 'Wrong files missing from migration_dir'
|
60
|
+
assert_set_equal [], plan.files_missing_from_plan, 'Wrong files missing from plan'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'reports no files missing when plan, and migration_dir are in sync' do
|
64
|
+
migration_dir = tempdir
|
65
|
+
migration_files = (1..4).map {|n| "file#{n}.sql"}
|
66
|
+
FileUtils.touch migration_files.map {|f| File.join(migration_dir,f)}
|
67
|
+
|
68
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), migration_dir)
|
69
|
+
|
70
|
+
assert_set_equal [], plan.files_missing_from_migration_dir, 'Wrong files missing from migration_dir'
|
71
|
+
assert_set_equal [], plan.files_missing_from_plan, 'Wrong files missing from plan'
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#to_be_run_migration_file_names' do
|
75
|
+
it 'returns all planned files when the db is uninitialized' do
|
76
|
+
sqlite_db_path = tempfile.path
|
77
|
+
|
78
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
79
|
+
db = Hummingbird::Database.new("sqlite://#{sqlite_db_path}", :hummingbird_migrations)
|
80
|
+
|
81
|
+
assert_equal(
|
82
|
+
['file1.sql','file2.sql','file3.sql','file4.sql'],
|
83
|
+
plan.to_be_run_migration_file_names(db.already_run_migrations)
|
84
|
+
)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'returns all planned files when no migrations have been run' do
|
88
|
+
sqlite_db_path = tempfile.path
|
89
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
90
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
91
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
92
|
+
|
93
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
94
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
95
|
+
|
96
|
+
assert_equal(
|
97
|
+
['file1.sql','file2.sql','file3.sql','file4.sql'],
|
98
|
+
plan.to_be_run_migration_file_names(db.already_run_migrations)
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns all planned files after the last run migration when plan and DB are in sync to that point' do
|
103
|
+
sqlite_db_path = tempfile.path
|
104
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
105
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
106
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
107
|
+
stmt = sqlite_db.prepare('INSERT INTO hummingbird_migrations (migration_name, run_on) VALUES (?,?);')
|
108
|
+
[ ['file1.sql', DateTime.new(2012,10, 1,12,0,0,'-7').strftime('%s')],
|
109
|
+
['file2.sql', DateTime.new(2012,10,11,13,0,0,'-7').strftime('%s')]].each {|data| stmt.execute(*data)}
|
110
|
+
|
111
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
112
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
113
|
+
|
114
|
+
assert_equal(
|
115
|
+
['file3.sql','file4.sql'],
|
116
|
+
plan.to_be_run_migration_file_names(db.already_run_migrations)
|
117
|
+
)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'raises when a yet-to-be-run planned file is before a recorded migration' do
|
121
|
+
sqlite_db_path = tempfile.path
|
122
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
123
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
124
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
125
|
+
stmt = sqlite_db.prepare('INSERT INTO hummingbird_migrations (migration_name, run_on) VALUES (?,?);')
|
126
|
+
file3_run_on = DateTime.new(2012,10,11,13,0,0,'-7')
|
127
|
+
[ ['file1.sql', DateTime.new(2012,10, 1,12,0,0,'-7').strftime('%s')],
|
128
|
+
['file3.sql', file3_run_on.strftime('%s')]].each {|data| stmt.execute(*data)}
|
129
|
+
|
130
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
131
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
132
|
+
|
133
|
+
e = assert_raises Hummingbird::PlanError do
|
134
|
+
plan.to_be_run_migration_file_names(db.already_run_migrations)
|
135
|
+
end
|
136
|
+
|
137
|
+
assert_equal "Plan has 'file2.sql' before 'file3.sql' which was run on #{file3_run_on.new_offset(0)}", e.message
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'raises when the plan file is not in the same order as the recorded migrations' do
|
141
|
+
sqlite_db_path = tempfile.path
|
142
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
143
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
144
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
145
|
+
stmt = sqlite_db.prepare('INSERT INTO hummingbird_migrations (migration_name, run_on) VALUES (?,?);')
|
146
|
+
file4_run_on = DateTime.new(2012,10,2,13,1,1,'-7')
|
147
|
+
[ ['file1.sql', DateTime.new(2012,10,1,12,0,0,'-7').strftime('%s')],
|
148
|
+
['file4.sql', file4_run_on.strftime('%s')],
|
149
|
+
['file3.sql', DateTime.new(2012,10,3,14,2,2,'-7').strftime('%s')],
|
150
|
+
['file2.sql', DateTime.new(2012,10,4,15,3,3,'-7').strftime('%s')]].each {|data| stmt.execute(*data)}
|
151
|
+
|
152
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
153
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
154
|
+
|
155
|
+
e = assert_raises Hummingbird::PlanError do
|
156
|
+
plan.to_be_run_migration_file_names(db.already_run_migrations)
|
157
|
+
end
|
158
|
+
|
159
|
+
assert_equal "Plan has 'file2.sql' before 'file4.sql' which was run on #{file4_run_on.new_offset(0)}", e.message
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'raises when a recorded migration is missing from the plan' do
|
163
|
+
sqlite_db_path = tempfile.path
|
164
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
165
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
166
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
167
|
+
stmt = sqlite_db.prepare('INSERT INTO hummingbird_migrations (migration_name, run_on) VALUES (?,?);')
|
168
|
+
[ ['file1.sql', DateTime.new(2012,10,1,12,0,0,'-7').strftime('%s')],
|
169
|
+
['file2.sql', DateTime.new(2012,10,2,13,1,1,'-7').strftime('%s')],
|
170
|
+
['file3.sql', DateTime.new(2012,10,3,14,2,2,'-7').strftime('%s')],
|
171
|
+
['file4.sql', DateTime.new(2012,10,4,15,3,3,'-7').strftime('%s')],
|
172
|
+
['file5.sql', DateTime.new(2012,10,5,16,4,4,'-7').strftime('%s')]].each {|data| stmt.execute(*data)}
|
173
|
+
|
174
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
175
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
176
|
+
|
177
|
+
e = assert_raises Hummingbird::PlanError do
|
178
|
+
plan.to_be_run_migration_file_names(db.already_run_migrations)
|
179
|
+
end
|
180
|
+
|
181
|
+
assert_equal "Plan is missing the following already run migrations: file5.sql", e.message
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'does not modify #planned_files' do
|
185
|
+
sqlite_db_path = tempfile.path
|
186
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
187
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
188
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
189
|
+
stmt = sqlite_db.prepare('INSERT INTO hummingbird_migrations (migration_name, run_on) VALUES (?,?);')
|
190
|
+
[ ['file1.sql', DateTime.new(2012,10, 1,12,0,0,'-7').strftime('%s')],
|
191
|
+
['file2.sql', DateTime.new(2012,10,11,13,0,0,'-7').strftime('%s')]].each {|data| stmt.execute(*data)}
|
192
|
+
|
193
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
194
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
195
|
+
|
196
|
+
assert_equal ['file1.sql','file2.sql','file3.sql','file4.sql'], plan.planned_files
|
197
|
+
|
198
|
+
plan.to_be_run_migration_file_names(db.already_run_migrations)
|
199
|
+
|
200
|
+
assert_equal ['file1.sql','file2.sql','file3.sql','file4.sql'], plan.planned_files
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe '#migrations_to_be_run' do
|
205
|
+
it 'attaches the migration file contents to the #to_be_run_migration_file_names list' do
|
206
|
+
sqlite_db_path = tempfile.path
|
207
|
+
connect_string = "sqlite://#{sqlite_db_path}"
|
208
|
+
sqlite_db = SQLite3::Database.new(sqlite_db_path)
|
209
|
+
sqlite_db.execute read_fixture('sql', 'migrations_table.sql')
|
210
|
+
stmt = sqlite_db.prepare('INSERT INTO hummingbird_migrations (migration_name, run_on) VALUES (?,?);')
|
211
|
+
[ ['file1.sql', DateTime.new(2012,10, 1,12,0,0,'-7').strftime('%s')],
|
212
|
+
['file2.sql', DateTime.new(2012,10,11,13,0,0,'-7').strftime('%s')]].each {|data| stmt.execute(*data)}
|
213
|
+
|
214
|
+
plan = Hummingbird::Plan.new(path_to_fixture('plan','basic.plan'), path_to_fixture('sql','migrations','basic'))
|
215
|
+
db = Hummingbird::Database.new(connect_string, :hummingbird_migrations)
|
216
|
+
|
217
|
+
migrations = plan.stub :to_be_run_migration_file_names, ['file3.sql','file4.sql'] do
|
218
|
+
plan.migrations_to_be_run(db.already_run_migrations)
|
219
|
+
end
|
220
|
+
|
221
|
+
assert_equal(
|
222
|
+
[
|
223
|
+
{migration_name: 'file3.sql', sql: "CREATE TABLE table3 (name text);\n"},
|
224
|
+
{migration_name: 'file4.sql', sql: "CREATE TABLE table4 (name text);\n"},
|
225
|
+
],
|
226
|
+
migrations
|
227
|
+
)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|