activerecord 2.2.3 → 2.3.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (120) hide show
  1. data/CHANGELOG +438 -396
  2. data/Rakefile +4 -2
  3. data/lib/active_record.rb +46 -43
  4. data/lib/active_record/association_preload.rb +34 -19
  5. data/lib/active_record/associations.rb +193 -251
  6. data/lib/active_record/associations/association_collection.rb +38 -21
  7. data/lib/active_record/associations/association_proxy.rb +11 -4
  8. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +2 -2
  9. data/lib/active_record/associations/has_many_association.rb +2 -2
  10. data/lib/active_record/associations/has_many_through_association.rb +8 -8
  11. data/lib/active_record/associations/has_one_association.rb +11 -2
  12. data/lib/active_record/attribute_methods.rb +1 -0
  13. data/lib/active_record/autosave_association.rb +349 -0
  14. data/lib/active_record/base.rb +292 -106
  15. data/lib/active_record/batches.rb +73 -0
  16. data/lib/active_record/calculations.rb +34 -16
  17. data/lib/active_record/callbacks.rb +37 -8
  18. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +16 -0
  19. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +3 -0
  20. data/lib/active_record/connection_adapters/abstract/database_statements.rb +103 -15
  21. data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -6
  22. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +28 -25
  23. data/lib/active_record/connection_adapters/abstract_adapter.rb +29 -5
  24. data/lib/active_record/connection_adapters/mysql_adapter.rb +50 -21
  25. data/lib/active_record/connection_adapters/postgresql_adapter.rb +26 -41
  26. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
  27. data/lib/active_record/connection_adapters/sqlite_adapter.rb +41 -21
  28. data/lib/active_record/dirty.rb +1 -1
  29. data/lib/active_record/dynamic_scope_match.rb +25 -0
  30. data/lib/active_record/fixtures.rb +193 -198
  31. data/lib/active_record/locale/en.yml +1 -1
  32. data/lib/active_record/locking/optimistic.rb +33 -0
  33. data/lib/active_record/migration.rb +8 -2
  34. data/lib/active_record/named_scope.rb +13 -6
  35. data/lib/active_record/nested_attributes.rb +329 -0
  36. data/lib/active_record/query_cache.rb +25 -13
  37. data/lib/active_record/reflection.rb +6 -1
  38. data/lib/active_record/schema_dumper.rb +2 -0
  39. data/lib/active_record/serialization.rb +3 -1
  40. data/lib/active_record/serializers/json_serializer.rb +19 -0
  41. data/lib/active_record/serializers/xml_serializer.rb +28 -13
  42. data/lib/active_record/session_store.rb +318 -0
  43. data/lib/active_record/test_case.rb +15 -9
  44. data/lib/active_record/timestamp.rb +2 -2
  45. data/lib/active_record/transactions.rb +58 -8
  46. data/lib/active_record/validations.rb +29 -24
  47. data/lib/active_record/version.rb +2 -2
  48. data/test/cases/ar_schema_test.rb +0 -1
  49. data/test/cases/associations/belongs_to_associations_test.rb +35 -131
  50. data/test/cases/associations/cascaded_eager_loading_test.rb +8 -0
  51. data/test/cases/associations/eager_load_nested_include_test.rb +29 -0
  52. data/test/cases/associations/eager_test.rb +137 -7
  53. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +45 -7
  54. data/test/cases/associations/has_many_associations_test.rb +110 -149
  55. data/test/cases/associations/has_many_through_associations_test.rb +39 -7
  56. data/test/cases/associations/has_one_associations_test.rb +39 -92
  57. data/test/cases/associations/has_one_through_associations_test.rb +34 -3
  58. data/test/cases/associations/inner_join_association_test.rb +0 -5
  59. data/test/cases/associations/join_model_test.rb +5 -7
  60. data/test/cases/attribute_methods_test.rb +13 -1
  61. data/test/cases/autosave_association_test.rb +901 -0
  62. data/test/cases/base_test.rb +41 -21
  63. data/test/cases/batches_test.rb +61 -0
  64. data/test/cases/calculations_test.rb +37 -17
  65. data/test/cases/callbacks_test.rb +43 -5
  66. data/test/cases/connection_pool_test.rb +25 -0
  67. data/test/cases/copy_table_test_sqlite.rb +11 -0
  68. data/test/cases/datatype_test_postgresql.rb +1 -0
  69. data/test/cases/defaults_test.rb +37 -26
  70. data/test/cases/dirty_test.rb +26 -2
  71. data/test/cases/finder_test.rb +79 -44
  72. data/test/cases/fixtures_test.rb +15 -19
  73. data/test/cases/helper.rb +26 -19
  74. data/test/cases/inheritance_test.rb +2 -2
  75. data/test/cases/json_serialization_test.rb +1 -1
  76. data/test/cases/locking_test.rb +23 -5
  77. data/test/cases/method_scoping_test.rb +126 -3
  78. data/test/cases/migration_test.rb +253 -237
  79. data/test/cases/named_scope_test.rb +73 -3
  80. data/test/cases/nested_attributes_test.rb +509 -0
  81. data/test/cases/query_cache_test.rb +0 -4
  82. data/test/cases/reflection_test.rb +13 -3
  83. data/test/cases/reload_models_test.rb +3 -1
  84. data/test/cases/repair_helper.rb +50 -0
  85. data/test/cases/schema_dumper_test.rb +0 -1
  86. data/test/cases/transactions_test.rb +177 -12
  87. data/test/cases/validations_i18n_test.rb +288 -294
  88. data/test/cases/validations_test.rb +230 -180
  89. data/test/cases/xml_serialization_test.rb +19 -1
  90. data/test/fixtures/fixture_database.sqlite3 +0 -0
  91. data/test/fixtures/fixture_database_2.sqlite3 +0 -0
  92. data/test/fixtures/member_types.yml +6 -0
  93. data/test/fixtures/members.yml +3 -1
  94. data/test/fixtures/people.yml +10 -1
  95. data/test/fixtures/toys.yml +4 -0
  96. data/test/models/author.rb +1 -2
  97. data/test/models/bird.rb +3 -0
  98. data/test/models/category.rb +1 -0
  99. data/test/models/company.rb +3 -0
  100. data/test/models/developer.rb +12 -0
  101. data/test/models/event.rb +3 -0
  102. data/test/models/member.rb +1 -0
  103. data/test/models/member_detail.rb +1 -0
  104. data/test/models/member_type.rb +3 -0
  105. data/test/models/owner.rb +2 -1
  106. data/test/models/parrot.rb +2 -0
  107. data/test/models/person.rb +6 -0
  108. data/test/models/pet.rb +2 -1
  109. data/test/models/pirate.rb +55 -1
  110. data/test/models/post.rb +6 -0
  111. data/test/models/project.rb +1 -0
  112. data/test/models/reply.rb +6 -0
  113. data/test/models/ship.rb +8 -1
  114. data/test/models/ship_part.rb +5 -0
  115. data/test/models/topic.rb +13 -1
  116. data/test/models/toy.rb +4 -0
  117. data/test/schema/schema.rb +35 -2
  118. metadata +70 -9
  119. data/test/fixtures/fixture_database.sqlite +0 -0
  120. data/test/fixtures/fixture_database_2.sqlite +0 -0
@@ -16,6 +16,7 @@ require 'models/post'
16
16
  require 'models/comment'
17
17
  require 'models/minimalistic'
18
18
  require 'models/warehouse_thing'
19
+ require 'models/parrot'
19
20
  require 'rexml/document'
20
21
 
21
22
  class Category < ActiveRecord::Base; end
@@ -423,8 +424,8 @@ class BasicsTest < ActiveRecord::TestCase
423
424
  def test_non_attribute_access_and_assignment
424
425
  topic = Topic.new
425
426
  assert !topic.respond_to?("mumbo")
426
- assert_raises(NoMethodError) { topic.mumbo }
427
- assert_raises(NoMethodError) { topic.mumbo = 5 }
427
+ assert_raise(NoMethodError) { topic.mumbo }
428
+ assert_raise(NoMethodError) { topic.mumbo = 5 }
428
429
  end
429
430
 
430
431
  def test_preserving_date_objects
@@ -489,7 +490,7 @@ class BasicsTest < ActiveRecord::TestCase
489
490
  end
490
491
 
491
492
  def test_record_not_found_exception
492
- assert_raises(ActiveRecord::RecordNotFound) { topicReloaded = Topic.find(99999) }
493
+ assert_raise(ActiveRecord::RecordNotFound) { topicReloaded = Topic.find(99999) }
493
494
  end
494
495
 
495
496
  def test_initialize_with_attributes
@@ -638,6 +639,13 @@ class BasicsTest < ActiveRecord::TestCase
638
639
  category.reload
639
640
  assert_not_nil category.categorizations_count
640
641
  assert_equal 4, category.categorizations_count
642
+
643
+ category_2 = categories(:technology)
644
+ count_1, count_2 = (category.categorizations_count || 0), (category_2.categorizations_count || 0)
645
+ Category.update_counters([category.id, category_2.id], "categorizations_count" => 2)
646
+ category.reload; category_2.reload
647
+ assert_equal count_1 + 2, category.categorizations_count
648
+ assert_equal count_2 + 2, category_2.categorizations_count
641
649
  end
642
650
 
643
651
  def test_update_all
@@ -840,7 +848,7 @@ class BasicsTest < ActiveRecord::TestCase
840
848
  client.delete
841
849
  assert client.frozen?
842
850
  assert_kind_of Firm, client.firm
843
- assert_raises(ActiveSupport::FrozenObjectError) { client.name = "something else" }
851
+ assert_raise(ActiveSupport::FrozenObjectError) { client.name = "something else" }
844
852
  end
845
853
 
846
854
  def test_destroy_new_record
@@ -854,7 +862,7 @@ class BasicsTest < ActiveRecord::TestCase
854
862
  client.destroy
855
863
  assert client.frozen?
856
864
  assert_kind_of Firm, client.firm
857
- assert_raises(ActiveSupport::FrozenObjectError) { client.name = "something else" }
865
+ assert_raise(ActiveSupport::FrozenObjectError) { client.name = "something else" }
858
866
  end
859
867
 
860
868
  def test_update_attribute
@@ -902,8 +910,8 @@ class BasicsTest < ActiveRecord::TestCase
902
910
 
903
911
  def test_mass_assignment_should_raise_exception_if_accessible_and_protected_attribute_writers_are_both_used
904
912
  topic = TopicWithProtectedContentAndAccessibleAuthorName.new
905
- assert_raises(RuntimeError) { topic.attributes = { "author_name" => "me" } }
906
- assert_raises(RuntimeError) { topic.attributes = { "content" => "stuff" } }
913
+ assert_raise(RuntimeError) { topic.attributes = { "author_name" => "me" } }
914
+ assert_raise(RuntimeError) { topic.attributes = { "content" => "stuff" } }
907
915
  end
908
916
 
909
917
  def test_mass_assignment_protection
@@ -941,7 +949,7 @@ class BasicsTest < ActiveRecord::TestCase
941
949
  def test_mass_assigning_invalid_attribute
942
950
  firm = Firm.new
943
951
 
944
- assert_raises(ActiveRecord::UnknownAttributeError) do
952
+ assert_raise(ActiveRecord::UnknownAttributeError) do
945
953
  firm.attributes = { "id" => 5, "type" => "Client", "i_dont_even_exist" => 20 }
946
954
  end
947
955
  end
@@ -1197,6 +1205,11 @@ class BasicsTest < ActiveRecord::TestCase
1197
1205
  assert b_true.value?
1198
1206
  end
1199
1207
 
1208
+ def test_new_record_returns_boolean
1209
+ assert_equal Topic.new.new_record?, true
1210
+ assert_equal Topic.find(1).new_record?, false
1211
+ end
1212
+
1200
1213
  def test_clone
1201
1214
  topic = Topic.find(1)
1202
1215
  cloned_topic = nil
@@ -1389,7 +1402,7 @@ class BasicsTest < ActiveRecord::TestCase
1389
1402
  end
1390
1403
 
1391
1404
  def test_sql_injection_via_find
1392
- assert_raises(ActiveRecord::RecordNotFound, ActiveRecord::StatementInvalid) do
1405
+ assert_raise(ActiveRecord::RecordNotFound, ActiveRecord::StatementInvalid) do
1393
1406
  Topic.find("123456 OR id > 0")
1394
1407
  end
1395
1408
  end
@@ -1742,6 +1755,13 @@ class BasicsTest < ActiveRecord::TestCase
1742
1755
  end
1743
1756
  end
1744
1757
 
1758
+ def test_scoped_find_with_group_and_having
1759
+ developers = Developer.with_scope(:find => { :group => 'salary', :having => "SUM(salary) > 10000", :select => "SUM(salary) as salary" }) do
1760
+ Developer.find(:all)
1761
+ end
1762
+ assert_equal 3, developers.size
1763
+ end
1764
+
1745
1765
  def test_find_last
1746
1766
  last = Developer.find :last
1747
1767
  assert_equal last, Developer.find(:first, :order => 'id desc')
@@ -1770,6 +1790,11 @@ class BasicsTest < ActiveRecord::TestCase
1770
1790
  assert_equal last, Developer.find(:all, :order => 'developers.name, developers.salary DESC').last
1771
1791
  end
1772
1792
 
1793
+ def test_find_symbol_ordered_last
1794
+ last = Developer.find :last, :order => :salary
1795
+ assert_equal last, Developer.find(:all, :order => :salary).last
1796
+ end
1797
+
1773
1798
  def test_find_scoped_ordered_last
1774
1799
  last_developer = Developer.with_scope(:find => { :order => 'developers.salary ASC' }) do
1775
1800
  Developer.find(:last)
@@ -2071,17 +2096,12 @@ class BasicsTest < ActiveRecord::TestCase
2071
2096
  ActiveRecord::Base.logger = original_logger
2072
2097
  end
2073
2098
 
2074
- private
2075
- def with_kcode(kcode)
2076
- if RUBY_VERSION < '1.9'
2077
- orig_kcode, $KCODE = $KCODE, kcode
2078
- begin
2079
- yield
2080
- ensure
2081
- $KCODE = orig_kcode
2082
- end
2083
- else
2084
- yield
2085
- end
2099
+ def test_create_with_custom_timestamps
2100
+ custom_datetime = 1.hour.ago.beginning_of_day
2101
+
2102
+ %w(created_at created_on updated_at updated_on).each do |attribute|
2103
+ parrot = LiveParrot.create(:name => "colombian", attribute => custom_datetime)
2104
+ assert_equal custom_datetime, parrot[attribute]
2086
2105
  end
2106
+ end
2087
2107
  end
@@ -0,0 +1,61 @@
1
+ require 'cases/helper'
2
+ require 'models/post'
3
+
4
+ class EachTest < ActiveRecord::TestCase
5
+ fixtures :posts
6
+
7
+ def setup
8
+ @posts = Post.all(:order => "id asc")
9
+ @total = Post.count
10
+ end
11
+
12
+ def test_each_should_excecute_one_query_per_batch
13
+ assert_queries(Post.count + 1) do
14
+ Post.find_each(:batch_size => 1) do |post|
15
+ assert_kind_of Post, post
16
+ end
17
+ end
18
+ end
19
+
20
+ def test_each_should_raise_if_the_order_is_set
21
+ assert_raise(RuntimeError) do
22
+ Post.find_each(:order => "title") { |post| post }
23
+ end
24
+ end
25
+
26
+ def test_each_should_raise_if_the_limit_is_set
27
+ assert_raise(RuntimeError) do
28
+ Post.find_each(:limit => 1) { |post| post }
29
+ end
30
+ end
31
+
32
+ def test_find_in_batches_should_return_batches
33
+ assert_queries(Post.count + 1) do
34
+ Post.find_in_batches(:batch_size => 1) do |batch|
35
+ assert_kind_of Array, batch
36
+ assert_kind_of Post, batch.first
37
+ end
38
+ end
39
+ end
40
+
41
+ def test_find_in_batches_should_start_from_the_start_option
42
+ assert_queries(Post.count) do
43
+ Post.find_in_batches(:batch_size => 1, :start => 2) do |batch|
44
+ assert_kind_of Array, batch
45
+ assert_kind_of Post, batch.first
46
+ end
47
+ end
48
+ end
49
+
50
+ def test_find_in_batches_shouldnt_excute_query_unless_needed
51
+ post_count = Post.count
52
+
53
+ assert_queries(2) do
54
+ Post.find_in_batches(:batch_size => post_count) {|batch| assert_kind_of Array, batch }
55
+ end
56
+
57
+ assert_queries(1) do
58
+ Post.find_in_batches(:batch_size => post_count + 1) {|batch| assert_kind_of Array, batch }
59
+ end
60
+ end
61
+ end
@@ -92,6 +92,14 @@ class CalculationsTest < ActiveRecord::TestCase
92
92
  assert_equal 60, c[2]
93
93
  end
94
94
 
95
+ def test_should_group_by_summed_field_having_sanitized_condition
96
+ c = Account.sum(:credit_limit, :group => :firm_id,
97
+ :having => ['sum(credit_limit) > ?', 50])
98
+ assert_nil c[1]
99
+ assert_equal 105, c[6]
100
+ assert_equal 60, c[2]
101
+ end
102
+
95
103
  def test_should_group_by_summed_association
96
104
  c = Account.sum(:credit_limit, :group => :firm)
97
105
  assert_equal 50, c[companies(:first_firm)]
@@ -156,24 +164,23 @@ class CalculationsTest < ActiveRecord::TestCase
156
164
  assert_equal 1, c[companies(:first_client)]
157
165
  end
158
166
 
159
- uses_mocha 'group_by_non_numeric_foreign_key_association' do
160
- def test_should_group_by_association_with_non_numeric_foreign_key
161
- ActiveRecord::Base.connection.expects(:select_all).returns([{"count_all" => 1, "firm_id" => "ABC"}])
167
+ def test_should_group_by_association_with_non_numeric_foreign_key
168
+ ActiveRecord::Base.connection.expects(:select_all).returns([{"count_all" => 1, "firm_id" => "ABC"}])
162
169
 
163
- firm = mock()
164
- firm.expects(:id).returns("ABC")
165
- firm.expects(:class).returns(Firm)
166
- Company.expects(:find).with(["ABC"]).returns([firm])
170
+ firm = mock()
171
+ firm.expects(:id).returns("ABC")
172
+ firm.expects(:class).returns(Firm)
173
+ Company.expects(:find).with(["ABC"]).returns([firm])
167
174
 
168
- column = mock()
169
- column.expects(:name).at_least_once.returns(:firm_id)
170
- column.expects(:type_cast).with("ABC").returns("ABC")
171
- Account.expects(:columns).at_least_once.returns([column])
175
+ column = mock()
176
+ column.expects(:name).at_least_once.returns(:firm_id)
177
+ column.expects(:type_cast).with("ABC").returns("ABC")
178
+ Account.expects(:columns).at_least_once.returns([column])
172
179
 
173
- c = Account.count(:all, :group => :firm)
174
- assert_equal Firm, c.first.first.class
175
- assert_equal 1, c.first.last
176
- end
180
+ c = Account.count(:all, :group => :firm)
181
+ first_key = c.keys.first
182
+ assert_equal Firm, first_key.class
183
+ assert_equal 1, c[first_key]
177
184
  end
178
185
 
179
186
  def test_should_calculate_grouped_association_with_foreign_key_option
@@ -248,8 +255,8 @@ class CalculationsTest < ActiveRecord::TestCase
248
255
  Company.send(:validate_calculation_options, :count, :include => true)
249
256
  end
250
257
 
251
- assert_raises(ArgumentError) { Company.send(:validate_calculation_options, :sum, :foo => :bar) }
252
- assert_raises(ArgumentError) { Company.send(:validate_calculation_options, :count, :foo => :bar) }
258
+ assert_raise(ArgumentError) { Company.send(:validate_calculation_options, :sum, :foo => :bar) }
259
+ assert_raise(ArgumentError) { Company.send(:validate_calculation_options, :count, :foo => :bar) }
253
260
  end
254
261
 
255
262
  def test_should_count_selected_field_with_include
@@ -257,6 +264,19 @@ class CalculationsTest < ActiveRecord::TestCase
257
264
  assert_equal 4, Account.count(:distinct => true, :include => :firm, :select => :credit_limit)
258
265
  end
259
266
 
267
+ def test_should_count_scoped_select
268
+ Account.update_all("credit_limit = NULL")
269
+ assert_equal 0, Account.scoped(:select => "credit_limit").count
270
+ end
271
+
272
+ def test_should_count_scoped_select_with_options
273
+ Account.update_all("credit_limit = NULL")
274
+ Account.last.update_attribute('credit_limit', 49)
275
+ Account.first.update_attribute('credit_limit', 51)
276
+
277
+ assert_equal 1, Account.scoped(:select => "credit_limit").count(:conditions => ['credit_limit >= 50'])
278
+ end
279
+
260
280
  def test_should_count_manual_select_with_include
261
281
  assert_equal 6, Account.count(:select => "DISTINCT accounts.id", :include => :firm)
262
282
  end
@@ -121,9 +121,19 @@ end
121
121
 
122
122
  class CallbackCancellationDeveloper < ActiveRecord::Base
123
123
  set_table_name 'developers'
124
- def before_create
125
- false
126
- end
124
+
125
+ attr_reader :after_save_called, :after_create_called, :after_update_called, :after_destroy_called
126
+ attr_accessor :cancel_before_save, :cancel_before_create, :cancel_before_update, :cancel_before_destroy
127
+
128
+ def before_save; !@cancel_before_save; end
129
+ def before_create; !@cancel_before_create; end
130
+ def before_update; !@cancel_before_update; end
131
+ def before_destroy; !@cancel_before_destroy; end
132
+
133
+ def after_save; @after_save_called = true; end
134
+ def after_update; @after_update_called = true; end
135
+ def after_create; @after_create_called = true; end
136
+ def after_destroy; @after_destroy_called = true; end
127
137
  end
128
138
 
129
139
  class CallbacksTest < ActiveRecord::TestCase
@@ -342,26 +352,54 @@ class CallbacksTest < ActiveRecord::TestCase
342
352
  david = ImmutableDeveloper.find(1)
343
353
  assert david.valid?
344
354
  assert !david.save
345
- assert_raises(ActiveRecord::RecordNotSaved) { david.save! }
355
+ assert_raise(ActiveRecord::RecordNotSaved) { david.save! }
346
356
 
347
357
  david = ImmutableDeveloper.find(1)
348
358
  david.salary = 10_000_000
349
359
  assert !david.valid?
350
360
  assert !david.save
351
- assert_raises(ActiveRecord::RecordInvalid) { david.save! }
361
+ assert_raise(ActiveRecord::RecordInvalid) { david.save! }
362
+
363
+ someone = CallbackCancellationDeveloper.find(1)
364
+ someone.cancel_before_save = true
365
+ assert someone.valid?
366
+ assert !someone.save
367
+ assert_save_callbacks_not_called(someone)
352
368
  end
353
369
 
354
370
  def test_before_create_returning_false
355
371
  someone = CallbackCancellationDeveloper.new
372
+ someone.cancel_before_create = true
356
373
  assert someone.valid?
357
374
  assert !someone.save
375
+ assert_save_callbacks_not_called(someone)
376
+ end
377
+
378
+ def test_before_update_returning_false
379
+ someone = CallbackCancellationDeveloper.find(1)
380
+ someone.cancel_before_update = true
381
+ assert someone.valid?
382
+ assert !someone.save
383
+ assert_save_callbacks_not_called(someone)
358
384
  end
359
385
 
360
386
  def test_before_destroy_returning_false
361
387
  david = ImmutableDeveloper.find(1)
362
388
  assert !david.destroy
363
389
  assert_not_nil ImmutableDeveloper.find_by_id(1)
390
+
391
+ someone = CallbackCancellationDeveloper.find(1)
392
+ someone.cancel_before_destroy = true
393
+ assert !someone.destroy
394
+ assert !someone.after_destroy_called
395
+ end
396
+
397
+ def assert_save_callbacks_not_called(someone)
398
+ assert !someone.after_save_called
399
+ assert !someone.after_create_called
400
+ assert !someone.after_update_called
364
401
  end
402
+ private :assert_save_callbacks_not_called
365
403
 
366
404
  def test_zzz_callback_returning_false # must be run last since we modify CallbackDeveloper
367
405
  david = CallbackDeveloper.find(1)
@@ -0,0 +1,25 @@
1
+ require "cases/helper"
2
+
3
+ class ConnectionManagementTest < ActiveRecord::TestCase
4
+ def setup
5
+ @env = {}
6
+ @app = stub('App')
7
+ @management = ActiveRecord::ConnectionAdapters::ConnectionManagement.new(@app)
8
+
9
+ @connections_cleared = false
10
+ ActiveRecord::Base.stubs(:clear_active_connections!).with { @connections_cleared = true }
11
+ end
12
+
13
+ test "clears active connections after each call" do
14
+ @app.expects(:call).with(@env)
15
+ @management.call(@env)
16
+ assert @connections_cleared
17
+ end
18
+
19
+ test "doesn't clear active connections when running in a test case" do
20
+ @env['rack.test'] = true
21
+ @app.expects(:call).with(@env)
22
+ @management.call(@env)
23
+ assert !@connections_cleared
24
+ end
25
+ end
@@ -46,6 +46,17 @@ class CopyTableTest < ActiveRecord::TestCase
46
46
  test_copy_table('developers_projects', 'programmers_projects')
47
47
  end
48
48
 
49
+ def test_copy_table_with_id_col_that_is_not_primary_key
50
+ test_copy_table('goofy_string_id', 'goofy_string_id2') do |from, to, options|
51
+ original_id = @connection.columns('goofy_string_id').detect{|col| col.name == 'id' }
52
+ copied_id = @connection.columns('goofy_string_id2').detect{|col| col.name == 'id' }
53
+ assert_equal original_id.type, copied_id.type
54
+ assert_equal original_id.sql_type, copied_id.sql_type
55
+ assert_equal original_id.limit, copied_id.limit
56
+ assert_equal original_id.primary, copied_id.primary
57
+ end
58
+ end
59
+
49
60
  protected
50
61
  def copy_table(from, to, options = {})
51
62
  @connection.copy_table(from, to, {:temporary => true}.merge(options))
@@ -26,6 +26,7 @@ class PostgresqlDataTypeTest < ActiveRecord::TestCase
26
26
 
27
27
  def setup
28
28
  @connection = ActiveRecord::Base.connection
29
+ @connection.execute("set lc_monetary = 'C'")
29
30
 
30
31
  @connection.execute("INSERT INTO postgresql_arrays (commission_by_quarter, nicknames) VALUES ( '{35000,21000,18000,17000}', '{foo,bar,baz}' )")
31
32
  @first_array = PostgresqlArray.find(1)
@@ -18,11 +18,43 @@ class DefaultTest < ActiveRecord::TestCase
18
18
  end
19
19
  end
20
20
 
21
- if current_adapter?(:MysqlAdapter)
21
+ if current_adapter?(:PostgreSQLAdapter, :FirebirdAdapter, :OpenBaseAdapter, :OracleAdapter)
22
+ def test_default_integers
23
+ default = Default.new
24
+ assert_instance_of Fixnum, default.positive_integer
25
+ assert_equal 1, default.positive_integer
26
+ assert_instance_of Fixnum, default.negative_integer
27
+ assert_equal -1, default.negative_integer
28
+ assert_instance_of BigDecimal, default.decimal_number
29
+ assert_equal BigDecimal.new("2.78"), default.decimal_number
30
+ end
31
+ end
32
+
33
+ if current_adapter?(:PostgreSQLAdapter)
34
+ def test_multiline_default_text
35
+ # older postgres versions represent the default with escapes ("\\012" for a newline)
36
+ assert ( "--- []\n\n" == Default.columns_hash['multiline_default'].default ||
37
+ "--- []\\012\\012" == Default.columns_hash['multiline_default'].default)
38
+ end
39
+ end
40
+ end
22
41
 
23
- #MySQL 5 and higher is quirky with not null text/blob columns.
24
- #With MySQL Text/blob columns cannot have defaults. If the column is not null MySQL will report that the column has a null default
25
- #but it behaves as though the column had a default of ''
42
+ if current_adapter?(:MysqlAdapter)
43
+ class DefaultsTestWithoutTransactionalFixtures < ActiveRecord::TestCase
44
+ # ActiveRecord::Base#create! (and #save and other related methods) will
45
+ # open a new transaction. When in transactional fixtures mode, this will
46
+ # cause ActiveRecord to create a new savepoint. However, since MySQL doesn't
47
+ # support DDL transactions, creating a table will result in any created
48
+ # savepoints to be automatically released. This in turn causes the savepoint
49
+ # release code in AbstractAdapter#transaction to fail.
50
+ #
51
+ # We don't want that to happen, so we disable transactional fixtures here.
52
+ self.use_transactional_fixtures = false
53
+
54
+ # MySQL 5 and higher is quirky with not null text/blob columns.
55
+ # With MySQL Text/blob columns cannot have defaults. If the column is not
56
+ # null MySQL will report that the column has a null default
57
+ # but it behaves as though the column had a default of ''
26
58
  def test_mysql_text_not_null_defaults
27
59
  klass = Class.new(ActiveRecord::Base)
28
60
  klass.table_name = 'test_mysql_text_not_null_defaults'
@@ -48,8 +80,7 @@ class DefaultTest < ActiveRecord::TestCase
48
80
  ensure
49
81
  klass.connection.drop_table(klass.table_name) rescue nil
50
82
  end
51
-
52
-
83
+
53
84
  # MySQL uses an implicit default 0 rather than NULL unless in strict mode.
54
85
  # We use an implicit NULL so schema.rb is compatible with other databases.
55
86
  def test_mysql_integer_not_null_defaults
@@ -77,24 +108,4 @@ class DefaultTest < ActiveRecord::TestCase
77
108
  klass.connection.drop_table(klass.table_name) rescue nil
78
109
  end
79
110
  end
80
-
81
- if current_adapter?(:PostgreSQLAdapter, :FirebirdAdapter, :OpenBaseAdapter, :OracleAdapter)
82
- def test_default_integers
83
- default = Default.new
84
- assert_instance_of Fixnum, default.positive_integer
85
- assert_equal 1, default.positive_integer
86
- assert_instance_of Fixnum, default.negative_integer
87
- assert_equal -1, default.negative_integer
88
- assert_instance_of BigDecimal, default.decimal_number
89
- assert_equal BigDecimal.new("2.78"), default.decimal_number
90
- end
91
- end
92
-
93
- if current_adapter?(:PostgreSQLAdapter)
94
- def test_multiline_default_text
95
- # older postgres versions represent the default with escapes ("\\012" for a newline)
96
- assert ( "--- []\n\n" == Default.columns_hash['multiline_default'].default ||
97
- "--- []\\012\\012" == Default.columns_hash['multiline_default'].default)
98
- end
99
- end
100
111
  end