sbf-dm-migrations 1.3.0.beta

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.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +38 -0
  3. data/.rspec +1 -0
  4. data/.rubocop.yml +468 -0
  5. data/.travis.yml +52 -0
  6. data/Gemfile +61 -0
  7. data/LICENSE +20 -0
  8. data/README.rdoc +39 -0
  9. data/Rakefile +4 -0
  10. data/db/migrations/1_create_people_table.rb +12 -0
  11. data/db/migrations/2_add_dob_to_people.rb +13 -0
  12. data/db/migrations/config.rb +4 -0
  13. data/dm-migrations.gemspec +20 -0
  14. data/examples/Rakefile +149 -0
  15. data/examples/sample_migration.rb +58 -0
  16. data/examples/sample_migration_spec.rb +46 -0
  17. data/lib/dm-migrations/adapters/dm-do-adapter.rb +304 -0
  18. data/lib/dm-migrations/adapters/dm-mysql-adapter.rb +306 -0
  19. data/lib/dm-migrations/adapters/dm-oracle-adapter.rb +339 -0
  20. data/lib/dm-migrations/adapters/dm-postgres-adapter.rb +152 -0
  21. data/lib/dm-migrations/adapters/dm-sqlite-adapter.rb +88 -0
  22. data/lib/dm-migrations/adapters/dm-sqlserver-adapter.rb +184 -0
  23. data/lib/dm-migrations/adapters/dm-yaml-adapter.rb +21 -0
  24. data/lib/dm-migrations/auto_migration.rb +227 -0
  25. data/lib/dm-migrations/exceptions/duplicate_migration.rb +6 -0
  26. data/lib/dm-migrations/migration.rb +323 -0
  27. data/lib/dm-migrations/migration_runner.rb +76 -0
  28. data/lib/dm-migrations/sql/column.rb +5 -0
  29. data/lib/dm-migrations/sql/mysql.rb +84 -0
  30. data/lib/dm-migrations/sql/oracle.rb +9 -0
  31. data/lib/dm-migrations/sql/postgres.rb +89 -0
  32. data/lib/dm-migrations/sql/sqlite.rb +59 -0
  33. data/lib/dm-migrations/sql/sqlserver.rb +9 -0
  34. data/lib/dm-migrations/sql/table.rb +15 -0
  35. data/lib/dm-migrations/sql/table_creator.rb +105 -0
  36. data/lib/dm-migrations/sql/table_modifier.rb +57 -0
  37. data/lib/dm-migrations/sql.rb +7 -0
  38. data/lib/dm-migrations/version.rb +5 -0
  39. data/lib/dm-migrations.rb +3 -0
  40. data/lib/spec/example/migration_example_group.rb +69 -0
  41. data/lib/spec/matchers/migration_matchers.rb +96 -0
  42. data/spec/integration/auto_migration_spec.rb +590 -0
  43. data/spec/integration/auto_upgrade_spec.rb +41 -0
  44. data/spec/integration/migration_runner_spec.rb +84 -0
  45. data/spec/integration/migration_spec.rb +156 -0
  46. data/spec/integration/sql_spec.rb +290 -0
  47. data/spec/isolated/require_after_setup_spec.rb +24 -0
  48. data/spec/isolated/require_before_setup_spec.rb +24 -0
  49. data/spec/isolated/require_spec.rb +23 -0
  50. data/spec/spec_helper.rb +16 -0
  51. data/spec/unit/migration_spec.rb +501 -0
  52. data/spec/unit/sql/column_spec.rb +14 -0
  53. data/spec/unit/sql/postgres_spec.rb +90 -0
  54. data/spec/unit/sql/sqlite_extensions_spec.rb +103 -0
  55. data/spec/unit/sql/table_creator_spec.rb +91 -0
  56. data/spec/unit/sql/table_modifier_spec.rb +47 -0
  57. data/spec/unit/sql/table_spec.rb +26 -0
  58. data/spec/unit/sql_spec.rb +7 -0
  59. data/tasks/spec.rake +21 -0
  60. data/tasks/yard.rake +9 -0
  61. data/tasks/yardstick.rake +19 -0
  62. metadata +120 -0
@@ -0,0 +1,84 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe 'The migration runner' do
4
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
5
+ before(:all) do
6
+ @adapter = DataMapper::Spec.adapter
7
+ @repository = DataMapper.repository(@adapter.name)
8
+ end
9
+
10
+ describe 'empty migration runner' do
11
+ it 'returns an empty array if no migrations have been defined' do
12
+ expect(migrations).to be_kind_of(Array)
13
+ expect(migrations.size).to eq 0
14
+ end
15
+ end
16
+
17
+ describe 'migration runner' do
18
+ # set up some 'global' setup and teardown tasks
19
+ before(:each) do
20
+ # FIXME: workaround because dm-migrations can only handle the :default repo
21
+ # DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[adapter.to_sym]
22
+ migration(1, :create_people_table) { nil }
23
+ end
24
+
25
+ after(:each) do
26
+ migrations.clear
27
+ end
28
+
29
+ describe '#migration' do
30
+ it 'creates a new migration object, and add it to the list of migrations' do
31
+ expect(migrations).to be_kind_of(Array)
32
+ expect(migrations.size).to eq 1
33
+ expect(migrations.first.name).to eq 'create_people_table'
34
+ end
35
+
36
+ it 'allows multiple migrations to be added' do
37
+ migration(2, :add_dob_to_people) { nil }
38
+ migration(2, :add_favorite_pet_to_people) { nil }
39
+ migration(3, :add_something_else_to_people) { nil }
40
+ expect(migrations.size).to eq 4
41
+ end
42
+
43
+ it 'raises an error on adding with a duplicated name' do
44
+ expect { migration(1, :create_people_table) { nil } }.to raise_error(RuntimeError, /Migration name conflict/)
45
+ end
46
+ end
47
+
48
+ describe '#migrate_up! and #migrate_down!' do
49
+ before(:each) do
50
+ migration(2, :add_dob_to_people) { nil }
51
+ migration(2, :add_favorite_pet_to_people) { nil }
52
+ migration(3, :add_something_else_to_people) { nil }
53
+ end
54
+
55
+ it 'calling migrate_up! migrates up all the migrations' do
56
+ # add our expectation that migrate_up should be called
57
+ migrations.each do |m|
58
+ expect(m).to receive(:perform_up)
59
+ end
60
+ migrate_up!
61
+ end
62
+
63
+ it 'calling migrate_up! with an argument only migrates to that level' do
64
+ migrations.each do |m|
65
+ if m.position <= 2
66
+ expect(m).to receive(:perform_up)
67
+ else
68
+ expect(m).not_to receive(:perform_up)
69
+ end
70
+ end
71
+ migrate_up!(2)
72
+ end
73
+
74
+ it 'calling migrate_down! migrates down all the migrations' do
75
+ # add our expectation that migrate_up should be called
76
+ migrations.each do |m|
77
+ expect(m).to receive(:perform_down)
78
+ end
79
+ migrate_down!
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,156 @@
1
+ require_relative '../spec_helper'
2
+
3
+ describe 'A Migration' do
4
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
5
+ describe DataMapper::Migration, 'interface' do
6
+ before(:all) do
7
+ @adapter = DataMapper::Spec.adapter
8
+ end
9
+
10
+ before do
11
+ @migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
12
+ end
13
+
14
+ before do
15
+ @original = $stderr
16
+ $stderr = StringIO.new
17
+ end
18
+
19
+ after do
20
+ $stderr = @original
21
+ end
22
+
23
+ it 'has a position attribute' do
24
+ expect(@migration).to respond_to(:position)
25
+
26
+ expect(@migration.position).to eq 1
27
+ end
28
+
29
+ it 'has a name attribute' do
30
+ expect(@migration).to respond_to(:name)
31
+
32
+ expect(@migration.name).to eq :create_people_table
33
+ end
34
+
35
+ it 'has a :repository option' do
36
+ m = DataMapper::Migration.new(2, :create_dogs_table, repository: :alternate) { nil }
37
+
38
+ expect(m.instance_variable_get(:@repository)).to eq :alternate
39
+ end
40
+
41
+ it 'uses the default repository by default' do
42
+ expect(@migration.instance_variable_get(:@repository)).to eq :default
43
+ end
44
+
45
+ it 'still supports a :database option' do
46
+ m = DataMapper::Migration.new(2, :create_legacy_table, database: :legacy) { nil }
47
+
48
+ expect(m.instance_variable_get(:@repository)).to eq :legacy
49
+ end
50
+
51
+ it 'warns when :database is used' do
52
+ DataMapper::Migration.new(2, :create_legacy_table, database: :legacy) { nil }
53
+ expect($stderr.string.chomp).to eq 'Using the :database option with migrations is deprecated, use :repository instead'
54
+ end
55
+
56
+ it 'has a verbose option' do
57
+ m = DataMapper::Migration.new(2, :create_dogs_table, verbose: false) { nil }
58
+ expect(m.instance_variable_get(:@verbose)).to eq false
59
+ end
60
+
61
+ it 'is verbose by default' do
62
+ m = DataMapper::Migration.new(2, :create_dogs_table) { nil }
63
+ expect(m.instance_variable_get(:@verbose)).to eq true
64
+ end
65
+
66
+ it 'is sortable, first by position, then name' do
67
+ m1 = DataMapper::Migration.new(1, :create_people_table) { nil }
68
+ m2 = DataMapper::Migration.new(2, :create_dogs_table) { nil }
69
+ m3 = DataMapper::Migration.new(2, :create_cats_table) { nil }
70
+ m4 = DataMapper::Migration.new(4, :create_birds_table) { nil }
71
+
72
+ expect([m1, m2, m3, m4].sort).to eq [m1, m3, m2, m4]
73
+ end
74
+
75
+ adapter = DataMapper::Spec.adapter_name
76
+
77
+ expected_module_lambda = {
78
+ sqlite: -> { SQL::Sqlite },
79
+ mysql: -> { SQL::Mysql },
80
+ postgres: -> { SQL::Postgres }
81
+ }[adapter.to_sym]
82
+
83
+ expected_module = expected_module_lambda&.call
84
+
85
+ if expected_module
86
+ it "extends with #{expected_module} when adapter is #{adapter}" do
87
+ migration = DataMapper::Migration.new(1, :"#{adapter}_adapter_test") { nil }
88
+ expect((class << migration.adapter; self; end).included_modules).to include(expected_module)
89
+ end
90
+ end
91
+ end
92
+
93
+ describe DataMapper::Migration, 'defining actions' do
94
+ before do
95
+ @migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
96
+ end
97
+
98
+ it 'has an #up method' do
99
+ expect(@migration).to respond_to(:up)
100
+ end
101
+
102
+ it 'saves the block passed into the #up method in @up_action' do
103
+ action = -> {}
104
+ @migration.up(&action)
105
+
106
+ expect(@migration.instance_variable_get(:@up_action)).to eq action
107
+ end
108
+
109
+ it 'has a #down method' do
110
+ expect(@migration).to respond_to(:down)
111
+ end
112
+
113
+ it 'saves the block passed into the #down method in @down_action' do
114
+ action = -> {}
115
+ @migration.down(&action)
116
+
117
+ expect(@migration.instance_variable_get(:@down_action)).to eq action
118
+ end
119
+
120
+ it 'makes available an #execute method' do
121
+ expect(@migration).to respond_to(:execute)
122
+ end
123
+
124
+ it 'makes available an #select method' do
125
+ expect(@migration).to respond_to(:select)
126
+ end
127
+
128
+ it 'runs the sql passed into the #execute method'
129
+ # TODO: Find out how to stub the DataMapper::database.execute method
130
+ end
131
+
132
+ describe DataMapper::Migration, 'output' do
133
+ before do
134
+ @migration = DataMapper::Migration.new(1, :create_people_table) { nil }
135
+ @migration.stub!(:write) # so that we don't actually write anything to the console!
136
+ end
137
+
138
+ it "#say's a string with an indent" do
139
+ expect(@migration).to receive(:write).with(' Foobar')
140
+ @migration.say('Foobar', 2)
141
+ end
142
+
143
+ it "#say's with a default indent of 4" do
144
+ expect(@migration).to receive(:write).with(' Foobar')
145
+ @migration.say('Foobar')
146
+ end
147
+
148
+ it '#say_with_time the running time of a block' do
149
+ expect(@migration).to receive(:write).with(/Block/)
150
+ expect(@migration).to receive(:write).with(/-> \d+/)
151
+
152
+ @migration.say_with_time('Block') { nil }
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,290 @@
1
+ require_relative '../spec_helper'
2
+
3
+ # Column type is expected to be inherited from DataMapper::Property::Text (CLOB, TEXT or whatever)
4
+ class MyCustomProperty < DataMapper::Property::Text; end
5
+
6
+ describe 'SQL generation' do
7
+ supported_by :postgres, :mysql, :sqlite, :oracle, :sqlserver do
8
+ describe DataMapper::Migration, '#create_table helper' do
9
+ before :all do
10
+ @adapter = DataMapper::Spec.adapter
11
+ @repository = DataMapper.repository(@adapter.name)
12
+
13
+ case DataMapper::Spec.adapter_name.to_sym
14
+ when :sqlite
15
+ @adapter.extend(SQL::Sqlite)
16
+ when :mysql
17
+ @adapter.extend(SQL::Mysql)
18
+ when :postgres
19
+ @adapter.extend(SQL::Postgres)
20
+ end
21
+ end
22
+
23
+ before do
24
+ @creator = DataMapper::Migration::TableCreator.new(@adapter, :people) do
25
+ column :id, DataMapper::Property::Serial
26
+ column :name, 'VARCHAR(50)', allow_nil: false
27
+ column :long_string, String, size: 200
28
+ column :very_custom, MyCustomProperty
29
+ end
30
+ end
31
+
32
+ it 'has a #create_table helper' do
33
+ @migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
34
+ expect(@migration).to respond_to(:create_table)
35
+ end
36
+
37
+ it 'has a table_name' do
38
+ expect(@creator.table_name).to eq 'people'
39
+ end
40
+
41
+ it 'has an adapter' do
42
+ expect(@creator.instance_eval('@adapter', __FILE__, __LINE__)).to eq @adapter
43
+ end
44
+
45
+ it 'has an options hash' do
46
+ expect(@creator.opts).to be_kind_of(Hash)
47
+ expect(@creator.opts).to eq({})
48
+ end
49
+
50
+ it 'has an array of columns' do
51
+ expect(@creator.instance_eval('@columns', __FILE__, __LINE__)).to be_kind_of(Array)
52
+ expect(@creator.instance_eval('@columns', __FILE__, __LINE__).size).to eq 4
53
+ expect(@creator.instance_eval('@columns', __FILE__, __LINE__).first).to be_kind_of(DataMapper::Migration::TableCreator::Column)
54
+ end
55
+
56
+ it 'quotes the table name for the adapter' do
57
+ expect(@creator.quoted_table_name).to eq((DataMapper::Spec.adapter_name.to_sym == :mysql) ? '`people`' : '"people"')
58
+ end
59
+
60
+ it 'allows for custom options' do
61
+ columns = @creator.instance_eval('@columns', __FILE__, __LINE__)
62
+ col = columns.detect { |c| c.name == 'long_string' }
63
+ expect(col.instance_eval('@type', __FILE__, __LINE__)).to include('200')
64
+ end
65
+
66
+ it 'generates a NOT NULL column when :allow_nil is false' do
67
+ expect(@creator.instance_eval('@columns', __FILE__, __LINE__)[1].type).to match(/NOT NULL/)
68
+ end
69
+
70
+ case DataMapper::Spec.adapter_name.to_sym
71
+ when :mysql
72
+ it 'creates an InnoDB database for MySQL' do
73
+ # can't get an exact == comparison here because character set and collation may differ per connection
74
+ expect(@creator.to_sql).to match(/^CREATE TABLE `people` \(`id` SERIAL PRIMARY KEY, `name` VARCHAR\(50\) NOT NULL, `long_string` VARCHAR\(200\), `very_custom` TEXT\) ENGINE = InnoDB CHARACTER SET \w+ COLLATE \w+\z/)
75
+ end
76
+
77
+ it 'allows for custom table creation options for MySQL' do
78
+ opts = {
79
+ storage_engine: 'MyISAM',
80
+ character_set: 'big5',
81
+ collation: 'big5_chinese_ci'
82
+ }
83
+
84
+ creator = DataMapper::Migration::TableCreator.new(@adapter, :people, opts) do
85
+ column :id, DataMapper::Property::Serial
86
+ end
87
+
88
+ expect(creator.to_sql).to match(/^CREATE TABLE `people` \(`id` SERIAL PRIMARY KEY\) ENGINE = MyISAM CHARACTER SET big5 COLLATE big5_chinese_ci\z/)
89
+ end
90
+
91
+ it 'respects default storage engine types specified by the MySQL adapter' do
92
+ adapter = DataMapper::Spec.adapter
93
+ adapter.extend(SQL::Mysql)
94
+
95
+ adapter.storage_engine = 'MyISAM'
96
+
97
+ creator = DataMapper::Migration::TableCreator.new(adapter, :people) do
98
+ column :id, DataMapper::Property::Serial
99
+ end
100
+
101
+ expect(creator.to_sql).to match(/^CREATE TABLE `people` \(`id` SERIAL PRIMARY KEY\) ENGINE = MyISAM CHARACTER SET \w+ COLLATE \w+\z/)
102
+ end
103
+
104
+ when :postgres
105
+ it 'outputs a CREATE TABLE statement when sent #to_sql' do
106
+ expect(@creator.to_sql).to eq 'CREATE TABLE "people" ("id" SERIAL PRIMARY KEY, "name" VARCHAR(50) NOT NULL, "long_string" VARCHAR(200), ' \
107
+ '"very_custom" TEXT)'
108
+ end
109
+ when :sqlite3, :sqlite
110
+ it 'outputs a CREATE TABLE statement when sent #to_sql' do
111
+ expect(@creator.to_sql).to eq 'CREATE TABLE "people" ("id" INTEGER PRIMARY KEY AUTOINCREMENT, "name" VARCHAR(50) NOT NULL, "long_string" ' \
112
+ 'VARCHAR(200), "very_custom" TEXT)'
113
+ end
114
+ end
115
+
116
+ context 'when the default string length is modified' do
117
+ before do
118
+ @original = DataMapper::Property::String.length
119
+ DataMapper::Property::String.length(255)
120
+
121
+ @creator = DataMapper::Migration::TableCreator.new(@adapter, :people) do
122
+ column :string, String
123
+ end
124
+ end
125
+
126
+ after do
127
+ DataMapper::Property::String.length(@original)
128
+ end
129
+
130
+ it 'uses the new length for the character column' do
131
+ expect(@creator.to_sql).to match(/CHAR\(255\)/)
132
+ end
133
+ end
134
+ end
135
+
136
+ describe DataMapper::Migration, '#modify_table helper' do
137
+ before do
138
+ @migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
139
+ end
140
+
141
+ it 'has a #modify_table helper' do
142
+ expect(@migration).to respond_to(:modify_table)
143
+ end
144
+
145
+ describe '#change_column' do
146
+ before do
147
+ @modifier = DataMapper::Migration::TableModifier.new(@adapter, :people) do
148
+ change_column :name, 'VARCHAR(200)'
149
+ end
150
+ end
151
+
152
+ case DataMapper::Spec.adapter_name.to_sym
153
+ when :mysql
154
+ it 'alters the column' do
155
+ expect(@modifier.to_sql).to eq 'ALTER TABLE `people` MODIFY COLUMN `name` VARCHAR(200)'
156
+ end
157
+ when :postgres
158
+ it 'alters the column' do
159
+ expect(@modifier.to_sql).to eq 'ALTER TABLE "people" ALTER COLUMN "name" VARCHAR(200)'
160
+ end
161
+ end
162
+ end
163
+
164
+ describe '#rename_column' do
165
+ case DataMapper::Spec.adapter_name.to_sym
166
+ when :postgres
167
+ before do
168
+ @modifier = DataMapper::Migration::TableModifier.new(@adapter, :people) do
169
+ rename_column :name, :first_name
170
+ end
171
+ end
172
+
173
+ it 'renames the column' do
174
+ expect(@modifier.to_sql).to eq 'ALTER TABLE "people" RENAME COLUMN "name" TO "first_name"'
175
+ end
176
+ when :mysql
177
+ before do
178
+ # create the table so the existing column schema can be introspected
179
+ @adapter.execute("CREATE TABLE `people` (name VARCHAR(50) DEFAULT 'John' NOT NULL)")
180
+
181
+ @modifier = DataMapper::Migration::TableModifier.new(@adapter, :people) do
182
+ rename_column :name, :first_name
183
+ end
184
+ end
185
+
186
+ after do
187
+ @adapter.execute('DROP TABLE `people`')
188
+ end
189
+
190
+ it 'changes the column' do
191
+ expect(@modifier.to_sql).to eq "ALTER TABLE `people` CHANGE `name` `first_name` varchar(50) DEFAULT 'John' NOT NULL"
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ describe DataMapper::Migration, 'other helpers' do
198
+ before do
199
+ @migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) { nil }
200
+ end
201
+
202
+ it 'has a #drop_table helper' do
203
+ expect(@migration).to respond_to(:drop_table)
204
+ end
205
+ end
206
+
207
+ describe DataMapper::Migration, 'version tracking' do
208
+ before(:each) do
209
+ @migration = DataMapper::Migration.new(1, :create_people_table, verbose: false) do
210
+ up { :ran_up }
211
+ down { :ran_down }
212
+ end
213
+
214
+ @migration.send(:create_migration_info_table_if_needed)
215
+ end
216
+
217
+ after(:each) { DataMapper::Spec.adapter.execute('DROP TABLE migration_info') rescue nil }
218
+
219
+ def insert_migration_record
220
+ DataMapper::Spec.adapter.execute("INSERT INTO migration_info (migration_name) VALUES ('create_people_table')")
221
+ end
222
+
223
+ it 'knows if the migration_info table exists' do
224
+ expect(@migration.send(:migration_info_table_exists?)).to be(true)
225
+ end
226
+
227
+ it 'knows if the migration_info table does not exist' do
228
+ DataMapper::Spec.adapter.execute('DROP TABLE migration_info') rescue nil
229
+ expect(@migration.send(:migration_info_table_exists?)).to be(false)
230
+ end
231
+
232
+ it 'is able to find the migration_info record for itself' do
233
+ insert_migration_record
234
+ expect(@migration.send(:migration_record)).not_to be_empty
235
+ end
236
+
237
+ it 'knows if a migration needs_up?' do
238
+ expect(@migration.send(:needs_up?)).to be(true)
239
+ insert_migration_record
240
+ expect(@migration.send(:needs_up?)).to be(false)
241
+ end
242
+
243
+ it 'knows if a migration needs_down?' do
244
+ expect(@migration.send(:needs_down?)).to be(false)
245
+ insert_migration_record
246
+ expect(@migration.send(:needs_down?)).to be(true)
247
+ end
248
+
249
+ it 'properly quotes the migration_info table via the adapter for use in queries' do
250
+ expect(@migration.send(:migration_info_table)).to eq @migration.quote_table_name('migration_info')
251
+ end
252
+
253
+ it 'properly quotes the migration_info.migration_name column via the adapter for use in queries' do
254
+ expect(@migration.send(:migration_name_column)).to eq @migration.quote_column_name('migration_name')
255
+ end
256
+
257
+ it "properly quotes the migration's name for use in queries"
258
+ # TODO: how to i call the adapter's #escape_sql method?
259
+
260
+ it "creates the migration_info table if it doesn't exist" do
261
+ DataMapper::Spec.adapter.execute('DROP TABLE migration_info')
262
+ expect(@migration.send(:migration_info_table_exists?)).to be(false)
263
+ @migration.send(:create_migration_info_table_if_needed)
264
+ expect(@migration.send(:migration_info_table_exists?)).to be(true)
265
+ end
266
+
267
+ it 'inserts a record into the migration_info table on up' do
268
+ expect(@migration.send(:migration_record)).to be_empty
269
+ expect(@migration.perform_up).to eq :ran_up
270
+ expect(@migration.send(:migration_record)).not_to be_empty
271
+ end
272
+
273
+ it 'removes a record from the migration_info table on down' do
274
+ insert_migration_record
275
+ expect(@migration.send(:migration_record)).not_to be_empty
276
+ expect(@migration.perform_down).to eq :ran_down
277
+ expect(@migration.send(:migration_record)).to be_empty
278
+ end
279
+
280
+ it 'does not run the up action if the record exists in the table' do
281
+ insert_migration_record
282
+ expect(@migration.perform_up).not_to eq :ran_up
283
+ end
284
+
285
+ it 'does not run the down action if the record does not exist in the table' do
286
+ expect(@migration.perform_down).not_to eq :ran_down
287
+ end
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,24 @@
1
+ require 'rspec'
2
+
3
+ require_relative 'require_spec'
4
+ require 'dm-core/spec/setup'
5
+
6
+ # To really test this behavior, this spec needs to be run in isolation and not
7
+ # as part of the typical rake spec run, which requires dm-transactions upfront
8
+ class ::Person
9
+ include DataMapper::Resource
10
+ property :id, Serial
11
+ end
12
+
13
+ if %w(postgres mysql sqlite oracle sqlserver).include?(ENV['ADAPTER'])
14
+ describe "require 'dm-migrations' after calling DataMapper.setup" do
15
+ before(:all) do
16
+ @adapter = DataMapper::Spec.adapter
17
+ require 'dm-migrations'
18
+
19
+ @model = Person
20
+ end
21
+
22
+ it_behaves_like "require 'dm-migrations'"
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ require 'rspec'
2
+
3
+ require_relative 'require_spec'
4
+ require 'dm-core/spec/setup'
5
+
6
+ # To really test this behavior, this spec needs to be run in isolation and not
7
+ # as part of the typical rake spec run, which requires dm-transactions upfront
8
+ class ::Person
9
+ include DataMapper::Resource
10
+ property :id, Serial
11
+ end
12
+
13
+ if %w(postgres mysql sqlite oracle sqlserver).include?(ENV['ADAPTER'])
14
+ describe "require 'dm-migrations' before calling DataMapper.setup" do
15
+ before(:all) do
16
+ require 'dm-migrations'
17
+ @adapter = DataMapper::Spec.adapter
18
+
19
+ @model = Person
20
+ end
21
+
22
+ it_behaves_like "require 'dm-migrations'"
23
+ end
24
+ end
@@ -0,0 +1,23 @@
1
+ shared_examples "require 'dm-migrations'" do
2
+ it 'includes the migration api in the DataMapper namespace' do
3
+ expect(DataMapper.respond_to?(:migrate!)).to be(true)
4
+ expect(DataMapper.respond_to?(:auto_migrate!)).to be(true)
5
+ expect(DataMapper.respond_to?(:auto_upgrade!)).to be(true)
6
+ expect(DataMapper.respond_to?(:auto_migrate_up!, true)).to be(true)
7
+ expect(DataMapper.respond_to?(:auto_migrate_down!, true)).to be(true)
8
+ end
9
+
10
+ %w(Repository Model).each do |name|
11
+ it "includes the migration api in DataMapper::#{name}" do
12
+ expect(DataMapper.const_get(name) < DataMapper::Migrations.const_get(name)).to be(true)
13
+ end
14
+ end
15
+
16
+ it 'includes the migration api into the adapter' do
17
+ expect(@adapter.respond_to?(:storage_exists?)).to be(true)
18
+ expect(@adapter.respond_to?(:field_exists?)).to be(true)
19
+ expect(@adapter.respond_to?(:upgrade_model_storage)).to be(true)
20
+ expect(@adapter.respond_to?(:create_model_storage)).to be(true)
21
+ expect(@adapter.respond_to?(:destroy_model_storage)).to be(true)
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ require 'dm-migrations'
2
+ require 'dm-migrations/migration_runner'
3
+
4
+ require 'dm-core/spec/setup'
5
+ require 'dm-core/spec/lib/adapter_helpers'
6
+ require 'dm-core/spec/lib/spec_helper'
7
+ require 'dm-core/spec/lib/pending_helpers'
8
+
9
+ RSpec.configure do |config|
10
+ config.extend(DataMapper::Spec::Adapters::Helpers)
11
+ config.include(DataMapper::Spec::PendingHelpers)
12
+
13
+ config.after :all do
14
+ DataMapper::Spec.cleanup_models
15
+ end
16
+ end