activerecord 1.9.1 → 1.10.0
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 +78 -0
- data/README +1 -1
- data/install.rb +7 -42
- data/lib/active_record.rb +2 -0
- data/lib/active_record/acts/list.rb +28 -4
- data/lib/active_record/acts/nested_set.rb +212 -0
- data/lib/active_record/associations.rb +203 -21
- data/lib/active_record/associations/association_proxy.rb +10 -2
- data/lib/active_record/associations/belongs_to_association.rb +0 -1
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +15 -9
- data/lib/active_record/associations/has_many_association.rb +25 -25
- data/lib/active_record/associations/has_one_association.rb +2 -2
- data/lib/active_record/base.rb +134 -110
- data/lib/active_record/connection_adapters/abstract_adapter.rb +9 -9
- data/lib/active_record/connection_adapters/mysql_adapter.rb +4 -0
- data/lib/active_record/connection_adapters/oci_adapter.rb +2 -2
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -2
- data/lib/active_record/deprecated_associations.rb +1 -19
- data/lib/active_record/deprecated_finders.rb +41 -0
- data/lib/active_record/fixtures.rb +24 -11
- data/lib/active_record/observer.rb +17 -11
- data/lib/active_record/reflection.rb +5 -1
- data/lib/active_record/transactions.rb +7 -0
- data/lib/active_record/validations.rb +32 -33
- data/rakefile +30 -6
- data/test/associations_go_eager_test.rb +55 -0
- data/test/associations_test.rb +72 -15
- data/test/base_test.rb +15 -21
- data/test/deprecated_associations_test.rb +0 -24
- data/test/deprecated_finder_test.rb +147 -0
- data/test/finder_test.rb +37 -37
- data/test/fixtures/author.rb +3 -0
- data/test/fixtures/authors.yml +7 -0
- data/test/fixtures/categories.yml +7 -0
- data/test/fixtures/categories_posts.yml +11 -0
- data/test/fixtures/category.rb +3 -0
- data/test/fixtures/comment.rb +5 -0
- data/test/fixtures/comments.yml +17 -0
- data/test/fixtures/company.rb +3 -0
- data/test/fixtures/courses.yml +4 -4
- data/test/fixtures/db_definitions/db2.drop.sql +6 -0
- data/test/fixtures/db_definitions/db2.sql +46 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +6 -1
- data/test/fixtures/db_definitions/mysql.sql +60 -12
- data/test/fixtures/db_definitions/mysql2.sql +1 -1
- data/test/fixtures/db_definitions/oci.drop.sql +5 -0
- data/test/fixtures/db_definitions/oci.sql +45 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +6 -0
- data/test/fixtures/db_definitions/postgresql.sql +45 -0
- data/test/fixtures/db_definitions/sqlite.drop.sql +6 -1
- data/test/fixtures/db_definitions/sqlite.sql +46 -0
- data/test/fixtures/db_definitions/sqlserver.drop.sql +7 -1
- data/test/fixtures/db_definitions/sqlserver.sql +46 -0
- data/test/fixtures/fk_test_has_fk.yml +3 -0
- data/test/fixtures/fk_test_has_pk.yml +2 -0
- data/test/fixtures/mixin.rb +18 -0
- data/test/fixtures/mixins.yml +30 -0
- data/test/fixtures/post.rb +8 -0
- data/test/fixtures/posts.yml +20 -0
- data/test/fixtures/task.rb +3 -0
- data/test/fixtures/tasks.yml +7 -0
- data/test/fixtures_test.rb +34 -2
- data/test/mixin_nested_set_test.rb +184 -0
- data/test/mixin_test.rb +28 -3
- data/test/validations_test.rb +16 -0
- metadata +21 -5
- data/test/fixtures/db_definitions/drop_oracle_tables.sql +0 -35
- data/test/fixtures/db_definitions/drop_oracle_tables2.sql +0 -3
data/rakefile
CHANGED
@@ -8,7 +8,7 @@ require 'rake/contrib/rubyforgepublisher'
|
|
8
8
|
|
9
9
|
PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
|
10
10
|
PKG_NAME = 'activerecord'
|
11
|
-
PKG_VERSION = '1.
|
11
|
+
PKG_VERSION = '1.10.0' + PKG_BUILD
|
12
12
|
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
13
13
|
|
14
14
|
RELEASE_NAME = "REL #{PKG_VERSION}"
|
@@ -38,7 +38,7 @@ Rake::TestTask.new("test_mysql_ruby") { |t|
|
|
38
38
|
t.verbose = true
|
39
39
|
}
|
40
40
|
|
41
|
-
for adapter in %( postgresql sqlite sqlite3 sqlserver db2 oci )
|
41
|
+
for adapter in %w( postgresql sqlite sqlite3 sqlserver db2 oci )
|
42
42
|
Rake::TestTask.new("test_#{adapter}") { |t|
|
43
43
|
t.libs << "test" << "test/connections/native_#{adapter}"
|
44
44
|
t.pattern = 'test/*_test.rb'
|
@@ -76,7 +76,7 @@ spec = Gem::Specification.new do |s|
|
|
76
76
|
s.files = s.files + Dir.glob( "#{dir}/**/*" ).delete_if { |item| item.include?( "\.svn" ) }
|
77
77
|
end
|
78
78
|
|
79
|
-
s.add_dependency('activesupport', '= 1.0.
|
79
|
+
s.add_dependency('activesupport', '= 1.0.4' + PKG_BUILD)
|
80
80
|
|
81
81
|
s.files.delete "test/fixtures/fixture_database.sqlite"
|
82
82
|
s.files.delete "test/fixtures/fixture_database_2.sqlite"
|
@@ -101,18 +101,42 @@ Rake::GemPackageTask.new(spec) do |p|
|
|
101
101
|
p.need_zip = true
|
102
102
|
end
|
103
103
|
|
104
|
+
task :lines do
|
105
|
+
lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
|
106
|
+
|
107
|
+
for file_name in FileList["lib/active_record/**/*.rb"]
|
108
|
+
next if file_name =~ /vendor/
|
109
|
+
f = File.open(file_name)
|
110
|
+
|
111
|
+
while line = f.gets
|
112
|
+
lines += 1
|
113
|
+
next if line =~ /^\s*$/
|
114
|
+
next if line =~ /^\s*#/
|
115
|
+
codelines += 1
|
116
|
+
end
|
117
|
+
puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}"
|
118
|
+
|
119
|
+
total_lines += lines
|
120
|
+
total_codelines += codelines
|
121
|
+
|
122
|
+
lines, codelines = 0, 0
|
123
|
+
end
|
124
|
+
|
125
|
+
puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
|
126
|
+
end
|
127
|
+
|
104
128
|
|
105
129
|
# Publishing ------------------------------------------------------
|
106
130
|
|
107
131
|
desc "Publish the beta gem"
|
108
132
|
task :pgem => [:package] do
|
109
|
-
Rake::SshFilePublisher.new("davidhh@
|
110
|
-
`ssh davidhh@
|
133
|
+
Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
|
134
|
+
`ssh davidhh@wrath.rubyonrails.com './gemupdate.sh'`
|
111
135
|
end
|
112
136
|
|
113
137
|
desc "Publish the API documentation"
|
114
138
|
task :pdoc => [:rdoc] do
|
115
|
-
Rake::SshDirPublisher.new("davidhh@
|
139
|
+
Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.com", "public_html/ar", "doc").upload
|
116
140
|
end
|
117
141
|
|
118
142
|
desc "Publish the release files to RubyForge."
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/post'
|
3
|
+
require 'fixtures/comment'
|
4
|
+
require 'fixtures/author'
|
5
|
+
require 'fixtures/category'
|
6
|
+
|
7
|
+
class EagerAssociationTest < Test::Unit::TestCase
|
8
|
+
fixtures :posts, :comments, :authors, :categories, :categories_posts
|
9
|
+
|
10
|
+
def test_loading_with_one_association
|
11
|
+
posts = Post.find(:all, :include => :comments)
|
12
|
+
assert_equal 2, posts.first.comments.size
|
13
|
+
assert posts.first.comments.include?(@greetings)
|
14
|
+
|
15
|
+
post = Post.find(:first, :include => :comments, :conditions => "posts.title = 'Welcome to the weblog'")
|
16
|
+
assert_equal 2, post.comments.size
|
17
|
+
assert post.comments.include?(@greetings)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_loading_with_multiple_associations
|
21
|
+
posts = Post.find(:all, :include => [ :comments, :author, :categories ], :order => "posts.id")
|
22
|
+
assert_equal 2, posts.first.comments.size
|
23
|
+
assert_equal 2, posts.first.categories.size
|
24
|
+
assert posts.first.comments.include?(@greetings)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_loading_from_an_association
|
28
|
+
posts = @david.posts.find(:all, :include => :comments)
|
29
|
+
assert_equal 2, posts.first.comments.size
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_loading_with_no_associations
|
33
|
+
assert_nil Post.find(@authorless.id, :include => :author).author
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_eager_association_loading_with_belongs_to
|
37
|
+
comments = Comment.find(:all, :include => :post)
|
38
|
+
assert_equal @welcome.title, comments.first.post.title
|
39
|
+
assert_equal @thinking.title, comments.last.post.title
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_eager_association_loading_with_habtm
|
43
|
+
posts = Post.find(:all, :include => :categories, :order => "posts.id")
|
44
|
+
assert_equal 2, posts[0].categories.size
|
45
|
+
assert_equal 1, posts[1].categories.size
|
46
|
+
assert_equal 0, posts[2].categories.size
|
47
|
+
assert posts[0].categories.include?(@technology)
|
48
|
+
assert posts[1].categories.include?(@general)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_eager_with_inheritance
|
52
|
+
posts = SpecialPost.find(:all, :include => [ :comments ])
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
data/test/associations_test.rb
CHANGED
@@ -105,6 +105,30 @@ class HasOneAssociationsTest < Test::Unit::TestCase
|
|
105
105
|
assert_equal 1, Account.find_all.length
|
106
106
|
end
|
107
107
|
|
108
|
+
def test_succesful_build_association
|
109
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
110
|
+
firm.save
|
111
|
+
|
112
|
+
account = firm.build_account("credit_limit" => 1000)
|
113
|
+
assert account.save
|
114
|
+
assert_equal account, firm.account
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_failing_build_association
|
118
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
119
|
+
firm.save
|
120
|
+
|
121
|
+
account = firm.build_account
|
122
|
+
assert !account.save
|
123
|
+
assert_equal "can't be empty", account.errors.on("credit_limit")
|
124
|
+
end
|
125
|
+
|
126
|
+
def test_create_association
|
127
|
+
firm = Firm.new("name" => "GlobalMegaCorp")
|
128
|
+
firm.save
|
129
|
+
assert_equal firm.create_account("credit_limit" => 1000), firm.account
|
130
|
+
end
|
131
|
+
|
108
132
|
def test_build
|
109
133
|
firm = Firm.new("name" => "GlobalMegaCorp")
|
110
134
|
firm.save
|
@@ -203,8 +227,9 @@ end
|
|
203
227
|
|
204
228
|
|
205
229
|
class HasManyAssociationsTest < Test::Unit::TestCase
|
230
|
+
fixtures :accounts, :companies, :developers, :projects, :developers_projects, :topics
|
231
|
+
|
206
232
|
def setup
|
207
|
-
create_fixtures "accounts", "companies", "developers", "projects", "developers_projects", "topics"
|
208
233
|
@signals37 = Firm.find(1)
|
209
234
|
end
|
210
235
|
|
@@ -249,6 +274,10 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
249
274
|
assert_equal 1, Firm.find_first.clients_using_counter_sql.size
|
250
275
|
assert_equal 0, Firm.find_first.clients_using_zero_counter_sql.size
|
251
276
|
end
|
277
|
+
|
278
|
+
def test_counting_non_existant_items_using_sql
|
279
|
+
assert_equal 0, Firm.find_first.no_clients_using_counter_sql.size
|
280
|
+
end
|
252
281
|
|
253
282
|
def test_belongs_to_sanity
|
254
283
|
c = Client.new
|
@@ -288,8 +317,8 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
288
317
|
def test_find_all
|
289
318
|
firm = Firm.find_first
|
290
319
|
assert_equal firm.clients, firm.clients.find_all
|
291
|
-
assert_equal 2, firm.clients.
|
292
|
-
assert_equal 1, firm.clients.
|
320
|
+
assert_equal 2, firm.clients.find(:all, :conditions => "type = 'Client'").length
|
321
|
+
assert_equal 1, firm.clients.find(:all, :conditions => "name = 'Summit'").length
|
293
322
|
end
|
294
323
|
|
295
324
|
def test_find_all_sanitized
|
@@ -481,9 +510,21 @@ class HasManyAssociationsTest < Test::Unit::TestCase
|
|
481
510
|
end
|
482
511
|
|
483
512
|
def test_dependence
|
484
|
-
assert_equal 2, Client.find_all.
|
513
|
+
assert_equal 2, Client.find_all.size
|
485
514
|
Firm.find_first.destroy
|
486
|
-
|
515
|
+
assert Client.find_all.empty?
|
516
|
+
end
|
517
|
+
|
518
|
+
def test_destroy_dependent_when_deleted_from_association
|
519
|
+
firm = Firm.find_first
|
520
|
+
assert_equal 2, firm.clients.size
|
521
|
+
|
522
|
+
client = firm.clients.first
|
523
|
+
firm.clients.delete(client)
|
524
|
+
|
525
|
+
assert_raise(ActiveRecord::RecordNotFound) { Client.find(client.id) }
|
526
|
+
assert_raise(ActiveRecord::RecordNotFound) { firm.clients.find(client.id) }
|
527
|
+
assert_equal 1, firm.clients.size
|
487
528
|
end
|
488
529
|
|
489
530
|
def test_three_levels_of_dependence
|
@@ -546,6 +587,19 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
546
587
|
assert_equal apple.id, citibank.firm_id
|
547
588
|
end
|
548
589
|
|
590
|
+
def test_creating_the_belonging_object
|
591
|
+
citibank = Account.create("credit_limit" => 10)
|
592
|
+
apple = citibank.create_firm("name" => "Apple")
|
593
|
+
assert_equal apple, citibank.firm
|
594
|
+
end
|
595
|
+
|
596
|
+
def test_building_the_belonging_object
|
597
|
+
citibank = Account.create("credit_limit" => 10)
|
598
|
+
apple = citibank.build_firm("name" => "Apple")
|
599
|
+
citibank.save
|
600
|
+
assert_equal apple.id, citibank.firm_id
|
601
|
+
end
|
602
|
+
|
549
603
|
def test_natural_assignment_to_nil
|
550
604
|
client = Client.find(3)
|
551
605
|
client.firm = nil
|
@@ -615,7 +669,7 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
615
669
|
|
616
670
|
def test_new_record_with_foreign_key_but_no_object
|
617
671
|
c = Client.new("firm_id" => 1)
|
618
|
-
assert_equal
|
672
|
+
assert_equal Firm.find_first, c.firm_with_basic_id
|
619
673
|
end
|
620
674
|
|
621
675
|
def test_forgetting_the_load_when_foreign_key_enters_late
|
@@ -623,12 +677,12 @@ class BelongsToAssociationsTest < Test::Unit::TestCase
|
|
623
677
|
assert_nil c.firm_with_basic_id
|
624
678
|
|
625
679
|
c.firm_id = 1
|
626
|
-
assert_equal
|
680
|
+
assert_equal Firm.find_first, c.firm_with_basic_id
|
627
681
|
end
|
628
682
|
|
629
683
|
def test_field_name_same_as_foreign_key
|
630
684
|
computer = Computer.find 1
|
631
|
-
assert_not_nil computer.developer, ":foreign key == attribute didn't lock up"
|
685
|
+
assert_not_nil computer.developer, ":foreign key == attribute didn't lock up" # '
|
632
686
|
end
|
633
687
|
|
634
688
|
def xtest_counter_cache
|
@@ -651,12 +705,7 @@ end
|
|
651
705
|
|
652
706
|
|
653
707
|
class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
654
|
-
|
655
|
-
@accounts, @companies, @developers, @projects, @developers_projects =
|
656
|
-
create_fixtures "accounts", "companies", "developers", "projects", "developers_projects"
|
657
|
-
|
658
|
-
@signals37 = Firm.find(1)
|
659
|
-
end
|
708
|
+
fixtures :accounts, :companies, :developers, :projects, :developers_projects
|
660
709
|
|
661
710
|
def test_has_and_belongs_to_many
|
662
711
|
david = Developer.find(1)
|
@@ -860,4 +909,12 @@ class HasAndBelongsToManyAssociationsTest < Test::Unit::TestCase
|
|
860
909
|
@active_record.developers.reload
|
861
910
|
assert_equal @developers["david"].find, @active_record.developers.find(@developers["david"]["id"]), "Ruby find"
|
862
911
|
end
|
863
|
-
|
912
|
+
|
913
|
+
def xtest_find_in_association_with_options
|
914
|
+
developers = @active_record.developers.find(:all)
|
915
|
+
assert_equal 2, developers.size
|
916
|
+
|
917
|
+
assert_equal @david, @active_record.developers.find(:first, :conditions => "salary < 10000")
|
918
|
+
assert_equal @jamis, @active_record.developers.find(:first, :order => "salary DESC")
|
919
|
+
end
|
920
|
+
end
|
data/test/base_test.rb
CHANGED
@@ -103,15 +103,14 @@ class BasicsTest < Test::Unit::TestCase
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def test_attributes_hash
|
106
|
-
assert_equal @projects[
|
106
|
+
assert_equal @projects['active_record'].to_hash, Project.find_first.attributes
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
def test_create
|
110
110
|
topic = Topic.new
|
111
111
|
topic.title = "New Topic"
|
112
112
|
topic.save
|
113
|
-
|
114
|
-
topicReloaded = Topic.find(id)
|
113
|
+
topicReloaded = Topic.find(topic.id)
|
115
114
|
assert_equal("New Topic", topicReloaded.title)
|
116
115
|
end
|
117
116
|
|
@@ -139,16 +138,13 @@ class BasicsTest < Test::Unit::TestCase
|
|
139
138
|
topic.title = "Another New Topic"
|
140
139
|
topic.written_on = "2003-12-12 23:23:00"
|
141
140
|
topic.save
|
142
|
-
|
143
|
-
assert_equal(id, topic.id)
|
144
|
-
|
145
|
-
topicReloaded = Topic.find(id)
|
141
|
+
topicReloaded = Topic.find(topic.id)
|
146
142
|
assert_equal("Another New Topic", topicReloaded.title)
|
147
143
|
|
148
144
|
topicReloaded.title = "Updated topic"
|
149
145
|
topicReloaded.save
|
150
146
|
|
151
|
-
topicReloadedAgain = Topic.find(id)
|
147
|
+
topicReloadedAgain = Topic.find(topic.id)
|
152
148
|
|
153
149
|
assert_equal("Updated topic", topicReloadedAgain.title)
|
154
150
|
end
|
@@ -157,9 +153,8 @@ class BasicsTest < Test::Unit::TestCase
|
|
157
153
|
topic = Topic.new
|
158
154
|
topic.title = "Still another topic"
|
159
155
|
topic.save
|
160
|
-
id = topic.id
|
161
156
|
|
162
|
-
topicReloaded = Topic.find(id)
|
157
|
+
topicReloaded = Topic.find(topic.id)
|
163
158
|
topicReloaded.title = "A New Topic"
|
164
159
|
topicReloaded.send :write_attribute, 'does_not_exist', 'test'
|
165
160
|
assert_nothing_raised { topicReloaded.save }
|
@@ -198,10 +193,9 @@ class BasicsTest < Test::Unit::TestCase
|
|
198
193
|
topic.title = "Yet Another New Topic"
|
199
194
|
topic.written_on = "2003-12-12 23:23:00"
|
200
195
|
topic.save
|
201
|
-
id = topic.id
|
202
196
|
topic.destroy
|
203
|
-
|
204
|
-
|
197
|
+
assert_raise(TypeError) { topic.save }
|
198
|
+
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(topic.id) }
|
205
199
|
end
|
206
200
|
|
207
201
|
def test_record_not_found_exception
|
@@ -353,7 +347,7 @@ class BasicsTest < Test::Unit::TestCase
|
|
353
347
|
def test_attribute_keys_on_new_instance
|
354
348
|
t = Topic.new
|
355
349
|
assert_equal nil, t.title, "The topics table has a title column, so it should be nil"
|
356
|
-
|
350
|
+
assert_raise(NoMethodError) { t.title2 }
|
357
351
|
end
|
358
352
|
|
359
353
|
def test_class_name
|
@@ -644,7 +638,7 @@ class BasicsTest < Test::Unit::TestCase
|
|
644
638
|
topic = Topic.create("content" => myobj)
|
645
639
|
Topic.serialize(:content, Hash)
|
646
640
|
|
647
|
-
|
641
|
+
assert_raise(ActiveRecord::SerializationTypeMismatch) { Topic.find(topic.id).content }
|
648
642
|
|
649
643
|
settings = { "color" => "blue" }
|
650
644
|
Topic.find(topic.id).update_attribute("content", settings)
|
@@ -660,19 +654,19 @@ class BasicsTest < Test::Unit::TestCase
|
|
660
654
|
|
661
655
|
def test_class_level_destroy
|
662
656
|
should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
|
663
|
-
|
657
|
+
Topic.find(1).replies << should_be_destroyed_reply
|
664
658
|
|
665
659
|
Topic.destroy(1)
|
666
|
-
|
667
|
-
|
660
|
+
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
|
661
|
+
assert_raise(ActiveRecord::RecordNotFound) { Reply.find(should_be_destroyed_reply.id) }
|
668
662
|
end
|
669
663
|
|
670
664
|
def test_class_level_delete
|
671
665
|
should_be_destroyed_reply = Reply.create("title" => "hello", "content" => "world")
|
672
|
-
|
666
|
+
Topic.find(1).replies << should_be_destroyed_reply
|
673
667
|
|
674
668
|
Topic.delete(1)
|
675
|
-
|
669
|
+
assert_raise(ActiveRecord::RecordNotFound) { Topic.find(1) }
|
676
670
|
assert_nothing_raised { Reply.find(should_be_destroyed_reply.id) }
|
677
671
|
end
|
678
672
|
|
@@ -174,30 +174,6 @@ class DeprecatedAssociationsTest < Test::Unit::TestCase
|
|
174
174
|
assert_equal @signals37.create_in_clients_of_firm("name" => "Another Client"), @signals37.clients_of_firm(true).last
|
175
175
|
end
|
176
176
|
|
177
|
-
def test_succesful_build_association
|
178
|
-
firm = Firm.new("name" => "GlobalMegaCorp")
|
179
|
-
firm.save
|
180
|
-
|
181
|
-
account = firm.build_account("credit_limit" => 1000)
|
182
|
-
assert account.save
|
183
|
-
assert_equal account, firm.account
|
184
|
-
end
|
185
|
-
|
186
|
-
def test_failing_build_association
|
187
|
-
firm = Firm.new("name" => "GlobalMegaCorp")
|
188
|
-
firm.save
|
189
|
-
|
190
|
-
account = firm.build_account
|
191
|
-
assert !account.save
|
192
|
-
assert_equal "can't be empty", account.errors.on("credit_limit")
|
193
|
-
end
|
194
|
-
|
195
|
-
def test_create_association
|
196
|
-
firm = Firm.new("name" => "GlobalMegaCorp")
|
197
|
-
firm.save
|
198
|
-
assert_equal firm.create_account("credit_limit" => 1000), firm.account
|
199
|
-
end
|
200
|
-
|
201
177
|
def test_has_and_belongs_to_many
|
202
178
|
david = Developer.find(1)
|
203
179
|
assert david.has_projects?
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/company'
|
3
|
+
require 'fixtures/topic'
|
4
|
+
require 'fixtures/entrant'
|
5
|
+
require 'fixtures/developer'
|
6
|
+
|
7
|
+
class FinderTest < Test::Unit::TestCase
|
8
|
+
fixtures :companies, :topics, :entrants, :developers
|
9
|
+
|
10
|
+
def test_find_all_with_limit
|
11
|
+
entrants = Entrant.find_all nil, "id ASC", 2
|
12
|
+
|
13
|
+
assert_equal(2, entrants.size)
|
14
|
+
assert_equal(@entrants["first"]["name"], entrants.first.name)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_find_all_with_prepared_limit_and_offset
|
18
|
+
if ActiveRecord::ConnectionAdapters.const_defined? :OracleAdapter
|
19
|
+
if ActiveRecord::Base.connection.instance_of?(ActiveRecord::ConnectionAdapters::OracleAdapter)
|
20
|
+
assert_raises(ArgumentError) { Entrant.find_all nil, "id ASC", [2, 1] }
|
21
|
+
end
|
22
|
+
else
|
23
|
+
entrants = Entrant.find_all nil, "id ASC", [2, 1]
|
24
|
+
|
25
|
+
assert_equal(2, entrants.size)
|
26
|
+
assert_equal(@entrants["second"]["name"], entrants.first.name)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_find_first
|
31
|
+
first = Topic.find_first "title = 'The First Topic'"
|
32
|
+
assert_equal(@topics["first"]["title"], first.title)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_find_first_failing
|
36
|
+
first = Topic.find_first "title = 'The First Topic!'"
|
37
|
+
assert_nil(first)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_deprecated_find_on_conditions
|
41
|
+
assert Topic.find_on_conditions(1, "approved = 0")
|
42
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find_on_conditions(1, "approved = 1") }
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_condition_interpolation
|
46
|
+
assert_kind_of Firm, Company.find_first(["name = '%s'", "37signals"])
|
47
|
+
assert_nil Company.find_first(["name = '%s'", "37signals!"])
|
48
|
+
assert_nil Company.find_first(["name = '%s'", "37signals!' OR 1=1"])
|
49
|
+
assert_kind_of Time, Topic.find_first(["id = %d", 1]).written_on
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_bind_variables
|
53
|
+
assert_kind_of Firm, Company.find_first(["name = ?", "37signals"])
|
54
|
+
assert_nil Company.find_first(["name = ?", "37signals!"])
|
55
|
+
assert_nil Company.find_first(["name = ?", "37signals!' OR 1=1"])
|
56
|
+
assert_kind_of Time, Topic.find_first(["id = ?", 1]).written_on
|
57
|
+
assert_raises(ActiveRecord::PreparedStatementInvalid) {
|
58
|
+
Company.find_first(["id=? AND name = ?", 2])
|
59
|
+
}
|
60
|
+
assert_raises(ActiveRecord::PreparedStatementInvalid) {
|
61
|
+
Company.find_first(["id=?", 2, 3, 4])
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_bind_variables_with_quotes
|
66
|
+
Company.create("name" => "37signals' go'es agains")
|
67
|
+
assert Company.find_first(["name = ?", "37signals' go'es agains"])
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_named_bind_variables_with_quotes
|
71
|
+
Company.create("name" => "37signals' go'es agains")
|
72
|
+
assert Company.find_first(["name = :name", {:name => "37signals' go'es agains"}])
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_named_bind_variables
|
76
|
+
assert_equal '1', bind(':a', :a => 1) # ' ruby-mode
|
77
|
+
assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode
|
78
|
+
|
79
|
+
assert_kind_of Firm, Company.find_first(["name = :name", { :name => "37signals" }])
|
80
|
+
assert_nil Company.find_first(["name = :name", { :name => "37signals!" }])
|
81
|
+
assert_nil Company.find_first(["name = :name", { :name => "37signals!' OR 1=1" }])
|
82
|
+
assert_kind_of Time, Topic.find_first(["id = :id", { :id => 1 }]).written_on
|
83
|
+
assert_raises(ActiveRecord::PreparedStatementInvalid) {
|
84
|
+
Company.find_first(["id=:id and name=:name", { :id=>3 }])
|
85
|
+
}
|
86
|
+
assert_raises(ActiveRecord::PreparedStatementInvalid) {
|
87
|
+
Company.find_first(["id=:id", { :id=>3, :name=>"37signals!" }])
|
88
|
+
}
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_count
|
92
|
+
assert_equal(0, Entrant.count("id > 3"))
|
93
|
+
assert_equal(1, Entrant.count(["id > ?", 2]))
|
94
|
+
assert_equal(2, Entrant.count(["id > ?", 1]))
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_count_by_sql
|
98
|
+
assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
|
99
|
+
assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
|
100
|
+
assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1]))
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_find_all_with_limit
|
104
|
+
first_five_developers = Developer.find_all nil, 'id ASC', 5
|
105
|
+
assert_equal 5, first_five_developers.length
|
106
|
+
assert_equal 'David', first_five_developers.first.name
|
107
|
+
assert_equal 'fixture_5', first_five_developers.last.name
|
108
|
+
|
109
|
+
no_developers = Developer.find_all nil, 'id ASC', 0
|
110
|
+
assert_equal 0, no_developers.length
|
111
|
+
|
112
|
+
assert_equal first_five_developers, Developer.find_all(nil, 'id ASC', [5])
|
113
|
+
assert_equal no_developers, Developer.find_all(nil, 'id ASC', [0])
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_find_all_with_limit_and_offset
|
117
|
+
first_three_developers = Developer.find_all nil, 'id ASC', [3, 0]
|
118
|
+
second_three_developers = Developer.find_all nil, 'id ASC', [3, 3]
|
119
|
+
last_two_developers = Developer.find_all nil, 'id ASC', [2, 8]
|
120
|
+
|
121
|
+
assert_equal 3, first_three_developers.length
|
122
|
+
assert_equal 3, second_three_developers.length
|
123
|
+
assert_equal 2, last_two_developers.length
|
124
|
+
|
125
|
+
assert_equal 'David', first_three_developers.first.name
|
126
|
+
assert_equal 'fixture_4', second_three_developers.first.name
|
127
|
+
assert_equal 'fixture_9', last_two_developers.first.name
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_find_all_by_one_attribute_with_options
|
131
|
+
topics = Topic.find_all_by_content("Have a nice day", nil, "id DESC")
|
132
|
+
assert @topics["first"].find, topics.last
|
133
|
+
|
134
|
+
topics = Topic.find_all_by_content("Have a nice day", nil, "id DESC")
|
135
|
+
assert @topics["first"].find, topics.first
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
protected
|
140
|
+
def bind(statement, *vars)
|
141
|
+
if vars.first.is_a?(Hash)
|
142
|
+
ActiveRecord::Base.send(:replace_named_bind_variables, statement, vars.first)
|
143
|
+
else
|
144
|
+
ActiveRecord::Base.send(:replace_bind_variables, statement, vars)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|