ibm_db 0.9.5 → 0.10.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.
Files changed (44) hide show
  1. data/CHANGES +5 -0
  2. data/README +63 -97
  3. data/ext/ibm_db.c +20 -4
  4. data/ext/ruby_ibm_db.h +10 -0
  5. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +2 -4
  6. data/test/{adapter_test.rb → cases/adapter_test.rb} +39 -14
  7. data/test/cases/associations/cascaded_eager_loading_test.rb +113 -0
  8. data/test/{associations → cases/associations}/eager_test.rb +231 -65
  9. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +686 -0
  10. data/test/cases/associations/join_model_test.rb +797 -0
  11. data/test/{base_test.rb → cases/base_test.rb} +605 -385
  12. data/test/cases/calculations_test.rb +275 -0
  13. data/test/cases/finder_test.rb +885 -0
  14. data/test/cases/fixtures_test.rb +630 -0
  15. data/test/{migration_test.rb → cases/migration_test.rb} +530 -146
  16. data/test/cases/query_cache_test.rb +127 -0
  17. data/test/cases/validations_test.rb +1509 -0
  18. data/test/connections/native_ibm_db/connection.rb +1 -1
  19. data/test/models/warehouse_thing.rb +5 -0
  20. data/test/schema/i5/ibm_db_specific_schema.rb +133 -0
  21. data/test/schema/ids/ibm_db_specific_schema.rb +136 -0
  22. data/test/schema/luw/ibm_db_specific_schema.rb +133 -0
  23. data/test/schema/schema.rb +432 -0
  24. data/test/schema/zOS/ibm_db_specific_schema.rb +204 -0
  25. metadata +29 -33
  26. data/test/associations_test.rb +0 -2151
  27. data/test/fixtures/db_definitions/i5/ibm_db.drop.sql +0 -33
  28. data/test/fixtures/db_definitions/i5/ibm_db.sql +0 -236
  29. data/test/fixtures/db_definitions/i5/ibm_db2.drop.sql +0 -2
  30. data/test/fixtures/db_definitions/i5/ibm_db2.sql +0 -5
  31. data/test/fixtures/db_definitions/ids/ibm_db.drop.sql +0 -33
  32. data/test/fixtures/db_definitions/ids/ibm_db.sql +0 -237
  33. data/test/fixtures/db_definitions/ids/ibm_db2.drop.sql +0 -2
  34. data/test/fixtures/db_definitions/ids/ibm_db2.sql +0 -5
  35. data/test/fixtures/db_definitions/luw/ibm_db.drop.sql +0 -33
  36. data/test/fixtures/db_definitions/luw/ibm_db.sql +0 -236
  37. data/test/fixtures/db_definitions/luw/ibm_db2.drop.sql +0 -2
  38. data/test/fixtures/db_definitions/luw/ibm_db2.sql +0 -5
  39. data/test/fixtures/db_definitions/schema.rb +0 -361
  40. data/test/fixtures/db_definitions/zOS/ibm_db.drop.sql +0 -33
  41. data/test/fixtures/db_definitions/zOS/ibm_db.sql +0 -288
  42. data/test/fixtures/db_definitions/zOS/ibm_db2.drop.sql +0 -2
  43. data/test/fixtures/db_definitions/zOS/ibm_db2.sql +0 -7
  44. data/test/locking_test.rb +0 -282
@@ -1,17 +1,19 @@
1
- require 'abstract_unit'
1
+ require "cases/helper"
2
2
  require 'bigdecimal/util'
3
3
 
4
- require 'fixtures/person'
5
- require 'fixtures/topic'
6
- require File.dirname(__FILE__) + '/fixtures/migrations/1_people_have_last_names'
7
- require File.dirname(__FILE__) + '/fixtures/migrations/2_we_need_reminders'
8
- require File.dirname(__FILE__) + '/fixtures/migrations_with_decimal/1_give_me_big_numbers'
4
+ require 'models/person'
5
+ require 'models/topic'
6
+
7
+ require MIGRATIONS_ROOT + "/valid/1_people_have_last_names"
8
+ require MIGRATIONS_ROOT + "/valid/2_we_need_reminders"
9
+ require MIGRATIONS_ROOT + "/decimal/1_give_me_big_numbers"
10
+ require MIGRATIONS_ROOT + "/interleaved/pass_3/2_i_raise_on_down"
9
11
 
10
12
  if ActiveRecord::Base.connection.supports_migrations?
11
13
  class BigNumber < ActiveRecord::Base; end
12
-
14
+
13
15
  class Reminder < ActiveRecord::Base; end
14
-
16
+
15
17
  class ActiveRecord::Migration
16
18
  class <<self
17
19
  attr_accessor :message_count
@@ -22,9 +24,9 @@ if ActiveRecord::Base.connection.supports_migrations?
22
24
  end
23
25
  end
24
26
 
25
- class IBMDBMigrationTest < Test::Unit::TestCase
27
+ class MigrationTest < ActiveRecord::TestCase
26
28
  self.use_transactional_fixtures = false
27
-
29
+
28
30
  fixtures :people
29
31
 
30
32
  def setup
@@ -33,8 +35,8 @@ if ActiveRecord::Base.connection.supports_migrations?
33
35
  end
34
36
 
35
37
  def teardown
36
- ActiveRecord::Base.connection.initialize_schema_information
37
- ActiveRecord::Base.connection.update "UPDATE #{ActiveRecord::Migrator.schema_info_table_name} SET version = 0"
38
+ ActiveRecord::Base.connection.initialize_schema_migrations_table
39
+ ActiveRecord::Base.connection.execute "DELETE FROM #{ActiveRecord::Migrator.schema_migrations_table_name}"
38
40
 
39
41
  %w(reminders people_reminders prefix_reminders_suffix).each do |table|
40
42
  Reminder.connection.drop_table(table) rescue nil
@@ -46,8 +48,8 @@ if ActiveRecord::Base.connection.supports_migrations?
46
48
  Person.connection.remove_column('people', column) rescue nil
47
49
  end
48
50
  Person.connection.remove_column("people", "first_name") rescue nil
49
- Person.connection.remove_column("people", "middle_name") rescue nil
50
- Person.connection.add_column("people", "first_name", :string, :limit => 40)
51
+ Person.connection.remove_column("people", "middle_name") rescue nil
52
+ Person.connection.add_column("people", "first_name", :string, :limit => 40)
51
53
  Person.reset_column_information
52
54
  end
53
55
 
@@ -77,10 +79,15 @@ if ActiveRecord::Base.connection.supports_migrations?
77
79
  # Note: changed index name from "key" to "key_idx" since "key" is a Firebird reserved word
78
80
  # OpenBase does not have named indexes. You must specify a single column name
79
81
  unless current_adapter?(:OpenBaseAdapter)
82
+ unless current_adapter?(:IBM_DBAdapter)
83
+ Person.update_all "#{Person.connection.quote_column_name 'key'}=#{Person.connection.quote_column_name 'id'}" #some databases (including sqlite2 won't add a unique index if existing data non unique)
84
+ else
85
+ Person.update_all "#{Person.connection.quote_column_name 'key'}=#{Person.connection.quote_column_name 'first_name'}" #some databases (including sqlite2 won't add a unique index if existing data non unique)
86
+ end
80
87
  assert_nothing_raised { Person.connection.add_index("people", ["key"], :name => "key_idx", :unique => true) }
81
88
  assert_nothing_raised { Person.connection.remove_index("people", :name => "key_idx", :unique => true) }
82
89
  end
83
-
90
+
84
91
  # Sybase adapter does not support indexes on :boolean columns
85
92
  # OpenBase does not have named indexes. You must specify a single column
86
93
  unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
@@ -116,10 +123,10 @@ if ActiveRecord::Base.connection.supports_migrations?
116
123
 
117
124
  def test_create_table_with_defaults
118
125
  # MySQL doesn't allow defaults on TEXT or BLOB columns.
119
- mysql = current_adapter?(:MysqlAdapter)
126
+ mysql = current_adapter?(:MysqlAdapter)
120
127
  ibm_ids_zOS = ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_IDS')||
121
128
  ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_DB2_ZOS')
122
-
129
+
123
130
  Person.connection.create_table :testings do |t|
124
131
  t.column :one, :string, :default => "hello"
125
132
  t.column :two, :boolean, :default => true
@@ -145,9 +152,7 @@ if ActiveRecord::Base.connection.supports_migrations?
145
152
  Person.connection.drop_table :testings rescue nil
146
153
  end
147
154
 
148
- # IBM data servers do not support limits on certain data types (unlike MySQL)
149
- # Limit is supported for the {float, decimal, numeric, varchar, clob, blob} data types.
150
- if current_adapter?(:IBM_DBAdapter)
155
+ if current_adapter?(:IBM_DBAdapter)
151
156
  def test_no_limits_datatypes_IBM_DB
152
157
  clasz = Class.new(ActiveRecord::Base)
153
158
  clasz.table_name = 'test_no_limits_datatypes_IBM_DB'
@@ -181,7 +186,7 @@ if ActiveRecord::Base.connection.supports_migrations?
181
186
  clasz.connection.drop_table(clasz.table_name) rescue nil
182
187
  end
183
188
  end
184
-
189
+
185
190
  def test_create_table_with_limits
186
191
  assert_nothing_raised do
187
192
  Person.connection.create_table :testings do |t|
@@ -219,6 +224,51 @@ if ActiveRecord::Base.connection.supports_migrations?
219
224
  Person.connection.drop_table :testings rescue nil
220
225
  end
221
226
 
227
+ def test_create_table_with_primary_key_prefix_as_table_name_with_underscore
228
+ ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
229
+
230
+ Person.connection.create_table :testings do |t|
231
+ t.column :foo, :string
232
+ end
233
+
234
+ assert_equal %w(foo testings_id), Person.connection.columns(:testings).map { |c| c.name }.sort
235
+ ensure
236
+ Person.connection.drop_table :testings rescue nil
237
+ ActiveRecord::Base.primary_key_prefix_type = nil
238
+ end
239
+
240
+ def test_create_table_with_primary_key_prefix_as_table_name
241
+ ActiveRecord::Base.primary_key_prefix_type = :table_name
242
+
243
+ Person.connection.create_table :testings do |t|
244
+ t.column :foo, :string
245
+ end
246
+
247
+ assert_equal %w(foo testingsid), Person.connection.columns(:testings).map { |c| c.name }.sort
248
+ ensure
249
+ Person.connection.drop_table :testings rescue nil
250
+ ActiveRecord::Base.primary_key_prefix_type = nil
251
+ end
252
+
253
+ uses_mocha('test_create_table_with_force_true_does_not_drop_nonexisting_table') do
254
+ def test_create_table_with_force_true_does_not_drop_nonexisting_table
255
+ if Person.connection.table_exists?(:testings2)
256
+ Person.connection.drop_table :testings2
257
+ end
258
+
259
+ # using a copy as we need the drop_table method to
260
+ # continue to work for the ensure block of the test
261
+ temp_conn = Person.connection.dup
262
+ temp_conn.expects(:drop_table).never
263
+ temp_conn.create_table :testings2, :force => true do |t|
264
+ t.column :foo, :string
265
+ end
266
+ ensure
267
+ Person.connection.drop_table :testings2 rescue nil
268
+ end
269
+ end
270
+
271
+
222
272
  # SQL Server, Sybase, and SQLite3 will not allow you to add a NOT NULL
223
273
  # column to a table without a default value.
224
274
  unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :SQLiteAdapter, :IBM_DBAdapter)
@@ -240,8 +290,8 @@ if ActiveRecord::Base.connection.supports_migrations?
240
290
  Person.connection.create_table :testings do |t|
241
291
  t.column :foo, :string
242
292
  end
243
-
244
- con = Person.connection
293
+
294
+ con = Person.connection
245
295
  Person.connection.enable_identity_insert("testings", true) if current_adapter?(:SybaseAdapter)
246
296
  Person.connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}) values (1, 'hello')"
247
297
  Person.connection.enable_identity_insert("testings", false) if current_adapter?(:SybaseAdapter)
@@ -272,7 +322,7 @@ if ActiveRecord::Base.connection.supports_migrations?
272
322
  # Do a manual insertion
273
323
  if current_adapter?(:OracleAdapter)
274
324
  Person.connection.execute "insert into people (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)"
275
- elsif current_adapter?(:OpenBaseAdapter)
325
+ elsif current_adapter?(:OpenBaseAdapter) || (current_adapter?(:MysqlAdapter) && Mysql.client_version < 50003) #before mysql 5.0.3 decimals stored as strings
276
326
  Person.connection.execute "insert into people (wealth) values ('12345678901234567890.0123456789')"
277
327
  else
278
328
  Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)"
@@ -307,6 +357,15 @@ if ActiveRecord::Base.connection.supports_migrations?
307
357
  Person.reset_column_information
308
358
  end
309
359
 
360
+ def test_add_column_with_precision_and_scale
361
+ Person.connection.add_column 'people', 'wealth', :decimal, :precision => 9, :scale => 7
362
+ Person.reset_column_information
363
+
364
+ wealth_column = Person.columns_hash['wealth']
365
+ assert_equal 9, wealth_column.precision
366
+ assert_equal 7, wealth_column.scale
367
+ end
368
+
310
369
  def test_native_types
311
370
  Person.delete_all
312
371
  Person.connection.add_column "people", "last_name", :string
@@ -336,11 +395,11 @@ if ActiveRecord::Base.connection.supports_migrations?
336
395
 
337
396
  # Test for 30 significent digits (beyond the 16 of float), 10 of them
338
397
  # after the decimal place.
339
-
398
+
340
399
  unless current_adapter?(:SQLite3Adapter)
341
400
  assert_equal BigDecimal.new("0012345678901234567890.0123456789"), bob.wealth
342
401
  end
343
-
402
+
344
403
  assert_equal true, bob.male?
345
404
 
346
405
  assert_equal String, bob.first_name.class
@@ -359,10 +418,16 @@ if ActiveRecord::Base.connection.supports_migrations?
359
418
  # Test DateTime column and defaults, including timezone.
360
419
  # FIXME: moment of truth may be Time on 64-bit platforms.
361
420
  if bob.moment_of_truth.is_a?(DateTime)
362
- assert_equal DateTime.now.offset, bob.moment_of_truth.offset
363
- assert_not_equal 0, bob.moment_of_truth.offset
364
- assert_not_equal "Z", bob.moment_of_truth.zone
365
- assert_equal DateTime::ITALY, bob.moment_of_truth.start
421
+
422
+ with_env_tz 'US/Eastern' do
423
+ assert_equal DateTime.local_offset, bob.moment_of_truth.offset
424
+ assert_not_equal 0, bob.moment_of_truth.offset
425
+ assert_not_equal "Z", bob.moment_of_truth.zone
426
+ # US/Eastern is -5 hours from GMT
427
+ assert_equal Rational(-5, 24), bob.moment_of_truth.offset
428
+ assert_match /\A-05:?00\Z/, bob.moment_of_truth.zone #ruby 1.8.6 uses HH:MM, prior versions use HHMM
429
+ assert_equal DateTime::ITALY, bob.moment_of_truth.start
430
+ end
366
431
  end
367
432
 
368
433
  assert_equal TrueClass, bob.male?.class
@@ -376,7 +441,7 @@ if ActiveRecord::Base.connection.supports_migrations?
376
441
  ActiveRecord::Migration.add_column :people, :intelligence_quotient, :tinyint
377
442
  Person.reset_column_information
378
443
  Person.create :intelligence_quotient => 300
379
- jonnyg = Person.find(:first)
444
+ jonnyg = Person.find(:first)
380
445
  assert_equal 127, jonnyg.intelligence_quotient
381
446
  jonnyg.destroy
382
447
  ensure
@@ -415,13 +480,14 @@ if ActiveRecord::Base.connection.supports_migrations?
415
480
  unless current_adapter?(:IBM_DBAdapter) # rename not supported
416
481
  def test_add_rename
417
482
  Person.delete_all
483
+
418
484
  begin
419
485
  Person.connection.add_column "people", "girlfriend", :string
420
486
  Person.reset_column_information
421
487
  Person.create :girlfriend => 'bobette'
422
-
423
- Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
424
488
 
489
+ Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
490
+
425
491
  Person.reset_column_information
426
492
  bob = Person.find(:first)
427
493
 
@@ -430,10 +496,9 @@ if ActiveRecord::Base.connection.supports_migrations?
430
496
  Person.connection.remove_column("people", "girlfriend") rescue nil
431
497
  Person.connection.remove_column("people", "exgirlfriend") rescue nil
432
498
  end
499
+
433
500
  end
434
- end
435
501
 
436
- unless current_adapter?(:IBM_DBAdapter) # rename not supported
437
502
  def test_rename_column_using_symbol_arguments
438
503
  begin
439
504
  names_before = Person.find(:all).map(&:first_name)
@@ -446,24 +511,20 @@ if ActiveRecord::Base.connection.supports_migrations?
446
511
  Person.connection.add_column("people","first_name", :string)
447
512
  end
448
513
  end
449
- end
450
514
 
451
- unless current_adapter?(:IBM_DBAdapter) # rename not supported
452
515
  def test_rename_column
453
- begin
454
- names_before = Person.find(:all).map(&:first_name)
455
- Person.connection.rename_column "people", "first_name", "nick_name"
456
- Person.reset_column_information
457
- assert Person.column_names.include?("nick_name")
458
- assert_equal names_before, Person.find(:all).map(&:nick_name)
459
- ensure
460
- Person.connection.remove_column("people","nick_name")
461
- Person.connection.add_column("people","first_name", :string)
462
- end
516
+ begin
517
+ names_before = Person.find(:all).map(&:first_name)
518
+ Person.connection.rename_column "people", "first_name", "nick_name"
519
+ Person.reset_column_information
520
+ assert Person.column_names.include?("nick_name")
521
+ assert_equal names_before, Person.find(:all).map(&:nick_name)
522
+ ensure
523
+ Person.connection.remove_column("people","nick_name")
524
+ Person.connection.add_column("people","first_name", :string)
525
+ end
463
526
  end
464
- end
465
527
 
466
- unless current_adapter?(:IBM_DBAdapter) # rename not supported
467
528
  def test_rename_column_with_sql_reserved_word
468
529
  begin
469
530
  assert_nothing_raised { Person.connection.rename_column "people", "first_name", "group" }
@@ -474,16 +535,54 @@ if ActiveRecord::Base.connection.supports_migrations?
474
535
  Person.connection.add_column("people", "first_name", :string) rescue nil
475
536
  end
476
537
  end
538
+
539
+ def test_rename_column_with_an_index
540
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
541
+ table.column :hat_name, :string, :limit => 100
542
+ table.column :hat_size, :integer
543
+ end
544
+ Person.connection.add_index :hats, :hat_name
545
+ assert_nothing_raised do
546
+ Person.connection.rename_column "hats", "hat_name", "name"
547
+ end
548
+ ensure
549
+ ActiveRecord::Base.connection.drop_table(:hats)
550
+ end
477
551
  end
478
-
552
+
553
+ def test_remove_column_with_index
554
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
555
+ table.column :hat_name, :string, :limit => 100
556
+ table.column :hat_size, :integer
557
+ end
558
+ ActiveRecord::Base.connection.add_index "hats", "hat_size"
559
+
560
+ assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
561
+ ensure
562
+ ActiveRecord::Base.connection.drop_table(:hats)
563
+ end
564
+
565
+ def test_remove_column_with_multi_column_index
566
+ ActiveRecord::Base.connection.create_table(:hats) do |table|
567
+ table.column :hat_name, :string, :limit => 100
568
+ table.column :hat_size, :integer
569
+ table.column :hat_style, :string, :limit => 100
570
+ end
571
+ ActiveRecord::Base.connection.add_index "hats", ["hat_style", "hat_size"], :unique => true
572
+
573
+ assert_nothing_raised { Person.connection.remove_column("hats", "hat_size") }
574
+ ensure
575
+ ActiveRecord::Base.connection.drop_table(:hats)
576
+ end
577
+
479
578
  unless current_adapter?(:IBM_DBAdapter) #incompatible types changes
480
579
  def test_change_type_of_not_null_column
481
580
  assert_nothing_raised do
482
- Topic.connection.change_column "topics", "written_on", :datetime, :null => false
483
- Topic.reset_column_information
484
-
485
- Topic.connection.change_column "topics", "written_on", :datetime, :null => false
486
- Topic.reset_column_information
581
+ Topic.connection.change_column "topics", "written_on", :datetime, :null => false
582
+ Topic.reset_column_information
583
+
584
+ Topic.connection.change_column "topics", "written_on", :datetime, :null => false
585
+ Topic.reset_column_information
487
586
  end
488
587
  end
489
588
  end
@@ -496,7 +595,7 @@ if ActiveRecord::Base.connection.supports_migrations?
496
595
  ActiveRecord::Base.connection.rename_table :octopuses, :octopi
497
596
 
498
597
  # Using explicit id in insert for compatibility across all databases
499
- con = ActiveRecord::Base.connection
598
+ con = ActiveRecord::Base.connection
500
599
  con.enable_identity_insert("octopi", true) if current_adapter?(:SybaseAdapter)
501
600
  assert_nothing_raised { con.execute "INSERT INTO octopi (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" }
502
601
  con.enable_identity_insert("octopi", false) if current_adapter?(:SybaseAdapter)
@@ -508,20 +607,20 @@ if ActiveRecord::Base.connection.supports_migrations?
508
607
  ActiveRecord::Base.connection.drop_table :octopi rescue nil
509
608
  end
510
609
  end
511
-
610
+
512
611
  def test_change_column_nullability
513
- Person.delete_all
612
+ Person.delete_all
514
613
  Person.connection.add_column "people", "funny", :boolean
515
614
  Person.reset_column_information
516
615
  assert Person.columns_hash["funny"].null, "Column 'funny' must initially allow nulls"
517
- unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
518
- Person.connection.change_column "people", "funny", :boolean, :null => false, :default => true
519
- Person.reset_column_information
520
- assert !Person.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"
521
- Person.connection.change_column "people", "funny", :boolean, :null => true
522
- Person.reset_column_information
523
- assert Person.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
524
- end
616
+ unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
617
+ Person.connection.change_column "people", "funny", :boolean, :null => false, :default => true
618
+ Person.reset_column_information
619
+ assert !Person.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"
620
+ Person.connection.change_column "people", "funny", :boolean, :null => true
621
+ Person.reset_column_information
622
+ assert Person.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
623
+ end
525
624
  end
526
625
 
527
626
  def test_rename_table_with_an_index
@@ -530,11 +629,11 @@ if ActiveRecord::Base.connection.supports_migrations?
530
629
  t.column :url, :string
531
630
  end
532
631
  ActiveRecord::Base.connection.add_index :octopuses, :url
533
-
632
+
534
633
  ActiveRecord::Base.connection.rename_table :octopuses, :octopi
535
634
 
536
635
  # Using explicit id in insert for compatibility across all databases
537
- con = ActiveRecord::Base.connection
636
+ con = ActiveRecord::Base.connection
538
637
  con.enable_identity_insert("octopi", true) if current_adapter?(:SybaseAdapter)
539
638
  assert_nothing_raised { con.execute "INSERT INTO octopi (#{con.quote_column_name('id')}, #{con.quote_column_name('url')}) VALUES (1, 'http://www.foreverflying.com/octopus-black7.jpg')" }
540
639
  con.enable_identity_insert("octopi", false) if current_adapter?(:SybaseAdapter)
@@ -552,9 +651,9 @@ if ActiveRecord::Base.connection.supports_migrations?
552
651
  Person.connection.add_column 'people', 'age', :integer
553
652
  old_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
554
653
  assert old_columns.find { |c| c.name == 'age' and c.type == :integer }
555
-
654
+
556
655
  assert_nothing_raised { Person.connection.change_column "people", "age", :string }
557
-
656
+
558
657
  new_columns = Person.connection.columns(Person.table_name, "#{name} Columns")
559
658
  assert_nil new_columns.find { |c| c.name == 'age' and c.type == :integer }
560
659
  assert new_columns.find { |c| c.name == 'age' and c.type == :string }
@@ -568,18 +667,17 @@ if ActiveRecord::Base.connection.supports_migrations?
568
667
  assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => true }
569
668
  end
570
669
  end
571
-
670
+
572
671
  def test_change_column_with_nil_default
573
672
  Person.connection.add_column "people", "contributor", :boolean, :default => true
574
673
  Person.reset_column_information
575
674
  assert Person.new.contributor?
576
-
577
675
  unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
578
676
  assert_nothing_raised { Person.connection.change_column "people", "contributor", :boolean, :default => nil }
579
677
  Person.reset_column_information
580
678
  assert !Person.new.contributor?
581
679
  assert_nil Person.new.contributor
582
- end
680
+ end
583
681
  ensure
584
682
  Person.connection.remove_column("people", "contributor") rescue nil
585
683
  end
@@ -588,16 +686,15 @@ if ActiveRecord::Base.connection.supports_migrations?
588
686
  Person.connection.add_column "people", "administrator", :boolean, :default => true
589
687
  Person.reset_column_information
590
688
  assert Person.new.administrator?
591
-
592
- unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
593
- assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => false }
594
- Person.reset_column_information
595
- assert !Person.new.administrator?
596
- end
689
+ unless current_adapter?(:IBM_DBAdapter) # incompatible types changes
690
+ assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => false }
691
+ Person.reset_column_information
692
+ assert !Person.new.administrator?
693
+ end
597
694
  ensure
598
695
  Person.connection.remove_column("people", "administrator") rescue nil
599
696
  end
600
-
697
+
601
698
  def test_change_column_default
602
699
  Person.connection.change_column_default "people", "first_name", "Tester"
603
700
  Person.reset_column_information
@@ -608,9 +705,10 @@ if ActiveRecord::Base.connection.supports_migrations?
608
705
  Person.connection.create_table :testings do |t|
609
706
  t.column :select, :string
610
707
  end
611
- unless current_adapter?(:IBM_DBAdapter) # altering a string column to size lesser than the previous not allowed
612
- assert_nothing_raised { Person.connection.change_column :testings, :select, :string, :limit => 10 }
613
- end
708
+ unless current_adapter?(:IBM_DBAdapter) # altering a string column to size
709
+ assert_nothing_raised { Person.connection.change_column :testings, :select, :string, :limit => 10 }
710
+ end
711
+
614
712
  assert_nothing_raised { Person.connection.execute "insert into testings (#{Person.connection.quote_column_name('select')}) values ('7 chars')" }
615
713
  ensure
616
714
  Person.connection.drop_table :testings rescue nil
@@ -626,8 +724,8 @@ if ActiveRecord::Base.connection.supports_migrations?
626
724
  assert !Reminder.table_exists?
627
725
 
628
726
  WeNeedReminders.up
629
-
630
- assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
727
+
728
+ assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
631
729
  assert_equal "hello world", Reminder.find(:first).content
632
730
 
633
731
  WeNeedReminders.down
@@ -659,17 +757,17 @@ if ActiveRecord::Base.connection.supports_migrations?
659
757
 
660
758
  # TODO: set world_population >= 2**62 to cover 64-bit platforms and test
661
759
  # is_a?(Bignum)
662
- unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
663
- assert_kind_of Integer, b.world_population
664
- else
665
- assert_kind_of BigDecimal, b.world_population
666
- end
760
+ unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
761
+ assert_kind_of Integer, b.world_population
762
+ else
763
+ assert_kind_of BigDecimal, b.world_population
764
+ end
667
765
  assert_equal 6000000000, b.world_population
668
- unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
669
- assert_kind_of Fixnum, b.my_house_population
670
- else
671
- assert_kind_of BigDecimal, b.my_house_population
672
- end
766
+ unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
767
+ assert_kind_of Fixnum, b.my_house_population
768
+ else
769
+ assert_kind_of BigDecimal, b.my_house_population
770
+ end
673
771
  assert_equal 3, b.my_house_population
674
772
  assert_kind_of BigDecimal, b.bank_balance
675
773
  assert_equal BigDecimal("1586.43"), b.bank_balance
@@ -699,11 +797,11 @@ if ActiveRecord::Base.connection.supports_migrations?
699
797
  assert_equal 3, b.value_of_e
700
798
  else
701
799
  # - SQL standard is an integer
702
- unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
703
- assert_kind_of Fixnum, b.value_of_e
704
- else
705
- assert_kind_of BigDecimal, b.value_of_e
706
- end
800
+ unless current_adapter?(:IBM_DBAdapter) # incompatible types retrieved
801
+ assert_kind_of Fixnum, b.value_of_e
802
+ else
803
+ assert_kind_of BigDecimal, b.value_of_e
804
+ end
707
805
  assert_equal 2, b.value_of_e
708
806
  end
709
807
 
@@ -715,7 +813,7 @@ if ActiveRecord::Base.connection.supports_migrations?
715
813
  assert !Person.column_methods_hash.include?(:last_name)
716
814
  assert !Reminder.table_exists?
717
815
 
718
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
816
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid")
719
817
 
720
818
  assert_equal 3, ActiveRecord::Migrator.current_version
721
819
  Person.reset_column_information
@@ -723,7 +821,7 @@ if ActiveRecord::Base.connection.supports_migrations?
723
821
  assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
724
822
  assert_equal "hello world", Reminder.find(:first).content
725
823
 
726
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/')
824
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid")
727
825
 
728
826
  assert_equal 0, ActiveRecord::Migrator.current_version
729
827
  Person.reset_column_information
@@ -735,78 +833,145 @@ if ActiveRecord::Base.connection.supports_migrations?
735
833
  assert !Person.column_methods_hash.include?(:last_name)
736
834
  assert !Reminder.table_exists?
737
835
 
738
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
836
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
739
837
 
740
838
  Person.reset_column_information
741
839
  assert Person.column_methods_hash.include?(:last_name)
742
840
  assert !Reminder.table_exists?
743
841
 
744
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 2)
842
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 2)
745
843
 
746
844
  assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
747
845
  assert_equal "hello world", Reminder.find(:first).content
748
846
  end
749
847
 
750
848
  def test_migrator_one_down
751
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/')
752
-
753
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
754
-
849
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid")
850
+
851
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 1)
852
+
755
853
  Person.reset_column_information
756
854
  assert Person.column_methods_hash.include?(:last_name)
757
855
  assert !Reminder.table_exists?
758
856
  end
759
857
 
760
858
  def test_migrator_one_up_one_down
761
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
762
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
859
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
860
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
763
861
 
764
862
  assert !Person.column_methods_hash.include?(:last_name)
765
863
  assert !Reminder.table_exists?
766
864
  end
767
865
 
866
+ def test_finds_migrations
867
+ migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/valid").migrations
868
+ [['1', 'people_have_last_names'],
869
+ ['2', 'we_need_reminders'],
870
+ ['3', 'innocent_jointable']].each_with_index do |pair, i|
871
+ migrations[i].version == pair.first
872
+ migrations[1].name == pair.last
873
+ end
874
+ end
875
+
876
+ def test_finds_pending_migrations
877
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2", 1)
878
+ migrations = ActiveRecord::Migrator.new(:up, MIGRATIONS_ROOT + "/interleaved/pass_2").pending_migrations
879
+ assert_equal 1, migrations.size
880
+ migrations[0].version == '3'
881
+ migrations[0].name == 'innocent_jointable'
882
+ end
883
+
884
+ def test_migrator_interleaved_migrations
885
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_1")
886
+
887
+ assert_nothing_raised do
888
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/interleaved/pass_2")
889
+ end
890
+
891
+ Person.reset_column_information
892
+ assert Person.column_methods_hash.include?(:last_name)
893
+
894
+ assert_nothing_raised do
895
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/interleaved/pass_3")
896
+ end
897
+ end
898
+
899
+ def test_migrator_db_has_no_schema_migrations_table
900
+ ActiveRecord::Base.connection.execute("DROP TABLE schema_migrations;")
901
+ assert_nothing_raised do
902
+ ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 1)
903
+ end
904
+ end
905
+
768
906
  def test_migrator_verbosity
769
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
907
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
770
908
  assert PeopleHaveLastNames.message_count > 0
771
909
  PeopleHaveLastNames.message_count = 0
772
910
 
773
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
911
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
774
912
  assert PeopleHaveLastNames.message_count > 0
775
913
  PeopleHaveLastNames.message_count = 0
776
914
  end
777
915
 
778
916
  def test_migrator_verbosity_off
779
917
  PeopleHaveLastNames.verbose = false
780
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
918
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
781
919
  assert PeopleHaveLastNames.message_count.zero?
782
- ActiveRecord::Migrator.down(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
920
+ ActiveRecord::Migrator.down(MIGRATIONS_ROOT + "/valid", 0)
783
921
  assert PeopleHaveLastNames.message_count.zero?
784
922
  end
785
923
 
786
924
  def test_migrator_going_down_due_to_version_target
787
- ActiveRecord::Migrator.up(File.dirname(__FILE__) + '/fixtures/migrations/', 1)
788
- ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/', 0)
925
+ ActiveRecord::Migrator.up(MIGRATIONS_ROOT + "/valid", 1)
926
+ ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid", 0)
789
927
 
790
928
  assert !Person.column_methods_hash.include?(:last_name)
791
929
  assert !Reminder.table_exists?
792
930
 
793
- ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations/')
931
+ ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid")
794
932
 
795
933
  Person.reset_column_information
796
934
  assert Person.column_methods_hash.include?(:last_name)
797
935
  assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
798
936
  assert_equal "hello world", Reminder.find(:first).content
799
937
  end
938
+
939
+ def test_migrator_rollback
940
+ ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/valid")
941
+ assert_equal(3, ActiveRecord::Migrator.current_version)
942
+
943
+ ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
944
+ assert_equal(2, ActiveRecord::Migrator.current_version)
945
+
946
+ ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
947
+ assert_equal(1, ActiveRecord::Migrator.current_version)
948
+
949
+ ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
950
+ assert_equal(0, ActiveRecord::Migrator.current_version)
951
+
952
+ ActiveRecord::Migrator.rollback(MIGRATIONS_ROOT + "/valid")
953
+ assert_equal(0, ActiveRecord::Migrator.current_version)
954
+ end
955
+
956
+ def test_migrator_run
957
+ assert_equal(0, ActiveRecord::Migrator.current_version)
958
+ ActiveRecord::Migrator.run(:up, MIGRATIONS_ROOT + "/valid", 3)
959
+ assert_equal(0, ActiveRecord::Migrator.current_version)
960
+
961
+ assert_equal(0, ActiveRecord::Migrator.current_version)
962
+ ActiveRecord::Migrator.run(:down, MIGRATIONS_ROOT + "/valid", 3)
963
+ assert_equal(0, ActiveRecord::Migrator.current_version)
964
+ end
800
965
 
801
- def test_schema_info_table_name
966
+ def test_schema_migrations_table_name
802
967
  ActiveRecord::Base.table_name_prefix = "prefix_"
803
968
  ActiveRecord::Base.table_name_suffix = "_suffix"
804
969
  Reminder.reset_table_name
805
- assert_equal "prefix_schema_info_suffix", ActiveRecord::Migrator.schema_info_table_name
970
+ assert_equal "prefix_schema_migrations_suffix", ActiveRecord::Migrator.schema_migrations_table_name
806
971
  ActiveRecord::Base.table_name_prefix = ""
807
972
  ActiveRecord::Base.table_name_suffix = ""
808
973
  Reminder.reset_table_name
809
- assert_equal "schema_info", ActiveRecord::Migrator.schema_info_table_name
974
+ assert_equal "schema_migrations", ActiveRecord::Migrator.schema_migrations_table_name
810
975
  ensure
811
976
  ActiveRecord::Base.table_name_prefix = ""
812
977
  ActiveRecord::Base.table_name_suffix = ""
@@ -850,6 +1015,7 @@ if ActiveRecord::Base.connection.supports_migrations?
850
1015
  WeNeedReminders.up
851
1016
  assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
852
1017
  assert_equal "hello world", Reminder.find(:first).content
1018
+
853
1019
  WeNeedReminders.down
854
1020
  assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
855
1021
  ensure
@@ -871,31 +1037,27 @@ if ActiveRecord::Base.connection.supports_migrations?
871
1037
  columns = Person.connection.columns(:binary_testings)
872
1038
  data_column = columns.detect { |c| c.name == "data" }
873
1039
 
874
- if current_adapter?(:MysqlAdapter)
875
- assert_equal '', data_column.default
876
- else
877
- assert_nil data_column.default
878
- end
1040
+ assert_nil data_column.default
879
1041
 
880
1042
  Person.connection.drop_table :binary_testings rescue nil
881
1043
  end
882
1044
 
883
1045
  def test_migrator_with_duplicates
884
1046
  assert_raises(ActiveRecord::DuplicateMigrationVersionError) do
885
- ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_duplicate/', nil)
1047
+ ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate", nil)
1048
+ end
1049
+ end
1050
+
1051
+ def test_migrator_with_duplicate_names
1052
+ assert_raises(ActiveRecord::DuplicateMigrationNameError, "Multiple migrations have the name Chunky") do
1053
+ ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/duplicate_names", nil)
886
1054
  end
887
1055
  end
888
1056
 
889
1057
  def test_migrator_with_missing_version_numbers
890
- ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_missing_versions/', 500)
891
- assert !Person.column_methods_hash.include?(:middle_name)
892
- assert_equal 4, ActiveRecord::Migrator.current_version
893
-
894
- ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_missing_versions/', 2)
895
- Person.reset_column_information
896
- assert !Reminder.table_exists?
897
- assert Person.column_methods_hash.include?(:last_name)
898
- assert_equal 2, ActiveRecord::Migrator.current_version
1058
+ assert_raise(ActiveRecord::UnknownMigrationVersionError) do
1059
+ ActiveRecord::Migrator.migrate(MIGRATIONS_ROOT + "/missing", 500)
1060
+ end
899
1061
  end
900
1062
 
901
1063
  def test_create_table_with_custom_sequence_name
@@ -934,17 +1096,26 @@ if ActiveRecord::Base.connection.supports_migrations?
934
1096
  Person.connection.execute("select suitably_short_seq.nextval from dual")
935
1097
  end
936
1098
  end
937
- end
938
1099
 
1100
+ protected
1101
+ def with_env_tz(new_tz = 'US/Eastern')
1102
+ old_tz, ENV['TZ'] = ENV['TZ'], new_tz
1103
+ yield
1104
+ ensure
1105
+ old_tz ? ENV['TZ'] = old_tz : ENV.delete('TZ')
1106
+ end
1107
+
1108
+ end
1109
+
939
1110
  uses_mocha 'Sexy migration tests' do
940
- class IBMDBSexyMigrationsTest < Test::Unit::TestCase
1111
+ class SexyMigrationsTest < ActiveRecord::TestCase
941
1112
  def test_references_column_type_adds_id
942
1113
  with_new_table do |t|
943
1114
  t.expects(:column).with('customer_id', :integer, {})
944
1115
  t.references :customer
945
1116
  end
946
1117
  end
947
-
1118
+
948
1119
  def test_references_column_type_with_polymorphic_adds_type
949
1120
  with_new_table do |t|
950
1121
  t.expects(:column).with('taggable_type', :string, {})
@@ -952,14 +1123,22 @@ if ActiveRecord::Base.connection.supports_migrations?
952
1123
  t.references :taggable, :polymorphic => true
953
1124
  end
954
1125
  end
955
-
1126
+
1127
+ def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag
1128
+ with_new_table do |t|
1129
+ t.expects(:column).with('taggable_type', :string, {:null => false})
1130
+ t.expects(:column).with('taggable_id', :integer, {:null => false})
1131
+ t.references :taggable, :polymorphic => true, :null => false
1132
+ end
1133
+ end
1134
+
956
1135
  def test_belongs_to_works_like_references
957
1136
  with_new_table do |t|
958
1137
  t.expects(:column).with('customer_id', :integer, {})
959
1138
  t.belongs_to :customer
960
1139
  end
961
1140
  end
962
-
1141
+
963
1142
  def test_timestamps_creates_updated_at_and_created_at
964
1143
  with_new_table do |t|
965
1144
  t.expects(:column).with(:created_at, :datetime)
@@ -967,7 +1146,7 @@ if ActiveRecord::Base.connection.supports_migrations?
967
1146
  t.timestamps
968
1147
  end
969
1148
  end
970
-
1149
+
971
1150
  def test_integer_creates_integer_column
972
1151
  with_new_table do |t|
973
1152
  t.expects(:column).with(:foo, 'integer', {})
@@ -975,7 +1154,7 @@ if ActiveRecord::Base.connection.supports_migrations?
975
1154
  t.integer :foo, :bar
976
1155
  end
977
1156
  end
978
-
1157
+
979
1158
  def test_string_creates_string_column
980
1159
  with_new_table do |t|
981
1160
  t.expects(:column).with(:foo, 'string', {})
@@ -983,17 +1162,222 @@ if ActiveRecord::Base.connection.supports_migrations?
983
1162
  t.string :foo, :bar
984
1163
  end
985
1164
  end
986
-
1165
+
987
1166
  protected
988
1167
  def with_new_table
989
- Person.connection.create_table :delete_me do |t|
1168
+ Person.connection.create_table :delete_me, :force => true do |t|
990
1169
  yield t
991
1170
  end
992
1171
  ensure
993
1172
  Person.connection.drop_table :delete_me rescue nil
994
1173
  end
995
-
1174
+
996
1175
  end # SexyMigrationsTest
997
1176
  end # uses_mocha
998
- end
999
1177
 
1178
+ uses_mocha 'ChangeTable migration tests' do
1179
+ class ChangeTableMigrationsTest < ActiveRecord::TestCase
1180
+ def setup
1181
+ @connection = Person.connection
1182
+ @connection.create_table :delete_me, :force => true do |t|
1183
+ end
1184
+ end
1185
+
1186
+ def teardown
1187
+ Person.connection.drop_table :delete_me rescue nil
1188
+ end
1189
+
1190
+ def test_references_column_type_adds_id
1191
+ with_change_table do |t|
1192
+ @connection.expects(:add_column).with(:delete_me, 'customer_id', :integer, {})
1193
+ t.references :customer
1194
+ end
1195
+ end
1196
+
1197
+ def test_remove_references_column_type_removes_id
1198
+ with_change_table do |t|
1199
+ @connection.expects(:remove_column).with(:delete_me, 'customer_id')
1200
+ t.remove_references :customer
1201
+ end
1202
+ end
1203
+
1204
+ def test_add_belongs_to_works_like_add_references
1205
+ with_change_table do |t|
1206
+ @connection.expects(:add_column).with(:delete_me, 'customer_id', :integer, {})
1207
+ t.belongs_to :customer
1208
+ end
1209
+ end
1210
+
1211
+ def test_remove_belongs_to_works_like_remove_references
1212
+ with_change_table do |t|
1213
+ @connection.expects(:remove_column).with(:delete_me, 'customer_id')
1214
+ t.remove_belongs_to :customer
1215
+ end
1216
+ end
1217
+
1218
+ def test_references_column_type_with_polymorphic_adds_type
1219
+ with_change_table do |t|
1220
+ @connection.expects(:add_column).with(:delete_me, 'taggable_type', :string, {})
1221
+ @connection.expects(:add_column).with(:delete_me, 'taggable_id', :integer, {})
1222
+ t.references :taggable, :polymorphic => true
1223
+ end
1224
+ end
1225
+
1226
+ def test_remove_references_column_type_with_polymorphic_removes_type
1227
+ with_change_table do |t|
1228
+ @connection.expects(:remove_column).with(:delete_me, 'taggable_type')
1229
+ @connection.expects(:remove_column).with(:delete_me, 'taggable_id')
1230
+ t.remove_references :taggable, :polymorphic => true
1231
+ end
1232
+ end
1233
+
1234
+ def test_references_column_type_with_polymorphic_and_options_null_is_false_adds_table_flag
1235
+ with_change_table do |t|
1236
+ @connection.expects(:add_column).with(:delete_me, 'taggable_type', :string, {:null => false})
1237
+ @connection.expects(:add_column).with(:delete_me, 'taggable_id', :integer, {:null => false})
1238
+ t.references :taggable, :polymorphic => true, :null => false
1239
+ end
1240
+ end
1241
+
1242
+ def test_remove_references_column_type_with_polymorphic_and_options_null_is_false_removes_table_flag
1243
+ with_change_table do |t|
1244
+ @connection.expects(:remove_column).with(:delete_me, 'taggable_type')
1245
+ @connection.expects(:remove_column).with(:delete_me, 'taggable_id')
1246
+ t.remove_references :taggable, :polymorphic => true, :null => false
1247
+ end
1248
+ end
1249
+
1250
+ def test_timestamps_creates_updated_at_and_created_at
1251
+ with_change_table do |t|
1252
+ @connection.expects(:add_timestamps).with(:delete_me)
1253
+ t.timestamps
1254
+ end
1255
+ end
1256
+
1257
+ def test_remove_timestamps_creates_updated_at_and_created_at
1258
+ with_change_table do |t|
1259
+ @connection.expects(:remove_timestamps).with(:delete_me)
1260
+ t.remove_timestamps
1261
+ end
1262
+ end
1263
+
1264
+ def string_column
1265
+ if current_adapter?(:PostgreSQLAdapter)
1266
+ "character varying(255)"
1267
+ else
1268
+ 'varchar(255)'
1269
+ end
1270
+ end
1271
+
1272
+ def integer_column
1273
+ if current_adapter?(:SQLite3Adapter) || current_adapter?(:SQLiteAdapter) || current_adapter?(:PostgreSQLAdapter)
1274
+ "integer"
1275
+ else
1276
+ 'int(11)'
1277
+ end
1278
+ end
1279
+
1280
+ def test_integer_creates_integer_column
1281
+ with_change_table do |t|
1282
+ @connection.expects(:add_column).with(:delete_me, :foo, integer_column, {})
1283
+ @connection.expects(:add_column).with(:delete_me, :bar, integer_column, {})
1284
+ t.integer :foo, :bar
1285
+ end
1286
+ end
1287
+
1288
+ def test_string_creates_string_column
1289
+ with_change_table do |t|
1290
+ @connection.expects(:add_column).with(:delete_me, :foo, string_column, {})
1291
+ @connection.expects(:add_column).with(:delete_me, :bar, string_column, {})
1292
+ t.string :foo, :bar
1293
+ end
1294
+ end
1295
+
1296
+ def test_column_creates_column
1297
+ with_change_table do |t|
1298
+ @connection.expects(:add_column).with(:delete_me, :bar, :integer, {})
1299
+ t.column :bar, :integer
1300
+ end
1301
+ end
1302
+
1303
+ def test_column_creates_column_with_options
1304
+ with_change_table do |t|
1305
+ @connection.expects(:add_column).with(:delete_me, :bar, :integer, {:null => false})
1306
+ t.column :bar, :integer, :null => false
1307
+ end
1308
+ end
1309
+
1310
+ def test_index_creates_index
1311
+ with_change_table do |t|
1312
+ @connection.expects(:add_index).with(:delete_me, :bar, {})
1313
+ t.index :bar
1314
+ end
1315
+ end
1316
+
1317
+ def test_index_creates_index_with_options
1318
+ with_change_table do |t|
1319
+ @connection.expects(:add_index).with(:delete_me, :bar, {:unique => true})
1320
+ t.index :bar, :unique => true
1321
+ end
1322
+ end
1323
+
1324
+ def test_change_changes_column
1325
+ with_change_table do |t|
1326
+ @connection.expects(:change_column).with(:delete_me, :bar, :string, {})
1327
+ t.change :bar, :string
1328
+ end
1329
+ end
1330
+
1331
+ def test_change_changes_column_with_options
1332
+ with_change_table do |t|
1333
+ @connection.expects(:change_column).with(:delete_me, :bar, :string, {:null => true})
1334
+ t.change :bar, :string, :null => true
1335
+ end
1336
+ end
1337
+
1338
+ def test_change_default_changes_column
1339
+ with_change_table do |t|
1340
+ @connection.expects(:change_column_default).with(:delete_me, :bar, :string)
1341
+ t.change_default :bar, :string
1342
+ end
1343
+ end
1344
+
1345
+ def test_remove_drops_single_column
1346
+ with_change_table do |t|
1347
+ @connection.expects(:remove_column).with(:delete_me, [:bar])
1348
+ t.remove :bar
1349
+ end
1350
+ end
1351
+
1352
+ def test_remove_drops_multiple_columns
1353
+ with_change_table do |t|
1354
+ @connection.expects(:remove_column).with(:delete_me, [:bar, :baz])
1355
+ t.remove :bar, :baz
1356
+ end
1357
+ end
1358
+
1359
+ def test_remove_index_removes_index_with_options
1360
+ with_change_table do |t|
1361
+ @connection.expects(:remove_index).with(:delete_me, {:unique => true})
1362
+ t.remove_index :unique => true
1363
+ end
1364
+ end
1365
+
1366
+ def test_rename_renames_column
1367
+ with_change_table do |t|
1368
+ @connection.expects(:rename_column).with(:delete_me, :bar, :baz)
1369
+ t.rename :bar, :baz
1370
+ end
1371
+ end
1372
+
1373
+ protected
1374
+ def with_change_table
1375
+ Person.connection.change_table :delete_me do |t|
1376
+ yield t
1377
+ end
1378
+ end
1379
+
1380
+ end # ChangeTable test
1381
+ end # uses_mocha
1382
+
1383
+ end