activerecord 1.11.1 → 1.12.1
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 +198 -0
- data/lib/active_record.rb +19 -14
- data/lib/active_record/acts/list.rb +8 -6
- data/lib/active_record/acts/tree.rb +33 -10
- data/lib/active_record/aggregations.rb +1 -7
- data/lib/active_record/associations.rb +151 -82
- data/lib/active_record/associations/association_collection.rb +25 -0
- data/lib/active_record/associations/association_proxy.rb +9 -8
- data/lib/active_record/associations/belongs_to_association.rb +19 -5
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +44 -69
- data/lib/active_record/associations/has_many_association.rb +6 -14
- data/lib/active_record/associations/has_one_association.rb +5 -3
- data/lib/active_record/base.rb +344 -130
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +128 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +104 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +51 -0
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +249 -0
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +245 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +29 -464
- data/lib/active_record/connection_adapters/db2_adapter.rb +40 -10
- data/lib/active_record/connection_adapters/mysql_adapter.rb +131 -60
- data/lib/active_record/connection_adapters/oci_adapter.rb +106 -26
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +211 -62
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +193 -44
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +24 -15
- data/lib/active_record/fixtures.rb +47 -24
- data/lib/active_record/migration.rb +34 -5
- data/lib/active_record/observer.rb +32 -2
- data/lib/active_record/query_cache.rb +12 -11
- data/lib/active_record/schema.rb +58 -0
- data/lib/active_record/schema_dumper.rb +84 -0
- data/lib/active_record/transactions.rb +1 -3
- data/lib/active_record/validations.rb +40 -26
- data/lib/active_record/vendor/mysql.rb +6 -0
- data/lib/active_record/version.rb +9 -0
- data/rakefile +5 -16
- data/test/abstract_unit.rb +6 -11
- data/test/adapter_test.rb +58 -0
- data/test/ar_schema_test.rb +33 -0
- data/test/association_callbacks_test.rb +14 -0
- data/test/associations_go_eager_test.rb +56 -14
- data/test/associations_test.rb +245 -25
- data/test/base_test.rb +205 -34
- data/test/binary_test.rb +25 -42
- data/test/callbacks_test.rb +75 -0
- data/test/conditions_scoping_test.rb +136 -0
- data/test/connections/native_mysql/connection.rb +0 -4
- data/test/connections/native_sqlite3/in_memory_connection.rb +17 -0
- data/test/copy_table_sqlite.rb +64 -0
- data/test/deprecated_associations_test.rb +7 -6
- data/test/deprecated_finder_test.rb +3 -3
- data/test/finder_test.rb +33 -3
- data/test/fixtures/accounts.yml +5 -0
- data/test/fixtures/categories_ordered.yml +7 -0
- data/test/fixtures/category.rb +11 -1
- data/test/fixtures/comment.rb +22 -2
- data/test/fixtures/comments.yml +6 -0
- data/test/fixtures/companies.yml +15 -0
- data/test/fixtures/company.rb +24 -1
- data/test/fixtures/db_definitions/db2.drop.sql +5 -1
- data/test/fixtures/db_definitions/db2.sql +15 -1
- data/test/fixtures/db_definitions/mysql.drop.sql +2 -0
- data/test/fixtures/db_definitions/mysql.sql +17 -2
- data/test/fixtures/db_definitions/oci.drop.sql +37 -5
- data/test/fixtures/db_definitions/oci.sql +47 -4
- data/test/fixtures/db_definitions/oci2.drop.sql +1 -1
- data/test/fixtures/db_definitions/oci2.sql +2 -2
- data/test/fixtures/db_definitions/postgresql.drop.sql +4 -0
- data/test/fixtures/db_definitions/postgresql.sql +33 -4
- data/test/fixtures/db_definitions/sqlite.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlite.sql +16 -2
- data/test/fixtures/db_definitions/sqlserver.drop.sql +2 -0
- data/test/fixtures/db_definitions/sqlserver.sql +16 -2
- data/test/fixtures/developer.rb +1 -1
- data/test/fixtures/flowers.jpg +0 -0
- data/test/fixtures/keyboard.rb +3 -0
- data/test/fixtures/mixins.yml +11 -1
- data/test/fixtures/order.rb +4 -0
- data/test/fixtures/post.rb +4 -0
- data/test/fixtures/posts.yml +7 -0
- data/test/fixtures/project.rb +1 -0
- data/test/fixtures/subject.rb +4 -0
- data/test/fixtures/subscriber.rb +2 -4
- data/test/fixtures/topics.yml +2 -2
- data/test/fixtures_test.rb +79 -7
- data/test/inheritance_test.rb +2 -2
- data/test/lifecycle_test.rb +14 -6
- data/test/migration_test.rb +164 -6
- data/test/mixin_test.rb +78 -2
- data/test/pk_test.rb +25 -1
- data/test/readonly_test.rb +31 -0
- data/test/reflection_test.rb +4 -1
- data/test/schema_dumper_test.rb +19 -0
- data/test/schema_test_postgresql.rb +3 -2
- data/test/synonym_test_oci.rb +17 -0
- data/test/threaded_connections_test.rb +2 -1
- data/test/transactions_test.rb +109 -10
- data/test/validations_test.rb +70 -42
- metadata +25 -5
- data/test/fixtures/associations.png +0 -0
- data/test/thread_safety_test.rb +0 -36
data/test/lifecycle_test.rb
CHANGED
@@ -5,6 +5,7 @@ require 'fixtures/reply'
|
|
5
5
|
|
6
6
|
class Topic; def after_find() end end
|
7
7
|
class Developer; def after_find() end end
|
8
|
+
class SpecialDeveloper < Developer; end
|
8
9
|
|
9
10
|
class TopicManualObserver
|
10
11
|
include Singleton
|
@@ -64,22 +65,22 @@ class LifecycleTest < Test::Unit::TestCase
|
|
64
65
|
end
|
65
66
|
|
66
67
|
def test_after_save
|
67
|
-
|
68
|
+
ActiveRecord::Base.observers = :topic_manual_observer
|
68
69
|
|
69
70
|
topic = Topic.find(1)
|
70
71
|
topic.title = "hello"
|
71
72
|
topic.save
|
72
73
|
|
73
|
-
assert
|
74
|
-
assert_equal :after_save,
|
74
|
+
assert TopicManualObserver.instance.has_been_notified?
|
75
|
+
assert_equal :after_save, TopicManualObserver.instance.callbacks.last["callback_method"]
|
75
76
|
end
|
76
77
|
|
77
78
|
def test_observer_update_on_save
|
78
|
-
|
79
|
+
ActiveRecord::Base.observers = TopicManualObserver
|
79
80
|
|
80
81
|
topic = Topic.find(1)
|
81
|
-
assert
|
82
|
-
assert_equal :after_find,
|
82
|
+
assert TopicManualObserver.instance.has_been_notified?
|
83
|
+
assert_equal :after_find, TopicManualObserver.instance.callbacks.first["callback_method"]
|
83
84
|
end
|
84
85
|
|
85
86
|
def test_auto_observer
|
@@ -105,4 +106,11 @@ class LifecycleTest < Test::Unit::TestCase
|
|
105
106
|
developer = Developer.find(1)
|
106
107
|
assert_equal multi_observer.record.name, developer.name
|
107
108
|
end
|
109
|
+
|
110
|
+
def test_observing_subclasses
|
111
|
+
multi_observer = MultiObserver.instance
|
112
|
+
|
113
|
+
developer = SpecialDeveloper.find(1)
|
114
|
+
assert_equal multi_observer.record.name, developer.name
|
115
|
+
end
|
108
116
|
end
|
data/test/migration_test.rb
CHANGED
@@ -8,12 +8,14 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
8
8
|
class Reminder < ActiveRecord::Base; end
|
9
9
|
|
10
10
|
class MigrationTest < Test::Unit::TestCase
|
11
|
+
self.use_transactional_fixtures = false
|
12
|
+
|
11
13
|
def setup
|
12
14
|
end
|
13
15
|
|
14
16
|
def teardown
|
15
17
|
ActiveRecord::Base.connection.initialize_schema_information
|
16
|
-
ActiveRecord::Base.connection.update "UPDATE
|
18
|
+
ActiveRecord::Base.connection.update "UPDATE #{ActiveRecord::Migrator.schema_info_table_name} SET version = 0"
|
17
19
|
|
18
20
|
Reminder.connection.drop_table("reminders") rescue nil
|
19
21
|
Reminder.connection.drop_table("people_reminders") rescue nil
|
@@ -32,12 +34,75 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
32
34
|
|
33
35
|
def test_add_index
|
34
36
|
Person.connection.add_column "people", "last_name", :string
|
37
|
+
Person.connection.add_column "people", "administrator", :boolean
|
35
38
|
|
36
39
|
assert_nothing_raised { Person.connection.add_index("people", "last_name") }
|
37
40
|
assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
|
38
41
|
|
39
42
|
assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
|
40
43
|
assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
|
44
|
+
|
45
|
+
assert_nothing_raised { Person.connection.add_index("people", %w(last_name first_name administrator), :name => "named_admin") }
|
46
|
+
assert_nothing_raised { Person.connection.remove_index("people", :name => "named_admin") }
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_create_table_adds_id
|
50
|
+
Person.connection.create_table :testings do |t|
|
51
|
+
t.column :foo, :string
|
52
|
+
end
|
53
|
+
|
54
|
+
assert_equal %w(foo id),
|
55
|
+
Person.connection.columns(:testings).map { |c| c.name }.sort
|
56
|
+
ensure
|
57
|
+
Person.connection.drop_table :testings rescue nil
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_create_table_with_not_null_column
|
61
|
+
Person.connection.create_table :testings do |t|
|
62
|
+
t.column :foo, :string, :null => false
|
63
|
+
end
|
64
|
+
|
65
|
+
assert_raises(ActiveRecord::StatementInvalid) do
|
66
|
+
Person.connection.execute "insert into testings (foo) values (NULL)"
|
67
|
+
end
|
68
|
+
ensure
|
69
|
+
Person.connection.drop_table :testings rescue nil
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_create_table_with_defaults
|
73
|
+
Person.connection.create_table :testings do |t|
|
74
|
+
t.column :one, :string, :default => "hello"
|
75
|
+
t.column :two, :boolean, :default => true
|
76
|
+
t.column :three, :boolean, :default => false
|
77
|
+
t.column :four, :integer, :default => 1
|
78
|
+
end
|
79
|
+
|
80
|
+
columns = Person.connection.columns(:testings)
|
81
|
+
one = columns.detect { |c| c.name == "one" }
|
82
|
+
two = columns.detect { |c| c.name == "two" }
|
83
|
+
three = columns.detect { |c| c.name == "three" }
|
84
|
+
four = columns.detect { |c| c.name == "four" }
|
85
|
+
|
86
|
+
assert_equal "hello", one.default
|
87
|
+
assert_equal true, two.default
|
88
|
+
assert_equal false, three.default
|
89
|
+
assert_equal 1, four.default
|
90
|
+
|
91
|
+
ensure
|
92
|
+
Person.connection.drop_table :testings rescue nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_add_column_not_null
|
96
|
+
Person.connection.create_table :testings do |t|
|
97
|
+
t.column :foo, :string
|
98
|
+
end
|
99
|
+
Person.connection.add_column :testings, :bar, :string, :null => false
|
100
|
+
|
101
|
+
assert_raises(ActiveRecord::StatementInvalid) do
|
102
|
+
Person.connection.execute "insert into testings (foo, bar) values ('hello', NULL)"
|
103
|
+
end
|
104
|
+
ensure
|
105
|
+
Person.connection.drop_table :testings rescue nil
|
41
106
|
end
|
42
107
|
|
43
108
|
def test_native_types
|
@@ -67,15 +132,29 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
67
132
|
assert_equal TrueClass, bob.male?.class
|
68
133
|
end
|
69
134
|
|
70
|
-
def
|
135
|
+
def test_add_remove_single_field_using_string_arguments
|
71
136
|
assert !Person.column_methods_hash.include?(:last_name)
|
72
137
|
|
73
|
-
|
138
|
+
ActiveRecord::Migration.add_column 'people', 'last_name', :string
|
74
139
|
|
75
140
|
Person.reset_column_information
|
76
141
|
assert Person.column_methods_hash.include?(:last_name)
|
77
142
|
|
78
|
-
|
143
|
+
ActiveRecord::Migration.remove_column 'people', 'last_name'
|
144
|
+
|
145
|
+
Person.reset_column_information
|
146
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_add_remove_single_field_using_symbol_arguments
|
150
|
+
assert !Person.column_methods_hash.include?(:last_name)
|
151
|
+
|
152
|
+
ActiveRecord::Migration.add_column :people, :last_name, :string
|
153
|
+
|
154
|
+
Person.reset_column_information
|
155
|
+
assert Person.column_methods_hash.include?(:last_name)
|
156
|
+
|
157
|
+
ActiveRecord::Migration.remove_column :people, :last_name
|
79
158
|
|
80
159
|
Person.reset_column_information
|
81
160
|
assert !Person.column_methods_hash.include?(:last_name)
|
@@ -101,6 +180,25 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
101
180
|
|
102
181
|
end
|
103
182
|
|
183
|
+
def test_rename_table
|
184
|
+
begin
|
185
|
+
ActiveRecord::Base.connection.create_table :octopuses do |t|
|
186
|
+
t.column :url, :string
|
187
|
+
end
|
188
|
+
ActiveRecord::Base.connection.rename_table :octopuses, :octopi
|
189
|
+
|
190
|
+
assert_nothing_raised do
|
191
|
+
ActiveRecord::Base.connection.execute "INSERT INTO octopi (url) VALUES ('http://www.foreverflying.com/octopus-black7.jpg')"
|
192
|
+
end
|
193
|
+
|
194
|
+
assert_equal 'http://www.foreverflying.com/octopus-black7.jpg', ActiveRecord::Base.connection.select_value("SELECT url FROM octopi WHERE id=1")
|
195
|
+
|
196
|
+
ensure
|
197
|
+
ActiveRecord::Base.connection.drop_table :octopuses rescue nil
|
198
|
+
ActiveRecord::Base.connection.drop_table :octopi rescue nil
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
104
202
|
def test_change_column
|
105
203
|
Person.connection.add_column "people", "bio", :string
|
106
204
|
assert_nothing_raised { Person.connection.change_column "people", "bio", :text }
|
@@ -197,5 +295,65 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
197
295
|
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
198
296
|
assert_equal "hello world", Reminder.find(:first).content
|
199
297
|
end
|
200
|
-
|
201
|
-
|
298
|
+
|
299
|
+
def test_schema_info_table_name
|
300
|
+
ActiveRecord::Base.table_name_prefix = "prefix_"
|
301
|
+
ActiveRecord::Base.table_name_suffix = "_suffix"
|
302
|
+
Reminder.reset_table_name
|
303
|
+
assert_equal "prefix_schema_info_suffix", ActiveRecord::Migrator.schema_info_table_name
|
304
|
+
ActiveRecord::Base.table_name_prefix = ""
|
305
|
+
ActiveRecord::Base.table_name_suffix = ""
|
306
|
+
Reminder.reset_table_name
|
307
|
+
assert_equal "schema_info", ActiveRecord::Migrator.schema_info_table_name
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_proper_table_name
|
311
|
+
assert_equal "table", ActiveRecord::Migrator.proper_table_name('table')
|
312
|
+
assert_equal "table", ActiveRecord::Migrator.proper_table_name(:table)
|
313
|
+
assert_equal "reminders", ActiveRecord::Migrator.proper_table_name(Reminder)
|
314
|
+
Reminder.reset_table_name
|
315
|
+
assert_equal Reminder.table_name, ActiveRecord::Migrator.proper_table_name(Reminder)
|
316
|
+
|
317
|
+
# Use the model's own prefix/suffix if a model is given
|
318
|
+
ActiveRecord::Base.table_name_prefix = "ARprefix_"
|
319
|
+
ActiveRecord::Base.table_name_suffix = "_ARsuffix"
|
320
|
+
Reminder.table_name_prefix = 'prefix_'
|
321
|
+
Reminder.table_name_suffix = '_suffix'
|
322
|
+
Reminder.reset_table_name
|
323
|
+
assert_equal "prefix_reminders_suffix", ActiveRecord::Migrator.proper_table_name(Reminder)
|
324
|
+
Reminder.table_name_prefix = ''
|
325
|
+
Reminder.table_name_suffix = ''
|
326
|
+
Reminder.reset_table_name
|
327
|
+
|
328
|
+
# Use AR::Base's prefix/suffix if string or symbol is given
|
329
|
+
ActiveRecord::Base.table_name_prefix = "prefix_"
|
330
|
+
ActiveRecord::Base.table_name_suffix = "_suffix"
|
331
|
+
Reminder.reset_table_name
|
332
|
+
assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name('table')
|
333
|
+
assert_equal "prefix_table_suffix", ActiveRecord::Migrator.proper_table_name(:table)
|
334
|
+
ActiveRecord::Base.table_name_prefix = ""
|
335
|
+
ActiveRecord::Base.table_name_suffix = ""
|
336
|
+
Reminder.reset_table_name
|
337
|
+
end
|
338
|
+
|
339
|
+
def test_add_drop_table_with_prefix_and_suffix
|
340
|
+
assert_raises(ActiveRecord::StatementInvalid) { Reminder.column_methods_hash }
|
341
|
+
|
342
|
+
ActiveRecord::Base.table_name_prefix = 'prefix_'
|
343
|
+
ActiveRecord::Base.table_name_suffix = '_suffix'
|
344
|
+
Reminder.reset_table_name
|
345
|
+
WeNeedReminders.up
|
346
|
+
|
347
|
+
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
348
|
+
assert_equal "hello world", Reminder.find(:first).content
|
349
|
+
|
350
|
+
WeNeedReminders.down
|
351
|
+
assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
|
352
|
+
ActiveRecord::Base.table_name_prefix = ''
|
353
|
+
ActiveRecord::Base.table_name_suffix = ''
|
354
|
+
Reminder.reset_table_name
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
end
|
data/test/mixin_test.rb
CHANGED
@@ -65,6 +65,22 @@ class ListTest < Test::Unit::TestCase
|
|
65
65
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
66
66
|
|
67
67
|
end
|
68
|
+
|
69
|
+
def test_move_to_bottom_with_next_to_last_item
|
70
|
+
assert_equal [mixins(:list_1),
|
71
|
+
mixins(:list_2),
|
72
|
+
mixins(:list_3),
|
73
|
+
mixins(:list_4)],
|
74
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
75
|
+
|
76
|
+
mixins(:list_3).move_to_bottom
|
77
|
+
|
78
|
+
assert_equal [mixins(:list_1),
|
79
|
+
mixins(:list_2),
|
80
|
+
mixins(:list_4),
|
81
|
+
mixins(:list_3)],
|
82
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
83
|
+
end
|
68
84
|
|
69
85
|
def test_next_prev
|
70
86
|
assert_equal mixins(:list_2), mixins(:list_1).lower_item
|
@@ -126,6 +142,15 @@ class ListTest < Test::Unit::TestCase
|
|
126
142
|
|
127
143
|
new4.reload
|
128
144
|
assert_equal 4, new4.pos
|
145
|
+
|
146
|
+
new5 = ListMixin.create("parent_id" => 20)
|
147
|
+
assert_equal 5, new5.pos
|
148
|
+
|
149
|
+
new5.insert_at(1)
|
150
|
+
assert_equal 1, new5.pos
|
151
|
+
|
152
|
+
new4.reload
|
153
|
+
assert_equal 5, new4.pos
|
129
154
|
end
|
130
155
|
|
131
156
|
def test_delete_middle
|
@@ -189,6 +214,13 @@ class TreeTest < Test::Unit::TestCase
|
|
189
214
|
assert_equal mixins(:tree_4).children, []
|
190
215
|
end
|
191
216
|
|
217
|
+
def test_has_parent
|
218
|
+
assert_equal false, mixins(:tree_1).has_parent?
|
219
|
+
assert_equal true, mixins(:tree_2).has_parent?
|
220
|
+
assert_equal true, mixins(:tree_3).has_parent?
|
221
|
+
assert_equal true, mixins(:tree_4).has_parent?
|
222
|
+
end
|
223
|
+
|
192
224
|
def test_parent
|
193
225
|
assert_equal mixins(:tree_2).parent, mixins(:tree_1)
|
194
226
|
assert_equal mixins(:tree_2).parent, mixins(:tree_4).parent
|
@@ -196,11 +228,14 @@ class TreeTest < Test::Unit::TestCase
|
|
196
228
|
end
|
197
229
|
|
198
230
|
def test_delete
|
199
|
-
assert_equal
|
231
|
+
assert_equal 6, TreeMixin.count
|
200
232
|
mixins(:tree_1).destroy
|
233
|
+
assert_equal 2, TreeMixin.count
|
234
|
+
mixins(:tree2_1).destroy
|
235
|
+
mixins(:tree3_1).destroy
|
201
236
|
assert_equal 0, TreeMixin.count
|
202
237
|
end
|
203
|
-
|
238
|
+
|
204
239
|
def test_insert
|
205
240
|
@extra = mixins(:tree_1).children.create
|
206
241
|
|
@@ -214,6 +249,46 @@ class TreeTest < Test::Unit::TestCase
|
|
214
249
|
assert mixins(:tree_1).children.include?(mixins(:tree_4))
|
215
250
|
end
|
216
251
|
|
252
|
+
def test_ancestors
|
253
|
+
assert_equal [], mixins(:tree_1).ancestors
|
254
|
+
assert_equal [mixins(:tree_1)], mixins(:tree_2).ancestors
|
255
|
+
assert_equal [mixins(:tree_2), mixins(:tree_1)], mixins(:tree_3).ancestors
|
256
|
+
assert_equal [mixins(:tree_1)], mixins(:tree_4).ancestors
|
257
|
+
assert_equal [], mixins(:tree2_1).ancestors
|
258
|
+
assert_equal [], mixins(:tree3_1).ancestors
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_root
|
262
|
+
assert_equal mixins(:tree_1), TreeMixin.root
|
263
|
+
assert_equal mixins(:tree_1), mixins(:tree_1).root
|
264
|
+
assert_equal mixins(:tree_1), mixins(:tree_2).root
|
265
|
+
assert_equal mixins(:tree_1), mixins(:tree_3).root
|
266
|
+
assert_equal mixins(:tree_1), mixins(:tree_4).root
|
267
|
+
assert_equal mixins(:tree2_1), mixins(:tree2_1).root
|
268
|
+
assert_equal mixins(:tree3_1), mixins(:tree3_1).root
|
269
|
+
end
|
270
|
+
|
271
|
+
def test_roots
|
272
|
+
assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], TreeMixin.roots
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_siblings
|
276
|
+
assert_equal [mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree_1).siblings
|
277
|
+
assert_equal [mixins(:tree_4)], mixins(:tree_2).siblings
|
278
|
+
assert_equal [], mixins(:tree_3).siblings
|
279
|
+
assert_equal [mixins(:tree_2)], mixins(:tree_4).siblings
|
280
|
+
assert_equal [mixins(:tree_1), mixins(:tree3_1)], mixins(:tree2_1).siblings
|
281
|
+
assert_equal [mixins(:tree_1), mixins(:tree2_1)], mixins(:tree3_1).siblings
|
282
|
+
end
|
283
|
+
|
284
|
+
def test_self_and_siblings
|
285
|
+
assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree_1).self_and_siblings
|
286
|
+
assert_equal [mixins(:tree_2), mixins(:tree_4)], mixins(:tree_2).self_and_siblings
|
287
|
+
assert_equal [mixins(:tree_3)], mixins(:tree_3).self_and_siblings
|
288
|
+
assert_equal [mixins(:tree_2), mixins(:tree_4)], mixins(:tree_4).self_and_siblings
|
289
|
+
assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree2_1).self_and_siblings
|
290
|
+
assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], mixins(:tree3_1).self_and_siblings
|
291
|
+
end
|
217
292
|
end
|
218
293
|
|
219
294
|
class TouchTest < Test::Unit::TestCase
|
@@ -264,4 +339,5 @@ class TouchTest < Test::Unit::TestCase
|
|
264
339
|
|
265
340
|
Mixin.record_timestamps = true
|
266
341
|
end
|
342
|
+
|
267
343
|
end
|
data/test/pk_test.rb
CHANGED
@@ -2,6 +2,7 @@ require 'abstract_unit'
|
|
2
2
|
require 'fixtures/topic'
|
3
3
|
require 'fixtures/subscriber'
|
4
4
|
require 'fixtures/movie'
|
5
|
+
require 'fixtures/keyboard'
|
5
6
|
|
6
7
|
class PrimaryKeysTest < Test::Unit::TestCase
|
7
8
|
fixtures :topics, :subscribers, :movies
|
@@ -22,6 +23,26 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|
22
23
|
assert_equal("New Topic", topicReloaded.title)
|
23
24
|
end
|
24
25
|
|
26
|
+
def test_customized_primary_key_auto_assigns_on_save
|
27
|
+
keyboard = Keyboard.new(:name => 'HHKB')
|
28
|
+
assert_nothing_raised { keyboard.save }
|
29
|
+
assert keyboard.id
|
30
|
+
assert_equal keyboard.id, Keyboard.find_by_name('HHKB').id
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_customized_primary_key_can_be_get_before_saving
|
34
|
+
keyboard = Keyboard.new
|
35
|
+
assert_respond_to(keyboard, :key_number)
|
36
|
+
assert_nothing_raised { keyboard.key_number }
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_customized_string_primary_key_settable_before_save
|
40
|
+
subscriber = Subscriber.new
|
41
|
+
assert_nothing_raised { subscriber.id = 'webster123' }
|
42
|
+
assert_equal 'webster123', subscriber.id
|
43
|
+
assert_equal 'webster123', subscriber.nick
|
44
|
+
end
|
45
|
+
|
25
46
|
def test_string_key
|
26
47
|
subscriber = Subscriber.find(subscribers(:first).nick)
|
27
48
|
assert_equal(subscribers(:first).name, subscriber.name)
|
@@ -32,7 +53,7 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|
32
53
|
subscriber.id = "jdoe"
|
33
54
|
assert_equal("jdoe", subscriber.id)
|
34
55
|
subscriber.name = "John Doe"
|
35
|
-
assert_nothing_raised{ subscriber.save }
|
56
|
+
assert_nothing_raised { subscriber.save! }
|
36
57
|
|
37
58
|
subscriberReloaded = Subscriber.find("jdoe")
|
38
59
|
assert_equal("John Doe", subscriberReloaded.name)
|
@@ -44,12 +65,15 @@ class PrimaryKeysTest < Test::Unit::TestCase
|
|
44
65
|
|
45
66
|
def test_primary_key_prefix
|
46
67
|
ActiveRecord::Base.primary_key_prefix_type = :table_name
|
68
|
+
Topic.reset_primary_key
|
47
69
|
assert_equal "topicid", Topic.primary_key
|
48
70
|
|
49
71
|
ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
|
72
|
+
Topic.reset_primary_key
|
50
73
|
assert_equal "topic_id", Topic.primary_key
|
51
74
|
|
52
75
|
ActiveRecord::Base.primary_key_prefix_type = nil
|
76
|
+
Topic.reset_primary_key
|
53
77
|
assert_equal "id", Topic.primary_key
|
54
78
|
end
|
55
79
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/topic'
|
3
|
+
|
4
|
+
class ReadOnlyTest < Test::Unit::TestCase
|
5
|
+
fixtures :topics
|
6
|
+
|
7
|
+
def test_cant_save_readonly_record
|
8
|
+
topic = Topic.find(:first)
|
9
|
+
assert !topic.readonly?
|
10
|
+
|
11
|
+
topic.readonly!
|
12
|
+
assert topic.readonly?
|
13
|
+
|
14
|
+
assert_nothing_raised do
|
15
|
+
topic.content = 'Luscious forbidden fruit.'
|
16
|
+
end
|
17
|
+
|
18
|
+
assert_raise(ActiveRecord::ReadOnlyRecord) { topic.save }
|
19
|
+
assert_raise(ActiveRecord::ReadOnlyRecord) { topic.save! }
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_find_with_readonly_option
|
23
|
+
Topic.find(:all).each { |t| assert !t.readonly? }
|
24
|
+
Topic.find(:all, :readonly => false).each { |t| assert !t.readonly? }
|
25
|
+
Topic.find(:all, :readonly => true).each { |t| assert t.readonly? }
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_find_with_joins_option_implies_readonly
|
29
|
+
Topic.find(:all, :joins => '').each { |t| assert t.readonly? }
|
30
|
+
end
|
31
|
+
end
|