ardm-migrations 1.2.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/.gitignore +35 -0
- data/.travis.yml +11 -0
- data/Gemfile +53 -0
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +4 -0
- data/ardm-migrations.gemspec +27 -0
- data/db/migrations/1_create_people_table.rb +12 -0
- data/db/migrations/2_add_dob_to_people.rb +13 -0
- data/db/migrations/config.rb +4 -0
- data/examples/Rakefile +144 -0
- data/examples/sample_migration.rb +58 -0
- data/examples/sample_migration_spec.rb +50 -0
- data/lib/ardm-migrations.rb +1 -0
- data/lib/dm-migrations/adapters/dm-do-adapter.rb +295 -0
- data/lib/dm-migrations/adapters/dm-mysql-adapter.rb +299 -0
- data/lib/dm-migrations/adapters/dm-oracle-adapter.rb +332 -0
- data/lib/dm-migrations/adapters/dm-postgres-adapter.rb +159 -0
- data/lib/dm-migrations/adapters/dm-sqlite-adapter.rb +96 -0
- data/lib/dm-migrations/adapters/dm-sqlserver-adapter.rb +177 -0
- data/lib/dm-migrations/adapters/dm-yaml-adapter.rb +23 -0
- data/lib/dm-migrations/auto_migration.rb +239 -0
- data/lib/dm-migrations/exceptions/duplicate_migration.rb +6 -0
- data/lib/dm-migrations/migration.rb +300 -0
- data/lib/dm-migrations/migration_runner.rb +85 -0
- data/lib/dm-migrations/sql/column.rb +5 -0
- data/lib/dm-migrations/sql/mysql.rb +61 -0
- data/lib/dm-migrations/sql/postgres.rb +82 -0
- data/lib/dm-migrations/sql/sqlite.rb +51 -0
- data/lib/dm-migrations/sql/table.rb +15 -0
- data/lib/dm-migrations/sql/table_creator.rb +109 -0
- data/lib/dm-migrations/sql/table_modifier.rb +57 -0
- data/lib/dm-migrations/sql.rb +5 -0
- data/lib/dm-migrations/version.rb +5 -0
- data/lib/dm-migrations.rb +3 -0
- data/lib/spec/example/migration_example_group.rb +73 -0
- data/lib/spec/matchers/migration_matchers.rb +106 -0
- data/spec/integration/auto_migration_spec.rb +553 -0
- data/spec/integration/auto_upgrade_spec.rb +40 -0
- data/spec/integration/migration_runner_spec.rb +89 -0
- data/spec/integration/migration_spec.rb +157 -0
- data/spec/integration/sql_spec.rb +250 -0
- data/spec/isolated/require_after_setup_spec.rb +30 -0
- data/spec/isolated/require_before_setup_spec.rb +30 -0
- data/spec/isolated/require_spec.rb +25 -0
- data/spec/rcov.opts +6 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/unit/migration_spec.rb +453 -0
- data/spec/unit/sql/column_spec.rb +14 -0
- data/spec/unit/sql/postgres_spec.rb +97 -0
- data/spec/unit/sql/sqlite_extensions_spec.rb +108 -0
- data/spec/unit/sql/table_creator_spec.rb +94 -0
- data/spec/unit/sql/table_modifier_spec.rb +49 -0
- data/spec/unit/sql/table_spec.rb +28 -0
- data/spec/unit/sql_spec.rb +7 -0
- data/tasks/spec.rake +38 -0
- data/tasks/yard.rake +9 -0
- data/tasks/yardstick.rake +19 -0
- metadata +150 -0
@@ -0,0 +1,453 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Migration' do
|
4
|
+
supported_by :postgres, :mysql, :sqlite do
|
5
|
+
before do
|
6
|
+
@adapter = mock('adapter', :class => DataMapper::Spec.adapter.class)
|
7
|
+
@repo = mock('DataMapper.repository', :adapter => @adapter)
|
8
|
+
DataMapper.stub!(:repository).and_return(@repo)
|
9
|
+
@m = DataMapper::Migration.new(1, :do_nothing, {}) {}
|
10
|
+
@m.stub!(:write) # silence any output
|
11
|
+
end
|
12
|
+
|
13
|
+
[:position, :name, :database, :adapter].each do |meth|
|
14
|
+
it "should respond to ##{meth}" do
|
15
|
+
@m.should respond_to(meth)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe 'initialization' do
|
20
|
+
it 'should set @position from the given position' do
|
21
|
+
@m.instance_variable_get(:@position).should == 1
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should set @name from the given name' do
|
25
|
+
@m.instance_variable_get(:@name).should == :do_nothing
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should set @options from the options hash' do
|
29
|
+
@m.instance_variable_get(:@options).should == {}
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should set @repository from the default repository if no :repository option is given' do
|
33
|
+
m = DataMapper::Migration.new(1, :do_nothing, {}) {}
|
34
|
+
|
35
|
+
m.instance_variable_get(:@repository).should == :default
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should set @repository to the specified :repository option' do
|
39
|
+
m = DataMapper::Migration.new(1, :do_nothing, :repository => :foobar) {}
|
40
|
+
|
41
|
+
m.instance_variable_get(:@repository).should == :foobar
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should set @verbose from the options hash' do
|
45
|
+
m = DataMapper::Migration.new(1, :do_nothing, :verbose => false) {}
|
46
|
+
m.instance_variable_get(:@verbose).should be(false)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should set @verbose to true by default' do
|
50
|
+
@m.instance_variable_get(:@verbose).should be(true)
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should set the @up_action to nil' do
|
54
|
+
@m.instance_variable_get(:@up_action).should be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should set the @down_action to nil' do
|
58
|
+
@m.instance_variable_get(:@down_action).should be_nil
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should evaluate the given block'
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should set the @up_action when #up is called with a block' do
|
66
|
+
action = lambda {}
|
67
|
+
@m.up(&action)
|
68
|
+
@m.instance_variable_get(:@up_action).should == action
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should set the @up_action when #up is called with a block' do
|
72
|
+
action = lambda {}
|
73
|
+
@m.down(&action)
|
74
|
+
@m.instance_variable_get(:@down_action).should == action
|
75
|
+
end
|
76
|
+
|
77
|
+
describe 'adapter' do
|
78
|
+
before(:each) do
|
79
|
+
@m.instance_variable_set(:@adapter, nil)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should determine the class of the adapter to be extended' do
|
83
|
+
@adapter.should_receive(:class).and_return(DataMapper::Spec.adapter.class)
|
84
|
+
|
85
|
+
@m.adapter
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should extend the adapter with the right module' do
|
89
|
+
@adapter.should_receive(:extend).with(SQL.const_get(DataMapper::Spec.adapter_name.capitalize))
|
90
|
+
|
91
|
+
@m.adapter
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should raise "Unsupported adapter" on an unknown adapter' do
|
95
|
+
@adapter.should_receive(:class).any_number_of_times.and_return("InvalidAdapter")
|
96
|
+
|
97
|
+
lambda { @m.adapter }.should raise_error
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'perform_up' do
|
102
|
+
before do
|
103
|
+
@up_action = mock('proc', :call => true)
|
104
|
+
@m.instance_variable_set(:@up_action, @up_action)
|
105
|
+
@m.stub!(:needs_up?).and_return(true)
|
106
|
+
@m.stub!(:update_migration_info)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should call the action assigned to @up_action and return the result' do
|
110
|
+
@up_action.should_receive(:call).and_return(:result)
|
111
|
+
@m.perform_up.should == :result
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should output a status message with the position and name of the migration' do
|
115
|
+
@m.should_receive(:write).with(/Performing Up Migration #1: do_nothing/)
|
116
|
+
@m.perform_up
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should not run if it doesnt need to be' do
|
120
|
+
@m.should_receive(:needs_up?).and_return(false)
|
121
|
+
@up_action.should_not_receive(:call)
|
122
|
+
@m.perform_up
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should update the migration info table' do
|
126
|
+
@m.should_receive(:update_migration_info).with(:up)
|
127
|
+
@m.perform_up
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should not update the migration info table if the migration does not need run' do
|
131
|
+
@m.should_receive(:needs_up?).and_return(false)
|
132
|
+
@m.should_not_receive(:update_migration_info)
|
133
|
+
@m.perform_up
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'perform_down' do
|
139
|
+
before do
|
140
|
+
@down_action = mock('proc', :call => true)
|
141
|
+
@m.instance_variable_set(:@down_action, @down_action)
|
142
|
+
@m.stub!(:needs_down?).and_return(true)
|
143
|
+
@m.stub!(:update_migration_info)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should call the action assigned to @down_action and return the result' do
|
147
|
+
@down_action.should_receive(:call).and_return(:result)
|
148
|
+
@m.perform_down.should == :result
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should output a status message with the position and name of the migration' do
|
152
|
+
@m.should_receive(:write).with(/Performing Down Migration #1: do_nothing/)
|
153
|
+
@m.perform_down
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should not run if it doesnt need to be' do
|
157
|
+
@m.should_receive(:needs_down?).and_return(false)
|
158
|
+
@down_action.should_not_receive(:call)
|
159
|
+
@m.perform_down
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should update the migration info table' do
|
163
|
+
@m.should_receive(:update_migration_info).with(:down)
|
164
|
+
@m.perform_down
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should not update the migration info table if the migration does not need run' do
|
168
|
+
@m.should_receive(:needs_down?).and_return(false)
|
169
|
+
@m.should_not_receive(:update_migration_info)
|
170
|
+
@m.perform_down
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
describe 'methods used in the action blocks' do
|
176
|
+
|
177
|
+
describe '#execute' do
|
178
|
+
before do
|
179
|
+
@adapter.stub!(:execute)
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should send the SQL it its executing to the adapter execute method' do
|
183
|
+
@adapter.should_receive(:execute).with('SELECT SOME SQL')
|
184
|
+
@m.execute('SELECT SOME SQL')
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'should output the SQL it is executing' do
|
188
|
+
@m.should_receive(:write).with(/SELECT SOME SQL/)
|
189
|
+
@m.execute('SELECT SOME SQL')
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe 'helpers' do
|
194
|
+
before do
|
195
|
+
@m.stub!(:execute) # don't actually run anything
|
196
|
+
end
|
197
|
+
|
198
|
+
describe '#create_table' do
|
199
|
+
before do
|
200
|
+
@tc = mock('TableCreator', :to_sql => 'CREATE TABLE')
|
201
|
+
SQL::TableCreator.stub!(:new).and_return(@tc)
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'should create a new TableCreator object' do
|
205
|
+
SQL::TableCreator.should_receive(:new).with(@adapter, :users, {}).and_return(@tc)
|
206
|
+
@m.create_table(:users) { }
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should convert the TableCreator object to an sql statement' do
|
210
|
+
@tc.should_receive(:to_sql).and_return('CREATE TABLE')
|
211
|
+
@m.create_table(:users) { }
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should execute the create table sql' do
|
215
|
+
@m.should_receive(:execute).with('CREATE TABLE')
|
216
|
+
@m.create_table(:users) { }
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|
220
|
+
|
221
|
+
describe '#drop_table' do
|
222
|
+
it 'should quote the table name' do
|
223
|
+
@adapter.should_receive(:quote_name).with('users')
|
224
|
+
@m.drop_table :users
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should execute the DROP TABLE sql for the table' do
|
228
|
+
@adapter.stub!(:quote_name).and_return("'users'")
|
229
|
+
@m.should_receive(:execute).with(%{DROP TABLE 'users'})
|
230
|
+
@m.drop_table :users
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
describe '#modify_table' do
|
236
|
+
before do
|
237
|
+
@tm = mock('TableModifier', :statements => [])
|
238
|
+
SQL::TableModifier.stub!(:new).and_return(@tm)
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'should create a new TableModifier object' do
|
242
|
+
SQL::TableModifier.should_receive(:new).with(@adapter, :users, {}).and_return(@tm)
|
243
|
+
@m.modify_table(:users){ }
|
244
|
+
end
|
245
|
+
|
246
|
+
it 'should get the statements from the TableModifier object' do
|
247
|
+
@tm.should_receive(:statements).and_return([])
|
248
|
+
@m.modify_table(:users){ }
|
249
|
+
end
|
250
|
+
|
251
|
+
it 'should iterate over the statements and execute each one' do
|
252
|
+
@tm.should_receive(:statements).and_return(['SELECT 1', 'SELECT 2'])
|
253
|
+
@m.should_receive(:execute).with('SELECT 1')
|
254
|
+
@m.should_receive(:execute).with('SELECT 2')
|
255
|
+
@m.modify_table(:users){ }
|
256
|
+
end
|
257
|
+
|
258
|
+
end
|
259
|
+
|
260
|
+
describe 'sorting' do
|
261
|
+
it 'should order things by position' do
|
262
|
+
m1 = DataMapper::Migration.new(1, :do_nothing){}
|
263
|
+
m2 = DataMapper::Migration.new(2, :do_nothing_else){}
|
264
|
+
|
265
|
+
(m1 <=> m2).should == -1
|
266
|
+
end
|
267
|
+
|
268
|
+
it 'should order things by name when they have the same position' do
|
269
|
+
m1 = DataMapper::Migration.new(1, :do_nothing_a){}
|
270
|
+
m2 = DataMapper::Migration.new(1, :do_nothing_b){}
|
271
|
+
|
272
|
+
(m1 <=> m2).should == -1
|
273
|
+
end
|
274
|
+
|
275
|
+
end
|
276
|
+
|
277
|
+
describe 'formatting output' do
|
278
|
+
describe '#say' do
|
279
|
+
it 'should output the message' do
|
280
|
+
@m.should_receive(:write).with(/Paul/)
|
281
|
+
@m.say("Paul")
|
282
|
+
end
|
283
|
+
|
284
|
+
it 'should indent the message with 4 spaces by default' do
|
285
|
+
@m.should_receive(:write).with(/^\s{4}/)
|
286
|
+
@m.say("Paul")
|
287
|
+
end
|
288
|
+
|
289
|
+
it 'should indext the message with a given number of spaces' do
|
290
|
+
@m.should_receive(:write).with(/^\s{3}/)
|
291
|
+
@m.say("Paul", 3)
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
describe '#say_with_time' do
|
296
|
+
before do
|
297
|
+
@m.stub!(:say)
|
298
|
+
end
|
299
|
+
|
300
|
+
it 'should say the message with an indent of 2' do
|
301
|
+
@m.should_receive(:say).with("Paul", 2)
|
302
|
+
@m.say_with_time("Paul"){}
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'should output the time it took' do
|
306
|
+
@m.should_receive(:say).with(/\d+/, 2)
|
307
|
+
@m.say_with_time("Paul"){}
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
describe '#write' do
|
312
|
+
before do
|
313
|
+
# need a new migration object, because the main one had #write stubbed to silence output
|
314
|
+
@m = DataMapper::Migration.new(1, :do_nothing) {}
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'should puts the message' do
|
318
|
+
@m.should_receive(:puts).with("Paul")
|
319
|
+
@m.write("Paul")
|
320
|
+
end
|
321
|
+
|
322
|
+
it 'should not puts the message if @verbose is false' do
|
323
|
+
@m.instance_variable_set(:@verbose, false)
|
324
|
+
@m.should_not_receive(:puts)
|
325
|
+
@m.write("Paul")
|
326
|
+
end
|
327
|
+
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
331
|
+
|
332
|
+
describe 'working with the migration_info table' do
|
333
|
+
before do
|
334
|
+
@adapter.stub!(:storage_exists?).and_return(true)
|
335
|
+
# --- Please remove stubs ---
|
336
|
+
@adapter.stub!(:quote_name).and_return { |name| "'#{name}'" }
|
337
|
+
end
|
338
|
+
|
339
|
+
describe '#update_migration_info' do
|
340
|
+
it 'should add a record of the migration' do
|
341
|
+
@m.should_receive(:execute).with(
|
342
|
+
%Q{INSERT INTO 'migration_info' ('migration_name') VALUES ('do_nothing')}
|
343
|
+
)
|
344
|
+
@m.update_migration_info(:up)
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'should remove the record of the migration' do
|
348
|
+
@m.should_receive(:execute).with(
|
349
|
+
%Q{DELETE FROM 'migration_info' WHERE 'migration_name' = 'do_nothing'}
|
350
|
+
)
|
351
|
+
@m.update_migration_info(:down)
|
352
|
+
end
|
353
|
+
|
354
|
+
it 'should try to create the migration_info table' do
|
355
|
+
@m.should_receive(:create_migration_info_table_if_needed)
|
356
|
+
@m.update_migration_info(:up)
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
describe '#create_migration_info_table_if_needed' do
|
361
|
+
it 'should create the migration info table' do
|
362
|
+
@m.should_receive(:migration_info_table_exists?).and_return(false)
|
363
|
+
@m.should_receive(:execute).with(
|
364
|
+
%Q{CREATE TABLE 'migration_info' ('migration_name' VARCHAR(255) UNIQUE)}
|
365
|
+
)
|
366
|
+
@m.create_migration_info_table_if_needed
|
367
|
+
end
|
368
|
+
|
369
|
+
it 'should not try to create the migration info table if it already exists' do
|
370
|
+
@m.should_receive(:migration_info_table_exists?).and_return(true)
|
371
|
+
@m.should_not_receive(:execute)
|
372
|
+
@m.create_migration_info_table_if_needed
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
it 'should quote the name of the migration for use in sql' do
|
377
|
+
@m.quoted_name.should == %{'do_nothing'}
|
378
|
+
end
|
379
|
+
|
380
|
+
it 'should query the adapter to see if the migration_info table exists' do
|
381
|
+
@adapter.should_receive(:storage_exists?).with('migration_info').and_return(true)
|
382
|
+
@m.migration_info_table_exists?.should == true
|
383
|
+
end
|
384
|
+
|
385
|
+
describe '#migration_record' do
|
386
|
+
it 'should query for the migration' do
|
387
|
+
@adapter.should_receive(:select).with(
|
388
|
+
%Q{SELECT 'migration_name' FROM 'migration_info' WHERE 'migration_name' = 'do_nothing'}
|
389
|
+
)
|
390
|
+
@m.migration_record
|
391
|
+
end
|
392
|
+
|
393
|
+
it 'should not try to query if the table does not exist' do
|
394
|
+
@m.stub!(:migration_info_table_exists?).and_return(false)
|
395
|
+
@adapter.should_not_receive(:select)
|
396
|
+
@m.migration_record
|
397
|
+
end
|
398
|
+
|
399
|
+
end
|
400
|
+
|
401
|
+
describe '#needs_up?' do
|
402
|
+
it 'should be true if there is no record' do
|
403
|
+
@m.should_receive(:migration_record).and_return([])
|
404
|
+
@m.needs_up?.should == true
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'should be false if the record exists' do
|
408
|
+
@m.should_receive(:migration_record).and_return([:not_empty])
|
409
|
+
@m.needs_up?.should == false
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'should be true if there is no migration_info table' do
|
413
|
+
@m.should_receive(:migration_info_table_exists?).and_return(false)
|
414
|
+
@m.needs_up?.should == true
|
415
|
+
end
|
416
|
+
|
417
|
+
end
|
418
|
+
|
419
|
+
describe '#needs_down?' do
|
420
|
+
it 'should be false if there is no record' do
|
421
|
+
@m.should_receive(:migration_record).and_return([])
|
422
|
+
@m.needs_down?.should == false
|
423
|
+
end
|
424
|
+
|
425
|
+
it 'should be true if the record exists' do
|
426
|
+
@m.should_receive(:migration_record).and_return([:not_empty])
|
427
|
+
@m.needs_down?.should == true
|
428
|
+
end
|
429
|
+
|
430
|
+
it 'should be false if there is no migration_info table' do
|
431
|
+
@m.should_receive(:migration_info_table_exists?).and_return(false)
|
432
|
+
@m.needs_down?.should == false
|
433
|
+
end
|
434
|
+
|
435
|
+
end
|
436
|
+
|
437
|
+
it 'should have the adapter quote the migration_info table' do
|
438
|
+
@adapter.should_receive(:quote_name).with('migration_info').and_return("'migration_info'")
|
439
|
+
@m.migration_info_table.should == "'migration_info'"
|
440
|
+
end
|
441
|
+
|
442
|
+
it 'should have a quoted migration_name_column' do
|
443
|
+
@adapter.should_receive(:quote_name).with('migration_name').and_return("'migration_name'")
|
444
|
+
@m.migration_name_column.should == "'migration_name'"
|
445
|
+
end
|
446
|
+
|
447
|
+
end
|
448
|
+
|
449
|
+
end
|
450
|
+
|
451
|
+
end
|
452
|
+
end
|
453
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SQL::Column do
|
4
|
+
before do
|
5
|
+
@column = SQL::Column.new
|
6
|
+
end
|
7
|
+
|
8
|
+
%w{name type not_null default_value primary_key unique}.each do |meth|
|
9
|
+
it "should have a ##{meth} attribute" do
|
10
|
+
@column.should respond_to(meth.intern)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# a dummy class to include the module into
|
4
|
+
class PostgresExtension
|
5
|
+
include SQL::Postgres
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "Postgres Extensions" do
|
9
|
+
before do
|
10
|
+
@pe = PostgresExtension.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should support schema-level transactions' do
|
14
|
+
@pe.supports_schema_transactions?.should be(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should support the serial column attribute' do
|
18
|
+
@pe.supports_serial?.should be(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should create a table object from the name' do
|
22
|
+
table = mock('Postgres Table')
|
23
|
+
SQL::Postgres::Table.should_receive(:new).with(@pe, 'users').and_return(table)
|
24
|
+
|
25
|
+
@pe.table('users').should == table
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'recreating the database' do
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'Table' do
|
32
|
+
before do
|
33
|
+
@cs1 = mock('Column Struct')
|
34
|
+
@cs2 = mock('Column Struct')
|
35
|
+
@adapter = mock('adapter', :select => [])
|
36
|
+
@adapter.stub!(:query_table).with('users').and_return([@cs1, @cs2])
|
37
|
+
|
38
|
+
@col1 = mock('Postgres Column')
|
39
|
+
@col2 = mock('Postgres Column')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should initialize columns by querying the table' do
|
43
|
+
SQL::Postgres::Column.should_receive(:new).with(@cs1).and_return(@col1)
|
44
|
+
SQL::Postgres::Column.should_receive(:new).with(@cs2).and_return(@col2)
|
45
|
+
@adapter.should_receive(:query_table).with('users').and_return([@cs1,@cs2])
|
46
|
+
SQL::Postgres::Table.new(@adapter, 'users')
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should create Postgres Column objects from the returned column structs' do
|
50
|
+
SQL::Postgres::Column.should_receive(:new).with(@cs1).and_return(@col1)
|
51
|
+
SQL::Postgres::Column.should_receive(:new).with(@cs2).and_return(@col2)
|
52
|
+
SQL::Postgres::Table.new(@adapter, 'users')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should set the @columns to the looked-up columns' do
|
56
|
+
SQL::Postgres::Column.should_receive(:new).with(@cs1).and_return(@col1)
|
57
|
+
SQL::Postgres::Column.should_receive(:new).with(@cs2).and_return(@col2)
|
58
|
+
t = SQL::Postgres::Table.new(@adapter, 'users')
|
59
|
+
t.columns.should == [@col1, @col2]
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#query_column_constraints' do
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'Column' do
|
69
|
+
before do
|
70
|
+
@cs = mock('Struct',
|
71
|
+
:column_name => 'id',
|
72
|
+
:data_type => 'integer',
|
73
|
+
:column_default => 123,
|
74
|
+
:is_nullable => 'NO')
|
75
|
+
@c = SQL::Postgres::Column.new(@cs)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should set the name from the column_name value' do
|
79
|
+
@c.name.should == 'id'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should set the type from the data_type value' do
|
83
|
+
@c.type.should == 'integer'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should set the default_value from the column_default value' do
|
87
|
+
@c.default_value.should == 123
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should set not_null based on the is_nullable value' do
|
91
|
+
@c.not_null.should == true
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# a dummy class to include the module into
|
4
|
+
class SqliteExtension
|
5
|
+
include SQL::Sqlite
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "SQLite3 Extensions" do
|
9
|
+
before do
|
10
|
+
@se = SqliteExtension.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should support schema-level transactions' do
|
14
|
+
@se.supports_schema_transactions?.should be(true)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should support the serial column attribute' do
|
18
|
+
@se.supports_serial?.should be(true)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should create a table object from the name' do
|
22
|
+
table = mock('SQLite3 Table')
|
23
|
+
SQL::Sqlite::Table.should_receive(:new).with(@se, 'users').and_return(table)
|
24
|
+
|
25
|
+
@se.table('users').should == table
|
26
|
+
end
|
27
|
+
|
28
|
+
describe 'recreating the database' do
|
29
|
+
before do
|
30
|
+
uri = mock('URI', :path => '/foo/bar.db')
|
31
|
+
@se.instance_variable_set('@uri', uri)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should rm the db file' do
|
35
|
+
FileUtils.should_receive(:rm_f).with('/foo/bar.db')
|
36
|
+
@se.recreate_database
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'Table' do
|
42
|
+
before do
|
43
|
+
@cs1 = mock('Column Struct')
|
44
|
+
@cs2 = mock('Column Struct')
|
45
|
+
@adapter = mock('adapter')
|
46
|
+
@adapter.stub!(:table_info).with('users').and_return([@cs1, @cs2])
|
47
|
+
|
48
|
+
@col1 = mock('SQLite3 Column')
|
49
|
+
@col2 = mock('SQLite3 Column')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should initialize columns by querying the table' do
|
53
|
+
SQL::Sqlite::Column.should_receive(:new).with(@cs1).and_return(@col1)
|
54
|
+
SQL::Sqlite::Column.should_receive(:new).with(@cs2).and_return(@col2)
|
55
|
+
@adapter.should_receive(:table_info).with('users').and_return([@cs1,@cs2])
|
56
|
+
SQL::Sqlite::Table.new(@adapter, 'users')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should create SQLite3 Column objects from the returned column structs' do
|
60
|
+
SQL::Sqlite::Column.should_receive(:new).with(@cs1).and_return(@col1)
|
61
|
+
SQL::Sqlite::Column.should_receive(:new).with(@cs2).and_return(@col2)
|
62
|
+
SQL::Sqlite::Table.new(@adapter, 'users')
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'should set the @columns to the looked-up columns' do
|
66
|
+
SQL::Sqlite::Column.should_receive(:new).with(@cs1).and_return(@col1)
|
67
|
+
SQL::Sqlite::Column.should_receive(:new).with(@cs2).and_return(@col2)
|
68
|
+
t = SQL::Sqlite::Table.new(@adapter, 'users')
|
69
|
+
t.columns.should == [ @col1, @col2 ]
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'Column' do
|
75
|
+
before do
|
76
|
+
@cs = mock('Struct',
|
77
|
+
:name => 'id',
|
78
|
+
:type => 'integer',
|
79
|
+
:dflt_value => 123,
|
80
|
+
:pk => true,
|
81
|
+
:notnull => 0)
|
82
|
+
@c = SQL::Sqlite::Column.new(@cs)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should set the name from the name value' do
|
86
|
+
@c.name.should == 'id'
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should set the type from the type value' do
|
90
|
+
@c.type.should == 'integer'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should set the default_value from the dflt_value value' do
|
94
|
+
@c.default_value.should == 123
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should set the primary_key from the pk value' do
|
98
|
+
@c.primary_key.should == true
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should set not_null based on the notnull value' do
|
102
|
+
@c.not_null.should == true
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
|
108
|
+
end
|