activerecord 1.14.4 → 1.15.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 +400 -1
- data/README +2 -2
- data/RUNNING_UNIT_TESTS +21 -3
- data/Rakefile +55 -10
- data/lib/active_record.rb +10 -4
- data/lib/active_record/acts/list.rb +15 -4
- data/lib/active_record/acts/nested_set.rb +11 -12
- data/lib/active_record/acts/tree.rb +13 -14
- data/lib/active_record/aggregations.rb +46 -22
- data/lib/active_record/associations.rb +213 -162
- data/lib/active_record/associations/association_collection.rb +45 -15
- data/lib/active_record/associations/association_proxy.rb +32 -13
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +18 -18
- data/lib/active_record/associations/has_many_association.rb +37 -17
- data/lib/active_record/associations/has_many_through_association.rb +120 -30
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/attribute_methods.rb +75 -0
- data/lib/active_record/base.rb +282 -203
- data/lib/active_record/calculations.rb +95 -54
- data/lib/active_record/callbacks.rb +13 -24
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +12 -1
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb.rej +21 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +30 -4
- data/lib/active_record/connection_adapters/abstract/quoting.rb +16 -9
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +121 -37
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +55 -23
- data/lib/active_record/connection_adapters/abstract_adapter.rb +8 -0
- data/lib/active_record/connection_adapters/db2_adapter.rb +1 -11
- data/lib/active_record/connection_adapters/firebird_adapter.rb +364 -50
- data/lib/active_record/connection_adapters/frontbase_adapter.rb +861 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +86 -33
- data/lib/active_record/connection_adapters/openbase_adapter.rb +4 -3
- data/lib/active_record/connection_adapters/oracle_adapter.rb +151 -127
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +125 -48
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +38 -10
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +183 -155
- data/lib/active_record/connection_adapters/sybase_adapter.rb +190 -212
- data/lib/active_record/deprecated_associations.rb +24 -10
- data/lib/active_record/deprecated_finders.rb +4 -1
- data/lib/active_record/fixtures.rb +37 -23
- data/lib/active_record/locking/optimistic.rb +106 -0
- data/lib/active_record/locking/pessimistic.rb +77 -0
- data/lib/active_record/migration.rb +8 -5
- data/lib/active_record/observer.rb +73 -34
- data/lib/active_record/reflection.rb +21 -7
- data/lib/active_record/schema_dumper.rb +33 -5
- data/lib/active_record/timestamp.rb +23 -34
- data/lib/active_record/transactions.rb +37 -30
- data/lib/active_record/validations.rb +46 -30
- data/lib/active_record/vendor/mysql.rb +20 -5
- data/lib/active_record/version.rb +2 -2
- data/lib/active_record/wrappings.rb +1 -2
- data/lib/active_record/xml_serialization.rb +308 -0
- data/test/aaa_create_tables_test.rb +5 -1
- data/test/abstract_unit.rb +18 -8
- data/test/{active_schema_mysql.rb → active_schema_test_mysql.rb} +2 -2
- data/test/adapter_test.rb +9 -7
- data/test/adapter_test_sqlserver.rb +81 -0
- data/test/aggregations_test.rb +29 -0
- data/test/{association_callbacks_test.rb → associations/callbacks_test.rb} +10 -8
- data/test/{associations_cascaded_eager_loading_test.rb → associations/cascaded_eager_loading_test.rb} +35 -3
- data/test/{associations_go_eager_test.rb → associations/eager_test.rb} +36 -2
- data/test/{associations_extensions_test.rb → associations/extension_test.rb} +5 -0
- data/test/{associations_join_model_test.rb → associations/join_model_test.rb} +118 -8
- data/test/associations_test.rb +339 -45
- data/test/attribute_methods_test.rb +49 -0
- data/test/base_test.rb +321 -67
- data/test/calculations_test.rb +48 -10
- data/test/callbacks_test.rb +13 -0
- data/test/connection_test_firebird.rb +8 -0
- data/test/connections/native_db2/connection.rb +18 -17
- data/test/connections/native_firebird/connection.rb +19 -17
- data/test/connections/native_frontbase/connection.rb +27 -0
- data/test/connections/native_mysql/connection.rb +18 -15
- data/test/connections/native_openbase/connection.rb +14 -15
- data/test/connections/native_oracle/connection.rb +16 -12
- data/test/connections/native_postgresql/connection.rb +16 -17
- data/test/connections/native_sqlite/connection.rb +3 -6
- data/test/connections/native_sqlite3/connection.rb +3 -6
- data/test/connections/native_sqlserver/connection.rb +16 -17
- data/test/connections/native_sqlserver_odbc/connection.rb +18 -19
- data/test/connections/native_sybase/connection.rb +16 -17
- data/test/datatype_test_postgresql.rb +52 -0
- data/test/defaults_test.rb +52 -10
- data/test/deprecated_associations_test.rb +151 -107
- data/test/deprecated_finder_test.rb +83 -66
- data/test/empty_date_time_test.rb +25 -0
- data/test/finder_test.rb +118 -11
- data/test/fixtures/accounts.yml +6 -1
- data/test/fixtures/author.rb +27 -4
- data/test/fixtures/categorizations.yml +8 -2
- data/test/fixtures/category.rb +1 -2
- data/test/fixtures/comments.yml +0 -6
- data/test/fixtures/companies.yml +6 -1
- data/test/fixtures/company.rb +23 -1
- data/test/fixtures/company_in_module.rb +8 -10
- data/test/fixtures/customer.rb +2 -2
- data/test/fixtures/customers.yml +9 -0
- data/test/fixtures/db_definitions/db2.drop.sql +1 -0
- data/test/fixtures/db_definitions/db2.sql +9 -0
- data/test/fixtures/db_definitions/firebird.drop.sql +3 -0
- data/test/fixtures/db_definitions/firebird.sql +13 -1
- data/test/fixtures/db_definitions/frontbase.drop.sql +31 -0
- data/test/fixtures/db_definitions/frontbase.sql +262 -0
- data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
- data/test/fixtures/db_definitions/frontbase2.sql +4 -0
- data/test/fixtures/db_definitions/mysql.drop.sql +1 -0
- data/test/fixtures/db_definitions/mysql.sql +23 -14
- data/test/fixtures/db_definitions/openbase.sql +13 -1
- data/test/fixtures/db_definitions/oracle.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle.sql +29 -2
- data/test/fixtures/db_definitions/postgresql.drop.sql +3 -1
- data/test/fixtures/db_definitions/postgresql.sql +13 -3
- data/test/fixtures/db_definitions/schema.rb +29 -1
- data/test/fixtures/db_definitions/sqlite.drop.sql +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +12 -3
- data/test/fixtures/db_definitions/sqlserver.drop.sql +3 -0
- data/test/fixtures/db_definitions/sqlserver.sql +35 -0
- data/test/fixtures/db_definitions/sybase.drop.sql +2 -0
- data/test/fixtures/db_definitions/sybase.sql +13 -4
- data/test/fixtures/developer.rb +12 -0
- data/test/fixtures/edge.rb +5 -0
- data/test/fixtures/edges.yml +6 -0
- data/test/fixtures/funny_jokes.yml +3 -7
- data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
- data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
- data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
- data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
- data/test/fixtures/mixin.rb +15 -0
- data/test/fixtures/mixins.yml +38 -0
- data/test/fixtures/post.rb +3 -2
- data/test/fixtures/project.rb +3 -1
- data/test/fixtures/topic.rb +6 -1
- data/test/fixtures/topics.yml +4 -4
- data/test/fixtures/vertex.rb +9 -0
- data/test/fixtures/vertices.yml +4 -0
- data/test/fixtures_test.rb +45 -0
- data/test/inheritance_test.rb +67 -6
- data/test/lifecycle_test.rb +40 -19
- data/test/locking_test.rb +170 -26
- data/test/method_scoping_test.rb +2 -2
- data/test/migration_test.rb +387 -110
- data/test/migration_test_firebird.rb +124 -0
- data/test/mixin_nested_set_test.rb +14 -2
- data/test/mixin_test.rb +56 -18
- data/test/modules_test.rb +8 -2
- data/test/multiple_db_test.rb +2 -2
- data/test/pk_test.rb +1 -0
- data/test/reflection_test.rb +8 -2
- data/test/schema_authorization_test_postgresql.rb +75 -0
- data/test/schema_dumper_test.rb +40 -4
- data/test/table_name_test_sqlserver.rb +23 -0
- data/test/threaded_connections_test.rb +19 -16
- data/test/transactions_test.rb +86 -72
- data/test/validations_test.rb +126 -56
- data/test/xml_serialization_test.rb +125 -0
- metadata +45 -11
- data/lib/active_record/locking.rb +0 -79
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'abstract_unit'
|
2
2
|
require 'fixtures/company'
|
3
3
|
require 'fixtures/topic'
|
4
|
+
require 'fixtures/reply'
|
4
5
|
require 'fixtures/entrant'
|
5
6
|
require 'fixtures/developer'
|
6
7
|
|
@@ -8,78 +9,88 @@ class DeprecatedFinderTest < Test::Unit::TestCase
|
|
8
9
|
fixtures :companies, :topics, :entrants, :developers
|
9
10
|
|
10
11
|
def test_find_all_with_limit
|
11
|
-
entrants = Entrant.find_all nil, "id ASC", 2
|
12
|
-
|
13
|
-
assert_equal(
|
14
|
-
assert_equal(entrants(:first).name, entrants.first.name)
|
12
|
+
entrants = assert_deprecated { Entrant.find_all nil, "id ASC", 2 }
|
13
|
+
assert_equal 2, entrants.size
|
14
|
+
assert_equal entrants(:first), entrants.first
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_find_all_with_prepared_limit_and_offset
|
18
|
-
entrants = Entrant.find_all nil, "id ASC", [2, 1]
|
19
|
-
|
20
|
-
assert_equal(
|
21
|
-
assert_equal(entrants(:second).name, entrants.first.name)
|
18
|
+
entrants = assert_deprecated { Entrant.find_all nil, "id ASC", [2, 1] }
|
19
|
+
assert_equal 2, entrants.size
|
20
|
+
assert_equal entrants(:second), entrants.first
|
22
21
|
end
|
23
22
|
|
24
23
|
def test_find_first
|
25
|
-
first = Topic.find_first "title = 'The First Topic'"
|
26
|
-
assert_equal
|
24
|
+
first = assert_deprecated { Topic.find_first "title = 'The First Topic'" }
|
25
|
+
assert_equal topics(:first), first
|
27
26
|
end
|
28
|
-
|
27
|
+
|
29
28
|
def test_find_first_failing
|
30
|
-
first = Topic.find_first "title = 'The First Topic!'"
|
31
|
-
assert_nil
|
29
|
+
first = assert_deprecated { Topic.find_first "title = 'The First Topic!'" }
|
30
|
+
assert_nil first
|
32
31
|
end
|
33
|
-
|
32
|
+
|
34
33
|
def test_deprecated_find_on_conditions
|
35
|
-
|
36
|
-
|
34
|
+
assert_deprecated 'find_on_conditions' do
|
35
|
+
assert Topic.find_on_conditions(1, ["approved = ?", false])
|
36
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find_on_conditions(1, ["approved = ?", true]) }
|
37
|
+
end
|
37
38
|
end
|
38
|
-
|
39
|
+
|
39
40
|
def test_condition_interpolation
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
41
|
+
assert_deprecated do
|
42
|
+
assert_kind_of Firm, Company.find_first(["name = '%s'", "37signals"])
|
43
|
+
assert_nil Company.find_first(["name = '%s'", "37signals!"])
|
44
|
+
assert_nil Company.find_first(["name = '%s'", "37signals!' OR 1=1"])
|
45
|
+
assert_kind_of Time, Topic.find_first(["id = %d", 1]).written_on
|
46
|
+
end
|
44
47
|
end
|
45
48
|
|
46
49
|
def test_bind_variables
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
assert_deprecated do
|
51
|
+
assert_kind_of Firm, Company.find_first(["name = ?", "37signals"])
|
52
|
+
assert_nil Company.find_first(["name = ?", "37signals!"])
|
53
|
+
assert_nil Company.find_first(["name = ?", "37signals!' OR 1=1"])
|
54
|
+
assert_kind_of Time, Topic.find_first(["id = ?", 1]).written_on
|
55
|
+
assert_raises(ActiveRecord::PreparedStatementInvalid) {
|
56
|
+
Company.find_first(["id=? AND name = ?", 2])
|
57
|
+
}
|
58
|
+
assert_raises(ActiveRecord::PreparedStatementInvalid) {
|
59
|
+
Company.find_first(["id=?", 2, 3, 4])
|
60
|
+
}
|
61
|
+
end
|
57
62
|
end
|
58
63
|
|
59
64
|
def test_bind_variables_with_quotes
|
60
65
|
Company.create("name" => "37signals' go'es agains")
|
61
|
-
|
66
|
+
assert_deprecated do
|
67
|
+
assert_not_nil Company.find_first(["name = ?", "37signals' go'es agains"])
|
68
|
+
end
|
62
69
|
end
|
63
70
|
|
64
71
|
def test_named_bind_variables_with_quotes
|
65
72
|
Company.create("name" => "37signals' go'es agains")
|
66
|
-
|
73
|
+
assert_deprecated do
|
74
|
+
assert_not_nil Company.find_first(["name = :name", {:name => "37signals' go'es agains"}])
|
75
|
+
end
|
67
76
|
end
|
68
77
|
|
69
78
|
def test_named_bind_variables
|
70
79
|
assert_equal '1', bind(':a', :a => 1) # ' ruby-mode
|
71
80
|
assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
81
|
+
|
82
|
+
assert_deprecated do
|
83
|
+
assert_kind_of Firm, Company.find_first(["name = :name", { :name => "37signals" }])
|
84
|
+
assert_nil Company.find_first(["name = :name", { :name => "37signals!" }])
|
85
|
+
assert_nil Company.find_first(["name = :name", { :name => "37signals!' OR 1=1" }])
|
86
|
+
assert_kind_of Time, Topic.find_first(["id = :id", { :id => 1 }]).written_on
|
87
|
+
end
|
77
88
|
end
|
78
89
|
|
79
90
|
def test_count
|
80
|
-
assert_equal(0, Entrant.count("id > 3"))
|
81
|
-
assert_equal(1, Entrant.count(["id > ?", 2]))
|
82
|
-
assert_equal(2, Entrant.count(["id > ?", 1]))
|
91
|
+
assert_equal(0, Entrant.count(:conditions => "id > 3"))
|
92
|
+
assert_equal(1, Entrant.count(:conditions => ["id > ?", 2]))
|
93
|
+
assert_equal(2, Entrant.count(:conditions => ["id > ?", 1]))
|
83
94
|
end
|
84
95
|
|
85
96
|
def test_count_by_sql
|
@@ -89,38 +100,44 @@ class DeprecatedFinderTest < Test::Unit::TestCase
|
|
89
100
|
end
|
90
101
|
|
91
102
|
def test_find_all_with_limit
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
103
|
+
assert_deprecated do
|
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
|
102
115
|
end
|
103
116
|
|
104
117
|
def test_find_all_with_limit_and_offset
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
118
|
+
assert_deprecated do
|
119
|
+
first_three_developers = Developer.find_all nil, 'id ASC', [3, 0]
|
120
|
+
second_three_developers = Developer.find_all nil, 'id ASC', [3, 3]
|
121
|
+
last_two_developers = Developer.find_all nil, 'id ASC', [2, 8]
|
122
|
+
|
123
|
+
assert_equal 3, first_three_developers.length
|
124
|
+
assert_equal 3, second_three_developers.length
|
125
|
+
assert_equal 2, last_two_developers.length
|
126
|
+
|
127
|
+
assert_equal 'David', first_three_developers.first.name
|
128
|
+
assert_equal 'fixture_4', second_three_developers.first.name
|
129
|
+
assert_equal 'fixture_9', last_two_developers.first.name
|
130
|
+
end
|
116
131
|
end
|
117
132
|
|
118
133
|
def test_find_all_by_one_attribute_with_options
|
119
|
-
|
120
|
-
|
134
|
+
assert_not_deprecated do
|
135
|
+
topics = Topic.find_all_by_content("Have a nice day", "id DESC")
|
136
|
+
assert topics(:first), topics.last
|
121
137
|
|
122
|
-
|
123
|
-
|
138
|
+
topics = Topic.find_all_by_content("Have a nice day", "id DESC")
|
139
|
+
assert topics(:first), topics.first
|
140
|
+
end
|
124
141
|
end
|
125
142
|
|
126
143
|
protected
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/topic'
|
3
|
+
require 'fixtures/task'
|
4
|
+
|
5
|
+
class EmptyDateTimeTest < Test::Unit::TestCase
|
6
|
+
def test_assign_empty_date_time
|
7
|
+
task = Task.new
|
8
|
+
task.starting = ''
|
9
|
+
task.ending = nil
|
10
|
+
assert_nil task.starting
|
11
|
+
assert_nil task.ending
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_assign_empty_date
|
15
|
+
topic = Topic.new
|
16
|
+
topic.last_read = ''
|
17
|
+
assert_nil topic.last_read
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_assign_empty_time
|
21
|
+
topic = Topic.new
|
22
|
+
topic.bonus_time = ''
|
23
|
+
assert_nil topic.bonus_time
|
24
|
+
end
|
25
|
+
end
|
data/test/finder_test.rb
CHANGED
@@ -13,11 +13,21 @@ class FinderTest < Test::Unit::TestCase
|
|
13
13
|
assert_equal(topics(:first).title, Topic.find(1).title)
|
14
14
|
end
|
15
15
|
|
16
|
+
# find should handle strings that come from URLs
|
17
|
+
# (example: Category.find(params[:id]))
|
18
|
+
def test_find_with_string
|
19
|
+
assert_equal(Topic.find(1).title,Topic.find("1").title)
|
20
|
+
end
|
21
|
+
|
16
22
|
def test_exists
|
17
|
-
assert
|
18
|
-
assert
|
19
|
-
assert
|
20
|
-
assert
|
23
|
+
assert Topic.exists?(1)
|
24
|
+
assert Topic.exists?("1")
|
25
|
+
assert Topic.exists?(:author_name => "David")
|
26
|
+
assert Topic.exists?(:author_name => "Mary", :approved => true)
|
27
|
+
assert Topic.exists?(["parent_id = ?", 1])
|
28
|
+
assert !Topic.exists?(45)
|
29
|
+
assert !Topic.exists?("foo")
|
30
|
+
assert_raise(NoMethodError) { Topic.exists?([1,2]) }
|
21
31
|
end
|
22
32
|
|
23
33
|
def test_find_by_array_of_one_id
|
@@ -83,6 +93,11 @@ class FinderTest < Test::Unit::TestCase
|
|
83
93
|
assert_equal(topics(:second).title, topics.first.title)
|
84
94
|
end
|
85
95
|
|
96
|
+
def test_find_by_sql_with_sti_on_joined_table
|
97
|
+
accounts = Account.find_by_sql("SELECT * FROM accounts INNER JOIN companies ON companies.id = accounts.firm_id")
|
98
|
+
assert_equal [Account], accounts.collect(&:class).uniq
|
99
|
+
end
|
100
|
+
|
86
101
|
def test_find_first
|
87
102
|
first = Topic.find(:first, :conditions => "title = 'The First Topic'")
|
88
103
|
assert_equal(topics(:first).title, first.title)
|
@@ -111,17 +126,58 @@ class FinderTest < Test::Unit::TestCase
|
|
111
126
|
assert topic.respond_to?("author_name")
|
112
127
|
end
|
113
128
|
|
114
|
-
def
|
129
|
+
def test_find_on_array_conditions
|
115
130
|
assert Topic.find(1, :conditions => ["approved = ?", false])
|
116
131
|
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => ["approved = ?", true]) }
|
117
132
|
end
|
118
133
|
|
119
|
-
def
|
134
|
+
def test_find_on_hash_conditions
|
135
|
+
assert Topic.find(1, :conditions => { :approved => false })
|
136
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :approved => true }) }
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_find_on_multiple_hash_conditions
|
140
|
+
assert Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => false })
|
141
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) }
|
142
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "HHC", :replies_count => 1, :approved => false }) }
|
143
|
+
assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) }
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_condition_array_interpolation
|
120
147
|
assert_kind_of Firm, Company.find(:first, :conditions => ["name = '%s'", "37signals"])
|
121
148
|
assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!"])
|
122
149
|
assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!' OR 1=1"])
|
123
150
|
assert_kind_of Time, Topic.find(:first, :conditions => ["id = %d", 1]).written_on
|
124
151
|
end
|
152
|
+
|
153
|
+
def test_condition_hash_interpolation
|
154
|
+
assert_kind_of Firm, Company.find(:first, :conditions => { :name => "37signals"})
|
155
|
+
assert_nil Company.find(:first, :conditions => { :name => "37signals!"})
|
156
|
+
assert_kind_of Time, Topic.find(:first, :conditions => {:id => 1}).written_on
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_hash_condition_find_malformed
|
160
|
+
assert_raises(ActiveRecord::StatementInvalid) {
|
161
|
+
Company.find(:first, :conditions => { :id => 2, :dhh => true })
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_hash_condition_find_with_escaped_characters
|
166
|
+
Company.create("name" => "Ain't noth'n like' \#stuff")
|
167
|
+
assert Company.find(:first, :conditions => { :name => "Ain't noth'n like' \#stuff" })
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_hash_condition_find_with_array
|
171
|
+
p1, p2 = Post.find(:all, :limit => 2, :order => 'id asc')
|
172
|
+
assert_equal [p1, p2], Post.find(:all, :conditions => { :id => [p1, p2] }, :order => 'id asc')
|
173
|
+
assert_equal [p1, p2], Post.find(:all, :conditions => { :id => [p1, p2.id] }, :order => 'id asc')
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_hash_condition_find_with_nil
|
177
|
+
topic = Topic.find(:first, :conditions => { :last_read => nil } )
|
178
|
+
assert_not_nil topic
|
179
|
+
assert_nil topic.last_read
|
180
|
+
end
|
125
181
|
|
126
182
|
def test_bind_variables
|
127
183
|
assert_kind_of Firm, Company.find(:first, :conditions => ["name = ?", "37signals"])
|
@@ -180,19 +236,34 @@ class FinderTest < Test::Unit::TestCase
|
|
180
236
|
assert_equal %('a','b','c'), bind(':a', :a => Set.new(%w(a b c))) # '
|
181
237
|
end
|
182
238
|
|
239
|
+
def test_bind_empty_enumerable
|
240
|
+
quoted_nil = ActiveRecord::Base.connection.quote(nil)
|
241
|
+
assert_equal quoted_nil, bind('?', [])
|
242
|
+
assert_equal " in (#{quoted_nil})", bind(' in (?)', [])
|
243
|
+
assert_equal "foo in (#{quoted_nil})", bind('foo in (?)', [])
|
244
|
+
end
|
245
|
+
|
183
246
|
def test_bind_string
|
184
247
|
assert_equal "''", bind('?', '')
|
185
248
|
end
|
186
249
|
|
250
|
+
def test_bind_record
|
251
|
+
o = Struct.new(:quoted_id).new(1)
|
252
|
+
assert_equal '1', bind('?', o)
|
253
|
+
|
254
|
+
os = [o] * 3
|
255
|
+
assert_equal '1,1,1', bind('?', os)
|
256
|
+
end
|
257
|
+
|
187
258
|
def test_string_sanitation
|
188
259
|
assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
|
189
260
|
assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table")
|
190
261
|
end
|
191
262
|
|
192
263
|
def test_count
|
193
|
-
assert_equal(0, Entrant.count("id > 3"))
|
194
|
-
assert_equal(1, Entrant.count(["id > ?", 2]))
|
195
|
-
assert_equal(2, Entrant.count(["id > ?", 1]))
|
264
|
+
assert_equal(0, Entrant.count(:conditions => "id > 3"))
|
265
|
+
assert_equal(1, Entrant.count(:conditions => ["id > ?", 2]))
|
266
|
+
assert_equal(2, Entrant.count(:conditions => ["id > ?", 1]))
|
196
267
|
end
|
197
268
|
|
198
269
|
def test_count_by_sql
|
@@ -222,6 +293,13 @@ class FinderTest < Test::Unit::TestCase
|
|
222
293
|
def test_find_by_one_missing_attribute
|
223
294
|
assert_raises(NoMethodError) { Topic.find_by_undertitle("The First Topic!") }
|
224
295
|
end
|
296
|
+
|
297
|
+
def test_find_by_invalid_method_syntax
|
298
|
+
assert_raises(NoMethodError) { Topic.fail_to_find_by_title("The First Topic") }
|
299
|
+
assert_raises(NoMethodError) { Topic.find_by_title?("The First Topic") }
|
300
|
+
assert_raises(NoMethodError) { Topic.fail_to_find_or_create_by_title("Nonexistent Title") }
|
301
|
+
assert_raises(NoMethodError) { Topic.find_or_create_by_title?("Nonexistent Title") }
|
302
|
+
end
|
225
303
|
|
226
304
|
def test_find_by_two_attributes
|
227
305
|
assert_equal topics(:first), Topic.find_by_title_and_author_name("The First Topic", "David")
|
@@ -286,6 +364,7 @@ class FinderTest < Test::Unit::TestCase
|
|
286
364
|
sig38 = Company.find_or_create_by_name("38signals")
|
287
365
|
assert_equal number_of_companies + 1, Company.count
|
288
366
|
assert_equal sig38, Company.find_or_create_by_name("38signals")
|
367
|
+
assert !sig38.new_record?
|
289
368
|
end
|
290
369
|
|
291
370
|
def test_find_or_create_from_two_attributes
|
@@ -293,6 +372,20 @@ class FinderTest < Test::Unit::TestCase
|
|
293
372
|
another = Topic.find_or_create_by_title_and_author_name("Another topic","John")
|
294
373
|
assert_equal number_of_topics + 1, Topic.count
|
295
374
|
assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John")
|
375
|
+
assert !another.new_record?
|
376
|
+
end
|
377
|
+
|
378
|
+
def test_find_or_initialize_from_one_attribute
|
379
|
+
sig38 = Company.find_or_initialize_by_name("38signals")
|
380
|
+
assert_equal "38signals", sig38.name
|
381
|
+
assert sig38.new_record?
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_find_or_initialize_from_two_attributes
|
385
|
+
another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John")
|
386
|
+
assert_equal "Another topic", another.title
|
387
|
+
assert_equal "John", another.author_name
|
388
|
+
assert another.new_record?
|
296
389
|
end
|
297
390
|
|
298
391
|
def test_find_with_bad_sql
|
@@ -357,6 +450,20 @@ class FinderTest < Test::Unit::TestCase
|
|
357
450
|
end
|
358
451
|
end
|
359
452
|
|
453
|
+
def test_find_by_empty_ids
|
454
|
+
assert_equal [], Post.find([])
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_find_by_empty_in_condition
|
458
|
+
assert_equal [], Post.find(:all, :conditions => ['id in (?)', []])
|
459
|
+
end
|
460
|
+
|
461
|
+
def test_find_by_records
|
462
|
+
p1, p2 = Post.find(:all, :limit => 2, :order => 'id asc')
|
463
|
+
assert_equal [p1, p2], Post.find(:all, :conditions => ['id in (?)', [p1, p2]], :order => 'id asc')
|
464
|
+
assert_equal [p1, p2], Post.find(:all, :conditions => ['id in (?)', [p1, p2.id]], :order => 'id asc')
|
465
|
+
end
|
466
|
+
|
360
467
|
def test_select_value
|
361
468
|
assert_equal "37signals", Company.connection.select_value("SELECT name FROM companies WHERE id = 1")
|
362
469
|
assert_nil Company.connection.select_value("SELECT name FROM companies WHERE id = -1")
|
@@ -366,8 +473,8 @@ class FinderTest < Test::Unit::TestCase
|
|
366
473
|
end
|
367
474
|
|
368
475
|
def test_select_values
|
369
|
-
assert_equal ["1","2","3","4","5","6","7","8"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
|
370
|
-
assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
|
476
|
+
assert_equal ["1","2","3","4","5","6","7","8","9"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
|
477
|
+
assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
|
371
478
|
end
|
372
479
|
|
373
480
|
protected
|