dm-migrations 0.9.2 → 0.9.3

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.
@@ -1,148 +1,158 @@
1
1
  require 'pathname'
2
2
  require Pathname(__FILE__).dirname.expand_path.parent + 'spec_helper'
3
3
 
4
- if HAS_SQLITE3 || HAS_MYSQL || HAS_POSTGRES
5
- describe DataMapper::Migration, "#create_table helper" do
6
- before do
7
- @creator = DataMapper::Migration::TableCreator.new(repository(:default).adapter, :people) do
8
- column :name, String
4
+ [:sqlite3, :mysql, :postgres].each do |adapter|
5
+ next unless eval("HAS_#{adapter.to_s.upcase}")
6
+ describe "Using Adapter #{adapter}, " do
7
+ describe DataMapper::Migration, "#create_table helper" do
8
+ before do
9
+ @creator = DataMapper::Migration::TableCreator.new(repository(adapter).adapter, :people) do
10
+ column :name, String
11
+ column :long_string, String, :size => 200
12
+ end
9
13
  end
10
- end
11
14
 
12
- it "should have a #create_table helper" do
13
- @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) { }
14
- @migration.should respond_to(:create_table)
15
- end
15
+ it "should have a #create_table helper" do
16
+ @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) { }
17
+ @migration.should respond_to(:create_table)
18
+ end
16
19
 
17
- it "should have a table_name" do
18
- @creator.table_name.should == "people"
19
- end
20
+ it "should have a table_name" do
21
+ @creator.table_name.should == "people"
22
+ end
20
23
 
21
- it "should have an adapter" do
22
- @creator.instance_eval("@adapter").should == repository(:default).adapter
23
- end
24
+ it "should have an adapter" do
25
+ @creator.instance_eval("@adapter").should == repository(adapter).adapter
26
+ end
24
27
 
25
- it "should have an options hash" do
26
- @creator.opts.should be_kind_of(Hash)
27
- @creator.opts.should == {}
28
- end
28
+ it "should have an options hash" do
29
+ @creator.opts.should be_kind_of(Hash)
30
+ @creator.opts.should == {}
31
+ end
29
32
 
30
- it "should have an array of columns" do
31
- @creator.instance_eval("@columns").should be_kind_of(Array)
32
- @creator.instance_eval("@columns").should have(1).item
33
- @creator.instance_eval("@columns").first.should be_kind_of(DataMapper::Migration::TableCreator::Column)
34
- end
33
+ it "should have an array of columns" do
34
+ @creator.instance_eval("@columns").should be_kind_of(Array)
35
+ @creator.instance_eval("@columns").should have(2).items
36
+ @creator.instance_eval("@columns").first.should be_kind_of(DataMapper::Migration::TableCreator::Column)
37
+ end
38
+
39
+ it "should quote the table name for the adapter" do
40
+ @creator.quoted_table_name.should == (adapter == :mysql ? '`people`' : '"people"')
41
+ end
42
+
43
+ it "should allow for custom options" do
44
+ columns = @creator.instance_eval("@columns")
45
+ col = columns.detect{|c| c.name == "long_string"}
46
+ col.instance_eval("@type").should include("200")
47
+ end
35
48
 
36
- it "should quote the table name for the adapter" do
37
- @creator.quoted_table_name.should == '"people"'
38
49
  end
39
50
 
40
- end
51
+ describe DataMapper::Migration, "#modify_table helper" do
52
+ before do
53
+ @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) { }
54
+ end
41
55
 
42
- describe DataMapper::Migration, "#modify_table helper" do
43
- before do
44
- @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) { }
45
- end
56
+ it "should have a #modify_table helper" do
57
+ @migration.should respond_to(:modify_table)
58
+ end
46
59
 
47
- it "should have a #modify_table helper" do
48
- @migration.should respond_to(:modify_table)
49
60
  end
50
61
 
51
- end
62
+ describe DataMapper::Migration, "other helpers" do
63
+ before do
64
+ @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) { }
65
+ end
52
66
 
53
- describe DataMapper::Migration, "other helpers" do
54
- before do
55
- @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) { }
56
- end
67
+ it "should have a #drop_table helper" do
68
+ @migration.should respond_to(:drop_table)
69
+ end
57
70
 
58
- it "should have a #drop_table helper" do
59
- @migration.should respond_to(:drop_table)
60
71
  end
61
72
 
62
- end
73
+ describe DataMapper::Migration, "version tracking" do
74
+ before do
75
+ @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) do
76
+ up { :ran_up }
77
+ down { :ran_down }
78
+ end
63
79
 
64
- describe DataMapper::Migration, "version tracking" do
65
- before do
66
- @migration = DataMapper::Migration.new(1, :create_people_table, :verbose => false) do
67
- up { :ran_up }
68
- down { :ran_down }
80
+ @migration.send(:create_migration_info_table_if_needed)
69
81
  end
70
82
 
71
- @migration.send(:create_migration_info_table_if_needed)
72
- end
73
-
74
- def insert_migration_record
75
- DataMapper.repository.adapter.execute("INSERT INTO migration_info (migration_name) VALUES ('create_people_table')")
76
- end
83
+ def insert_migration_record
84
+ DataMapper.repository.adapter.execute("INSERT INTO migration_info (migration_name) VALUES ('create_people_table')")
85
+ end
77
86
 
78
- it "should know if the migration_info table exists" do
79
- @migration.send(:migration_info_table_exists?).should be_true
80
- end
87
+ it "should know if the migration_info table exists" do
88
+ @migration.send(:migration_info_table_exists?).should be_true
89
+ end
81
90
 
82
- it "should know if the migration_info table does not exist" do
83
- repository.adapter.execute("DROP TABLE migration_info") rescue nil
84
- @migration.send(:migration_info_table_exists?).should be_false
85
- end
91
+ it "should know if the migration_info table does not exist" do
92
+ repository.adapter.execute("DROP TABLE migration_info") rescue nil
93
+ @migration.send(:migration_info_table_exists?).should be_false
94
+ end
86
95
 
87
- it "should be able to find the migration_info record for itself" do
88
- insert_migration_record
89
- @migration.send(:migration_record).should_not be_empty
90
- end
96
+ it "should be able to find the migration_info record for itself" do
97
+ insert_migration_record
98
+ @migration.send(:migration_record).should_not be_empty
99
+ end
91
100
 
92
- it "should know if a migration needs_up?" do
93
- @migration.send(:needs_up?).should be_true
94
- insert_migration_record
95
- @migration.send(:needs_up?).should be_false
96
- end
101
+ it "should know if a migration needs_up?" do
102
+ @migration.send(:needs_up?).should be_true
103
+ insert_migration_record
104
+ @migration.send(:needs_up?).should be_false
105
+ end
97
106
 
98
- it "should know if a migration needs_down?" do
99
- @migration.send(:needs_down?).should be_false
100
- insert_migration_record
101
- @migration.send(:needs_down?).should be_true
102
- end
107
+ it "should know if a migration needs_down?" do
108
+ @migration.send(:needs_down?).should be_false
109
+ insert_migration_record
110
+ @migration.send(:needs_down?).should be_true
111
+ end
103
112
 
104
- it "should properly quote the migration_info table for use in queries" do
105
- @migration.send(:migration_info_table).should == '"migration_info"'
106
- end
113
+ it "should properly quote the migration_info table for use in queries" do
114
+ @migration.send(:migration_info_table).should == '"migration_info"'
115
+ end
107
116
 
108
- it "should properly quote the migration_info.migration_name column for use in queries" do
109
- @migration.send(:migration_name_column).should == '"migration_name"'
110
- end
117
+ it "should properly quote the migration_info.migration_name column for use in queries" do
118
+ @migration.send(:migration_name_column).should == '"migration_name"'
119
+ end
111
120
 
112
- it "should properly quote the migration's name for use in queries"
113
- # TODO how to i call the adapter's #escape_sql method?
121
+ it "should properly quote the migration's name for use in queries"
122
+ # TODO how to i call the adapter's #escape_sql method?
114
123
 
115
- it "should create the migration_info table if it doesn't exist" do
116
- repository.adapter.execute("DROP TABLE migration_info")
117
- @migration.send(:migration_info_table_exists?).should be_false
118
- @migration.send(:create_migration_info_table_if_needed)
119
- @migration.send(:migration_info_table_exists?).should be_true
120
- end
124
+ it "should create the migration_info table if it doesn't exist" do
125
+ repository.adapter.execute("DROP TABLE migration_info")
126
+ @migration.send(:migration_info_table_exists?).should be_false
127
+ @migration.send(:create_migration_info_table_if_needed)
128
+ @migration.send(:migration_info_table_exists?).should be_true
129
+ end
121
130
 
122
- it "should insert a record into the migration_info table on up" do
123
- @migration.send(:migration_record).should be_empty
124
- @migration.perform_up.should == :ran_up
125
- @migration.send(:migration_record).should_not be_empty
126
- end
131
+ it "should insert a record into the migration_info table on up" do
132
+ @migration.send(:migration_record).should be_empty
133
+ @migration.perform_up.should == :ran_up
134
+ @migration.send(:migration_record).should_not be_empty
135
+ end
127
136
 
128
- it "should remove a record from the migration_info table on down" do
129
- insert_migration_record
130
- @migration.send(:migration_record).should_not be_empty
131
- @migration.perform_down.should == :ran_down
132
- @migration.send(:migration_record).should be_empty
133
- end
137
+ it "should remove a record from the migration_info table on down" do
138
+ insert_migration_record
139
+ @migration.send(:migration_record).should_not be_empty
140
+ @migration.perform_down.should == :ran_down
141
+ @migration.send(:migration_record).should be_empty
142
+ end
134
143
 
135
- it "should not run the up action if the record exists in the table" do
136
- insert_migration_record
137
- @migration.perform_up.should_not == :ran_up
138
- end
144
+ it "should not run the up action if the record exists in the table" do
145
+ insert_migration_record
146
+ @migration.perform_up.should_not == :ran_up
147
+ end
139
148
 
140
- it "should not run the down action if the record does not exist in the table" do
141
- @migration.perform_down.should_not == :ran_down
142
- end
149
+ it "should not run the down action if the record does not exist in the table" do
150
+ @migration.perform_down.should_not == :ran_down
151
+ end
143
152
 
144
- after do
145
- repository.adapter.execute("DELETE FROM migration_info") rescue Sqlite3Error
153
+ after do
154
+ repository.adapter.execute("DELETE FROM migration_info") if @migration.send(:migration_info_table_exists?)
155
+ end
146
156
  end
147
157
  end
148
158
  end
@@ -1,2 +1,3 @@
1
- --format specdoc
2
1
  --colour
2
+ --format progress
3
+
@@ -5,24 +5,17 @@ require 'pathname'
5
5
  require Pathname(__FILE__).dirname.parent.expand_path + 'lib/dm-migrations'
6
6
  require Pathname(__FILE__).dirname.parent.expand_path + 'lib/migration_runner'
7
7
 
8
- #require 'fileutils'
9
-
10
- #DB_FILE = "#{Dir.pwd}/migration_test.db"
11
- #FileUtils.touch DB_FILE
12
-
13
- #DataMapper.setup(:default, "sqlite3://#{DB_FILE}")
14
- #DataMapper::Logger.new(nil, :debug)
15
-
16
8
  def load_driver(name, default_uri)
17
- return false if ENV['ADAPTER'] != name.to_s
9
+ #return false if ENV['ADAPTER'] != name.to_s
18
10
 
19
11
  lib = "do_#{name}"
20
12
 
21
13
  begin
22
- gem lib, '=0.9.2'
14
+ gem lib, '=0.9.3'
23
15
  require lib
24
- DataMapper.setup(name, ENV["#{name.to_s.upcase}_SPEC_URI"] || default_uri)
16
+ DataMapper.setup(name, default_uri)
25
17
  DataMapper::Repository.adapters[:default] = DataMapper::Repository.adapters[name]
18
+ puts "Loaded #{name}"
26
19
  true
27
20
  rescue Gem::LoadError => e
28
21
  warn "Could not load #{lib}: #{e}"
@@ -0,0 +1,447 @@
1
+ require 'pathname'
2
+ require Pathname(__FILE__).dirname + '../spec_helper'
3
+
4
+ require Pathname(__FILE__).dirname + '../../lib/migration'
5
+
6
+ describe 'Migration' do
7
+
8
+ before do
9
+ @adapter = mock('adapter', :class => DataMapper::Adapters::Sqlite3Adapter)
10
+ @repo = mock('DataMapper.repository', :adapter => @adapter)
11
+ DataMapper.stub!(:repository).and_return(@repo)
12
+ @m = DataMapper::Migration.new(1, :do_nothing, {}) {}
13
+ @m.stub!(:write) # silence any output
14
+ end
15
+
16
+ [:position, :name, :database, :adapter].each do |meth|
17
+ it "should respond to ##{meth}" do
18
+ @m.should respond_to(meth)
19
+ end
20
+ end
21
+
22
+ describe 'initialization' do
23
+ it 'should set @position from the given position' do
24
+ @m.instance_variable_get(:@position).should == 1
25
+ end
26
+
27
+ it 'should set @name from the given name' do
28
+ @m.instance_variable_get(:@name).should == :do_nothing
29
+ end
30
+
31
+ it 'should set @options from the options hash' do
32
+ @m.instance_variable_get(:@options).should == {}
33
+ end
34
+
35
+ it 'should set @database from the default repository if no :database option is given' do
36
+ DataMapper.should_receive(:repository).with(:default).and_return(@repo)
37
+ DataMapper::Migration.new(1, :do_nothing, {}) {}
38
+ end
39
+
40
+ it 'should set @database to the repository specified with the :database option' do
41
+ DataMapper.should_receive(:repository).with(:foobar).and_return(@repo)
42
+ DataMapper::Migration.new(1, :do_nothing, :database => :foobar) {}
43
+ end
44
+
45
+ it 'should determine the class of the adapter to be extended' do
46
+ @adapter.should_receive(:class).and_return(DataMapper::Adapters::Sqlite3Adapter)
47
+ DataMapper::Migration.new(1, :do_nothing, {}) {}
48
+ end
49
+
50
+ it 'should extend the adapter with the right module' do
51
+ @adapter.should_receive(:extend).with(SQL::Sqlite3)
52
+ DataMapper::Migration.new(1, :do_nothing, {}) {}
53
+ end
54
+
55
+ it 'should raise "Unsupported adapter" on an unknown adapter' do
56
+ @adapter.should_receive(:class).any_number_of_times.and_return("InvalidAdapter")
57
+ lambda {
58
+ DataMapper::Migration.new(1, :do_nothing, {}) {}
59
+ }.should raise_error
60
+ end
61
+
62
+ it 'should set @verbose from the options hash' do
63
+ m = DataMapper::Migration.new(1, :do_nothing, :verbose => false) {}
64
+ m.instance_variable_get(:@verbose).should be_false
65
+ end
66
+
67
+ it 'should set @verbose to true by default' do
68
+ @m.instance_variable_get(:@verbose).should be_true
69
+ end
70
+
71
+ it 'should set the @up_action to an empty block' do
72
+ @m.instance_variable_get(:@up_action).should be_kind_of(Proc)
73
+ end
74
+
75
+ it 'should set the @down_action to an empty block' do
76
+ @m.instance_variable_get(:@down_action).should be_kind_of(Proc)
77
+ end
78
+
79
+ it 'should evaluate the given block'
80
+
81
+ end
82
+
83
+ it 'should set the @up_action when #up is called with a block' do
84
+ action = lambda {}
85
+ @m.up(&action)
86
+ @m.instance_variable_get(:@up_action).should == action
87
+ end
88
+
89
+ it 'should set the @up_action when #up is called with a block' do
90
+ action = lambda {}
91
+ @m.down(&action)
92
+ @m.instance_variable_get(:@down_action).should == action
93
+ end
94
+
95
+ describe 'perform_up' do
96
+ before do
97
+ @up_action = mock('proc', :call => true)
98
+ @m.instance_variable_set(:@up_action, @up_action)
99
+ @m.stub!(:needs_up?).and_return(true)
100
+ @m.stub!(:update_migration_info)
101
+ end
102
+
103
+ it 'should call the action assigned to @up_action and return the result' do
104
+ @up_action.should_receive(:call).and_return(:result)
105
+ @m.perform_up.should == :result
106
+ end
107
+
108
+ it 'should output a status message with the position and name of the migration' do
109
+ @m.should_receive(:write).with(/Performing Up Migration #1: do_nothing/)
110
+ @m.perform_up
111
+ end
112
+
113
+ it 'should not run if it doesnt need to be' do
114
+ @m.should_receive(:needs_up?).and_return(false)
115
+ @up_action.should_not_receive(:call)
116
+ @m.perform_up
117
+ end
118
+
119
+ it 'should update the migration info table' do
120
+ @m.should_receive(:update_migration_info).with(:up)
121
+ @m.perform_up
122
+ end
123
+
124
+ it 'should not update the migration info table if the migration does not need run' do
125
+ @m.should_receive(:needs_up?).and_return(false)
126
+ @m.should_not_receive(:update_migration_info)
127
+ @m.perform_up
128
+ end
129
+
130
+ end
131
+
132
+ describe 'perform_down' do
133
+ before do
134
+ @down_action = mock('proc', :call => true)
135
+ @m.instance_variable_set(:@down_action, @down_action)
136
+ @m.stub!(:needs_down?).and_return(true)
137
+ @m.stub!(:update_migration_info)
138
+ end
139
+
140
+ it 'should call the action assigned to @down_action and return the result' do
141
+ @down_action.should_receive(:call).and_return(:result)
142
+ @m.perform_down.should == :result
143
+ end
144
+
145
+ it 'should output a status message with the position and name of the migration' do
146
+ @m.should_receive(:write).with(/Performing Down Migration #1: do_nothing/)
147
+ @m.perform_down
148
+ end
149
+
150
+ it 'should not run if it doesnt need to be' do
151
+ @m.should_receive(:needs_down?).and_return(false)
152
+ @down_action.should_not_receive(:call)
153
+ @m.perform_down
154
+ end
155
+
156
+ it 'should update the migration info table' do
157
+ @m.should_receive(:update_migration_info).with(:down)
158
+ @m.perform_down
159
+ end
160
+
161
+ it 'should not update the migration info table if the migration does not need run' do
162
+ @m.should_receive(:needs_down?).and_return(false)
163
+ @m.should_not_receive(:update_migration_info)
164
+ @m.perform_down
165
+ end
166
+
167
+ end
168
+
169
+ describe 'methods used in the action blocks' do
170
+
171
+ describe '#execute' do
172
+ before do
173
+ @adapter.stub!(:execute)
174
+ end
175
+
176
+ it 'should send the SQL it its executing to the adapter execute method' do
177
+ @adapter.should_receive(:execute).with('SELECT SOME SQL')
178
+ @m.execute('SELECT SOME SQL')
179
+ end
180
+
181
+ it 'should output the SQL it is executing' do
182
+ @m.should_receive(:write).with(/SELECT SOME SQL/)
183
+ @m.execute('SELECT SOME SQL')
184
+ end
185
+ end
186
+
187
+ describe 'helpers' do
188
+ before do
189
+ @m.stub!(:execute) # don't actually run anything
190
+ end
191
+
192
+ describe '#create_table' do
193
+ before do
194
+ @tc = mock('TableCreator', :to_sql => 'CREATE TABLE')
195
+ SQL::TableCreator.stub!(:new).and_return(@tc)
196
+ end
197
+
198
+ it 'should create a new TableCreator object' do
199
+ SQL::TableCreator.should_receive(:new).with(@adapter, :users, {}).and_return(@tc)
200
+ @m.create_table(:users) { }
201
+ end
202
+
203
+ it 'should convert the TableCreator object to an sql statement' do
204
+ @tc.should_receive(:to_sql).and_return('CREATE TABLE')
205
+ @m.create_table(:users) { }
206
+ end
207
+
208
+ it 'should execute the create table sql' do
209
+ @m.should_receive(:execute).with('CREATE TABLE')
210
+ @m.create_table(:users) { }
211
+ end
212
+
213
+ end
214
+
215
+ describe '#drop_table' do
216
+ it 'should quote the table name' do
217
+ @adapter.should_receive(:quote_table_name).with('users')
218
+ @m.drop_table :users
219
+ end
220
+
221
+ it 'should execute the DROP TABLE sql for the table' do
222
+ @adapter.stub!(:quote_table_name).and_return("'users'")
223
+ @m.should_receive(:execute).with(%{DROP TABLE 'users'})
224
+ @m.drop_table :users
225
+ end
226
+
227
+ end
228
+
229
+ describe '#modify_table' do
230
+ before do
231
+ @tm = mock('TableModifier', :statements => [])
232
+ SQL::TableModifier.stub!(:new).and_return(@tm)
233
+ end
234
+
235
+ it 'should create a new TableModifier object' do
236
+ SQL::TableModifier.should_receive(:new).with(@adapter, :users, {}).and_return(@tm)
237
+ @m.modify_table(:users){ }
238
+ end
239
+
240
+ it 'should get the statements from the TableModifier object' do
241
+ @tm.should_receive(:statements).and_return([])
242
+ @m.modify_table(:users){ }
243
+ end
244
+
245
+ it 'should iterate over the statements and execute each one' do
246
+ @tm.should_receive(:statements).and_return(['SELECT 1', 'SELECT 2'])
247
+ @m.should_receive(:execute).with('SELECT 1')
248
+ @m.should_receive(:execute).with('SELECT 2')
249
+ @m.modify_table(:users){ }
250
+ end
251
+
252
+ end
253
+
254
+ describe 'sorting' do
255
+ it 'should order things by position' do
256
+ m1 = DataMapper::Migration.new(1, :do_nothing){}
257
+ m2 = DataMapper::Migration.new(2, :do_nothing_else){}
258
+
259
+ (m1 <=> m2).should == -1
260
+ end
261
+
262
+ it 'should order things by name when they have the same position' do
263
+ m1 = DataMapper::Migration.new(1, :do_nothing_a){}
264
+ m2 = DataMapper::Migration.new(1, :do_nothing_b){}
265
+
266
+ (m1 <=> m2).should == -1
267
+ end
268
+
269
+ end
270
+
271
+ describe 'formatting output' do
272
+ describe '#say' do
273
+ it 'should output the message' do
274
+ @m.should_receive(:write).with(/Paul/)
275
+ @m.say("Paul")
276
+ end
277
+
278
+ it 'should indent the message with 4 spaces by default' do
279
+ @m.should_receive(:write).with(/^\s{4}/)
280
+ @m.say("Paul")
281
+ end
282
+
283
+ it 'should indext the message with a given number of spaces' do
284
+ @m.should_receive(:write).with(/^\s{3}/)
285
+ @m.say("Paul", 3)
286
+ end
287
+ end
288
+
289
+ describe '#say_with_time' do
290
+ before do
291
+ @m.stub!(:say)
292
+ end
293
+
294
+ it 'should say the message with an indent of 2' do
295
+ @m.should_receive(:say).with("Paul", 2)
296
+ @m.say_with_time("Paul"){}
297
+ end
298
+
299
+ it 'should output the time it took' do
300
+ @m.should_receive(:say).with(/\d+/, 2)
301
+ @m.say_with_time("Paul"){}
302
+ end
303
+ end
304
+
305
+ describe '#write' do
306
+ before do
307
+ # need a new migration object, because the main one had #write stubbed to silence output
308
+ @m = DataMapper::Migration.new(1, :do_nothing) {}
309
+ end
310
+
311
+ it 'should puts the message' do
312
+ @m.should_receive(:puts).with("Paul")
313
+ @m.write("Paul")
314
+ end
315
+
316
+ it 'should not puts the message if @verbose is false' do
317
+ @m.instance_variable_set(:@verbose, false)
318
+ @m.should_not_receive(:puts)
319
+ @m.write("Paul")
320
+ end
321
+
322
+ end
323
+
324
+ end
325
+
326
+ describe 'working with the migration_info table' do
327
+ before do
328
+ @adapter.stub!(:storage_exists?).and_return(true)
329
+ @adapter.stub!(:quote_table_name).and_return(%{'users'})
330
+ @adapter.stub!(:quote_column_name).and_return(%{'migration_name'})
331
+ end
332
+
333
+ describe '#update_migration_info' do
334
+ it 'should add a record of the migration' do
335
+ @m.should_receive(:execute).with(
336
+ %Q{INSERT INTO 'users' ('migration_name') VALUES ('do_nothing')}
337
+ )
338
+ @m.update_migration_info(:up)
339
+ end
340
+
341
+ it 'should remove the record of the migration' do
342
+ @m.should_receive(:execute).with(
343
+ %Q{DELETE FROM 'users' WHERE 'migration_name' = 'do_nothing'}
344
+ )
345
+ @m.update_migration_info(:down)
346
+ end
347
+
348
+ it 'should try to create the migration_info table' do
349
+ @m.should_receive(:create_migration_info_table_if_needed)
350
+ @m.update_migration_info(:up)
351
+ end
352
+ end
353
+
354
+ describe '#create_migration_info_table_if_needed' do
355
+ it 'should create the migration info table' do
356
+ @m.should_receive(:migration_info_table_exists?).and_return(false)
357
+ @m.should_receive(:execute).with(
358
+ %Q{CREATE TABLE 'users' ('migration_name' VARCHAR(255) UNIQUE)}
359
+ )
360
+ @m.create_migration_info_table_if_needed
361
+ end
362
+
363
+ it 'should not try to create the migration info table if it already exists' do
364
+ @m.should_receive(:migration_info_table_exists?).and_return(true)
365
+ @m.should_not_receive(:execute)
366
+ @m.create_migration_info_table_if_needed
367
+ end
368
+ end
369
+
370
+ it 'should quote the name of the migration for use in sql' do
371
+ @m.quoted_name.should == %{'do_nothing'}
372
+ end
373
+
374
+ it 'should query the adapter to see if the migration_info table exists' do
375
+ @adapter.should_receive(:storage_exists?).with('migration_info').and_return(true)
376
+ @m.migration_info_table_exists?.should == true
377
+ end
378
+
379
+ describe '#migration_record' do
380
+ it 'should query for the migration' do
381
+ @adapter.should_receive(:query).with(
382
+ %Q{SELECT 'migration_name' FROM 'users' WHERE 'migration_name' = 'do_nothing'}
383
+ )
384
+ @m.migration_record
385
+ end
386
+
387
+ it 'should not try to query if the table does not exist' do
388
+ @m.stub!(:migration_info_table_exists?).and_return(false)
389
+ @adapter.should_not_receive(:query)
390
+ @m.migration_record
391
+ end
392
+
393
+ end
394
+
395
+ describe '#needs_up?' do
396
+ it 'should be true if there is no record' do
397
+ @m.should_receive(:migration_record).and_return([])
398
+ @m.needs_up?.should == true
399
+ end
400
+
401
+ it 'should be false if the record exists' do
402
+ @m.should_receive(:migration_record).and_return([:not_empty])
403
+ @m.needs_up?.should == false
404
+ end
405
+
406
+ it 'should be true if there is no migration_info table' do
407
+ @m.should_receive(:migration_info_table_exists?).and_return(false)
408
+ @m.needs_up?.should == true
409
+ end
410
+
411
+ end
412
+
413
+ describe '#needs_down?' do
414
+ it 'should be false if there is no record' do
415
+ @m.should_receive(:migration_record).and_return([])
416
+ @m.needs_down?.should == false
417
+ end
418
+
419
+ it 'should be true if the record exists' do
420
+ @m.should_receive(:migration_record).and_return([:not_empty])
421
+ @m.needs_down?.should == true
422
+ end
423
+
424
+ it 'should be false if there is no migration_info table' do
425
+ @m.should_receive(:migration_info_table_exists?).and_return(false)
426
+ @m.needs_down?.should == false
427
+ end
428
+
429
+ end
430
+
431
+ it 'should have the adapter quote the migration_info table' do
432
+ @adapter.should_receive(:quote_table_name).with('migration_info').and_return("'migration_info'")
433
+ @m.migration_info_table.should == "'migration_info'"
434
+ end
435
+
436
+ it 'should have a quoted migration_name_column' do
437
+ @adapter.should_receive(:quote_column_name).with('migration_name').and_return("'migration_name'")
438
+ @m.migration_name_column.should == "'migration_name'"
439
+ end
440
+
441
+ end
442
+
443
+ end
444
+
445
+ end
446
+ end
447
+