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/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 BasicsTest < Test::Unit::TestCase
57
- fixtures :topics, :companies, :developers, :projects, :computers, :accounts
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 test_reader_generation
286
- Topic.find(:first).title
287
- Firm.find(:first).name
288
- Client.find(:first).name
289
- if ActiveRecord::Base.generate_read_methods
290
- assert_readers(Topic, %w(type replies_count))
291
- assert_readers(Firm, %w(type))
292
- assert_readers(Client, %w(type ruby_type rating?))
293
- else
294
- [Topic, Firm, Client].each {|klass| assert_equal klass.read_methods, {}}
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
- # column names which aren't legal ruby ids
300
- topic = Topic.find(:first)
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 test_customized_primary_key_remains_protected_when_refered_to_as_id
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 [ :credit_rating, :administrator ], LoosePerson.protected_attributes
851
+ assert_equal Set.new([ 'credit_rating', 'administrator' ]), LoosePerson.protected_attributes
742
852
 
743
853
  assert_nil LooseDescendant.accessible_attributes
744
- assert_equal [ :credit_rating, :administrator, :phone_number ], LooseDescendant.protected_attributes
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 [ :name, :address ], TightPerson.accessible_attributes
860
+ assert_equal Set.new([ 'name', 'address' ]), TightPerson.accessible_attributes
748
861
 
749
862
  assert_nil TightDescendant.protected_attributes
750
- assert_equal [ :name, :address, :phone_number ], TightDescendant.accessible_attributes
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
- unless current_adapter?(:IBM_DBAdapter)
1007
- assert_kind_of Integer, m1.world_population
1008
- else
1009
- assert_kind_of BigDecimal, m1.world_population
1010
- end
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
- unless current_adapter?(:IBM_DBAdapter)
1014
- assert_kind_of Fixnum, m1.my_house_population
1015
- else
1016
- assert_kind_of BigDecimal, m1.my_house_population
1017
- end
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 test_serialized_attribute_with_class_constraint
1209
+ def test_nil_serialized_attribute_with_class_constraint
1080
1210
  myobj = MyObject.new('value1', 'value2')
1081
- topic = Topic.create("content" => myobj)
1082
- Topic.serialize(:content, Hash)
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.find(topic.id).update_attribute("content", settings)
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 1, topics(:first).replies_count
1130
- topics(:first).increment! :replies_count
1131
- assert_equal 2, topics(:first, :reload).replies_count
1132
-
1133
- topics(:first).increment(:replies_count).increment!(:replies_count)
1134
- assert_equal 4, topics(:first, :reload).replies_count
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
- topics(:first).increment(:replies_count).increment!(:replies_count)
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
- topics(:first).decrement(:replies_count).decrement!(:replies_count)
1151
- assert_equal 0, topics(:first, :reload).replies_count
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
- res2 = nil
1231
- assert_deprecated 'count' do
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
- 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"
1255
- res7 = nil
1256
- assert_nothing_raised do
1257
- res7 = Post.count(:conditions => "p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id",
1258
- :joins => "p, comments co",
1259
- :select => "p.id",
1260
- :distinct => true)
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
- ensure
1410
- unless Object.const_defined?(:LooseDescendant)
1411
- Object.const_set :LooseDescendant, old_class
1412
- end
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, :skip_instruct => true)
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
- assert_equal "<topic>", xml.first(7)
1428
- assert xml.include?(%(<title>The First Topic</title>))
1429
- assert xml.include?(%(<author-name>David</author-name>))
1430
- assert xml.include?(%(<id type="integer">1</id>))
1431
- assert xml.include?(%(<replies-count type="integer">1</replies-count>))
1432
- unless current_adapter?(:IBM_DBAdapter)
1433
- assert xml.include?(%(<written-on type="datetime">#{written_on_in_current_timezone}</written-on>))
1434
- end
1435
- assert xml.include?(%(<content>Have a nice day</content>))
1436
- assert xml.include?(%(<author-email-address>david@loudthinking.com</author-email-address>))
1437
- assert xml.match(%(<parent-id type="integer"></parent-id>))
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
- assert xml.include?(%(<last-read type="datetime">#{last_read_in_current_timezone}</last-read>))
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
- assert xml.include?(%(<last-read type="date">2004-04-15</last-read>))
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, :IBM_DBAdapter)
1445
- assert xml.include?(%(<approved type="boolean">false</approved>)), "Approved should be a boolean"
1446
- assert xml.include?(%(<bonus-time type="datetime">#{bonus_time_in_current_timezone}</bonus-time>))
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
- # FIXME: this test ought to run, but it needs to run sandboxed so that it
1551
- # doesn't b0rk the current test environment by undefing everything.
1552
- #
1553
- #def test_dev_mode_memory_leak
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
- private
1573
- def assert_readers(model, exceptions)
1574
- expected_readers = Set.new(model.column_names - ['id'])
1575
- expected_readers += expected_readers.map { |col| "#{col}?" }
1576
- expected_readers -= exceptions
1577
- assert_equal expected_readers, model.read_methods
1578
- end
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