ibm_db 0.9.4 → 0.9.5
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.
- data/CHANGES +15 -0
- data/README +11 -4
- data/ext/ibm_db.c +16 -15
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +268 -73
- data/test/adapter_test.rb +26 -8
- data/test/associations/eager_test.rb +63 -58
- data/test/associations_test.rb +584 -272
- data/test/base_test.rb +312 -130
- data/test/fixtures/db_definitions/i5/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/i5/ibm_db.sql +5 -1
- data/test/fixtures/db_definitions/ids/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/ids/ibm_db.sql +3 -0
- data/test/fixtures/db_definitions/luw/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/luw/ibm_db.sql +5 -1
- data/test/fixtures/db_definitions/schema.rb +361 -0
- data/test/fixtures/db_definitions/zOS/ibm_db.drop.sql +1 -0
- data/test/fixtures/db_definitions/zOS/ibm_db.sql +5 -1
- data/test/locking_test.rb +95 -3
- data/test/migration_test.rb +308 -142
- metadata +3 -2
data/test/base_test.rb
CHANGED
@@ -11,6 +11,8 @@ require 'fixtures/column_name'
|
|
11
11
|
require 'fixtures/subscriber'
|
12
12
|
require 'fixtures/keyboard'
|
13
13
|
require 'fixtures/post'
|
14
|
+
require 'fixtures/minimalistic'
|
15
|
+
require 'rexml/document'
|
14
16
|
|
15
17
|
class Category < ActiveRecord::Base; end
|
16
18
|
class Smarts < ActiveRecord::Base; end
|
@@ -38,6 +40,11 @@ class LooseDescendant < LoosePerson
|
|
38
40
|
attr_protected :phone_number
|
39
41
|
end
|
40
42
|
|
43
|
+
class LooseDescendantSecond< LoosePerson
|
44
|
+
attr_protected :phone_number
|
45
|
+
attr_protected :name
|
46
|
+
end
|
47
|
+
|
41
48
|
class TightPerson < ActiveRecord::Base
|
42
49
|
self.table_name = 'people'
|
43
50
|
attr_accessible :name, :address
|
@@ -47,14 +54,24 @@ class TightDescendant < TightPerson
|
|
47
54
|
attr_accessible :phone_number
|
48
55
|
end
|
49
56
|
|
57
|
+
class ReadonlyTitlePost < Post
|
58
|
+
attr_readonly :title
|
59
|
+
end
|
60
|
+
|
50
61
|
class Booleantest < ActiveRecord::Base; end
|
51
62
|
|
52
63
|
class Task < ActiveRecord::Base
|
53
64
|
attr_protected :starting
|
54
65
|
end
|
55
66
|
|
56
|
-
class
|
57
|
-
|
67
|
+
class TopicWithProtectedContentAndAccessibleAuthorName < ActiveRecord::Base
|
68
|
+
self.table_name = 'topics'
|
69
|
+
attr_accessible :author_name
|
70
|
+
attr_protected :content
|
71
|
+
end
|
72
|
+
|
73
|
+
class IBMDBBasicsTest < Test::Unit::TestCase
|
74
|
+
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics
|
58
75
|
|
59
76
|
def test_table_exists
|
60
77
|
assert !NonExistentTable.table_exists?
|
@@ -164,8 +181,25 @@ class BasicsTest < Test::Unit::TestCase
|
|
164
181
|
topic.reload
|
165
182
|
assert_equal("null", topic.title)
|
166
183
|
assert_equal("null", topic.author_name)
|
167
|
-
end
|
168
|
-
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_save_nil_string_attributes
|
187
|
+
topic = Topic.find(1)
|
188
|
+
topic.title = nil
|
189
|
+
topic.save!
|
190
|
+
topic.reload
|
191
|
+
assert_nil topic.title
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_save_for_record_with_only_primary_key
|
195
|
+
minimalistic = Minimalistic.new
|
196
|
+
assert_nothing_raised { minimalistic.save }
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_save_for_record_with_only_primary_key_that_is_provided
|
200
|
+
assert_nothing_raised { Minimalistic.create!(:id => 2) }
|
201
|
+
end
|
202
|
+
|
169
203
|
def test_hashes_not_mangled
|
170
204
|
new_topic = { :title => "New Topic" }
|
171
205
|
new_topic_values = { :title => "AnotherTopic" }
|
@@ -222,6 +256,11 @@ class BasicsTest < Test::Unit::TestCase
|
|
222
256
|
topicReloaded.send :write_attribute, 'does_not_exist', 'test'
|
223
257
|
assert_nothing_raised { topicReloaded.save }
|
224
258
|
end
|
259
|
+
|
260
|
+
def test_update_for_record_with_only_primary_key
|
261
|
+
minimalistic = minimalistics(:first)
|
262
|
+
assert_nothing_raised { minimalistic.save }
|
263
|
+
end
|
225
264
|
|
226
265
|
def test_write_attribute
|
227
266
|
topic = Topic.new
|
@@ -281,25 +320,59 @@ class BasicsTest < Test::Unit::TestCase
|
|
281
320
|
assert topic.approved?, "approved should be true"
|
282
321
|
# puts ""
|
283
322
|
end
|
284
|
-
|
285
|
-
def
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
323
|
+
|
324
|
+
def test_query_attribute_string
|
325
|
+
[nil, "", " "].each do |value|
|
326
|
+
assert_equal false, Topic.new(:author_name => value).author_name?
|
327
|
+
end
|
328
|
+
|
329
|
+
assert_equal true, Topic.new(:author_name => "Name").author_name?
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_query_attribute_number
|
333
|
+
[nil, 0, "0"].each do |value|
|
334
|
+
assert_equal false, Developer.new(:salary => value).salary?
|
295
335
|
end
|
336
|
+
|
337
|
+
assert_equal true, Developer.new(:salary => 1).salary?
|
338
|
+
assert_equal true, Developer.new(:salary => "1").salary?
|
296
339
|
end
|
340
|
+
|
341
|
+
def test_query_attribute_boolean
|
342
|
+
[nil, "", false, "false", "f", 0].each do |value|
|
343
|
+
assert_equal false, Topic.new(:approved => value).approved?
|
344
|
+
end
|
345
|
+
|
346
|
+
[true, "true", "1", 1].each do |value|
|
347
|
+
assert_equal true, Topic.new(:approved => value).approved?
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
def test_query_attribute_with_custom_fields
|
352
|
+
object = Company.find_by_sql(<<-SQL).first
|
353
|
+
SELECT c1.*, c2.ruby_type as string_value, c2.rating as int_value
|
354
|
+
FROM companies c1, companies c2
|
355
|
+
WHERE c1.firm_id = c2.id
|
356
|
+
AND c1.id = 2
|
357
|
+
SQL
|
358
|
+
|
359
|
+
assert_equal "Firm", object.string_value
|
360
|
+
assert object.string_value?
|
361
|
+
|
362
|
+
object.string_value = " "
|
363
|
+
assert !object.string_value?
|
364
|
+
|
365
|
+
assert_equal 1, object.int_value.to_i
|
366
|
+
assert object.int_value?
|
367
|
+
|
368
|
+
object.int_value = "0"
|
369
|
+
assert !object.int_value?
|
370
|
+
end
|
371
|
+
|
297
372
|
|
298
373
|
def test_reader_for_invalid_column_names
|
299
|
-
|
300
|
-
|
301
|
-
topic.send(:define_read_method, "mumub-jumbo".to_sym, "mumub-jumbo", nil)
|
302
|
-
assert !Topic.read_methods.include?("mumub-jumbo")
|
374
|
+
Topic.send(:define_read_method, "mumub-jumbo".to_sym, "mumub-jumbo", nil)
|
375
|
+
assert !Topic.generated_methods.include?("mumub-jumbo")
|
303
376
|
end
|
304
377
|
|
305
378
|
def test_non_attribute_access_and_assignment
|
@@ -313,8 +386,9 @@ class BasicsTest < Test::Unit::TestCase
|
|
313
386
|
# SQL Server doesn't have a separate column type just for dates, so all are returned as time
|
314
387
|
return true if current_adapter?(:SQLServerAdapter)
|
315
388
|
|
316
|
-
if current_adapter?(:SybaseAdapter)
|
389
|
+
if current_adapter?(:SybaseAdapter, :OracleAdapter)
|
317
390
|
# Sybase ctlib does not (yet?) support the date type; use datetime instead.
|
391
|
+
# Oracle treats all dates/times as Time.
|
318
392
|
assert_kind_of(
|
319
393
|
Time, Topic.find(1).last_read,
|
320
394
|
"The last_read attribute should be of the Time class"
|
@@ -345,6 +419,13 @@ class BasicsTest < Test::Unit::TestCase
|
|
345
419
|
assert_equal 9900, Topic.find(2).written_on.usec
|
346
420
|
end
|
347
421
|
end
|
422
|
+
|
423
|
+
def test_custom_mutator
|
424
|
+
topic = Topic.find(1)
|
425
|
+
# This mutator is protected in the class definition
|
426
|
+
topic.send(:approved=, true)
|
427
|
+
assert topic.instance_variable_get("@custom_approved")
|
428
|
+
end
|
348
429
|
|
349
430
|
def test_destroy
|
350
431
|
topic = Topic.find(1)
|
@@ -486,17 +567,33 @@ class BasicsTest < Test::Unit::TestCase
|
|
486
567
|
Topic.decrement_counter("replies_count", 2)
|
487
568
|
assert_equal -2, Topic.find(2).replies_count
|
488
569
|
end
|
489
|
-
|
490
|
-
def test_update_all
|
491
|
-
# The ADO library doesn't support the number of affected rows
|
492
|
-
return true if current_adapter?(:SQLServerAdapter)
|
493
570
|
|
571
|
+
def test_update_all
|
494
572
|
assert_equal 2, Topic.update_all("content = 'bulk updated!'")
|
495
573
|
assert_equal "bulk updated!", Topic.find(1).content
|
496
574
|
assert_equal "bulk updated!", Topic.find(2).content
|
575
|
+
|
497
576
|
assert_equal 2, Topic.update_all(['content = ?', 'bulk updated again!'])
|
498
577
|
assert_equal "bulk updated again!", Topic.find(1).content
|
499
578
|
assert_equal "bulk updated again!", Topic.find(2).content
|
579
|
+
|
580
|
+
assert_equal 2, Topic.update_all(['content = ?', nil])
|
581
|
+
assert_nil Topic.find(1).content
|
582
|
+
end
|
583
|
+
|
584
|
+
def test_update_all_with_hash
|
585
|
+
assert_not_nil Topic.find(1).last_read
|
586
|
+
assert_equal 2, Topic.update_all(:content => 'bulk updated with hash!', :last_read => nil)
|
587
|
+
assert_equal "bulk updated with hash!", Topic.find(1).content
|
588
|
+
assert_equal "bulk updated with hash!", Topic.find(2).content
|
589
|
+
assert_nil Topic.find(1).last_read
|
590
|
+
assert_nil Topic.find(2).last_read
|
591
|
+
end
|
592
|
+
|
593
|
+
if current_adapter?(:MysqlAdapter)
|
594
|
+
def test_update_all_with_order_and_limit
|
595
|
+
assert_equal 1, Topic.update_all("content = 'bulk updated!'", nil, :limit => 1, :order => 'id DESC')
|
596
|
+
end
|
500
597
|
end
|
501
598
|
|
502
599
|
def test_update_many
|
@@ -509,9 +606,6 @@ class BasicsTest < Test::Unit::TestCase
|
|
509
606
|
end
|
510
607
|
|
511
608
|
def test_delete_all
|
512
|
-
# The ADO library doesn't support the number of affected rows
|
513
|
-
return true if current_adapter?(:SQLServerAdapter)
|
514
|
-
|
515
609
|
assert_equal 2, Topic.delete_all
|
516
610
|
end
|
517
611
|
|
@@ -695,11 +789,27 @@ class BasicsTest < Test::Unit::TestCase
|
|
695
789
|
assert_raise(ActiveRecord::RecordInvalid) { reply.update_attributes!(:title => nil, :content => "Have a nice evening") }
|
696
790
|
end
|
697
791
|
|
792
|
+
def test_mass_assignment_should_raise_exception_if_accessible_and_protected_attribute_writers_are_both_used
|
793
|
+
topic = TopicWithProtectedContentAndAccessibleAuthorName.new
|
794
|
+
assert_raises(RuntimeError) { topic.attributes = { "author_name" => "me" } }
|
795
|
+
assert_raises(RuntimeError) { topic.attributes = { "content" => "stuff" } }
|
796
|
+
end
|
797
|
+
|
698
798
|
def test_mass_assignment_protection
|
699
799
|
firm = Firm.new
|
700
800
|
firm.attributes = { "name" => "Next Angle", "rating" => 5 }
|
701
801
|
assert_equal 1, firm.rating
|
702
802
|
end
|
803
|
+
|
804
|
+
def test_mass_assignment_protection_against_class_attribute_writers
|
805
|
+
[:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :colorize_logging,
|
806
|
+
:default_timezone, :allow_concurrency, :schema_format, :verification_timeout, :lock_optimistically, :record_timestamps].each do |method|
|
807
|
+
assert Task.respond_to?(method)
|
808
|
+
assert Task.respond_to?("#{method}=")
|
809
|
+
assert Task.new.respond_to?(method)
|
810
|
+
assert !Task.new.respond_to?("#{method}=")
|
811
|
+
end
|
812
|
+
end
|
703
813
|
|
704
814
|
def test_customized_primary_key_remains_protected
|
705
815
|
subscriber = Subscriber.new(:nick => 'webster123', :name => 'nice try')
|
@@ -709,7 +819,7 @@ class BasicsTest < Test::Unit::TestCase
|
|
709
819
|
assert_nil keyboard.id
|
710
820
|
end
|
711
821
|
|
712
|
-
def
|
822
|
+
def test_customized_primary_key_remains_protected_when_referred_to_as_id
|
713
823
|
subscriber = Subscriber.new(:id => 'webster123', :name => 'nice try')
|
714
824
|
assert_nil subscriber.id
|
715
825
|
|
@@ -738,16 +848,32 @@ class BasicsTest < Test::Unit::TestCase
|
|
738
848
|
|
739
849
|
def test_mass_assignment_protection_inheritance
|
740
850
|
assert_nil LoosePerson.accessible_attributes
|
741
|
-
assert_equal [
|
851
|
+
assert_equal Set.new([ 'credit_rating', 'administrator' ]), LoosePerson.protected_attributes
|
742
852
|
|
743
853
|
assert_nil LooseDescendant.accessible_attributes
|
744
|
-
assert_equal [
|
854
|
+
assert_equal Set.new([ 'credit_rating', 'administrator', 'phone_number' ]), LooseDescendant.protected_attributes
|
855
|
+
|
856
|
+
assert_nil LooseDescendantSecond.accessible_attributes
|
857
|
+
assert_equal Set.new([ 'credit_rating', 'administrator', 'phone_number', 'name' ]), LooseDescendantSecond.protected_attributes, 'Running attr_protected twice in one class should merge the protections'
|
745
858
|
|
746
859
|
assert_nil TightPerson.protected_attributes
|
747
|
-
assert_equal [
|
860
|
+
assert_equal Set.new([ 'name', 'address' ]), TightPerson.accessible_attributes
|
748
861
|
|
749
862
|
assert_nil TightDescendant.protected_attributes
|
750
|
-
assert_equal [
|
863
|
+
assert_equal Set.new([ 'name', 'address', 'phone_number' ]), TightDescendant.accessible_attributes
|
864
|
+
end
|
865
|
+
|
866
|
+
def test_readonly_attributes
|
867
|
+
assert_equal Set.new([ 'title' ]), ReadonlyTitlePost.readonly_attributes
|
868
|
+
|
869
|
+
post = ReadonlyTitlePost.create(:title => "cannot change this", :body => "changeable")
|
870
|
+
post.reload
|
871
|
+
assert_equal "cannot change this", post.title
|
872
|
+
|
873
|
+
post.update_attributes(:title => "try to change", :body => "changed")
|
874
|
+
post.reload
|
875
|
+
assert_equal "cannot change this", post.title
|
876
|
+
assert_equal "changed", post.body
|
751
877
|
end
|
752
878
|
|
753
879
|
def test_multiparameter_attributes_on_date
|
@@ -867,6 +993,10 @@ class BasicsTest < Test::Unit::TestCase
|
|
867
993
|
cloned_topic.title["a"] = "c"
|
868
994
|
assert_equal "b", topic.title["a"]
|
869
995
|
|
996
|
+
#test if attributes set as part of after_initialize are cloned correctly
|
997
|
+
assert_equal topic.author_email_address, cloned_topic.author_email_address
|
998
|
+
|
999
|
+
# test if saved clone object differs from original
|
870
1000
|
cloned_topic.save
|
871
1001
|
assert !cloned_topic.new_record?
|
872
1002
|
assert cloned_topic.id != topic.id
|
@@ -1003,18 +1133,18 @@ class BasicsTest < Test::Unit::TestCase
|
|
1003
1133
|
# As with migration_test.rb, we should make world_population >= 2**62
|
1004
1134
|
# to cover 64-bit platforms and test it is a Bignum, but the main thing
|
1005
1135
|
# is that it's an Integer.
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1136
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1137
|
+
assert_kind_of Integer, m1.world_population
|
1138
|
+
else
|
1139
|
+
assert_kind_of BigDecimal, m1.world_population
|
1140
|
+
end
|
1011
1141
|
assert_equal 6000000000, m1.world_population
|
1012
1142
|
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1143
|
+
unless current_adapter?(:IBM_DBAdapter)
|
1144
|
+
assert_kind_of Fixnum, m1.my_house_population
|
1145
|
+
else
|
1146
|
+
assert_kind_of BigDecimal, m1.my_house_population
|
1147
|
+
end
|
1018
1148
|
assert_equal 3, m1.my_house_population
|
1019
1149
|
|
1020
1150
|
assert_kind_of BigDecimal, m1.bank_balance
|
@@ -1076,16 +1206,29 @@ class BasicsTest < Test::Unit::TestCase
|
|
1076
1206
|
assert_equal(myobj, topic.content)
|
1077
1207
|
end
|
1078
1208
|
|
1079
|
-
def
|
1209
|
+
def test_nil_serialized_attribute_with_class_constraint
|
1080
1210
|
myobj = MyObject.new('value1', 'value2')
|
1081
|
-
topic = Topic.
|
1082
|
-
|
1211
|
+
topic = Topic.new
|
1212
|
+
assert_nil topic.content
|
1213
|
+
end
|
1083
1214
|
|
1215
|
+
def test_should_raise_exception_on_serialized_attribute_with_type_mismatch
|
1216
|
+
myobj = MyObject.new('value1', 'value2')
|
1217
|
+
topic = Topic.new(:content => myobj)
|
1218
|
+
assert topic.save
|
1219
|
+
Topic.serialize(:content, Hash)
|
1084
1220
|
assert_raise(ActiveRecord::SerializationTypeMismatch) { Topic.find(topic.id).content }
|
1221
|
+
ensure
|
1222
|
+
Topic.serialize(:content)
|
1223
|
+
end
|
1085
1224
|
|
1225
|
+
def test_serialized_attribute_with_class_constraint
|
1086
1226
|
settings = { "color" => "blue" }
|
1087
|
-
Topic.
|
1227
|
+
Topic.serialize(:content, Hash)
|
1228
|
+
topic = Topic.new(:content => settings)
|
1229
|
+
assert topic.save
|
1088
1230
|
assert_equal(settings, Topic.find(topic.id).content)
|
1231
|
+
ensure
|
1089
1232
|
Topic.serialize(:content)
|
1090
1233
|
end
|
1091
1234
|
|
@@ -1126,12 +1269,12 @@ class BasicsTest < Test::Unit::TestCase
|
|
1126
1269
|
end
|
1127
1270
|
|
1128
1271
|
def test_increment_attribute
|
1129
|
-
assert_equal
|
1130
|
-
|
1131
|
-
assert_equal
|
1132
|
-
|
1133
|
-
|
1134
|
-
assert_equal
|
1272
|
+
assert_equal 50, accounts(:signals37).credit_limit
|
1273
|
+
accounts(:signals37).increment! :credit_limit
|
1274
|
+
assert_equal 51, accounts(:signals37, :reload).credit_limit
|
1275
|
+
|
1276
|
+
accounts(:signals37).increment(:credit_limit).increment!(:credit_limit)
|
1277
|
+
assert_equal 53, accounts(:signals37, :reload).credit_limit
|
1135
1278
|
end
|
1136
1279
|
|
1137
1280
|
def test_increment_nil_attribute
|
@@ -1141,14 +1284,13 @@ class BasicsTest < Test::Unit::TestCase
|
|
1141
1284
|
end
|
1142
1285
|
|
1143
1286
|
def test_decrement_attribute
|
1144
|
-
|
1145
|
-
assert_equal 3, topics(:first).replies_count
|
1146
|
-
|
1147
|
-
topics(:first).decrement!(:replies_count)
|
1148
|
-
assert_equal 2, topics(:first, :reload).replies_count
|
1287
|
+
assert_equal 50, accounts(:signals37).credit_limit
|
1149
1288
|
|
1150
|
-
|
1151
|
-
assert_equal
|
1289
|
+
accounts(:signals37).decrement!(:credit_limit)
|
1290
|
+
assert_equal 49, accounts(:signals37, :reload).credit_limit
|
1291
|
+
|
1292
|
+
accounts(:signals37).decrement(:credit_limit).decrement!(:credit_limit)
|
1293
|
+
assert_equal 47, accounts(:signals37, :reload).credit_limit
|
1152
1294
|
end
|
1153
1295
|
|
1154
1296
|
def test_toggle_attribute
|
@@ -1227,11 +1369,8 @@ class BasicsTest < Test::Unit::TestCase
|
|
1227
1369
|
|
1228
1370
|
def test_count_with_join
|
1229
1371
|
res = Post.count_by_sql "SELECT COUNT(*) FROM posts LEFT JOIN comments ON posts.id=comments.post_id WHERE posts.#{QUOTED_TYPE} = 'Post'"
|
1230
|
-
|
1231
|
-
|
1232
|
-
res2 = Post.count("posts.#{QUOTED_TYPE} = 'Post'",
|
1233
|
-
"LEFT JOIN comments ON posts.id=comments.post_id")
|
1234
|
-
end
|
1372
|
+
|
1373
|
+
res2 = Post.count(:conditions => "posts.#{QUOTED_TYPE} = 'Post'", :joins => "LEFT JOIN comments ON posts.id=comments.post_id")
|
1235
1374
|
assert_equal res, res2
|
1236
1375
|
|
1237
1376
|
res3 = nil
|
@@ -1251,15 +1390,17 @@ class BasicsTest < Test::Unit::TestCase
|
|
1251
1390
|
|
1252
1391
|
assert_equal res4, res5
|
1253
1392
|
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1393
|
+
unless current_adapter?(:SQLite2Adapter, :DeprecatedSQLiteAdapter)
|
1394
|
+
res6 = Post.count_by_sql "SELECT COUNT(DISTINCT p.id) FROM posts p, comments co WHERE p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id"
|
1395
|
+
res7 = nil
|
1396
|
+
assert_nothing_raised do
|
1397
|
+
res7 = Post.count(:conditions => "p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id",
|
1398
|
+
:joins => "p, comments co",
|
1399
|
+
:select => "p.id",
|
1400
|
+
:distinct => true)
|
1401
|
+
end
|
1402
|
+
assert_equal res6, res7
|
1261
1403
|
end
|
1262
|
-
assert_equal res6, res7
|
1263
1404
|
end
|
1264
1405
|
|
1265
1406
|
def test_clear_association_cache_stored
|
@@ -1276,12 +1417,12 @@ class BasicsTest < Test::Unit::TestCase
|
|
1276
1417
|
client_new = Client.new
|
1277
1418
|
client_new.name = "The Joneses"
|
1278
1419
|
clients = [ client_stored, client_new ]
|
1279
|
-
|
1420
|
+
|
1280
1421
|
firm.clients << clients
|
1422
|
+
assert_equal clients.map(&:name).to_set, firm.clients.map(&:name).to_set
|
1281
1423
|
|
1282
1424
|
firm.clear_association_cache
|
1283
|
-
|
1284
|
-
assert_equal firm.clients.collect{ |x| x.name }.sort, clients.collect{ |x| x.name }.sort
|
1425
|
+
assert_equal clients.map(&:name).to_set, firm.clients.map(&:name).to_set
|
1285
1426
|
end
|
1286
1427
|
|
1287
1428
|
def test_interpolate_sql
|
@@ -1401,15 +1542,14 @@ class BasicsTest < Test::Unit::TestCase
|
|
1401
1542
|
|
1402
1543
|
def test_find_on_abstract_base_class_doesnt_use_type_condition
|
1403
1544
|
old_class = LooseDescendant
|
1404
|
-
|
1405
1545
|
Object.send :remove_const, :LooseDescendant
|
1406
|
-
descendant = old_class.create!
|
1407
1546
|
|
1547
|
+
descendant = old_class.create!
|
1408
1548
|
assert_not_nil LoosePerson.find(descendant.id), "Should have found instance of LooseDescendant when finding abstract LoosePerson: #{descendant.inspect}"
|
1409
|
-
|
1410
|
-
|
1411
|
-
|
1412
|
-
|
1549
|
+
ensure
|
1550
|
+
unless Object.const_defined?(:LooseDescendant)
|
1551
|
+
Object.const_set :LooseDescendant, old_class
|
1552
|
+
end
|
1413
1553
|
end
|
1414
1554
|
|
1415
1555
|
def test_assert_queries
|
@@ -1420,30 +1560,52 @@ class BasicsTest < Test::Unit::TestCase
|
|
1420
1560
|
end
|
1421
1561
|
|
1422
1562
|
def test_to_xml
|
1423
|
-
xml = topics(:first).to_xml(:indent => 0
|
1563
|
+
xml = REXML::Document.new(topics(:first).to_xml(:indent => 0))
|
1424
1564
|
bonus_time_in_current_timezone = topics(:first).bonus_time.xmlschema
|
1425
1565
|
written_on_in_current_timezone = topics(:first).written_on.xmlschema
|
1426
1566
|
last_read_in_current_timezone = topics(:first).last_read.xmlschema
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1567
|
+
|
1568
|
+
assert_equal "topic", xml.root.name
|
1569
|
+
assert_equal "The First Topic" , xml.elements["//title"].text
|
1570
|
+
assert_equal "David" , xml.elements["//author-name"].text
|
1571
|
+
|
1572
|
+
assert_equal "1", xml.elements["//id"].text
|
1573
|
+
unless ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_IDS')
|
1574
|
+
assert_equal "integer" , xml.elements["//id"].attributes['type']
|
1575
|
+
else
|
1576
|
+
assert_equal "serial" , xml.elements["//id"].attributes['type']
|
1577
|
+
end
|
1578
|
+
|
1579
|
+
assert_equal "1", xml.elements["//replies-count"].text
|
1580
|
+
assert_equal "integer" , xml.elements["//replies-count"].attributes['type']
|
1581
|
+
|
1582
|
+
assert_equal written_on_in_current_timezone, xml.elements["//written-on"].text
|
1583
|
+
assert_equal "datetime" , xml.elements["//written-on"].attributes['type']
|
1584
|
+
|
1585
|
+
assert_equal "--- Have a nice day\n" , xml.elements["//content"].text
|
1586
|
+
assert_equal "yaml" , xml.elements["//content"].attributes['type']
|
1587
|
+
|
1588
|
+
assert_equal "david@loudthinking.com", xml.elements["//author-email-address"].text
|
1589
|
+
|
1590
|
+
assert_equal nil, xml.elements["//parent-id"].text
|
1591
|
+
assert_equal "integer", xml.elements["//parent-id"].attributes['type']
|
1592
|
+
assert_equal "true", xml.elements["//parent-id"].attributes['nil']
|
1593
|
+
|
1438
1594
|
if current_adapter?(:SybaseAdapter, :SQLServerAdapter, :OracleAdapter)
|
1439
|
-
|
1595
|
+
assert_equal last_read_in_current_timezone, xml.elements["//last-read"].text
|
1596
|
+
assert_equal "datetime" , xml.elements["//last-read"].attributes['type']
|
1440
1597
|
else
|
1441
|
-
|
1598
|
+
assert_equal "2004-04-15", xml.elements["//last-read"].text
|
1599
|
+
assert_equal "date" , xml.elements["//last-read"].attributes['type']
|
1442
1600
|
end
|
1601
|
+
|
1443
1602
|
# Oracle and DB2 don't have true boolean or time-only fields
|
1444
|
-
unless current_adapter?(:OracleAdapter, :DB2Adapter
|
1445
|
-
|
1446
|
-
|
1603
|
+
unless current_adapter?(:OracleAdapter, :DB2Adapter)
|
1604
|
+
assert_equal "false", xml.elements["//approved"].text
|
1605
|
+
assert_equal "boolean" , xml.elements["//approved"].attributes['type']
|
1606
|
+
|
1607
|
+
assert_equal bonus_time_in_current_timezone, xml.elements["//bonus-time"].text
|
1608
|
+
assert_equal "datetime" , xml.elements["//bonus-time"].attributes['type']
|
1447
1609
|
end
|
1448
1610
|
end
|
1449
1611
|
|
@@ -1461,13 +1623,13 @@ class BasicsTest < Test::Unit::TestCase
|
|
1461
1623
|
def test_to_xml_including_has_many_association
|
1462
1624
|
xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :include => :replies, :except => :replies_count)
|
1463
1625
|
assert_equal "<topic>", xml.first(7)
|
1464
|
-
assert xml.include?(%(<replies><reply>))
|
1626
|
+
assert xml.include?(%(<replies type="array"><reply>))
|
1465
1627
|
assert xml.include?(%(<title>The Second Topic's of the day</title>))
|
1466
1628
|
end
|
1467
1629
|
|
1468
1630
|
def test_array_to_xml_including_has_many_association
|
1469
1631
|
xml = [ topics(:first), topics(:second) ].to_xml(:indent => 0, :skip_instruct => true, :include => :replies)
|
1470
|
-
assert xml.include?(%(<replies><reply>))
|
1632
|
+
assert xml.include?(%(<replies type="array"><reply>))
|
1471
1633
|
end
|
1472
1634
|
|
1473
1635
|
def test_array_to_xml_including_methods
|
@@ -1501,7 +1663,7 @@ class BasicsTest < Test::Unit::TestCase
|
|
1501
1663
|
xml = companies(:first_firm).to_xml(:indent => 0, :skip_instruct => true, :include => [ :clients, :account ])
|
1502
1664
|
assert_equal "<firm>", xml.first(6)
|
1503
1665
|
assert xml.include?(%(<account>))
|
1504
|
-
assert xml.include?(%(<clients><client>))
|
1666
|
+
assert xml.include?(%(<clients type="array"><client>))
|
1505
1667
|
end
|
1506
1668
|
|
1507
1669
|
def test_to_xml_including_multiple_associations_with_options
|
@@ -1512,7 +1674,7 @@ class BasicsTest < Test::Unit::TestCase
|
|
1512
1674
|
|
1513
1675
|
assert_equal "<firm>", xml.first(6)
|
1514
1676
|
assert xml.include?(%(<client><name>Summit</name></client>))
|
1515
|
-
assert xml.include?(%(<clients><client>))
|
1677
|
+
assert xml.include?(%(<clients type="array"><client>))
|
1516
1678
|
end
|
1517
1679
|
|
1518
1680
|
def test_to_xml_including_methods
|
@@ -1521,6 +1683,15 @@ class BasicsTest < Test::Unit::TestCase
|
|
1521
1683
|
assert xml.include?(%(<arbitrary-method>I am Jack's profound disappointment</arbitrary-method>))
|
1522
1684
|
end
|
1523
1685
|
|
1686
|
+
def test_to_xml_with_block
|
1687
|
+
value = "Rockin' the block"
|
1688
|
+
xml = Company.new.to_xml(:skip_instruct => true) do |xml|
|
1689
|
+
xml.tag! "arbitrary-element", value
|
1690
|
+
end
|
1691
|
+
assert_equal "<company>", xml.first(9)
|
1692
|
+
assert xml.include?(%(<arbitrary-element>#{value}</arbitrary-element>))
|
1693
|
+
end
|
1694
|
+
|
1524
1695
|
def test_except_attributes
|
1525
1696
|
assert_equal(
|
1526
1697
|
%w( author_name type id approved replies_count bonus_time written_on content author_email_address parent_id last_read),
|
@@ -1546,34 +1717,45 @@ class BasicsTest < Test::Unit::TestCase
|
|
1546
1717
|
def test_to_param_should_return_string
|
1547
1718
|
assert_kind_of String, Client.find(:first).to_param
|
1548
1719
|
end
|
1720
|
+
|
1721
|
+
def test_inspect_class
|
1722
|
+
assert_equal 'ActiveRecord::Base', ActiveRecord::Base.inspect
|
1723
|
+
assert_equal 'LoosePerson(abstract)', LoosePerson.inspect
|
1724
|
+
unless ActiveRecord::Base.connection.servertype.class.name.include?('::IBM_IDS')
|
1725
|
+
assert_match(/^Topic\(id: integer, title: string/, Topic.inspect)
|
1726
|
+
else
|
1727
|
+
assert_match(/^Topic\(id: serial, title: string/, Topic.inspect)
|
1728
|
+
end
|
1729
|
+
end
|
1730
|
+
|
1731
|
+
def test_inspect_instance
|
1732
|
+
topic = topics(:first)
|
1733
|
+
assert_equal %(#<Topic id: 1, title: "The First Topic", author_name: "David", author_email_address: "david@loudthinking.com", written_on: "#{topic.written_on.to_s(:db)}", bonus_time: "#{topic.bonus_time.to_s(:db)}", last_read: "#{topic.last_read.to_s(:db)}", content: "Have a nice day", approved: false, replies_count: 1, parent_id: nil, type: nil>), topic.inspect
|
1734
|
+
end
|
1735
|
+
|
1736
|
+
def test_inspect_new_instance
|
1737
|
+
assert_match /Topic id: nil/, Topic.new.inspect
|
1738
|
+
end
|
1549
1739
|
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
# counts = []
|
1555
|
-
# 2.times do
|
1556
|
-
# require_dependency 'fixtures/company'
|
1557
|
-
# Firm.find(:first)
|
1558
|
-
# Dependencies.clear
|
1559
|
-
# ActiveRecord::Base.reset_subclasses
|
1560
|
-
# Dependencies.remove_subclasses_for(ActiveRecord::Base)
|
1561
|
-
#
|
1562
|
-
# GC.start
|
1563
|
-
#
|
1564
|
-
# count = 0
|
1565
|
-
# ObjectSpace.each_object(Proc) { count += 1 }
|
1566
|
-
# counts << count
|
1567
|
-
# end
|
1568
|
-
# assert counts.last <= counts.first,
|
1569
|
-
# "expected last count (#{counts.last}) to be <= first count (#{counts.first})"
|
1570
|
-
#end
|
1740
|
+
def test_inspect_limited_select_instance
|
1741
|
+
assert_equal %(#<Topic id: 1>), Topic.find(:first, :select => 'id', :conditions => 'id = 1').inspect
|
1742
|
+
assert_equal %(#<Topic id: 1, title: "The First Topic">), Topic.find(:first, :select => 'id, title', :conditions => 'id = 1').inspect
|
1743
|
+
end
|
1571
1744
|
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1745
|
+
def test_inspect_class_without_table
|
1746
|
+
assert_equal "NonExistentTable(Table doesn't exist)", NonExistentTable.inspect
|
1747
|
+
end
|
1748
|
+
|
1749
|
+
def test_attribute_for_inspect
|
1750
|
+
t = topics(:first)
|
1751
|
+
t.title = "The First Topic Now Has A Title With\nNewlines And More Than 50 Characters"
|
1752
|
+
|
1753
|
+
assert_equal %("#{t.written_on.to_s(:db)}"), t.attribute_for_inspect(:written_on)
|
1754
|
+
assert_equal '"The First Topic Now Has A Title With\nNewlines And M..."', t.attribute_for_inspect(:title)
|
1755
|
+
end
|
1756
|
+
|
1757
|
+
def test_becomes
|
1758
|
+
assert_kind_of Reply, topics(:first).becomes(Reply)
|
1759
|
+
assert_equal "The First Topic", topics(:first).becomes(Reply).title
|
1760
|
+
end
|
1579
1761
|
end
|