activerecord 1.13.0 → 1.13.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 +91 -0
- data/lib/active_record.rb +2 -2
- data/lib/active_record/acts/list.rb +16 -12
- data/lib/active_record/acts/tree.rb +2 -2
- data/lib/active_record/aggregations.rb +6 -0
- data/lib/active_record/associations.rb +38 -16
- data/lib/active_record/associations/has_many_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +1 -1
- data/lib/active_record/base.rb +46 -33
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +33 -9
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +11 -2
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +3 -0
- data/lib/active_record/connection_adapters/abstract_adapter.rb +41 -21
- data/lib/active_record/connection_adapters/firebird_adapter.rb +414 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +68 -29
- data/lib/active_record/connection_adapters/oci_adapter.rb +141 -21
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +82 -21
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +3 -3
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +39 -6
- data/lib/active_record/fixtures.rb +1 -0
- data/lib/active_record/migration.rb +30 -13
- data/lib/active_record/validations.rb +18 -7
- data/lib/active_record/vendor/mysql.rb +89 -12
- data/lib/active_record/version.rb +2 -2
- data/rakefile +38 -3
- data/test/abstract_unit.rb +5 -0
- data/test/aggregations_test.rb +19 -0
- data/test/associations_go_eager_test.rb +26 -2
- data/test/associations_test.rb +29 -10
- data/test/base_test.rb +57 -6
- data/test/binary_test.rb +3 -3
- data/test/connections/native_db2/connection.rb +1 -1
- data/test/connections/native_firebird/connection.rb +24 -0
- data/test/connections/native_mysql/connection.rb +1 -1
- data/test/connections/native_oci/connection.rb +1 -1
- data/test/connections/native_postgresql/connection.rb +6 -6
- data/test/connections/native_sqlite/connection.rb +1 -1
- data/test/connections/native_sqlite3/connection.rb +1 -1
- data/test/connections/native_sqlite3/in_memory_connection.rb +1 -1
- data/test/connections/native_sqlserver/connection.rb +1 -1
- data/test/connections/native_sqlserver_odbc/connection.rb +1 -1
- data/test/default_test_firebird.rb +16 -0
- data/test/deprecated_associations_test.rb +1 -1
- data/test/finder_test.rb +11 -1
- data/test/fixtures/author.rb +30 -30
- data/test/fixtures/comment.rb +1 -1
- data/test/fixtures/company.rb +3 -1
- data/test/fixtures/customer.rb +4 -0
- data/test/fixtures/db_definitions/firebird.drop.sql +54 -0
- data/test/fixtures/db_definitions/firebird.sql +259 -0
- data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
- data/test/fixtures/db_definitions/firebird2.sql +6 -0
- data/test/fixtures/db_definitions/oci.sql +8 -0
- data/test/fixtures/db_definitions/postgresql.sql +3 -2
- data/test/fixtures/developer.rb +10 -0
- data/test/fixtures/fixture_database.sqlite +0 -0
- data/test/fixtures/fixture_database_2.sqlite +0 -0
- data/test/fixtures/mixin.rb +11 -1
- data/test/fixtures/mixins.yml +20 -1
- data/test/fixtures_test.rb +65 -45
- data/test/inheritance_test.rb +1 -1
- data/test/migration_test.rb +7 -1
- data/test/mixin_test.rb +267 -98
- data/test/multiple_db_test.rb +13 -1
- data/test/pk_test.rb +1 -0
- metadata +11 -5
- data/lib/active_record/vendor/mysql411.rb +0 -311
- data/test/debug.log +0 -2857
@@ -261,3 +261,11 @@ create table keyboards (
|
|
261
261
|
);
|
262
262
|
create sequence keyboards_seq minvalue 10000;
|
263
263
|
|
264
|
+
create table test_oci_defaults (
|
265
|
+
id integer not null primary key,
|
266
|
+
test_char char(1) default 'X' not null,
|
267
|
+
test_string varchar2(20) default 'hello' not null,
|
268
|
+
test_int integer default 3 not null
|
269
|
+
);
|
270
|
+
create sequence test_oci_defaults_seq minvalue 10000;
|
271
|
+
|
@@ -1,10 +1,11 @@
|
|
1
|
+
CREATE SEQUENCE public.accounts_id_seq START 100;
|
2
|
+
|
1
3
|
CREATE TABLE accounts (
|
2
|
-
id
|
4
|
+
id integer DEFAULT nextval('public.accounts_id_seq'),
|
3
5
|
firm_id integer,
|
4
6
|
credit_limit integer,
|
5
7
|
PRIMARY KEY (id)
|
6
8
|
);
|
7
|
-
SELECT setval('accounts_id_seq', 100);
|
8
9
|
|
9
10
|
CREATE SEQUENCE companies_nonstd_seq START 101;
|
10
11
|
|
data/test/fixtures/developer.rb
CHANGED
@@ -28,3 +28,13 @@ class DeveloperWithAggregate < ActiveRecord::Base
|
|
28
28
|
self.table_name = 'developers'
|
29
29
|
composed_of :salary, :class_name => 'DeveloperSalary', :mapping => [%w(salary amount)]
|
30
30
|
end
|
31
|
+
|
32
|
+
class DeveloperWithBeforeDestroyRaise < ActiveRecord::Base
|
33
|
+
self.table_name = 'developers'
|
34
|
+
has_and_belongs_to_many :projects, :join_table => 'developers_projects', :foreign_key => 'developer_id'
|
35
|
+
before_destroy :raise_if_projects_empty!
|
36
|
+
|
37
|
+
def raise_if_projects_empty!
|
38
|
+
raise if projects.empty?
|
39
|
+
end
|
40
|
+
end
|
Binary file
|
Binary file
|
data/test/fixtures/mixin.rb
CHANGED
@@ -6,12 +6,22 @@ class TreeMixin < Mixin
|
|
6
6
|
acts_as_tree :foreign_key => "parent_id", :order => "id"
|
7
7
|
end
|
8
8
|
|
9
|
+
class TreeMixinWithoutOrder < Mixin
|
10
|
+
acts_as_tree :foreign_key => "parent_id"
|
11
|
+
end
|
12
|
+
|
9
13
|
class ListMixin < Mixin
|
10
14
|
acts_as_list :column => "pos", :scope => :parent
|
11
15
|
|
12
16
|
def self.table_name() "mixins" end
|
13
17
|
end
|
14
18
|
|
19
|
+
class ListMixinSub1 < ListMixin
|
20
|
+
end
|
21
|
+
|
22
|
+
class ListMixinSub2 < ListMixin
|
23
|
+
end
|
24
|
+
|
15
25
|
|
16
26
|
class ListWithStringScopeMixin < ActiveRecord::Base
|
17
27
|
acts_as_list :column => "pos", :scope => 'parent_id = #{parent_id}'
|
@@ -35,4 +45,4 @@ class NestedSetWithSymbolScope < Mixin
|
|
35
45
|
acts_as_nested_set :scope => :root
|
36
46
|
|
37
47
|
def self.table_name() "mixins" end
|
38
|
-
end
|
48
|
+
end
|
data/test/fixtures/mixins.yml
CHANGED
@@ -28,7 +28,17 @@ tree3_1:
|
|
28
28
|
id: 1006
|
29
29
|
type: TreeMixin
|
30
30
|
parent_id:
|
31
|
-
|
31
|
+
|
32
|
+
tree_without_order_1:
|
33
|
+
id: 1101
|
34
|
+
type: TreeMixinWithoutOrder
|
35
|
+
parent_id:
|
36
|
+
|
37
|
+
tree_without_order_2:
|
38
|
+
id: 1100
|
39
|
+
type: TreeMixinWithoutOrder
|
40
|
+
parent_id:
|
41
|
+
|
32
42
|
# List mixins
|
33
43
|
|
34
44
|
<% (1..4).each do |counter| %>
|
@@ -68,3 +78,12 @@ tree_<%= set[0] %>:
|
|
68
78
|
root_id: 42
|
69
79
|
|
70
80
|
<% end %>
|
81
|
+
|
82
|
+
# subclasses of list items
|
83
|
+
<% (1..4).each do |i| %>
|
84
|
+
list_sub_<%= i %>:
|
85
|
+
id: <%= i + 5000 %>
|
86
|
+
pos: <%= i %>
|
87
|
+
parent_id: 5000
|
88
|
+
type: <%= (i % 2 == 1) ? ListMixinSub1 : ListMixinSub2 %>
|
89
|
+
<% end %>
|
data/test/fixtures_test.rb
CHANGED
@@ -51,42 +51,44 @@ class FixturesTest < Test::Unit::TestCase
|
|
51
51
|
assert_nil(secondRow["author_email_address"])
|
52
52
|
end
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
54
|
+
if ActiveRecord::Base.connection.supports_migrations?
|
55
|
+
def test_inserts_with_pre_and_suffix
|
56
|
+
ActiveRecord::Base.connection.create_table :prefix_topics_suffix do |t|
|
57
|
+
t.column :title, :string
|
58
|
+
t.column :author_name, :string
|
59
|
+
t.column :author_email_address, :string
|
60
|
+
t.column :written_on, :datetime
|
61
|
+
t.column :bonus_time, :time
|
62
|
+
t.column :last_read, :date
|
63
|
+
t.column :content, :text
|
64
|
+
t.column :approved, :boolean, :default => true
|
65
|
+
t.column :replies_count, :integer, :default => 0
|
66
|
+
t.column :parent_id, :integer
|
67
|
+
t.column :type, :string, :limit => 50
|
68
|
+
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
# Store existing prefix/suffix
|
71
|
+
old_prefix = ActiveRecord::Base.table_name_prefix
|
72
|
+
old_suffix = ActiveRecord::Base.table_name_suffix
|
72
73
|
|
73
|
-
|
74
|
-
|
75
|
-
|
74
|
+
# Set a prefix/suffix we can test against
|
75
|
+
ActiveRecord::Base.table_name_prefix = 'prefix_'
|
76
|
+
ActiveRecord::Base.table_name_suffix = '_suffix'
|
76
77
|
|
77
|
-
|
78
|
+
topics = create_fixtures("topics")
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
80
|
+
# Restore prefix/suffix to its previous values
|
81
|
+
ActiveRecord::Base.table_name_prefix = old_prefix
|
82
|
+
ActiveRecord::Base.table_name_suffix = old_suffix
|
82
83
|
|
83
|
-
|
84
|
-
|
84
|
+
firstRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'David'")
|
85
|
+
assert_equal("The First Topic", firstRow["title"])
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
87
|
+
secondRow = ActiveRecord::Base.connection.select_one("SELECT * FROM prefix_topics_suffix WHERE author_name = 'Mary'")
|
88
|
+
assert_nil(secondRow["author_email_address"])
|
89
|
+
ensure
|
90
|
+
ActiveRecord::Base.connection.drop_table :prefix_topics_suffix rescue nil
|
91
|
+
end
|
90
92
|
end
|
91
93
|
|
92
94
|
def test_insert_with_datetime
|
@@ -173,27 +175,45 @@ end
|
|
173
175
|
if Account.connection.respond_to?(:reset_pk_sequence!)
|
174
176
|
class FixturesResetPkSequenceTest < Test::Unit::TestCase
|
175
177
|
fixtures :accounts
|
178
|
+
fixtures :companies
|
179
|
+
|
180
|
+
def setup
|
181
|
+
@instances = [Account.new(:credit_limit => 50), Company.new(:name => 'RoR Consulting')]
|
182
|
+
end
|
176
183
|
|
177
|
-
def
|
178
|
-
|
179
|
-
|
184
|
+
def test_resets_to_min_pk_with_specified_pk_and_sequence
|
185
|
+
@instances.each do |instance|
|
186
|
+
model = instance.class
|
187
|
+
model.delete_all
|
188
|
+
model.connection.reset_pk_sequence!(model.table_name, model.primary_key, model.sequence_name)
|
180
189
|
|
181
|
-
|
182
|
-
|
183
|
-
|
190
|
+
instance.save!
|
191
|
+
assert_equal 1, instance.id, "Sequence reset for #{model.table_name} failed."
|
192
|
+
end
|
184
193
|
end
|
185
194
|
|
186
|
-
def
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
195
|
+
def test_resets_to_min_pk_with_default_pk_and_sequence
|
196
|
+
@instances.each do |instance|
|
197
|
+
model = instance.class
|
198
|
+
model.delete_all
|
199
|
+
model.connection.reset_pk_sequence!(model.table_name)
|
200
|
+
|
201
|
+
instance.save!
|
202
|
+
assert_equal 1, instance.id, "Sequence reset for #{model.table_name} failed."
|
191
203
|
end
|
204
|
+
end
|
192
205
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
206
|
+
def test_create_fixtures_resets_sequences
|
207
|
+
@instances.each do |instance|
|
208
|
+
max_id = create_fixtures(instance.class.table_name).inject(0) do |max_id, (name, fixture)|
|
209
|
+
fixture_id = fixture['id'].to_i
|
210
|
+
fixture_id > max_id ? fixture_id : max_id
|
211
|
+
end
|
212
|
+
|
213
|
+
# Clone the last fixture to check that it gets the next greatest id.
|
214
|
+
instance.save!
|
215
|
+
assert_equal max_id + 1, instance.id, "Sequence reset for #{instance.class.table_name} failed."
|
216
|
+
end
|
197
217
|
end
|
198
218
|
end
|
199
219
|
end
|
data/test/inheritance_test.rb
CHANGED
@@ -11,7 +11,7 @@ class InheritanceTest < Test::Unit::TestCase
|
|
11
11
|
if current_adapter?(:SQLServerAdapter)
|
12
12
|
Company.connection.execute "SET IDENTITY_INSERT companies ON"
|
13
13
|
end
|
14
|
-
Company.connection.insert "INSERT INTO companies (id,
|
14
|
+
Company.connection.insert "INSERT INTO companies (id, #{QUOTED_TYPE}, name) VALUES(100, 'bad_class!', 'Not happening')"
|
15
15
|
|
16
16
|
#We then need to turn it back Off before continuing.
|
17
17
|
if current_adapter?(:SQLServerAdapter)
|
data/test/migration_test.rb
CHANGED
@@ -362,6 +362,9 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
362
362
|
ActiveRecord::Base.table_name_suffix = ""
|
363
363
|
Reminder.reset_table_name
|
364
364
|
assert_equal "schema_info", ActiveRecord::Migrator.schema_info_table_name
|
365
|
+
ensure
|
366
|
+
ActiveRecord::Base.table_name_prefix = ""
|
367
|
+
ActiveRecord::Base.table_name_suffix = ""
|
365
368
|
end
|
366
369
|
|
367
370
|
def test_proper_table_name
|
@@ -398,17 +401,20 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
398
401
|
ActiveRecord::Base.table_name_prefix = 'prefix_'
|
399
402
|
ActiveRecord::Base.table_name_suffix = '_suffix'
|
400
403
|
Reminder.reset_table_name
|
404
|
+
Reminder.reset_sequence_name
|
401
405
|
WeNeedReminders.up
|
402
406
|
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
403
407
|
assert_equal "hello world", Reminder.find(:first).content
|
404
408
|
|
405
409
|
WeNeedReminders.down
|
406
410
|
assert_raises(ActiveRecord::StatementInvalid) { Reminder.find(:first) }
|
411
|
+
ensure
|
407
412
|
ActiveRecord::Base.table_name_prefix = ''
|
408
413
|
ActiveRecord::Base.table_name_suffix = ''
|
409
414
|
Reminder.reset_table_name
|
415
|
+
Reminder.reset_sequence_name
|
410
416
|
end
|
411
|
-
|
417
|
+
|
412
418
|
def test_migrator_with_duplicates
|
413
419
|
assert_raises(ActiveRecord::DuplicateMigrationVersionError) do
|
414
420
|
ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_duplicate/', nil)
|
data/test/mixin_test.rb
CHANGED
@@ -6,96 +6,95 @@ require 'fixtures/mixin'
|
|
6
6
|
|
7
7
|
class ListTest < Test::Unit::TestCase
|
8
8
|
fixtures :mixins
|
9
|
-
|
9
|
+
|
10
10
|
def test_reordering
|
11
|
-
|
12
|
-
|
13
|
-
mixins(:
|
14
|
-
mixins(:
|
15
|
-
mixins(:list_4)],
|
11
|
+
assert_equal [mixins(:list_1),
|
12
|
+
mixins(:list_2),
|
13
|
+
mixins(:list_3),
|
14
|
+
mixins(:list_4)],
|
16
15
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
17
|
-
|
16
|
+
|
18
17
|
mixins(:list_2).move_lower
|
19
|
-
|
20
|
-
assert_equal [mixins(:list_1),
|
21
|
-
mixins(:list_3),
|
22
|
-
mixins(:list_2),
|
23
|
-
mixins(:list_4)],
|
18
|
+
|
19
|
+
assert_equal [mixins(:list_1),
|
20
|
+
mixins(:list_3),
|
21
|
+
mixins(:list_2),
|
22
|
+
mixins(:list_4)],
|
24
23
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
25
|
-
|
24
|
+
|
26
25
|
mixins(:list_2).move_higher
|
27
26
|
|
28
|
-
assert_equal [mixins(:list_1),
|
29
|
-
mixins(:list_2),
|
30
|
-
mixins(:list_3),
|
31
|
-
mixins(:list_4)],
|
27
|
+
assert_equal [mixins(:list_1),
|
28
|
+
mixins(:list_2),
|
29
|
+
mixins(:list_3),
|
30
|
+
mixins(:list_4)],
|
32
31
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
33
|
-
|
32
|
+
|
34
33
|
mixins(:list_1).move_to_bottom
|
35
34
|
|
36
|
-
assert_equal [mixins(:list_2),
|
37
|
-
mixins(:list_3),
|
38
|
-
mixins(:list_4),
|
39
|
-
mixins(:list_1)],
|
35
|
+
assert_equal [mixins(:list_2),
|
36
|
+
mixins(:list_3),
|
37
|
+
mixins(:list_4),
|
38
|
+
mixins(:list_1)],
|
40
39
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
41
40
|
|
42
41
|
mixins(:list_1).move_to_top
|
43
42
|
|
44
|
-
assert_equal [mixins(:list_1),
|
45
|
-
mixins(:list_2),
|
46
|
-
mixins(:list_3),
|
43
|
+
assert_equal [mixins(:list_1),
|
44
|
+
mixins(:list_2),
|
45
|
+
mixins(:list_3),
|
47
46
|
mixins(:list_4)],
|
48
47
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
49
|
-
|
50
|
-
|
48
|
+
|
49
|
+
|
51
50
|
mixins(:list_2).move_to_bottom
|
52
|
-
|
53
|
-
assert_equal [mixins(:list_1),
|
54
|
-
mixins(:list_3),
|
55
|
-
mixins(:list_4),
|
51
|
+
|
52
|
+
assert_equal [mixins(:list_1),
|
53
|
+
mixins(:list_3),
|
54
|
+
mixins(:list_4),
|
56
55
|
mixins(:list_2)],
|
57
56
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
58
57
|
|
59
58
|
mixins(:list_4).move_to_top
|
60
59
|
|
61
|
-
assert_equal [mixins(:list_4),
|
62
|
-
mixins(:list_1),
|
63
|
-
mixins(:list_3),
|
60
|
+
assert_equal [mixins(:list_4),
|
61
|
+
mixins(:list_1),
|
62
|
+
mixins(:list_3),
|
64
63
|
mixins(:list_2)],
|
65
64
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
66
|
-
|
65
|
+
|
67
66
|
end
|
68
67
|
|
69
68
|
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)],
|
69
|
+
assert_equal [mixins(:list_1),
|
70
|
+
mixins(:list_2),
|
71
|
+
mixins(:list_3),
|
72
|
+
mixins(:list_4)],
|
74
73
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
75
74
|
|
76
75
|
mixins(:list_3).move_to_bottom
|
77
76
|
|
78
|
-
assert_equal [mixins(:list_1),
|
79
|
-
mixins(:list_2),
|
80
|
-
mixins(:list_4),
|
81
|
-
mixins(:list_3)],
|
77
|
+
assert_equal [mixins(:list_1),
|
78
|
+
mixins(:list_2),
|
79
|
+
mixins(:list_4),
|
80
|
+
mixins(:list_3)],
|
82
81
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
83
82
|
end
|
84
|
-
|
83
|
+
|
85
84
|
def test_next_prev
|
86
85
|
assert_equal mixins(:list_2), mixins(:list_1).lower_item
|
87
86
|
assert_nil mixins(:list_1).higher_item
|
88
87
|
assert_equal mixins(:list_3), mixins(:list_4).higher_item
|
89
88
|
assert_nil mixins(:list_4).lower_item
|
90
89
|
end
|
91
|
-
|
92
|
-
|
90
|
+
|
91
|
+
|
93
92
|
def test_injection
|
94
93
|
item = ListMixin.new("parent_id"=>1)
|
95
94
|
assert_equal "parent_id = 1", item.scope_condition
|
96
95
|
assert_equal "pos", item.position_column
|
97
|
-
end
|
98
|
-
|
96
|
+
end
|
97
|
+
|
99
98
|
def test_insert
|
100
99
|
new = ListMixin.create("parent_id"=>20)
|
101
100
|
assert_equal 1, new.pos
|
@@ -106,37 +105,37 @@ class ListTest < Test::Unit::TestCase
|
|
106
105
|
assert_equal 2, new.pos
|
107
106
|
assert !new.first?
|
108
107
|
assert new.last?
|
109
|
-
|
108
|
+
|
110
109
|
new = ListMixin.create("parent_id"=>20)
|
111
|
-
assert_equal 3, new.pos
|
110
|
+
assert_equal 3, new.pos
|
112
111
|
assert !new.first?
|
113
112
|
assert new.last?
|
114
|
-
|
113
|
+
|
115
114
|
new = ListMixin.create("parent_id"=>0)
|
116
115
|
assert_equal 1, new.pos
|
117
116
|
assert new.first?
|
118
117
|
assert new.last?
|
119
|
-
end
|
118
|
+
end
|
120
119
|
|
121
120
|
def test_insert_at
|
122
121
|
new = ListMixin.create("parent_id" => 20)
|
123
122
|
assert_equal 1, new.pos
|
124
123
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
124
|
+
new = ListMixin.create("parent_id" => 20)
|
125
|
+
assert_equal 2, new.pos
|
126
|
+
|
127
|
+
new = ListMixin.create("parent_id" => 20)
|
128
|
+
assert_equal 3, new.pos
|
129
|
+
|
130
|
+
new4 = ListMixin.create("parent_id" => 20)
|
131
|
+
assert_equal 4, new4.pos
|
130
132
|
|
131
|
-
|
132
|
-
|
133
|
+
new4.insert_at(3)
|
134
|
+
assert_equal 3, new4.pos
|
133
135
|
|
134
|
-
|
135
|
-
|
136
|
+
new.reload
|
137
|
+
assert_equal 4, new.pos
|
136
138
|
|
137
|
-
new.reload
|
138
|
-
assert_equal 4, new.pos
|
139
|
-
|
140
139
|
new.insert_at(2)
|
141
140
|
assert_equal 2, new.pos
|
142
141
|
|
@@ -152,54 +151,54 @@ class ListTest < Test::Unit::TestCase
|
|
152
151
|
new4.reload
|
153
152
|
assert_equal 5, new4.pos
|
154
153
|
end
|
155
|
-
|
154
|
+
|
156
155
|
def test_delete_middle
|
157
|
-
|
158
|
-
|
159
|
-
mixins(:
|
160
|
-
mixins(:
|
161
|
-
mixins(:list_4)],
|
156
|
+
assert_equal [mixins(:list_1),
|
157
|
+
mixins(:list_2),
|
158
|
+
mixins(:list_3),
|
159
|
+
mixins(:list_4)],
|
162
160
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
163
|
-
|
161
|
+
|
164
162
|
mixins(:list_2).destroy
|
165
|
-
|
166
|
-
assert_equal [mixins(:list_1, :reload),
|
167
|
-
mixins(:list_3, :reload),
|
168
|
-
mixins(:list_4, :reload)],
|
163
|
+
|
164
|
+
assert_equal [mixins(:list_1, :reload),
|
165
|
+
mixins(:list_3, :reload),
|
166
|
+
mixins(:list_4, :reload)],
|
169
167
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
170
|
-
|
168
|
+
|
171
169
|
assert_equal 1, mixins(:list_1).pos
|
172
170
|
assert_equal 2, mixins(:list_3).pos
|
173
171
|
assert_equal 3, mixins(:list_4).pos
|
174
172
|
|
175
173
|
mixins(:list_1).destroy
|
176
174
|
|
177
|
-
assert_equal [mixins(:list_3, :reload),
|
178
|
-
mixins(:list_4, :reload)],
|
175
|
+
assert_equal [mixins(:list_3, :reload),
|
176
|
+
mixins(:list_4, :reload)],
|
179
177
|
ListMixin.find(:all, :conditions => 'parent_id = 5', :order => 'pos')
|
180
|
-
|
178
|
+
|
181
179
|
assert_equal 1, mixins(:list_3).pos
|
182
180
|
assert_equal 2, mixins(:list_4).pos
|
183
|
-
|
184
|
-
end
|
181
|
+
|
182
|
+
end
|
185
183
|
|
186
184
|
def test_with_string_based_scope
|
187
185
|
new = ListWithStringScopeMixin.create("parent_id"=>500)
|
188
186
|
assert_equal 1, new.pos
|
189
187
|
assert new.first?
|
190
188
|
assert new.last?
|
191
|
-
end
|
189
|
+
end
|
192
190
|
|
193
191
|
def test_nil_scope
|
194
192
|
new1, new2, new3 = ListMixin.create, ListMixin.create, ListMixin.create
|
195
193
|
new2.move_higher
|
196
194
|
assert_equal [new2, new1, new3], ListMixin.find(:all, :conditions => 'parent_id IS NULL', :order => 'pos')
|
197
195
|
end
|
196
|
+
|
198
197
|
end
|
199
198
|
|
200
199
|
class TreeTest < Test::Unit::TestCase
|
201
200
|
fixtures :mixins
|
202
|
-
|
201
|
+
|
203
202
|
def test_has_child
|
204
203
|
assert_equal true, mixins(:tree_1).has_children?
|
205
204
|
assert_equal true, mixins(:tree_2).has_children?
|
@@ -226,7 +225,7 @@ class TreeTest < Test::Unit::TestCase
|
|
226
225
|
assert_equal mixins(:tree_2).parent, mixins(:tree_4).parent
|
227
226
|
assert_nil mixins(:tree_1).parent
|
228
227
|
end
|
229
|
-
|
228
|
+
|
230
229
|
def test_delete
|
231
230
|
assert_equal 6, TreeMixin.count
|
232
231
|
mixins(:tree_1).destroy
|
@@ -238,9 +237,9 @@ class TreeTest < Test::Unit::TestCase
|
|
238
237
|
|
239
238
|
def test_insert
|
240
239
|
@extra = mixins(:tree_1).children.create
|
241
|
-
|
240
|
+
|
242
241
|
assert @extra
|
243
|
-
|
242
|
+
|
244
243
|
assert_equal @extra.parent, mixins(:tree_1)
|
245
244
|
|
246
245
|
assert_equal 3, mixins(:tree_1).children.size
|
@@ -257,7 +256,7 @@ class TreeTest < Test::Unit::TestCase
|
|
257
256
|
assert_equal [], mixins(:tree2_1).ancestors
|
258
257
|
assert_equal [], mixins(:tree3_1).ancestors
|
259
258
|
end
|
260
|
-
|
259
|
+
|
261
260
|
def test_root
|
262
261
|
assert_equal mixins(:tree_1), TreeMixin.root
|
263
262
|
assert_equal mixins(:tree_1), mixins(:tree_1).root
|
@@ -266,7 +265,7 @@ class TreeTest < Test::Unit::TestCase
|
|
266
265
|
assert_equal mixins(:tree_1), mixins(:tree_4).root
|
267
266
|
assert_equal mixins(:tree2_1), mixins(:tree2_1).root
|
268
267
|
assert_equal mixins(:tree3_1), mixins(:tree3_1).root
|
269
|
-
end
|
268
|
+
end
|
270
269
|
|
271
270
|
def test_roots
|
272
271
|
assert_equal [mixins(:tree_1), mixins(:tree2_1), mixins(:tree3_1)], TreeMixin.roots
|
@@ -291,40 +290,50 @@ class TreeTest < Test::Unit::TestCase
|
|
291
290
|
end
|
292
291
|
end
|
293
292
|
|
293
|
+
class TreeTestWithoutOrder < Test::Unit::TestCase
|
294
|
+
fixtures :mixins
|
295
|
+
|
296
|
+
def test_root
|
297
|
+
assert [mixins(:tree_without_order_1), mixins(:tree_without_order_2)].include?(TreeMixinWithoutOrder.root)
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_roots
|
301
|
+
assert_equal [], [mixins(:tree_without_order_1), mixins(:tree_without_order_2)] - TreeMixinWithoutOrder.roots
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
294
305
|
class TouchTest < Test::Unit::TestCase
|
295
306
|
fixtures :mixins
|
296
|
-
|
307
|
+
|
297
308
|
def test_update
|
298
|
-
|
299
|
-
|
300
|
-
|
309
|
+
stamped = Mixin.new
|
310
|
+
|
301
311
|
assert_nil stamped.updated_at
|
302
312
|
assert_nil stamped.created_at
|
303
313
|
stamped.save
|
304
314
|
assert_not_nil stamped.updated_at
|
305
315
|
assert_not_nil stamped.created_at
|
306
|
-
end
|
316
|
+
end
|
307
317
|
|
308
318
|
def test_create
|
309
319
|
@obj = Mixin.create
|
310
320
|
assert_not_nil @obj.updated_at
|
311
321
|
assert_not_nil @obj.created_at
|
312
|
-
end
|
322
|
+
end
|
313
323
|
|
314
324
|
def test_many_updates
|
315
|
-
|
316
|
-
stamped = Mixin.new
|
325
|
+
stamped = Mixin.new
|
317
326
|
|
318
327
|
assert_nil stamped.updated_at
|
319
328
|
assert_nil stamped.created_at
|
320
329
|
stamped.save
|
321
330
|
assert_not_nil stamped.created_at
|
322
331
|
assert_not_nil stamped.updated_at
|
323
|
-
|
332
|
+
|
324
333
|
old_updated_at = stamped.updated_at
|
325
334
|
|
326
335
|
sleep 1
|
327
|
-
stamped.save
|
336
|
+
stamped.save
|
328
337
|
assert_not_equal stamped.created_at, stamped.updated_at
|
329
338
|
assert_not_equal old_updated_at, stamped.updated_at
|
330
339
|
|
@@ -341,3 +350,163 @@ class TouchTest < Test::Unit::TestCase
|
|
341
350
|
end
|
342
351
|
|
343
352
|
end
|
353
|
+
|
354
|
+
|
355
|
+
class ListSubTest < Test::Unit::TestCase
|
356
|
+
fixtures :mixins
|
357
|
+
|
358
|
+
def test_reordering
|
359
|
+
assert_equal [mixins(:list_sub_1),
|
360
|
+
mixins(:list_sub_2),
|
361
|
+
mixins(:list_sub_3),
|
362
|
+
mixins(:list_sub_4)],
|
363
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
364
|
+
|
365
|
+
mixins(:list_sub_2).move_lower
|
366
|
+
|
367
|
+
assert_equal [mixins(:list_sub_1),
|
368
|
+
mixins(:list_sub_3),
|
369
|
+
mixins(:list_sub_2),
|
370
|
+
mixins(:list_sub_4)],
|
371
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
372
|
+
|
373
|
+
mixins(:list_sub_2).move_higher
|
374
|
+
|
375
|
+
assert_equal [mixins(:list_sub_1),
|
376
|
+
mixins(:list_sub_2),
|
377
|
+
mixins(:list_sub_3),
|
378
|
+
mixins(:list_sub_4)],
|
379
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
380
|
+
|
381
|
+
mixins(:list_sub_1).move_to_bottom
|
382
|
+
|
383
|
+
assert_equal [mixins(:list_sub_2),
|
384
|
+
mixins(:list_sub_3),
|
385
|
+
mixins(:list_sub_4),
|
386
|
+
mixins(:list_sub_1)],
|
387
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
388
|
+
|
389
|
+
mixins(:list_sub_1).move_to_top
|
390
|
+
|
391
|
+
assert_equal [mixins(:list_sub_1),
|
392
|
+
mixins(:list_sub_2),
|
393
|
+
mixins(:list_sub_3),
|
394
|
+
mixins(:list_sub_4)],
|
395
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
396
|
+
|
397
|
+
|
398
|
+
mixins(:list_sub_2).move_to_bottom
|
399
|
+
|
400
|
+
assert_equal [mixins(:list_sub_1),
|
401
|
+
mixins(:list_sub_3),
|
402
|
+
mixins(:list_sub_4),
|
403
|
+
mixins(:list_sub_2)],
|
404
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
405
|
+
|
406
|
+
mixins(:list_sub_4).move_to_top
|
407
|
+
|
408
|
+
assert_equal [mixins(:list_sub_4),
|
409
|
+
mixins(:list_sub_1),
|
410
|
+
mixins(:list_sub_3),
|
411
|
+
mixins(:list_sub_2)],
|
412
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
413
|
+
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_move_to_bottom_with_next_to_last_item
|
417
|
+
assert_equal [mixins(:list_sub_1),
|
418
|
+
mixins(:list_sub_2),
|
419
|
+
mixins(:list_sub_3),
|
420
|
+
mixins(:list_sub_4)],
|
421
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
422
|
+
|
423
|
+
mixins(:list_sub_3).move_to_bottom
|
424
|
+
|
425
|
+
assert_equal [mixins(:list_sub_1),
|
426
|
+
mixins(:list_sub_2),
|
427
|
+
mixins(:list_sub_4),
|
428
|
+
mixins(:list_sub_3)],
|
429
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_next_prev
|
433
|
+
assert_equal mixins(:list_sub_2), mixins(:list_sub_1).lower_item
|
434
|
+
assert_nil mixins(:list_sub_1).higher_item
|
435
|
+
assert_equal mixins(:list_sub_3), mixins(:list_sub_4).higher_item
|
436
|
+
assert_nil mixins(:list_sub_4).lower_item
|
437
|
+
end
|
438
|
+
|
439
|
+
|
440
|
+
def test_injection
|
441
|
+
item = ListMixin.new("parent_id"=>1)
|
442
|
+
assert_equal "parent_id = 1", item.scope_condition
|
443
|
+
assert_equal "pos", item.position_column
|
444
|
+
end
|
445
|
+
|
446
|
+
|
447
|
+
def test_insert_at
|
448
|
+
new = ListMixin.create("parent_id" => 20)
|
449
|
+
assert_equal 1, new.pos
|
450
|
+
|
451
|
+
new = ListMixinSub1.create("parent_id" => 20)
|
452
|
+
assert_equal 2, new.pos
|
453
|
+
|
454
|
+
new = ListMixinSub2.create("parent_id" => 20)
|
455
|
+
assert_equal 3, new.pos
|
456
|
+
|
457
|
+
new4 = ListMixin.create("parent_id" => 20)
|
458
|
+
assert_equal 4, new4.pos
|
459
|
+
|
460
|
+
new4.insert_at(3)
|
461
|
+
assert_equal 3, new4.pos
|
462
|
+
|
463
|
+
new.reload
|
464
|
+
assert_equal 4, new.pos
|
465
|
+
|
466
|
+
new.insert_at(2)
|
467
|
+
assert_equal 2, new.pos
|
468
|
+
|
469
|
+
new4.reload
|
470
|
+
assert_equal 4, new4.pos
|
471
|
+
|
472
|
+
new5 = ListMixinSub1.create("parent_id" => 20)
|
473
|
+
assert_equal 5, new5.pos
|
474
|
+
|
475
|
+
new5.insert_at(1)
|
476
|
+
assert_equal 1, new5.pos
|
477
|
+
|
478
|
+
new4.reload
|
479
|
+
assert_equal 5, new4.pos
|
480
|
+
end
|
481
|
+
|
482
|
+
def test_delete_middle
|
483
|
+
assert_equal [mixins(:list_sub_1),
|
484
|
+
mixins(:list_sub_2),
|
485
|
+
mixins(:list_sub_3),
|
486
|
+
mixins(:list_sub_4)],
|
487
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
488
|
+
|
489
|
+
mixins(:list_sub_2).destroy
|
490
|
+
|
491
|
+
assert_equal [mixins(:list_sub_1, :reload),
|
492
|
+
mixins(:list_sub_3, :reload),
|
493
|
+
mixins(:list_sub_4, :reload)],
|
494
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
495
|
+
|
496
|
+
assert_equal 1, mixins(:list_sub_1).pos
|
497
|
+
assert_equal 2, mixins(:list_sub_3).pos
|
498
|
+
assert_equal 3, mixins(:list_sub_4).pos
|
499
|
+
|
500
|
+
mixins(:list_sub_1).destroy
|
501
|
+
|
502
|
+
assert_equal [mixins(:list_sub_3, :reload),
|
503
|
+
mixins(:list_sub_4, :reload)],
|
504
|
+
ListMixin.find(:all, :conditions => 'parent_id = 5000', :order => 'pos')
|
505
|
+
|
506
|
+
assert_equal 1, mixins(:list_sub_3).pos
|
507
|
+
assert_equal 2, mixins(:list_sub_4).pos
|
508
|
+
|
509
|
+
end
|
510
|
+
|
511
|
+
end
|
512
|
+
|