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.
- data/CHANGELOG +438 -396
- data/Rakefile +4 -2
- data/lib/active_record.rb +46 -43
- data/lib/active_record/association_preload.rb +34 -19
- data/lib/active_record/associations.rb +193 -251
- data/lib/active_record/associations/association_collection.rb +38 -21
- data/lib/active_record/associations/association_proxy.rb +11 -4
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +2 -2
- data/lib/active_record/associations/has_many_association.rb +2 -2
- data/lib/active_record/associations/has_many_through_association.rb +8 -8
- data/lib/active_record/associations/has_one_association.rb +11 -2
- data/lib/active_record/attribute_methods.rb +1 -0
- data/lib/active_record/autosave_association.rb +349 -0
- data/lib/active_record/base.rb +292 -106
- data/lib/active_record/batches.rb +73 -0
- data/lib/active_record/calculations.rb +34 -16
- data/lib/active_record/callbacks.rb +37 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +16 -0
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +3 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +103 -15
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +28 -25
- data/lib/active_record/connection_adapters/abstract_adapter.rb +29 -5
- data/lib/active_record/connection_adapters/mysql_adapter.rb +50 -21
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +26 -41
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +41 -21
- data/lib/active_record/dirty.rb +1 -1
- data/lib/active_record/dynamic_scope_match.rb +25 -0
- data/lib/active_record/fixtures.rb +193 -198
- data/lib/active_record/locale/en.yml +1 -1
- data/lib/active_record/locking/optimistic.rb +33 -0
- data/lib/active_record/migration.rb +8 -2
- data/lib/active_record/named_scope.rb +13 -6
- data/lib/active_record/nested_attributes.rb +329 -0
- data/lib/active_record/query_cache.rb +25 -13
- data/lib/active_record/reflection.rb +6 -1
- data/lib/active_record/schema_dumper.rb +2 -0
- data/lib/active_record/serialization.rb +3 -1
- data/lib/active_record/serializers/json_serializer.rb +19 -0
- data/lib/active_record/serializers/xml_serializer.rb +28 -13
- data/lib/active_record/session_store.rb +318 -0
- data/lib/active_record/test_case.rb +15 -9
- data/lib/active_record/timestamp.rb +2 -2
- data/lib/active_record/transactions.rb +58 -8
- data/lib/active_record/validations.rb +29 -24
- data/lib/active_record/version.rb +2 -2
- data/test/cases/ar_schema_test.rb +0 -1
- data/test/cases/associations/belongs_to_associations_test.rb +35 -131
- data/test/cases/associations/cascaded_eager_loading_test.rb +8 -0
- data/test/cases/associations/eager_load_nested_include_test.rb +29 -0
- data/test/cases/associations/eager_test.rb +137 -7
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +45 -7
- data/test/cases/associations/has_many_associations_test.rb +110 -149
- data/test/cases/associations/has_many_through_associations_test.rb +39 -7
- data/test/cases/associations/has_one_associations_test.rb +39 -92
- data/test/cases/associations/has_one_through_associations_test.rb +34 -3
- data/test/cases/associations/inner_join_association_test.rb +0 -5
- data/test/cases/associations/join_model_test.rb +5 -7
- data/test/cases/attribute_methods_test.rb +13 -1
- data/test/cases/autosave_association_test.rb +901 -0
- data/test/cases/base_test.rb +41 -21
- data/test/cases/batches_test.rb +61 -0
- data/test/cases/calculations_test.rb +37 -17
- data/test/cases/callbacks_test.rb +43 -5
- data/test/cases/connection_pool_test.rb +25 -0
- data/test/cases/copy_table_test_sqlite.rb +11 -0
- data/test/cases/datatype_test_postgresql.rb +1 -0
- data/test/cases/defaults_test.rb +37 -26
- data/test/cases/dirty_test.rb +26 -2
- data/test/cases/finder_test.rb +79 -44
- data/test/cases/fixtures_test.rb +15 -19
- data/test/cases/helper.rb +26 -19
- data/test/cases/inheritance_test.rb +2 -2
- data/test/cases/json_serialization_test.rb +1 -1
- data/test/cases/locking_test.rb +23 -5
- data/test/cases/method_scoping_test.rb +126 -3
- data/test/cases/migration_test.rb +253 -237
- data/test/cases/named_scope_test.rb +73 -3
- data/test/cases/nested_attributes_test.rb +509 -0
- data/test/cases/query_cache_test.rb +0 -4
- data/test/cases/reflection_test.rb +13 -3
- data/test/cases/reload_models_test.rb +3 -1
- data/test/cases/repair_helper.rb +50 -0
- data/test/cases/schema_dumper_test.rb +0 -1
- data/test/cases/transactions_test.rb +177 -12
- data/test/cases/validations_i18n_test.rb +288 -294
- data/test/cases/validations_test.rb +230 -180
- data/test/cases/xml_serialization_test.rb +19 -1
- data/test/fixtures/fixture_database.sqlite3 +0 -0
- data/test/fixtures/fixture_database_2.sqlite3 +0 -0
- data/test/fixtures/member_types.yml +6 -0
- data/test/fixtures/members.yml +3 -1
- data/test/fixtures/people.yml +10 -1
- data/test/fixtures/toys.yml +4 -0
- data/test/models/author.rb +1 -2
- data/test/models/bird.rb +3 -0
- data/test/models/category.rb +1 -0
- data/test/models/company.rb +3 -0
- data/test/models/developer.rb +12 -0
- data/test/models/event.rb +3 -0
- data/test/models/member.rb +1 -0
- data/test/models/member_detail.rb +1 -0
- data/test/models/member_type.rb +3 -0
- data/test/models/owner.rb +2 -1
- data/test/models/parrot.rb +2 -0
- data/test/models/person.rb +6 -0
- data/test/models/pet.rb +2 -1
- data/test/models/pirate.rb +55 -1
- data/test/models/post.rb +6 -0
- data/test/models/project.rb +1 -0
- data/test/models/reply.rb +6 -0
- data/test/models/ship.rb +8 -1
- data/test/models/ship_part.rb +5 -0
- data/test/models/topic.rb +13 -1
- data/test/models/toy.rb +4 -0
- data/test/schema/schema.rb +35 -2
- metadata +70 -9
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
data/test/cases/base_test.rb
CHANGED
@@ -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
|
-
|
427
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
906
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
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
|
-
|
160
|
-
|
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
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
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
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
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
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
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
|
-
|
252
|
-
|
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
|
-
|
125
|
-
|
126
|
-
|
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
|
-
|
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
|
-
|
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)
|
data/test/cases/defaults_test.rb
CHANGED
@@ -18,11 +18,43 @@ class DefaultTest < ActiveRecord::TestCase
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
if current_adapter?(:
|
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
|
-
|
24
|
-
|
25
|
-
#
|
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
|