activerecord 1.15.6 → 2.0.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 +2454 -34
- data/README +1 -1
- data/RUNNING_UNIT_TESTS +3 -34
- data/Rakefile +98 -77
- data/install.rb +1 -1
- data/lib/active_record.rb +13 -22
- data/lib/active_record/aggregations.rb +38 -49
- data/lib/active_record/associations.rb +452 -333
- data/lib/active_record/associations/association_collection.rb +66 -20
- data/lib/active_record/associations/association_proxy.rb +9 -8
- data/lib/active_record/associations/has_and_belongs_to_many_association.rb +46 -51
- data/lib/active_record/associations/has_many_association.rb +21 -57
- data/lib/active_record/associations/has_many_through_association.rb +38 -18
- data/lib/active_record/associations/has_one_association.rb +30 -14
- data/lib/active_record/attribute_methods.rb +253 -0
- data/lib/active_record/base.rb +719 -494
- data/lib/active_record/calculations.rb +62 -63
- data/lib/active_record/callbacks.rb +57 -83
- data/lib/active_record/connection_adapters/abstract/connection_specification.rb +38 -9
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +56 -15
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +87 -0
- data/lib/active_record/connection_adapters/abstract/quoting.rb +23 -12
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +191 -62
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +37 -34
- data/lib/active_record/connection_adapters/abstract_adapter.rb +28 -17
- data/lib/active_record/connection_adapters/mysql_adapter.rb +119 -37
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +473 -210
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
- data/lib/active_record/connection_adapters/sqlite_adapter.rb +91 -107
- data/lib/active_record/fixtures.rb +503 -113
- data/lib/active_record/locking/optimistic.rb +72 -34
- data/lib/active_record/migration.rb +80 -57
- data/lib/active_record/observer.rb +13 -10
- data/lib/active_record/query_cache.rb +16 -57
- data/lib/active_record/reflection.rb +35 -38
- data/lib/active_record/schema.rb +5 -5
- data/lib/active_record/schema_dumper.rb +35 -13
- data/lib/active_record/serialization.rb +98 -0
- data/lib/active_record/serializers/json_serializer.rb +71 -0
- data/lib/active_record/{xml_serialization.rb → serializers/xml_serializer.rb} +90 -83
- data/lib/active_record/timestamp.rb +20 -21
- data/lib/active_record/transactions.rb +39 -43
- data/lib/active_record/validations.rb +256 -107
- data/lib/active_record/version.rb +3 -3
- data/lib/activerecord.rb +1 -0
- data/test/aaa_create_tables_test.rb +15 -2
- data/test/abstract_unit.rb +24 -17
- data/test/active_schema_test_mysql.rb +20 -8
- data/test/adapter_test.rb +23 -5
- data/test/adapter_test_sqlserver.rb +15 -1
- data/test/aggregations_test.rb +16 -1
- data/test/all.sh +2 -2
- data/test/associations/ar_joins_test.rb +0 -0
- data/test/associations/callbacks_test.rb +51 -30
- data/test/associations/cascaded_eager_loading_test.rb +1 -29
- data/test/associations/eager_singularization_test.rb +145 -0
- data/test/associations/eager_test.rb +42 -6
- data/test/associations/extension_test.rb +6 -1
- data/test/associations/inner_join_association_test.rb +88 -0
- data/test/associations/join_model_test.rb +47 -16
- data/test/associations_test.rb +449 -226
- data/test/attribute_methods_test.rb +97 -0
- data/test/base_test.rb +251 -105
- data/test/binary_test.rb +22 -27
- data/test/calculations_test.rb +37 -5
- data/test/callbacks_test.rb +23 -0
- data/test/connection_test_firebird.rb +2 -2
- data/test/connection_test_mysql.rb +30 -0
- data/test/connections/native_mysql/connection.rb +3 -0
- data/test/connections/native_sqlite/connection.rb +5 -14
- data/test/connections/native_sqlite3/connection.rb +5 -14
- data/test/connections/native_sqlite3/in_memory_connection.rb +1 -1
- data/test/{copy_table_sqlite.rb → copy_table_test_sqlite.rb} +8 -3
- data/test/datatype_test_postgresql.rb +178 -27
- data/test/{empty_date_time_test.rb → date_time_test.rb} +13 -1
- data/test/defaults_test.rb +8 -1
- data/test/deprecated_finder_test.rb +7 -128
- data/test/finder_test.rb +192 -54
- data/test/fixtures/all/developers.yml +0 -0
- data/test/fixtures/all/people.csv +0 -0
- data/test/fixtures/all/tasks.yml +0 -0
- data/test/fixtures/author.rb +12 -5
- data/test/fixtures/binaries.yml +130 -435
- data/test/fixtures/category.rb +6 -0
- data/test/fixtures/company.rb +8 -1
- data/test/fixtures/computer.rb +1 -0
- data/test/fixtures/contact.rb +16 -0
- data/test/fixtures/customer.rb +2 -2
- data/test/fixtures/db_definitions/db2.drop.sql +1 -0
- data/test/fixtures/db_definitions/db2.sql +4 -0
- data/test/fixtures/db_definitions/firebird.drop.sql +3 -1
- data/test/fixtures/db_definitions/firebird.sql +6 -0
- data/test/fixtures/db_definitions/frontbase.drop.sql +1 -0
- data/test/fixtures/db_definitions/frontbase.sql +5 -0
- data/test/fixtures/db_definitions/openbase.sql +41 -25
- data/test/fixtures/db_definitions/oracle.drop.sql +2 -0
- data/test/fixtures/db_definitions/oracle.sql +5 -0
- data/test/fixtures/db_definitions/postgresql.drop.sql +7 -0
- data/test/fixtures/db_definitions/postgresql.sql +87 -58
- data/test/fixtures/db_definitions/postgresql2.sql +1 -2
- data/test/fixtures/db_definitions/schema.rb +280 -0
- data/test/fixtures/db_definitions/schema2.rb +11 -0
- data/test/fixtures/db_definitions/sqlite.drop.sql +1 -0
- data/test/fixtures/db_definitions/sqlite.sql +4 -0
- data/test/fixtures/db_definitions/sybase.drop.sql +1 -0
- data/test/fixtures/db_definitions/sybase.sql +4 -0
- data/test/fixtures/developer.rb +10 -0
- data/test/fixtures/example.log +1 -0
- data/test/fixtures/flowers.jpg +0 -0
- data/test/fixtures/item.rb +7 -0
- data/test/fixtures/items.yml +4 -0
- data/test/fixtures/joke.rb +0 -3
- data/test/fixtures/matey.rb +4 -0
- data/test/fixtures/mateys.yml +4 -0
- data/test/fixtures/minimalistic.rb +2 -0
- data/test/fixtures/minimalistics.yml +2 -0
- data/test/fixtures/mixins.yml +2 -100
- data/test/fixtures/parrot.rb +13 -0
- data/test/fixtures/parrots.yml +27 -0
- data/test/fixtures/parrots_pirates.yml +7 -0
- data/test/fixtures/pirate.rb +5 -0
- data/test/fixtures/pirates.yml +9 -0
- data/test/fixtures/post.rb +1 -0
- data/test/fixtures/project.rb +3 -2
- data/test/fixtures/reserved_words/distinct.yml +5 -0
- data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
- data/test/fixtures/reserved_words/group.yml +14 -0
- data/test/fixtures/reserved_words/select.yml +8 -0
- data/test/fixtures/reserved_words/values.yml +7 -0
- data/test/fixtures/ship.rb +3 -0
- data/test/fixtures/ships.yml +5 -0
- data/test/fixtures/tagging.rb +4 -0
- data/test/fixtures/taggings.yml +8 -1
- data/test/fixtures/topic.rb +13 -1
- data/test/fixtures/treasure.rb +4 -0
- data/test/fixtures/treasures.yml +10 -0
- data/test/fixtures_test.rb +205 -24
- data/test/inheritance_test.rb +7 -1
- data/test/json_serialization_test.rb +180 -0
- data/test/lifecycle_test.rb +1 -1
- data/test/locking_test.rb +85 -2
- data/test/migration_test.rb +206 -40
- data/test/mixin_test.rb +13 -515
- data/test/pk_test.rb +3 -6
- data/test/query_cache_test.rb +104 -0
- data/test/reflection_test.rb +16 -0
- data/test/reserved_word_test_mysql.rb +177 -0
- data/test/schema_dumper_test.rb +38 -3
- data/test/serialization_test.rb +47 -0
- data/test/transactions_test.rb +74 -23
- data/test/unconnected_test.rb +1 -1
- data/test/validations_test.rb +322 -32
- data/test/xml_serialization_test.rb +121 -44
- metadata +48 -41
- data/examples/associations.rb +0 -87
- data/examples/shared_setup.rb +0 -15
- data/examples/validation.rb +0 -85
- data/lib/active_record/acts/list.rb +0 -256
- data/lib/active_record/acts/nested_set.rb +0 -211
- data/lib/active_record/acts/tree.rb +0 -96
- data/lib/active_record/connection_adapters/db2_adapter.rb +0 -228
- data/lib/active_record/connection_adapters/firebird_adapter.rb +0 -728
- data/lib/active_record/connection_adapters/frontbase_adapter.rb +0 -861
- data/lib/active_record/connection_adapters/openbase_adapter.rb +0 -350
- data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -690
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +0 -591
- data/lib/active_record/connection_adapters/sybase_adapter.rb +0 -662
- data/lib/active_record/deprecated_associations.rb +0 -104
- data/lib/active_record/deprecated_finders.rb +0 -44
- data/lib/active_record/vendor/simple.rb +0 -693
- data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
- data/lib/active_record/wrappings.rb +0 -58
- data/test/connections/native_sqlserver/connection.rb +0 -23
- data/test/connections/native_sqlserver_odbc/connection.rb +0 -25
- data/test/deprecated_associations_test.rb +0 -396
- data/test/fixtures/db_definitions/mysql.drop.sql +0 -32
- data/test/fixtures/db_definitions/mysql.sql +0 -234
- data/test/fixtures/db_definitions/mysql2.drop.sql +0 -2
- data/test/fixtures/db_definitions/mysql2.sql +0 -5
- data/test/fixtures/db_definitions/sqlserver.drop.sql +0 -34
- data/test/fixtures/db_definitions/sqlserver.sql +0 -243
- data/test/fixtures/db_definitions/sqlserver2.drop.sql +0 -2
- data/test/fixtures/db_definitions/sqlserver2.sql +0 -5
- data/test/fixtures/mixin.rb +0 -63
- data/test/mixin_nested_set_test.rb +0 -196
data/test/inheritance_test.rb
CHANGED
@@ -6,6 +6,13 @@ require 'fixtures/subscriber'
|
|
6
6
|
class InheritanceTest < Test::Unit::TestCase
|
7
7
|
fixtures :companies, :projects, :subscribers, :accounts
|
8
8
|
|
9
|
+
def test_company_descends_from_active_record
|
10
|
+
assert_raise(NoMethodError) { ActiveRecord::Base.descends_from_active_record? }
|
11
|
+
assert AbstractCompany.descends_from_active_record?, 'AbstractCompany should descend from ActiveRecord::Base'
|
12
|
+
assert Company.descends_from_active_record?, 'Company should descend from ActiveRecord::Base'
|
13
|
+
assert !Class.new(Company).descends_from_active_record?, 'Company subclass should not descend from ActiveRecord::Base'
|
14
|
+
end
|
15
|
+
|
9
16
|
def test_a_bad_type_column
|
10
17
|
#SQLServer need to turn Identity Insert On before manually inserting into the Identity column
|
11
18
|
if current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
@@ -144,7 +151,6 @@ class InheritanceTest < Test::Unit::TestCase
|
|
144
151
|
switch_to_alt_inheritance_column
|
145
152
|
test_eager_load_belongs_to_something_inherited
|
146
153
|
switch_to_default_inheritance_column
|
147
|
-
ActiveRecord::Base.logger.debug "cocksucker"
|
148
154
|
end
|
149
155
|
|
150
156
|
def test_inheritance_without_mapping
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'abstract_unit'
|
2
|
+
require 'fixtures/contact'
|
3
|
+
require 'fixtures/post'
|
4
|
+
require 'fixtures/author'
|
5
|
+
require 'fixtures/tagging'
|
6
|
+
require 'fixtures/tag'
|
7
|
+
require 'fixtures/comment'
|
8
|
+
|
9
|
+
class JsonSerializationTest < Test::Unit::TestCase
|
10
|
+
def setup
|
11
|
+
@contact = Contact.new(
|
12
|
+
:name => 'Konata Izumi',
|
13
|
+
:age => 16,
|
14
|
+
:avatar => 'binarydata',
|
15
|
+
:created_at => Time.utc(2006, 8, 1),
|
16
|
+
:awesome => true,
|
17
|
+
:preferences => { :shows => 'anime' }
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_should_encode_all_encodable_attributes
|
22
|
+
json = @contact.to_json
|
23
|
+
|
24
|
+
assert_match %r{"name": "Konata Izumi"}, json
|
25
|
+
assert_match %r{"age": 16}, json
|
26
|
+
assert json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
|
27
|
+
assert_match %r{"awesome": true}, json
|
28
|
+
assert_match %r{"preferences": \{"shows": "anime"\}}, json
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_should_allow_attribute_filtering_with_only
|
32
|
+
json = @contact.to_json(:only => [:name, :age])
|
33
|
+
|
34
|
+
assert_match %r{"name": "Konata Izumi"}, json
|
35
|
+
assert_match %r{"age": 16}, json
|
36
|
+
assert_no_match %r{"awesome": true}, json
|
37
|
+
assert !json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
|
38
|
+
assert_no_match %r{"preferences": \{"shows": "anime"\}}, json
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_should_allow_attribute_filtering_with_except
|
42
|
+
json = @contact.to_json(:except => [:name, :age])
|
43
|
+
|
44
|
+
assert_no_match %r{"name": "Konata Izumi"}, json
|
45
|
+
assert_no_match %r{"age": 16}, json
|
46
|
+
assert_match %r{"awesome": true}, json
|
47
|
+
assert json.include?(%("created_at": #{ActiveSupport::JSON.encode(Time.utc(2006, 8, 1))}))
|
48
|
+
assert_match %r{"preferences": \{"shows": "anime"\}}, json
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_methods_are_called_on_object
|
52
|
+
# Define methods on fixture.
|
53
|
+
def @contact.label; "Has cheezburger"; end
|
54
|
+
def @contact.favorite_quote; "Constraints are liberating"; end
|
55
|
+
|
56
|
+
# Single method.
|
57
|
+
assert_match %r{"label": "Has cheezburger"}, @contact.to_json(:only => :name, :methods => :label)
|
58
|
+
|
59
|
+
# Both methods.
|
60
|
+
methods_json = @contact.to_json(:only => :name, :methods => [:label, :favorite_quote])
|
61
|
+
assert_match %r{"label": "Has cheezburger"}, methods_json
|
62
|
+
assert_match %r{"favorite_quote": "Constraints are liberating"}, methods_json
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class DatabaseConnectedJsonEncodingTest < Test::Unit::TestCase
|
67
|
+
fixtures :authors, :posts, :comments, :tags, :taggings
|
68
|
+
|
69
|
+
def setup
|
70
|
+
@david = authors(:david)
|
71
|
+
@mary = authors(:mary)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_includes_uses_association_name
|
75
|
+
json = @david.to_json(:include => :posts)
|
76
|
+
|
77
|
+
assert_match %r{"posts": \[}, json
|
78
|
+
|
79
|
+
assert_match %r{"id": 1}, json
|
80
|
+
assert_match %r{"name": "David"}, json
|
81
|
+
|
82
|
+
assert_match %r{"author_id": 1}, json
|
83
|
+
assert_match %r{"title": "Welcome to the weblog"}, json
|
84
|
+
assert_match %r{"body": "Such a lovely day"}, json
|
85
|
+
|
86
|
+
assert_match %r{"title": "So I was thinking"}, json
|
87
|
+
assert_match %r{"body": "Like I hopefully always am"}, json
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_includes_uses_association_name_and_applies_attribute_filters
|
91
|
+
json = @david.to_json(:include => { :posts => { :only => :title } })
|
92
|
+
|
93
|
+
assert_match %r{"name": "David"}, json
|
94
|
+
assert_match %r{"posts": \[}, json
|
95
|
+
|
96
|
+
assert_match %r{"title": "Welcome to the weblog"}, json
|
97
|
+
assert_no_match %r{"body": "Such a lovely day"}, json
|
98
|
+
|
99
|
+
assert_match %r{"title": "So I was thinking"}, json
|
100
|
+
assert_no_match %r{"body": "Like I hopefully always am"}, json
|
101
|
+
end
|
102
|
+
|
103
|
+
def test_includes_fetches_second_level_associations
|
104
|
+
json = @david.to_json(:include => { :posts => { :include => { :comments => { :only => :body } } } })
|
105
|
+
|
106
|
+
assert_match %r{"name": "David"}, json
|
107
|
+
assert_match %r{"posts": \[}, json
|
108
|
+
|
109
|
+
assert_match %r{"comments": \[}, json
|
110
|
+
assert_match %r{\{"body": "Thank you again for the welcome"\}}, json
|
111
|
+
assert_match %r{\{"body": "Don't think too hard"\}}, json
|
112
|
+
assert_no_match %r{"post_id": }, json
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_includes_fetches_nth_level_associations
|
116
|
+
json = @david.to_json(
|
117
|
+
:include => {
|
118
|
+
:posts => {
|
119
|
+
:include => {
|
120
|
+
:taggings => {
|
121
|
+
:include => {
|
122
|
+
:tag => { :only => :name }
|
123
|
+
}
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
})
|
128
|
+
|
129
|
+
assert_match %r{"name": "David"}, json
|
130
|
+
assert_match %r{"posts": \[}, json
|
131
|
+
|
132
|
+
assert_match %r{"taggings": \[}, json
|
133
|
+
assert_match %r{"tag": \{"name": "General"\}}, json
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_should_not_call_methods_on_associations_that_dont_respond
|
137
|
+
def @david.favorite_quote; "Constraints are liberating"; end
|
138
|
+
json = @david.to_json(:include => :posts, :methods => :favorite_quote)
|
139
|
+
|
140
|
+
assert !@david.posts.first.respond_to?(:favorite_quote)
|
141
|
+
assert_match %r{"favorite_quote": "Constraints are liberating"}, json
|
142
|
+
assert_equal %r{"favorite_quote": }.match(json).size, 1
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_should_allow_only_option_for_list_of_authors
|
146
|
+
authors = [@david, @mary]
|
147
|
+
|
148
|
+
assert_equal %([{"name": "David"}, {"name": "Mary"}]), authors.to_json(:only => :name)
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_should_allow_except_option_for_list_of_authors
|
152
|
+
authors = [@david, @mary]
|
153
|
+
|
154
|
+
assert_equal %([{"id": 1}, {"id": 2}]), authors.to_json(:except => [:name, :author_address_id])
|
155
|
+
end
|
156
|
+
|
157
|
+
def test_should_allow_includes_for_list_of_authors
|
158
|
+
authors = [@david, @mary]
|
159
|
+
json = authors.to_json(
|
160
|
+
:only => :name,
|
161
|
+
:include => {
|
162
|
+
:posts => { :only => :id }
|
163
|
+
}
|
164
|
+
)
|
165
|
+
|
166
|
+
['"name": "David"', '"posts": [', '{"id": 1}', '{"id": 2}', '{"id": 4}',
|
167
|
+
'{"id": 5}', '{"id": 6}', '"name": "Mary"', '"posts": [{"id": 7}]'].each do |fragment|
|
168
|
+
assert json.include?(fragment), json
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_should_allow_options_for_hash_of_authors
|
173
|
+
authors_hash = {
|
174
|
+
1 => @david,
|
175
|
+
2 => @mary
|
176
|
+
}
|
177
|
+
|
178
|
+
assert_equal %({1: {"name": "David"}}), authors_hash.to_json(:only => [1, :name])
|
179
|
+
end
|
180
|
+
end
|
data/test/lifecycle_test.rb
CHANGED
data/test/locking_test.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'abstract_unit'
|
2
2
|
require 'fixtures/person'
|
3
|
+
require 'fixtures/reader'
|
3
4
|
require 'fixtures/legacy_thing'
|
4
5
|
|
5
6
|
class LockWithoutDefault < ActiveRecord::Base; end
|
@@ -9,9 +10,18 @@ class LockWithCustomColumnWithoutDefault < ActiveRecord::Base
|
|
9
10
|
set_locking_column :custom_lock_version
|
10
11
|
end
|
11
12
|
|
13
|
+
class ReadonlyFirstNamePerson < Person
|
14
|
+
attr_readonly :first_name
|
15
|
+
end
|
16
|
+
|
12
17
|
class OptimisticLockingTest < Test::Unit::TestCase
|
13
18
|
fixtures :people, :legacy_things
|
14
19
|
|
20
|
+
# need to disable transactional fixtures, because otherwise the sqlite3
|
21
|
+
# adapter (at least) chokes when we try and change the schema in the middle
|
22
|
+
# of a test (see test_increment_counter_*).
|
23
|
+
self.use_transactional_fixtures = false
|
24
|
+
|
15
25
|
def test_lock_existing
|
16
26
|
p1 = Person.find(1)
|
17
27
|
p2 = Person.find(1)
|
@@ -24,6 +34,20 @@ class OptimisticLockingTest < Test::Unit::TestCase
|
|
24
34
|
|
25
35
|
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
|
26
36
|
end
|
37
|
+
|
38
|
+
def test_lock_repeating
|
39
|
+
p1 = Person.find(1)
|
40
|
+
p2 = Person.find(1)
|
41
|
+
assert_equal 0, p1.lock_version
|
42
|
+
assert_equal 0, p2.lock_version
|
43
|
+
|
44
|
+
p1.save!
|
45
|
+
assert_equal 1, p1.lock_version
|
46
|
+
assert_equal 0, p2.lock_version
|
47
|
+
|
48
|
+
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
|
49
|
+
assert_raises(ActiveRecord::StaleObjectError) { p2.save! }
|
50
|
+
end
|
27
51
|
|
28
52
|
def test_lock_new
|
29
53
|
p1 = Person.new(:first_name => 'anika')
|
@@ -73,6 +97,65 @@ class OptimisticLockingTest < Test::Unit::TestCase
|
|
73
97
|
t1 = LockWithCustomColumnWithoutDefault.new
|
74
98
|
assert_equal 0, t1.custom_lock_version
|
75
99
|
end
|
100
|
+
|
101
|
+
def test_readonly_attributes
|
102
|
+
assert_equal Set.new([ 'first_name' ]), ReadonlyFirstNamePerson.readonly_attributes
|
103
|
+
|
104
|
+
p = ReadonlyFirstNamePerson.create(:first_name => "unchangeable name")
|
105
|
+
p.reload
|
106
|
+
assert_equal "unchangeable name", p.first_name
|
107
|
+
|
108
|
+
p.update_attributes(:first_name => "changed name")
|
109
|
+
p.reload
|
110
|
+
assert_equal "unchangeable name", p.first_name
|
111
|
+
end
|
112
|
+
|
113
|
+
{ :lock_version => Person, :custom_lock_version => LegacyThing }.each do |name, model|
|
114
|
+
define_method("test_increment_counter_updates_#{name}") do
|
115
|
+
counter_test model, 1 do |id|
|
116
|
+
model.increment_counter :test_count, id
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
define_method("test_decrement_counter_updates_#{name}") do
|
121
|
+
counter_test model, -1 do |id|
|
122
|
+
model.decrement_counter :test_count, id
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
define_method("test_update_counters_updates_#{name}") do
|
127
|
+
counter_test model, 1 do |id|
|
128
|
+
model.update_counters id, :test_count => 1
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def add_counter_column_to(model)
|
136
|
+
model.connection.add_column model.table_name, :test_count, :integer, :null => false, :default => 0
|
137
|
+
model.reset_column_information
|
138
|
+
# OpenBase does not set a value to existing rows when adding a not null default column
|
139
|
+
model.update_all(:test_count => 0) if current_adapter?(:OpenBaseAdapter)
|
140
|
+
end
|
141
|
+
|
142
|
+
def remove_counter_column_from(model)
|
143
|
+
model.connection.remove_column model.table_name, :test_count
|
144
|
+
model.reset_column_information
|
145
|
+
end
|
146
|
+
|
147
|
+
def counter_test(model, expected_count)
|
148
|
+
add_counter_column_to(model)
|
149
|
+
object = model.find(:first)
|
150
|
+
assert_equal 0, object.test_count
|
151
|
+
assert_equal 0, object.send(model.locking_column)
|
152
|
+
yield object.id
|
153
|
+
object.reload
|
154
|
+
assert_equal expected_count, object.test_count
|
155
|
+
assert_equal 1, object.send(model.locking_column)
|
156
|
+
ensure
|
157
|
+
remove_counter_column_from(model)
|
158
|
+
end
|
76
159
|
end
|
77
160
|
|
78
161
|
|
@@ -81,9 +164,9 @@ end
|
|
81
164
|
# blocks, so separate script called by Kernel#system is needed.
|
82
165
|
# (See exec vs. async_exec in the PostgreSQL adapter.)
|
83
166
|
|
84
|
-
# TODO: The SQL Server and
|
167
|
+
# TODO: The SQL Server, Sybase, and OpenBase adapters currently have no support for pessimistic locking
|
85
168
|
|
86
|
-
unless current_adapter?(:SQLServerAdapter, :SybaseAdapter)
|
169
|
+
unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :OpenBaseAdapter)
|
87
170
|
class PessimisticLockingTest < Test::Unit::TestCase
|
88
171
|
self.use_transactional_fixtures = false
|
89
172
|
fixtures :people, :readers
|
data/test/migration_test.rb
CHANGED
@@ -24,6 +24,8 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
24
24
|
|
25
25
|
class MigrationTest < Test::Unit::TestCase
|
26
26
|
self.use_transactional_fixtures = false
|
27
|
+
|
28
|
+
fixtures :people
|
27
29
|
|
28
30
|
def setup
|
29
31
|
ActiveRecord::Migration.verbose = true
|
@@ -40,7 +42,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
40
42
|
Reminder.reset_column_information
|
41
43
|
|
42
44
|
%w(last_name key bio age height wealth birthday favorite_day
|
43
|
-
male administrator).each do |column|
|
45
|
+
moment_of_truth male administrator funny).each do |column|
|
44
46
|
Person.connection.remove_column('people', column) rescue nil
|
45
47
|
end
|
46
48
|
Person.connection.remove_column("people", "first_name") rescue nil
|
@@ -59,7 +61,8 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
59
61
|
assert_nothing_raised { Person.connection.remove_index("people", "last_name") }
|
60
62
|
|
61
63
|
# Orcl nds shrt indx nms. Sybs 2.
|
62
|
-
|
64
|
+
# OpenBase does not have named indexes. You must specify a single column name
|
65
|
+
unless current_adapter?(:OracleAdapter, :SybaseAdapter, :OpenBaseAdapter)
|
63
66
|
assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
|
64
67
|
assert_nothing_raised { Person.connection.remove_index("people", :column => ["last_name", "first_name"]) }
|
65
68
|
assert_nothing_raised { Person.connection.add_index("people", ["last_name", "first_name"]) }
|
@@ -72,11 +75,15 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
72
75
|
|
73
76
|
# quoting
|
74
77
|
# Note: changed index name from "key" to "key_idx" since "key" is a Firebird reserved word
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
+
# OpenBase does not have named indexes. You must specify a single column name
|
79
|
+
unless current_adapter?(:OpenBaseAdapter)
|
80
|
+
assert_nothing_raised { Person.connection.add_index("people", ["key"], :name => "key_idx", :unique => true) }
|
81
|
+
assert_nothing_raised { Person.connection.remove_index("people", :name => "key_idx", :unique => true) }
|
82
|
+
end
|
83
|
+
|
78
84
|
# Sybase adapter does not support indexes on :boolean columns
|
79
|
-
|
85
|
+
# OpenBase does not have named indexes. You must specify a single column
|
86
|
+
unless current_adapter?(:SybaseAdapter, :OpenBaseAdapter)
|
80
87
|
assert_nothing_raised { Person.connection.add_index("people", %w(last_name first_name administrator), :name => "named_admin") }
|
81
88
|
assert_nothing_raised { Person.connection.remove_index("people", :name => "named_admin") }
|
82
89
|
end
|
@@ -108,11 +115,15 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
108
115
|
end
|
109
116
|
|
110
117
|
def test_create_table_with_defaults
|
118
|
+
# MySQL doesn't allow defaults on TEXT or BLOB columns.
|
119
|
+
mysql = current_adapter?(:MysqlAdapter)
|
120
|
+
|
111
121
|
Person.connection.create_table :testings do |t|
|
112
122
|
t.column :one, :string, :default => "hello"
|
113
123
|
t.column :two, :boolean, :default => true
|
114
124
|
t.column :three, :boolean, :default => false
|
115
125
|
t.column :four, :integer, :default => 1
|
126
|
+
t.column :five, :text, :default => "hello" unless mysql
|
116
127
|
end
|
117
128
|
|
118
129
|
columns = Person.connection.columns(:testings)
|
@@ -120,11 +131,13 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
120
131
|
two = columns.detect { |c| c.name == "two" }
|
121
132
|
three = columns.detect { |c| c.name == "three" }
|
122
133
|
four = columns.detect { |c| c.name == "four" }
|
134
|
+
five = columns.detect { |c| c.name == "five" } unless mysql
|
123
135
|
|
124
136
|
assert_equal "hello", one.default
|
125
137
|
assert_equal true, two.default
|
126
138
|
assert_equal false, three.default
|
127
139
|
assert_equal 1, four.default
|
140
|
+
assert_equal "hello", five.default unless mysql
|
128
141
|
|
129
142
|
ensure
|
130
143
|
Person.connection.drop_table :testings rescue nil
|
@@ -167,9 +180,8 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
167
180
|
Person.connection.drop_table :testings rescue nil
|
168
181
|
end
|
169
182
|
|
170
|
-
# SQL Server and
|
171
|
-
# to a table without
|
172
|
-
# following test must be skipped
|
183
|
+
# SQL Server, Sybase, and SQLite3 will not allow you to add a NOT NULL
|
184
|
+
# column to a table without a default value.
|
173
185
|
unless current_adapter?(:SQLServerAdapter, :SybaseAdapter, :SQLiteAdapter)
|
174
186
|
def test_add_column_not_null_without_default
|
175
187
|
Person.connection.create_table :testings do |t|
|
@@ -197,7 +209,12 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
197
209
|
assert_nothing_raised {Person.connection.add_column :testings, :bar, :string, :null => false, :default => "default" }
|
198
210
|
|
199
211
|
assert_raises(ActiveRecord::StatementInvalid) do
|
200
|
-
|
212
|
+
unless current_adapter?(:OpenBaseAdapter)
|
213
|
+
Person.connection.execute "insert into testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) values (2, 'hello', NULL)"
|
214
|
+
else
|
215
|
+
Person.connection.insert("INSERT INTO testings (#{con.quote_column_name('id')}, #{con.quote_column_name('foo')}, #{con.quote_column_name('bar')}) VALUES (2, 'hello', NULL)",
|
216
|
+
"Testing Insert","id",2)
|
217
|
+
end
|
201
218
|
end
|
202
219
|
ensure
|
203
220
|
Person.connection.drop_table :testings rescue nil
|
@@ -207,8 +224,6 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
207
224
|
# functionality. This allows us to more easily catch INSERT being broken,
|
208
225
|
# but SELECT actually working fine.
|
209
226
|
def test_native_decimal_insert_manual_vs_automatic
|
210
|
-
# SQLite3 always uses float in violation of SQL
|
211
|
-
# 16 decimal places
|
212
227
|
correct_value = '0012345678901234567890.0123456789'.to_d
|
213
228
|
|
214
229
|
Person.delete_all
|
@@ -218,6 +233,8 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
218
233
|
# Do a manual insertion
|
219
234
|
if current_adapter?(:OracleAdapter)
|
220
235
|
Person.connection.execute "insert into people (id, wealth) values (people_seq.nextval, 12345678901234567890.0123456789)"
|
236
|
+
elsif current_adapter?(:OpenBaseAdapter)
|
237
|
+
Person.connection.execute "insert into people (wealth) values ('12345678901234567890.0123456789')"
|
221
238
|
else
|
222
239
|
Person.connection.execute "insert into people (wealth) values (12345678901234567890.0123456789)"
|
223
240
|
end
|
@@ -230,6 +247,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
230
247
|
unless current_adapter?(:SQLite3Adapter)
|
231
248
|
assert_equal correct_value, row.wealth
|
232
249
|
end
|
250
|
+
|
233
251
|
# Reset to old state
|
234
252
|
Person.delete_all
|
235
253
|
|
@@ -244,6 +262,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
244
262
|
unless current_adapter?(:SQLite3Adapter)
|
245
263
|
assert_equal correct_value, row.wealth
|
246
264
|
end
|
265
|
+
|
247
266
|
# Reset to old state
|
248
267
|
Person.connection.del_column "people", "wealth" rescue nil
|
249
268
|
Person.reset_column_information
|
@@ -258,10 +277,19 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
258
277
|
Person.connection.add_column "people", "wealth", :decimal, :precision => '30', :scale => '10'
|
259
278
|
Person.connection.add_column "people", "birthday", :datetime
|
260
279
|
Person.connection.add_column "people", "favorite_day", :date
|
280
|
+
Person.connection.add_column "people", "moment_of_truth", :datetime
|
261
281
|
Person.connection.add_column "people", "male", :boolean
|
262
|
-
|
263
|
-
bob = Person.find(:first)
|
282
|
+
Person.reset_column_information
|
264
283
|
|
284
|
+
assert_nothing_raised do
|
285
|
+
Person.create :first_name => 'bob', :last_name => 'bobsen',
|
286
|
+
:bio => "I was born ....", :age => 18, :height => 1.78,
|
287
|
+
:wealth => BigDecimal.new("12345678901234567890.0123456789"),
|
288
|
+
:birthday => 18.years.ago, :favorite_day => 10.days.ago,
|
289
|
+
:moment_of_truth => "1782-10-10 21:40:18", :male => true
|
290
|
+
end
|
291
|
+
|
292
|
+
bob = Person.find(:first)
|
265
293
|
assert_equal 'bob', bob.first_name
|
266
294
|
assert_equal 'bobsen', bob.last_name
|
267
295
|
assert_equal "I was born ....", bob.bio
|
@@ -269,10 +297,11 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
269
297
|
|
270
298
|
# Test for 30 significent digits (beyond the 16 of float), 10 of them
|
271
299
|
# after the decimal place.
|
300
|
+
|
272
301
|
unless current_adapter?(:SQLite3Adapter)
|
273
302
|
assert_equal BigDecimal.new("0012345678901234567890.0123456789"), bob.wealth
|
274
303
|
end
|
275
|
-
|
304
|
+
|
276
305
|
assert_equal true, bob.male?
|
277
306
|
|
278
307
|
assert_equal String, bob.first_name.class
|
@@ -288,10 +317,34 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
288
317
|
assert_equal Date, bob.favorite_day.class
|
289
318
|
end
|
290
319
|
|
320
|
+
# Test DateTime column and defaults, including timezone.
|
321
|
+
# FIXME: moment of truth may be Time on 64-bit platforms.
|
322
|
+
if bob.moment_of_truth.is_a?(DateTime)
|
323
|
+
assert_equal DateTime.now.offset, bob.moment_of_truth.offset
|
324
|
+
assert_not_equal 0, bob.moment_of_truth.offset
|
325
|
+
assert_not_equal "Z", bob.moment_of_truth.zone
|
326
|
+
assert_equal DateTime::ITALY, bob.moment_of_truth.start
|
327
|
+
end
|
328
|
+
|
291
329
|
assert_equal TrueClass, bob.male?.class
|
292
330
|
assert_kind_of BigDecimal, bob.wealth
|
293
331
|
end
|
294
332
|
|
333
|
+
if current_adapter?(:MysqlAdapter)
|
334
|
+
def test_unabstracted_database_dependent_types
|
335
|
+
Person.delete_all
|
336
|
+
|
337
|
+
ActiveRecord::Migration.add_column :people, :intelligence_quotient, :tinyint
|
338
|
+
Person.reset_column_information
|
339
|
+
Person.create :intelligence_quotient => 300
|
340
|
+
jonnyg = Person.find(:first)
|
341
|
+
assert_equal 127, jonnyg.intelligence_quotient
|
342
|
+
jonnyg.destroy
|
343
|
+
ensure
|
344
|
+
ActiveRecord::Migration.remove_column :people, :intelligence_quotient rescue nil
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
295
348
|
def test_add_remove_single_field_using_string_arguments
|
296
349
|
assert !Person.column_methods_hash.include?(:last_name)
|
297
350
|
|
@@ -325,6 +378,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
325
378
|
|
326
379
|
begin
|
327
380
|
Person.connection.add_column "people", "girlfriend", :string
|
381
|
+
Person.reset_column_information
|
328
382
|
Person.create :girlfriend => 'bobette'
|
329
383
|
|
330
384
|
Person.connection.rename_column "people", "girlfriend", "exgirlfriend"
|
@@ -342,9 +396,11 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
342
396
|
|
343
397
|
def test_rename_column_using_symbol_arguments
|
344
398
|
begin
|
399
|
+
names_before = Person.find(:all).map(&:first_name)
|
345
400
|
Person.connection.rename_column :people, :first_name, :nick_name
|
346
401
|
Person.reset_column_information
|
347
402
|
assert Person.column_names.include?("nick_name")
|
403
|
+
assert_equal names_before, Person.find(:all).map(&:nick_name)
|
348
404
|
ensure
|
349
405
|
Person.connection.remove_column("people","nick_name")
|
350
406
|
Person.connection.add_column("people","first_name", :string)
|
@@ -353,15 +409,38 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
353
409
|
|
354
410
|
def test_rename_column
|
355
411
|
begin
|
412
|
+
names_before = Person.find(:all).map(&:first_name)
|
356
413
|
Person.connection.rename_column "people", "first_name", "nick_name"
|
357
414
|
Person.reset_column_information
|
358
415
|
assert Person.column_names.include?("nick_name")
|
416
|
+
assert_equal names_before, Person.find(:all).map(&:nick_name)
|
359
417
|
ensure
|
360
418
|
Person.connection.remove_column("people","nick_name")
|
361
419
|
Person.connection.add_column("people","first_name", :string)
|
362
420
|
end
|
363
421
|
end
|
364
422
|
|
423
|
+
def test_rename_column_with_sql_reserved_word
|
424
|
+
begin
|
425
|
+
assert_nothing_raised { Person.connection.rename_column "people", "first_name", "group" }
|
426
|
+
Person.reset_column_information
|
427
|
+
assert Person.column_names.include?("group")
|
428
|
+
ensure
|
429
|
+
Person.connection.remove_column("people", "group") rescue nil
|
430
|
+
Person.connection.add_column("people", "first_name", :string) rescue nil
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def test_change_type_of_not_null_column
|
435
|
+
assert_nothing_raised do
|
436
|
+
Topic.connection.change_column "topics", "written_on", :datetime, :null => false
|
437
|
+
Topic.reset_column_information
|
438
|
+
|
439
|
+
Topic.connection.change_column "topics", "written_on", :datetime, :null => false
|
440
|
+
Topic.reset_column_information
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
365
444
|
def test_rename_table
|
366
445
|
begin
|
367
446
|
ActiveRecord::Base.connection.create_table :octopuses do |t|
|
@@ -382,6 +461,19 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
382
461
|
ActiveRecord::Base.connection.drop_table :octopi rescue nil
|
383
462
|
end
|
384
463
|
end
|
464
|
+
|
465
|
+
def test_change_column_nullability
|
466
|
+
Person.delete_all
|
467
|
+
Person.connection.add_column "people", "funny", :boolean
|
468
|
+
Person.reset_column_information
|
469
|
+
assert Person.columns_hash["funny"].null, "Column 'funny' must initially allow nulls"
|
470
|
+
Person.connection.change_column "people", "funny", :boolean, :null => false, :default => true
|
471
|
+
Person.reset_column_information
|
472
|
+
assert !Person.columns_hash["funny"].null, "Column 'funny' must *not* allow nulls at this point"
|
473
|
+
Person.connection.change_column "people", "funny", :boolean, :null => true
|
474
|
+
Person.reset_column_information
|
475
|
+
assert Person.columns_hash["funny"].null, "Column 'funny' must allow nulls again at this point"
|
476
|
+
end
|
385
477
|
|
386
478
|
def test_rename_table_with_an_index
|
387
479
|
begin
|
@@ -420,7 +512,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
420
512
|
old_columns = Topic.connection.columns(Topic.table_name, "#{name} Columns")
|
421
513
|
assert old_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
|
422
514
|
assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => false }
|
423
|
-
new_columns = Topic.connection.columns(Topic.table_name, "#{name} Columns")
|
515
|
+
new_columns = Topic.connection.columns(Topic.table_name, "#{name} Columns")
|
424
516
|
assert_nil new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == true }
|
425
517
|
assert new_columns.find { |c| c.name == 'approved' and c.type == :boolean and c.default == false }
|
426
518
|
assert_nothing_raised { Topic.connection.change_column :topics, :approved, :boolean, :default => true }
|
@@ -435,6 +527,8 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
435
527
|
Person.reset_column_information
|
436
528
|
assert !Person.new.contributor?
|
437
529
|
assert_nil Person.new.contributor
|
530
|
+
ensure
|
531
|
+
Person.connection.remove_column("people", "contributor") rescue nil
|
438
532
|
end
|
439
533
|
|
440
534
|
def test_change_column_with_new_default
|
@@ -445,6 +539,8 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
445
539
|
assert_nothing_raised { Person.connection.change_column "people", "administrator", :boolean, :default => false }
|
446
540
|
Person.reset_column_information
|
447
541
|
assert !Person.new.administrator?
|
542
|
+
ensure
|
543
|
+
Person.connection.remove_column("people", "administrator") rescue nil
|
448
544
|
end
|
449
545
|
|
450
546
|
def test_change_column_default
|
@@ -452,7 +548,19 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
452
548
|
Person.reset_column_information
|
453
549
|
assert_equal "Tester", Person.new.first_name
|
454
550
|
end
|
455
|
-
|
551
|
+
|
552
|
+
def test_change_column_quotes_column_names
|
553
|
+
Person.connection.create_table :testings do |t|
|
554
|
+
t.column :select, :string
|
555
|
+
end
|
556
|
+
|
557
|
+
assert_nothing_raised { Person.connection.change_column :testings, :select, :string, :limit => 10 }
|
558
|
+
|
559
|
+
assert_nothing_raised { Person.connection.execute "insert into testings (#{Person.connection.quote_column_name('select')}) values ('7 chars')" }
|
560
|
+
ensure
|
561
|
+
Person.connection.drop_table :testings rescue nil
|
562
|
+
end
|
563
|
+
|
456
564
|
def test_change_column_default_to_null
|
457
565
|
Person.connection.change_column_default "people", "first_name", nil
|
458
566
|
Person.reset_column_information
|
@@ -463,8 +571,8 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
463
571
|
assert !Reminder.table_exists?
|
464
572
|
|
465
573
|
WeNeedReminders.up
|
466
|
-
|
467
|
-
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
574
|
+
|
575
|
+
assert Reminder.create("content" => "hello world", "remind_at" => Time.now)
|
468
576
|
assert_equal "hello world", Reminder.find(:first).content
|
469
577
|
|
470
578
|
WeNeedReminders.down
|
@@ -506,7 +614,7 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
506
614
|
assert_equal BigDecimal("1000234000567.95"), b.big_bank_balance
|
507
615
|
|
508
616
|
# This one is fun. The 'value_of_e' field is defined as 'DECIMAL' with
|
509
|
-
# precision/scale
|
617
|
+
# precision/scale explicitly left out. By the SQL standard, numbers
|
510
618
|
# assigned to this field should be truncated but that's seldom respected.
|
511
619
|
if current_adapter?(:PostgreSQLAdapter, :SQLite2Adapter)
|
512
620
|
# - PostgreSQL changes the SQL spec on columns declared simply as
|
@@ -685,29 +793,27 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
685
793
|
Reminder.reset_sequence_name
|
686
794
|
end
|
687
795
|
|
688
|
-
|
689
|
-
|
690
|
-
def test_create_table_with_binary_column
|
691
|
-
Person.connection.drop_table :binary_testings rescue nil
|
796
|
+
def test_create_table_with_binary_column
|
797
|
+
Person.connection.drop_table :binary_testings rescue nil
|
692
798
|
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
end
|
697
|
-
}
|
698
|
-
|
699
|
-
columns = Person.connection.columns(:binary_testings)
|
700
|
-
data_column = columns.detect { |c| c.name == "data" }
|
701
|
-
|
702
|
-
if current_adapter?(:OracleAdapter)
|
703
|
-
assert_equal "empty_blob()", data_column.default
|
704
|
-
else
|
705
|
-
assert_equal "", data_column.default
|
799
|
+
assert_nothing_raised {
|
800
|
+
Person.connection.create_table :binary_testings do |t|
|
801
|
+
t.column "data", :binary, :null => false
|
706
802
|
end
|
803
|
+
}
|
804
|
+
|
805
|
+
columns = Person.connection.columns(:binary_testings)
|
806
|
+
data_column = columns.detect { |c| c.name == "data" }
|
707
807
|
|
708
|
-
|
808
|
+
if current_adapter?(:MysqlAdapter)
|
809
|
+
assert_equal '', data_column.default
|
810
|
+
else
|
811
|
+
assert_nil data_column.default
|
709
812
|
end
|
813
|
+
|
814
|
+
Person.connection.drop_table :binary_testings rescue nil
|
710
815
|
end
|
816
|
+
|
711
817
|
def test_migrator_with_duplicates
|
712
818
|
assert_raises(ActiveRecord::DuplicateMigrationVersionError) do
|
713
819
|
ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_duplicate/', nil)
|
@@ -720,11 +826,12 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
720
826
|
assert_equal 4, ActiveRecord::Migrator.current_version
|
721
827
|
|
722
828
|
ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/fixtures/migrations_with_missing_versions/', 2)
|
829
|
+
Person.reset_column_information
|
723
830
|
assert !Reminder.table_exists?
|
724
831
|
assert Person.column_methods_hash.include?(:last_name)
|
725
832
|
assert_equal 2, ActiveRecord::Migrator.current_version
|
726
833
|
end
|
727
|
-
|
834
|
+
|
728
835
|
def test_create_table_with_custom_sequence_name
|
729
836
|
return unless current_adapter? :OracleAdapter
|
730
837
|
|
@@ -761,7 +868,66 @@ if ActiveRecord::Base.connection.supports_migrations?
|
|
761
868
|
Person.connection.execute("select suitably_short_seq.nextval from dual")
|
762
869
|
end
|
763
870
|
end
|
764
|
-
|
765
871
|
end
|
872
|
+
|
873
|
+
uses_mocha 'Sexy migration tests' do
|
874
|
+
class SexyMigrationsTest < Test::Unit::TestCase
|
875
|
+
def test_references_column_type_adds_id
|
876
|
+
with_new_table do |t|
|
877
|
+
t.expects(:column).with('customer_id', :integer, {})
|
878
|
+
t.references :customer
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
882
|
+
def test_references_column_type_with_polymorphic_adds_type
|
883
|
+
with_new_table do |t|
|
884
|
+
t.expects(:column).with('taggable_type', :string, {})
|
885
|
+
t.expects(:column).with('taggable_id', :integer, {})
|
886
|
+
t.references :taggable, :polymorphic => true
|
887
|
+
end
|
888
|
+
end
|
889
|
+
|
890
|
+
def test_belongs_to_works_like_references
|
891
|
+
with_new_table do |t|
|
892
|
+
t.expects(:column).with('customer_id', :integer, {})
|
893
|
+
t.belongs_to :customer
|
894
|
+
end
|
895
|
+
end
|
896
|
+
|
897
|
+
def test_timestamps_creates_updated_at_and_created_at
|
898
|
+
with_new_table do |t|
|
899
|
+
t.expects(:column).with(:created_at, :datetime)
|
900
|
+
t.expects(:column).with(:updated_at, :datetime)
|
901
|
+
t.timestamps
|
902
|
+
end
|
903
|
+
end
|
904
|
+
|
905
|
+
def test_integer_creates_integer_column
|
906
|
+
with_new_table do |t|
|
907
|
+
t.expects(:column).with(:foo, 'integer', {})
|
908
|
+
t.expects(:column).with(:bar, 'integer', {})
|
909
|
+
t.integer :foo, :bar
|
910
|
+
end
|
911
|
+
end
|
912
|
+
|
913
|
+
def test_string_creates_string_column
|
914
|
+
with_new_table do |t|
|
915
|
+
t.expects(:column).with(:foo, 'string', {})
|
916
|
+
t.expects(:column).with(:bar, 'string', {})
|
917
|
+
t.string :foo, :bar
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
protected
|
922
|
+
def with_new_table
|
923
|
+
Person.connection.create_table :delete_me do |t|
|
924
|
+
yield t
|
925
|
+
end
|
926
|
+
ensure
|
927
|
+
Person.connection.drop_table :delete_me rescue nil
|
928
|
+
end
|
929
|
+
|
930
|
+
end # SexyMigrationsTest
|
931
|
+
end # uses_mocha
|
766
932
|
end
|
767
933
|
|