ibm_db 1.0.0 → 1.0.1
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 +6 -0
- data/README +17 -17
- data/ext/extconf.rb +18 -15
- data/ext/ibm_db.c +91 -3
- data/ext/ruby_ibm_db.h +17 -0
- data/lib/active_record/connection_adapters/ibm_db_adapter.rb +65 -39
- data/test/cases/adapter_test.rb +6 -0
- data/test/cases/associations/eager_test.rb +54 -5
- data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +71 -4
- data/test/cases/associations/has_many_through_associations_test.rb +50 -3
- data/test/cases/base_test.rb +106 -34
- data/test/cases/calculations_test.rb +5 -0
- data/test/cases/finder_test.rb +162 -11
- data/test/cases/fixtures_test.rb +32 -3
- data/test/cases/migration_test.rb +60 -22
- data/test/cases/validations_test.rb +44 -33
- data/test/schema/schema.rb +13 -2
- metadata +2 -2
@@ -68,6 +68,16 @@ class DeveloperWithSymbolsForKeys < ActiveRecord::Base
|
|
68
68
|
:foreign_key => "developer_id"
|
69
69
|
end
|
70
70
|
|
71
|
+
class DeveloperWithCounterSQL < ActiveRecord::Base
|
72
|
+
set_table_name 'developers'
|
73
|
+
has_and_belongs_to_many :projects,
|
74
|
+
:class_name => "DeveloperWithCounterSQL",
|
75
|
+
:join_table => "developers_projects",
|
76
|
+
:association_foreign_key => "project_id",
|
77
|
+
:foreign_key => "developer_id",
|
78
|
+
:counter_sql => 'SELECT COUNT(*) AS count_all FROM projects INNER JOIN developers_projects ON projects.id = developers_projects.project_id WHERE developers_projects.developer_id =#{id}'
|
79
|
+
end
|
80
|
+
|
71
81
|
class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
72
82
|
fixtures :accounts, :companies, :categories, :posts, :categories_posts, :developers, :projects, :developers_projects,
|
73
83
|
:parrots, :pirates, :treasures, :price_estimates, :tags, :taggings
|
@@ -253,8 +263,8 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
253
263
|
assert !devel.projects.loaded?
|
254
264
|
|
255
265
|
assert_equal devel.projects.last, proj
|
256
|
-
assert devel.projects.loaded?
|
257
|
-
|
266
|
+
assert !devel.projects.loaded?
|
267
|
+
|
258
268
|
assert !proj.new_record?
|
259
269
|
assert_equal Developer.find(1).projects.sort_by(&:id).last, proj # prove join table is updated
|
260
270
|
end
|
@@ -636,11 +646,39 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
636
646
|
assert_equal 3, Developer.find(:all, :include => {:projects => :developers}, :conditions => 'developers_projects_join.joined_on IS NOT NULL', :group => group.join(",")).size
|
637
647
|
end
|
638
648
|
|
649
|
+
def test_find_grouped
|
650
|
+
all_posts_from_category1 = Post.find(:all, :conditions => "category_id = 1", :joins => :categories)
|
651
|
+
grouped_posts_of_category1 = Post.find(:all, :conditions => "category_id = 1", :group => "author_id", :select => 'count(posts.id) as posts_count', :joins => :categories)
|
652
|
+
assert_equal 4, all_posts_from_category1.size
|
653
|
+
assert_equal 1, grouped_posts_of_category1.size
|
654
|
+
end
|
655
|
+
|
656
|
+
def test_find_scoped_grouped
|
657
|
+
assert_equal 4, categories(:general).posts_gruoped_by_title.size
|
658
|
+
assert_equal 1, categories(:technology).posts_gruoped_by_title.size
|
659
|
+
end
|
660
|
+
|
639
661
|
def test_get_ids
|
640
662
|
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developers(:david).project_ids.sort
|
641
663
|
assert_equal [projects(:active_record).id], developers(:jamis).project_ids
|
642
664
|
end
|
643
665
|
|
666
|
+
def test_get_ids_for_loaded_associations
|
667
|
+
developer = developers(:david)
|
668
|
+
developer.projects(true)
|
669
|
+
assert_queries(0) do
|
670
|
+
developer.project_ids
|
671
|
+
developer.project_ids
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
def test_get_ids_for_unloaded_associations_does_not_load_them
|
676
|
+
developer = developers(:david)
|
677
|
+
assert !developer.projects.loaded?
|
678
|
+
assert_equal projects(:active_record, :action_controller).map(&:id).sort, developer.project_ids.sort
|
679
|
+
assert !developer.projects.loaded?
|
680
|
+
end
|
681
|
+
|
644
682
|
def test_assign_ids
|
645
683
|
developer = Developer.new("name" => "Joe")
|
646
684
|
developer.project_ids = projects(:active_record, :action_controller).map(&:id)
|
@@ -706,5 +744,34 @@ class HasAndBelongsToManyAssociationsTest < ActiveRecord::TestCase
|
|
706
744
|
# due to Unknown column 'authors.id'
|
707
745
|
assert Category.find(1).posts_with_authors_sorted_by_author_id.find_by_title('Welcome to the weblog')
|
708
746
|
end
|
709
|
-
|
710
|
-
|
747
|
+
|
748
|
+
def test_counting_on_habtm_association_and_not_array
|
749
|
+
david = Developer.find(1)
|
750
|
+
# Extra parameter just to make sure we aren't falling back to
|
751
|
+
# Array#count in Ruby >=1.8.7, which would raise an ArgumentError
|
752
|
+
assert_nothing_raised { david.projects.count(:all, :conditions => '1=1') }
|
753
|
+
end
|
754
|
+
|
755
|
+
def test_count
|
756
|
+
david = Developer.find(1)
|
757
|
+
assert_equal 2, david.projects.count
|
758
|
+
end
|
759
|
+
|
760
|
+
def test_count_with_counter_sql
|
761
|
+
developer = DeveloperWithCounterSQL.create(:name => 'tekin')
|
762
|
+
developer.project_ids = [projects(:active_record).id]
|
763
|
+
developer.save
|
764
|
+
developer.reload
|
765
|
+
assert_equal 1, developer.projects.count
|
766
|
+
end
|
767
|
+
|
768
|
+
uses_mocha 'mocking Post.transaction' do
|
769
|
+
def test_association_proxy_transaction_method_starts_transaction_in_association_class
|
770
|
+
Post.expects(:transaction)
|
771
|
+
Category.find(:first).posts.transaction do
|
772
|
+
# nothing
|
773
|
+
end
|
774
|
+
end
|
775
|
+
end
|
776
|
+
end
|
777
|
+
end
|
@@ -2,15 +2,18 @@ require "cases/helper"
|
|
2
2
|
require 'models/post'
|
3
3
|
require 'models/person'
|
4
4
|
require 'models/reader'
|
5
|
+
require 'models/comment'
|
5
6
|
|
6
7
|
class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
7
|
-
fixtures :posts, :readers, :people
|
8
|
+
fixtures :posts, :readers, :people, :comments, :authors
|
8
9
|
|
9
10
|
def test_associate_existing
|
10
11
|
assert_queries(2) { posts(:thinking);people(:david) }
|
11
|
-
|
12
|
+
|
13
|
+
posts(:thinking).people
|
14
|
+
|
12
15
|
assert_queries(1) do
|
13
|
-
|
16
|
+
posts(:thinking).people << people(:david)
|
14
17
|
end
|
15
18
|
|
16
19
|
assert_queries(1) do
|
@@ -199,4 +202,48 @@ class HasManyThroughAssociationsTest < ActiveRecord::TestCase
|
|
199
202
|
def test_count_with_include_should_alias_join_table
|
200
203
|
assert_equal 2, people(:michael).posts.count(:include => :readers)
|
201
204
|
end
|
205
|
+
|
206
|
+
def test_get_ids
|
207
|
+
assert_equal [posts(:welcome).id, posts(:authorless).id].sort, people(:michael).post_ids.sort
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_get_ids_for_loaded_associations
|
211
|
+
person = people(:michael)
|
212
|
+
person.posts(true)
|
213
|
+
assert_queries(0) do
|
214
|
+
person.post_ids
|
215
|
+
person.post_ids
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_get_ids_for_unloaded_associations_does_not_load_them
|
220
|
+
person = people(:michael)
|
221
|
+
assert !person.posts.loaded?
|
222
|
+
assert_equal [posts(:welcome).id, posts(:authorless).id].sort, person.post_ids.sort
|
223
|
+
assert !person.posts.loaded?
|
224
|
+
end
|
225
|
+
|
226
|
+
uses_mocha 'mocking Tag.transaction' do
|
227
|
+
def test_association_proxy_transaction_method_starts_transaction_in_association_class
|
228
|
+
Tag.expects(:transaction)
|
229
|
+
Post.find(:first).tags.transaction do
|
230
|
+
# nothing
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_has_many_association_through_a_belongs_to_association_where_the_association_doesnt_exist
|
236
|
+
author = authors(:mary)
|
237
|
+
post = Post.create!(:title => "TITLE", :body => "BODY")
|
238
|
+
assert_equal [], post.author_favorites
|
239
|
+
end
|
240
|
+
|
241
|
+
def test_has_many_association_through_a_belongs_to_association
|
242
|
+
author = authors(:mary)
|
243
|
+
post = Post.create!(:author => author, :title => "TITLE", :body => "BODY")
|
244
|
+
author.author_favorites.create(:favorite_author_id => 1)
|
245
|
+
author.author_favorites.create(:favorite_author_id => 2)
|
246
|
+
author.author_favorites.create(:favorite_author_id => 3)
|
247
|
+
assert_equal post.author.author_favorites, post.author_favorites
|
248
|
+
end
|
202
249
|
end
|
data/test/cases/base_test.rb
CHANGED
@@ -76,7 +76,7 @@ class TopicWithProtectedContentAndAccessibleAuthorName < ActiveRecord::Base
|
|
76
76
|
end
|
77
77
|
|
78
78
|
class BasicsTest < ActiveRecord::TestCase
|
79
|
-
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, :warehouse_things, :authors, :categorizations, :categories
|
79
|
+
fixtures :topics, :companies, :developers, :projects, :computers, :accounts, :minimalistics, :warehouse_things, :authors, :categorizations, :categories, :posts
|
80
80
|
|
81
81
|
def test_table_exists
|
82
82
|
assert !NonExistentTable.table_exists?
|
@@ -138,7 +138,7 @@ class BasicsTest < ActiveRecord::TestCase
|
|
138
138
|
if current_adapter?(:MysqlAdapter)
|
139
139
|
def test_read_attributes_before_type_cast_on_boolean
|
140
140
|
bool = Booleantest.create({ "value" => false })
|
141
|
-
assert_equal 0, bool.attributes_before_type_cast["value"]
|
141
|
+
assert_equal "0", bool.reload.attributes_before_type_cast["value"]
|
142
142
|
end
|
143
143
|
end
|
144
144
|
|
@@ -428,9 +428,6 @@ class BasicsTest < ActiveRecord::TestCase
|
|
428
428
|
end
|
429
429
|
|
430
430
|
def test_preserving_date_objects
|
431
|
-
# SQL Server doesn't have a separate column type just for dates, so all are returned as time
|
432
|
-
return true if current_adapter?(:SQLServerAdapter)
|
433
|
-
|
434
431
|
if current_adapter?(:SybaseAdapter, :OracleAdapter)
|
435
432
|
# Sybase ctlib does not (yet?) support the date type; use datetime instead.
|
436
433
|
# Oracle treats all dates/times as Time.
|
@@ -471,7 +468,19 @@ class BasicsTest < ActiveRecord::TestCase
|
|
471
468
|
topic.send(:approved=, true)
|
472
469
|
assert topic.instance_variable_get("@custom_approved")
|
473
470
|
end
|
474
|
-
|
471
|
+
|
472
|
+
def test_delete
|
473
|
+
topic = Topic.find(1)
|
474
|
+
assert_equal topic, topic.delete, 'topic.delete did not return self'
|
475
|
+
assert topic.frozen?, 'topic not frozen after delete'
|
476
|
+
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_delete_doesnt_run_callbacks
|
480
|
+
Topic.find(1).delete
|
481
|
+
assert_not_nil Topic.find(2)
|
482
|
+
end
|
483
|
+
|
475
484
|
def test_destroy
|
476
485
|
topic = Topic.find(1)
|
477
486
|
assert_equal topic, topic.destroy, 'topic.destroy did not return self'
|
@@ -663,11 +672,22 @@ class BasicsTest < ActiveRecord::TestCase
|
|
663
672
|
assert_equal 1, Topic.update_all("content = 'bulk updated!'", nil, :limit => 1, :order => 'id DESC')
|
664
673
|
end
|
665
674
|
end
|
666
|
-
|
667
|
-
def
|
668
|
-
author =
|
675
|
+
|
676
|
+
def test_update_all_ignores_order_without_limit_from_association
|
677
|
+
author = authors(:david)
|
678
|
+
assert_nothing_raised do
|
679
|
+
assert_equal author.posts_with_comments_and_categories.length, author.posts_with_comments_and_categories.update_all([ "body = ?", "bulk update!" ])
|
680
|
+
end
|
681
|
+
end
|
682
|
+
|
683
|
+
def test_update_all_with_order_and_limit_updates_subset_only
|
684
|
+
author = authors(:david)
|
669
685
|
assert_nothing_raised do
|
670
|
-
assert_equal
|
686
|
+
assert_equal 1, author.posts_sorted_by_id_limited.size
|
687
|
+
assert_equal 2, author.posts_sorted_by_id_limited.find(:all, :limit => 2).size
|
688
|
+
assert_equal 1, author.posts_sorted_by_id_limited.update_all([ "body = ?", "bulk update!" ])
|
689
|
+
assert_equal "bulk update!", posts(:welcome).body
|
690
|
+
assert_not_equal "bulk update!", posts(:thinking).body
|
671
691
|
end
|
672
692
|
end
|
673
693
|
|
@@ -753,9 +773,9 @@ class BasicsTest < ActiveRecord::TestCase
|
|
753
773
|
assert_equal 3, test.test_int
|
754
774
|
end
|
755
775
|
end
|
756
|
-
|
757
|
-
# Oracle,
|
758
|
-
unless current_adapter?(:
|
776
|
+
|
777
|
+
# Oracle, and Sybase do not have a TIME datatype.
|
778
|
+
unless current_adapter?(:OracleAdapter, :SybaseAdapter)
|
759
779
|
def test_utc_as_time_zone
|
760
780
|
Topic.default_timezone = :utc
|
761
781
|
attributes = { "bonus_time" => "5:42:00AM" }
|
@@ -808,7 +828,21 @@ class BasicsTest < ActiveRecord::TestCase
|
|
808
828
|
def test_hashing
|
809
829
|
assert_equal [ Topic.find(1) ], [ Topic.find(2).topic ] & [ Topic.find(1) ]
|
810
830
|
end
|
811
|
-
|
831
|
+
|
832
|
+
def test_delete_new_record
|
833
|
+
client = Client.new
|
834
|
+
client.delete
|
835
|
+
assert client.frozen?
|
836
|
+
end
|
837
|
+
|
838
|
+
def test_delete_record_with_associations
|
839
|
+
client = Client.find(3)
|
840
|
+
client.delete
|
841
|
+
assert client.frozen?
|
842
|
+
assert_kind_of Firm, client.firm
|
843
|
+
assert_raises(ActiveSupport::FrozenObjectError) { client.name = "something else" }
|
844
|
+
end
|
845
|
+
|
812
846
|
def test_destroy_new_record
|
813
847
|
client = Client.new
|
814
848
|
client.destroy
|
@@ -880,7 +914,7 @@ class BasicsTest < ActiveRecord::TestCase
|
|
880
914
|
|
881
915
|
def test_mass_assignment_protection_against_class_attribute_writers
|
882
916
|
[:logger, :configurations, :primary_key_prefix_type, :table_name_prefix, :table_name_suffix, :pluralize_table_names, :colorize_logging,
|
883
|
-
:default_timezone, :
|
917
|
+
:default_timezone, :schema_format, :lock_optimistically, :record_timestamps].each do |method|
|
884
918
|
assert Task.respond_to?(method)
|
885
919
|
assert Task.respond_to?("#{method}=")
|
886
920
|
assert Task.new.respond_to?(method)
|
@@ -903,7 +937,15 @@ class BasicsTest < ActiveRecord::TestCase
|
|
903
937
|
keyboard = Keyboard.new(:id => 9, :name => 'nice try')
|
904
938
|
assert_nil keyboard.id
|
905
939
|
end
|
906
|
-
|
940
|
+
|
941
|
+
def test_mass_assigning_invalid_attribute
|
942
|
+
firm = Firm.new
|
943
|
+
|
944
|
+
assert_raises(ActiveRecord::UnknownAttributeError) do
|
945
|
+
firm.attributes = { "id" => 5, "type" => "Client", "i_dont_even_exist" => 20 }
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
907
949
|
def test_mass_assignment_protection_on_defaults
|
908
950
|
firm = Firm.new
|
909
951
|
firm.attributes = { "id" => 5, "type" => "Client" }
|
@@ -1112,9 +1154,9 @@ class BasicsTest < ActiveRecord::TestCase
|
|
1112
1154
|
end
|
1113
1155
|
|
1114
1156
|
def test_attributes_on_dummy_time
|
1115
|
-
# Oracle,
|
1116
|
-
return true if current_adapter?(:
|
1117
|
-
|
1157
|
+
# Oracle, and Sybase do not have a TIME datatype.
|
1158
|
+
return true if current_adapter?(:OracleAdapter, :SybaseAdapter)
|
1159
|
+
|
1118
1160
|
attributes = {
|
1119
1161
|
"bonus_time" => "5:42:00AM"
|
1120
1162
|
}
|
@@ -1124,11 +1166,15 @@ class BasicsTest < ActiveRecord::TestCase
|
|
1124
1166
|
end
|
1125
1167
|
|
1126
1168
|
def test_boolean
|
1169
|
+
b_nil = Booleantest.create({ "value" => nil })
|
1170
|
+
nil_id = b_nil.id
|
1127
1171
|
b_false = Booleantest.create({ "value" => false })
|
1128
1172
|
false_id = b_false.id
|
1129
1173
|
b_true = Booleantest.create({ "value" => true })
|
1130
1174
|
true_id = b_true.id
|
1131
|
-
|
1175
|
+
|
1176
|
+
b_nil = Booleantest.find(nil_id)
|
1177
|
+
assert_nil b_nil.value
|
1132
1178
|
b_false = Booleantest.find(false_id)
|
1133
1179
|
assert !b_false.value?
|
1134
1180
|
b_true = Booleantest.find(true_id)
|
@@ -1136,11 +1182,15 @@ class BasicsTest < ActiveRecord::TestCase
|
|
1136
1182
|
end
|
1137
1183
|
|
1138
1184
|
def test_boolean_cast_from_string
|
1185
|
+
b_blank = Booleantest.create({ "value" => "" })
|
1186
|
+
blank_id = b_blank.id
|
1139
1187
|
b_false = Booleantest.create({ "value" => "0" })
|
1140
1188
|
false_id = b_false.id
|
1141
1189
|
b_true = Booleantest.create({ "value" => "1" })
|
1142
1190
|
true_id = b_true.id
|
1143
|
-
|
1191
|
+
|
1192
|
+
b_blank = Booleantest.find(blank_id)
|
1193
|
+
assert_nil b_blank.value
|
1144
1194
|
b_false = Booleantest.find(false_id)
|
1145
1195
|
assert !b_false.value?
|
1146
1196
|
b_true = Booleantest.find(true_id)
|
@@ -1383,6 +1433,12 @@ class BasicsTest < ActiveRecord::TestCase
|
|
1383
1433
|
topic = Topic.create("content" => myobj).reload
|
1384
1434
|
assert_equal(myobj, topic.content)
|
1385
1435
|
end
|
1436
|
+
|
1437
|
+
def test_serialized_string_attribute
|
1438
|
+
myobj = "Yes"
|
1439
|
+
topic = Topic.create("content" => myobj).reload
|
1440
|
+
assert_equal(myobj, topic.content)
|
1441
|
+
end
|
1386
1442
|
|
1387
1443
|
def test_nil_serialized_attribute_with_class_constraint
|
1388
1444
|
myobj = MyObject.new('value1', 'value2')
|
@@ -1418,15 +1474,17 @@ class BasicsTest < ActiveRecord::TestCase
|
|
1418
1474
|
|
1419
1475
|
if RUBY_VERSION < '1.9'
|
1420
1476
|
def test_quote_chars
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1477
|
+
with_kcode('UTF8') do
|
1478
|
+
str = 'The Narrator'
|
1479
|
+
topic = Topic.create(:author_name => str)
|
1480
|
+
assert_equal str, topic.author_name
|
1481
|
+
|
1482
|
+
assert_kind_of ActiveSupport::Multibyte.proxy_class, str.mb_chars
|
1483
|
+
topic = Topic.find_by_author_name(str.mb_chars)
|
1484
|
+
|
1485
|
+
assert_kind_of Topic, topic
|
1486
|
+
assert_equal str, topic.author_name, "The right topic should have been found by name even with name passed as Chars"
|
1487
|
+
end
|
1430
1488
|
end
|
1431
1489
|
end
|
1432
1490
|
|
@@ -1582,8 +1640,8 @@ class BasicsTest < ActiveRecord::TestCase
|
|
1582
1640
|
res5 = nil
|
1583
1641
|
assert_nothing_raised do
|
1584
1642
|
res5 = Post.count(:conditions => "p.#{QUOTED_TYPE} = 'Post' AND p.id=co.post_id",
|
1585
|
-
|
1586
|
-
|
1643
|
+
:joins => "p, comments co",
|
1644
|
+
:select => "p.id")
|
1587
1645
|
end
|
1588
1646
|
|
1589
1647
|
assert_equal res4, res5
|
@@ -1819,8 +1877,8 @@ class BasicsTest < ActiveRecord::TestCase
|
|
1819
1877
|
assert_equal nil, xml.elements["//parent-id"].text
|
1820
1878
|
assert_equal "integer", xml.elements["//parent-id"].attributes['type']
|
1821
1879
|
assert_equal "true", xml.elements["//parent-id"].attributes['nil']
|
1822
|
-
|
1823
|
-
if current_adapter?(:SybaseAdapter, :
|
1880
|
+
|
1881
|
+
if current_adapter?(:SybaseAdapter, :OracleAdapter)
|
1824
1882
|
assert_equal last_read_in_current_timezone, xml.elements["//last-read"].text
|
1825
1883
|
assert_equal "datetime" , xml.elements["//last-read"].attributes['type']
|
1826
1884
|
else
|
@@ -2019,4 +2077,18 @@ class BasicsTest < ActiveRecord::TestCase
|
|
2019
2077
|
ensure
|
2020
2078
|
ActiveRecord::Base.logger = original_logger
|
2021
2079
|
end
|
2080
|
+
|
2081
|
+
private
|
2082
|
+
def with_kcode(kcode)
|
2083
|
+
if RUBY_VERSION < '1.9'
|
2084
|
+
orig_kcode, $KCODE = $KCODE, kcode
|
2085
|
+
begin
|
2086
|
+
yield
|
2087
|
+
ensure
|
2088
|
+
$KCODE = orig_kcode
|
2089
|
+
end
|
2090
|
+
else
|
2091
|
+
yield
|
2092
|
+
end
|
2093
|
+
end
|
2022
2094
|
end
|
@@ -25,6 +25,11 @@ class CalculationsTest < ActiveRecord::TestCase
|
|
25
25
|
def test_should_return_nil_as_average
|
26
26
|
assert_nil NumericData.average(:bank_balance)
|
27
27
|
end
|
28
|
+
|
29
|
+
def test_type_cast_calculated_value_should_convert_db_averages_of_fixnum_class_to_decimal
|
30
|
+
assert_equal 0, NumericData.send(:type_cast_calculated_value, 0, nil, 'avg')
|
31
|
+
assert_equal 53.0, NumericData.send(:type_cast_calculated_value, 53, nil, 'avg')
|
32
|
+
end
|
28
33
|
|
29
34
|
def test_should_get_maximum_of_field
|
30
35
|
assert_equal 60, Account.maximum(:credit_limit)
|
data/test/cases/finder_test.rb
CHANGED
@@ -12,6 +12,57 @@ require 'models/customer'
|
|
12
12
|
require 'models/job'
|
13
13
|
require 'models/categorization'
|
14
14
|
|
15
|
+
class DynamicFinderMatchTest < ActiveRecord::TestCase
|
16
|
+
def test_find_no_match
|
17
|
+
assert_nil ActiveRecord::DynamicFinderMatch.match("not_a_finder")
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_find_by
|
21
|
+
match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location")
|
22
|
+
assert_not_nil match
|
23
|
+
assert match.finder?
|
24
|
+
assert_equal :first, match.finder
|
25
|
+
assert_equal %w(age sex location), match.attribute_names
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_by_bang
|
29
|
+
match = ActiveRecord::DynamicFinderMatch.match("find_by_age_and_sex_and_location!")
|
30
|
+
assert_not_nil match
|
31
|
+
assert match.finder?
|
32
|
+
assert match.bang?
|
33
|
+
assert_equal :first, match.finder
|
34
|
+
assert_equal %w(age sex location), match.attribute_names
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_find_all_by
|
38
|
+
match = ActiveRecord::DynamicFinderMatch.match("find_all_by_age_and_sex_and_location")
|
39
|
+
assert_not_nil match
|
40
|
+
assert match.finder?
|
41
|
+
assert_equal :all, match.finder
|
42
|
+
assert_equal %w(age sex location), match.attribute_names
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_find_or_initialize_by
|
46
|
+
match = ActiveRecord::DynamicFinderMatch.match("find_or_initialize_by_age_and_sex_and_location")
|
47
|
+
assert_not_nil match
|
48
|
+
assert !match.finder?
|
49
|
+
assert match.instantiator?
|
50
|
+
assert_equal :first, match.finder
|
51
|
+
assert_equal :new, match.instantiator
|
52
|
+
assert_equal %w(age sex location), match.attribute_names
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_find_or_create_by
|
56
|
+
match = ActiveRecord::DynamicFinderMatch.match("find_or_create_by_age_and_sex_and_location")
|
57
|
+
assert_not_nil match
|
58
|
+
assert !match.finder?
|
59
|
+
assert match.instantiator?
|
60
|
+
assert_equal :first, match.finder
|
61
|
+
assert_equal :create, match.instantiator
|
62
|
+
assert_equal %w(age sex location), match.attribute_names
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
15
66
|
class FinderTest < ActiveRecord::TestCase
|
16
67
|
fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :comments, :accounts, :authors, :customers
|
17
68
|
|
@@ -117,7 +168,13 @@ class FinderTest < ActiveRecord::TestCase
|
|
117
168
|
assert_equal(1, developers.size)
|
118
169
|
assert_equal("fixture_3", developers.first.name)
|
119
170
|
end
|
120
|
-
|
171
|
+
|
172
|
+
def test_find_with_group
|
173
|
+
developers = Developer.find(:all, :group => "salary", :select => "salary")
|
174
|
+
assert_equal 4, developers.size
|
175
|
+
assert_equal 4, developers.map(&:salary).uniq.size
|
176
|
+
end
|
177
|
+
|
121
178
|
def test_find_with_entire_select_statement
|
122
179
|
topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
|
123
180
|
|
@@ -199,7 +256,24 @@ class FinderTest < ActiveRecord::TestCase
|
|
199
256
|
assert Topic.find(1, :conditions => { 'topics.approved' => false })
|
200
257
|
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { 'topics.approved' => true }) }
|
201
258
|
end
|
202
|
-
|
259
|
+
|
260
|
+
def test_find_on_hash_conditions_with_hashed_table_name
|
261
|
+
assert Topic.find(1, :conditions => {:topics => { :approved => false }})
|
262
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => {:topics => { :approved => true }}) }
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_find_with_hash_conditions_on_joined_table
|
266
|
+
firms = Firm.all :joins => :account, :conditions => {:accounts => { :credit_limit => 50 }}
|
267
|
+
assert_equal 1, firms.size
|
268
|
+
assert_equal companies(:first_firm), firms.first
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_find_with_hash_conditions_on_joined_table_and_with_range
|
272
|
+
firms = DependentFirm.all :joins => :account, :conditions => {:name => 'RailsCore', :accounts => { :credit_limit => 55..60 }}
|
273
|
+
assert_equal 1, firms.size
|
274
|
+
assert_equal companies(:rails_core), firms.first
|
275
|
+
end
|
276
|
+
|
203
277
|
def test_find_on_hash_conditions_with_explicit_table_name_and_aggregate
|
204
278
|
david = customers(:david)
|
205
279
|
assert Customer.find(david.id, :conditions => { 'customers.name' => david.name, :address => david.address })
|
@@ -387,12 +461,13 @@ class FinderTest < ActiveRecord::TestCase
|
|
387
461
|
assert_equal ActiveRecord::Base.connection.quote(''), bind('?', '')
|
388
462
|
end
|
389
463
|
|
390
|
-
def
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
assert_equal
|
464
|
+
def test_bind_chars
|
465
|
+
quoted_bambi = ActiveRecord::Base.connection.quote("Bambi")
|
466
|
+
quoted_bambi_and_thumper = ActiveRecord::Base.connection.quote("Bambi\nand\nThumper")
|
467
|
+
assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi")
|
468
|
+
assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper")
|
469
|
+
assert_equal "name=#{quoted_bambi}", bind('name=?', "Bambi".mb_chars)
|
470
|
+
assert_equal "name=#{quoted_bambi_and_thumper}", bind('name=?', "Bambi\nand\nThumper".mb_chars)
|
396
471
|
end
|
397
472
|
|
398
473
|
def test_bind_record
|
@@ -425,12 +500,34 @@ class FinderTest < ActiveRecord::TestCase
|
|
425
500
|
assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
|
426
501
|
assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1]))
|
427
502
|
end
|
428
|
-
|
503
|
+
|
504
|
+
uses_mocha('test_dynamic_finder_should_go_through_the_find_class_method') do
|
505
|
+
def test_dynamic_finders_should_go_through_the_find_class_method
|
506
|
+
Topic.expects(:find).with(:first, :conditions => { :title => 'The First Topic!' })
|
507
|
+
Topic.find_by_title("The First Topic!")
|
508
|
+
|
509
|
+
Topic.expects(:find).with(:last, :conditions => { :title => 'The Last Topic!' })
|
510
|
+
Topic.find_last_by_title("The Last Topic!")
|
511
|
+
|
512
|
+
Topic.expects(:find).with(:all, :conditions => { :title => 'A Topic.' })
|
513
|
+
Topic.find_all_by_title("A Topic.")
|
514
|
+
|
515
|
+
Topic.expects(:find).with(:first, :conditions => { :title => 'Does not exist yet for sure!' }).times(2)
|
516
|
+
Topic.find_or_initialize_by_title('Does not exist yet for sure!')
|
517
|
+
Topic.find_or_create_by_title('Does not exist yet for sure!')
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
429
521
|
def test_find_by_one_attribute
|
430
522
|
assert_equal topics(:first), Topic.find_by_title("The First Topic")
|
431
523
|
assert_nil Topic.find_by_title("The First Topic!")
|
432
524
|
end
|
433
|
-
|
525
|
+
|
526
|
+
def test_find_by_one_attribute_bang
|
527
|
+
assert_equal topics(:first), Topic.find_by_title!("The First Topic")
|
528
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find_by_title!("The First Topic!") }
|
529
|
+
end
|
530
|
+
|
434
531
|
def test_find_by_one_attribute_caches_dynamic_finder
|
435
532
|
# ensure this test can run independently of order
|
436
533
|
class << Topic; self; end.send(:remove_method, :find_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_by_title' }
|
@@ -524,6 +621,38 @@ class FinderTest < ActiveRecord::TestCase
|
|
524
621
|
assert_nil Topic.find_by_title_and_author_name("The First Topic", "Mary")
|
525
622
|
end
|
526
623
|
|
624
|
+
def test_find_last_by_one_attribute
|
625
|
+
assert_equal Topic.last, Topic.find_last_by_title(Topic.last.title)
|
626
|
+
assert_nil Topic.find_last_by_title("A title with no matches")
|
627
|
+
end
|
628
|
+
|
629
|
+
def test_find_last_by_one_attribute_caches_dynamic_finder
|
630
|
+
# ensure this test can run independently of order
|
631
|
+
class << Topic; self; end.send(:remove_method, :find_last_by_title) if Topic.public_methods.any? { |m| m.to_s == 'find_last_by_title' }
|
632
|
+
assert !Topic.public_methods.any? { |m| m.to_s == 'find_last_by_title' }
|
633
|
+
t = Topic.find_last_by_title(Topic.last.title)
|
634
|
+
assert Topic.public_methods.any? { |m| m.to_s == 'find_last_by_title' }
|
635
|
+
end
|
636
|
+
|
637
|
+
def test_find_last_by_invalid_method_syntax
|
638
|
+
assert_raises(NoMethodError) { Topic.fail_to_find_last_by_title("The First Topic") }
|
639
|
+
assert_raises(NoMethodError) { Topic.find_last_by_title?("The First Topic") }
|
640
|
+
end
|
641
|
+
|
642
|
+
def test_find_last_by_one_attribute_with_several_options
|
643
|
+
assert_equal accounts(:signals37), Account.find_last_by_credit_limit(50, :order => 'id DESC', :conditions => ['id != ?', 3])
|
644
|
+
end
|
645
|
+
|
646
|
+
def test_find_last_by_one_missing_attribute
|
647
|
+
assert_raises(NoMethodError) { Topic.find_last_by_undertitle("The Last Topic!") }
|
648
|
+
end
|
649
|
+
|
650
|
+
def test_find_last_by_two_attributes
|
651
|
+
topic = Topic.last
|
652
|
+
assert_equal topic, Topic.find_last_by_title_and_author_name(topic.title, topic.author_name)
|
653
|
+
assert_nil Topic.find_last_by_title_and_author_name(topic.title, "Anonymous")
|
654
|
+
end
|
655
|
+
|
527
656
|
def test_find_all_by_one_attribute
|
528
657
|
topics = Topic.find_all_by_content("Have a nice day")
|
529
658
|
assert_equal 2, topics.size
|
@@ -717,7 +846,18 @@ class FinderTest < ActiveRecord::TestCase
|
|
717
846
|
assert c.valid?
|
718
847
|
assert !c.new_record?
|
719
848
|
end
|
720
|
-
|
849
|
+
|
850
|
+
def test_find_or_create_should_work_with_block_on_first_call
|
851
|
+
class << Company
|
852
|
+
undef_method(:find_or_create_by_name) if method_defined?(:find_or_create_by_name)
|
853
|
+
end
|
854
|
+
c = Company.find_or_create_by_name(:name => "Fortune 1000") { |f| f.rating = 1000 }
|
855
|
+
assert_equal "Fortune 1000", c.name
|
856
|
+
assert_equal 1000.to_f, c.rating.to_f
|
857
|
+
assert c.valid?
|
858
|
+
assert !c.new_record?
|
859
|
+
end
|
860
|
+
|
721
861
|
def test_dynamic_find_or_initialize_from_one_attribute_caches_method
|
722
862
|
class << Company; self; end.send(:remove_method, :find_or_initialize_by_name) if Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
|
723
863
|
assert !Company.public_methods.any? { |m| m.to_s == 'find_or_initialize_by_name' }
|
@@ -824,6 +964,17 @@ class FinderTest < ActiveRecord::TestCase
|
|
824
964
|
assert_equal 1, first.id
|
825
965
|
end
|
826
966
|
|
967
|
+
def test_joins_with_string_array
|
968
|
+
person_with_reader_and_post = Post.find(
|
969
|
+
:all,
|
970
|
+
:joins => [
|
971
|
+
"INNER JOIN categorizations ON categorizations.post_id = posts.id",
|
972
|
+
"INNER JOIN categories ON categories.id = categorizations.category_id AND categories.type = 'SpecialCategory'"
|
973
|
+
]
|
974
|
+
)
|
975
|
+
assert_equal 1, person_with_reader_and_post.size
|
976
|
+
end
|
977
|
+
|
827
978
|
def test_find_by_id_with_conditions_with_or
|
828
979
|
assert_nothing_raised do
|
829
980
|
Post.find([1,2,3],
|