activerecord 2.0.5 → 2.1.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.

Files changed (289) hide show
  1. data/CHANGELOG +168 -6
  2. data/README +27 -22
  3. data/RUNNING_UNIT_TESTS +7 -4
  4. data/Rakefile +22 -25
  5. data/lib/active_record.rb +8 -2
  6. data/lib/active_record/aggregations.rb +21 -12
  7. data/lib/active_record/association_preload.rb +277 -0
  8. data/lib/active_record/associations.rb +481 -295
  9. data/lib/active_record/associations/association_collection.rb +162 -37
  10. data/lib/active_record/associations/association_proxy.rb +71 -7
  11. data/lib/active_record/associations/belongs_to_association.rb +5 -3
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +5 -6
  13. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +12 -64
  14. data/lib/active_record/associations/has_many_association.rb +8 -73
  15. data/lib/active_record/associations/has_many_through_association.rb +68 -117
  16. data/lib/active_record/associations/has_one_association.rb +7 -5
  17. data/lib/active_record/associations/has_one_through_association.rb +28 -0
  18. data/lib/active_record/attribute_methods.rb +69 -19
  19. data/lib/active_record/base.rb +496 -275
  20. data/lib/active_record/calculations.rb +28 -21
  21. data/lib/active_record/callbacks.rb +9 -38
  22. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +3 -2
  23. data/lib/active_record/connection_adapters/abstract/database_statements.rb +2 -2
  24. data/lib/active_record/connection_adapters/abstract/query_cache.rb +6 -0
  25. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +232 -45
  26. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +141 -27
  27. data/lib/active_record/connection_adapters/abstract_adapter.rb +9 -13
  28. data/lib/active_record/connection_adapters/mysql_adapter.rb +57 -24
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +143 -42
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -1
  31. data/lib/active_record/connection_adapters/sqlite_adapter.rb +18 -10
  32. data/lib/active_record/dirty.rb +158 -0
  33. data/lib/active_record/fixtures.rb +121 -156
  34. data/lib/active_record/locking/optimistic.rb +14 -11
  35. data/lib/active_record/locking/pessimistic.rb +2 -2
  36. data/lib/active_record/migration.rb +157 -77
  37. data/lib/active_record/named_scope.rb +163 -0
  38. data/lib/active_record/observer.rb +19 -5
  39. data/lib/active_record/reflection.rb +34 -14
  40. data/lib/active_record/schema.rb +7 -14
  41. data/lib/active_record/schema_dumper.rb +4 -4
  42. data/lib/active_record/serialization.rb +5 -5
  43. data/lib/active_record/serializers/json_serializer.rb +37 -28
  44. data/lib/active_record/serializers/xml_serializer.rb +52 -29
  45. data/lib/active_record/test_case.rb +36 -0
  46. data/lib/active_record/timestamp.rb +4 -4
  47. data/lib/active_record/transactions.rb +3 -3
  48. data/lib/active_record/validations.rb +182 -248
  49. data/lib/active_record/version.rb +2 -2
  50. data/test/{fixtures → assets}/example.log +0 -0
  51. data/test/{fixtures → assets}/flowers.jpg +0 -0
  52. data/test/cases/aaa_create_tables_test.rb +24 -0
  53. data/test/cases/active_schema_test_mysql.rb +95 -0
  54. data/test/cases/active_schema_test_postgresql.rb +24 -0
  55. data/test/{adapter_test.rb → cases/adapter_test.rb} +15 -14
  56. data/test/{adapter_test_sqlserver.rb → cases/adapter_test_sqlserver.rb} +95 -95
  57. data/test/{aggregations_test.rb → cases/aggregations_test.rb} +20 -20
  58. data/test/{ar_schema_test.rb → cases/ar_schema_test.rb} +6 -6
  59. data/test/cases/associations/belongs_to_associations_test.rb +412 -0
  60. data/test/{associations → cases/associations}/callbacks_test.rb +24 -10
  61. data/test/{associations → cases/associations}/cascaded_eager_loading_test.rb +18 -17
  62. data/test/cases/associations/eager_load_nested_include_test.rb +83 -0
  63. data/test/{associations → cases/associations}/eager_singularization_test.rb +5 -5
  64. data/test/{associations → cases/associations}/eager_test.rb +216 -51
  65. data/test/{associations → cases/associations}/extension_test.rb +8 -8
  66. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +684 -0
  67. data/test/cases/associations/has_many_associations_test.rb +932 -0
  68. data/test/cases/associations/has_many_through_associations_test.rb +190 -0
  69. data/test/cases/associations/has_one_associations_test.rb +323 -0
  70. data/test/cases/associations/has_one_through_associations_test.rb +74 -0
  71. data/test/{associations → cases/associations}/inner_join_association_test.rb +20 -20
  72. data/test/{associations → cases/associations}/join_model_test.rb +175 -35
  73. data/test/cases/associations_test.rb +262 -0
  74. data/test/{attribute_methods_test.rb → cases/attribute_methods_test.rb} +103 -11
  75. data/test/{base_test.rb → cases/base_test.rb} +338 -191
  76. data/test/{binary_test.rb → cases/binary_test.rb} +6 -4
  77. data/test/{calculations_test.rb → cases/calculations_test.rb} +35 -23
  78. data/test/{callbacks_test.rb → cases/callbacks_test.rb} +7 -7
  79. data/test/{class_inheritable_attributes_test.rb → cases/class_inheritable_attributes_test.rb} +3 -3
  80. data/test/{column_alias_test.rb → cases/column_alias_test.rb} +3 -3
  81. data/test/{connection_test_firebird.rb → cases/connection_test_firebird.rb} +2 -2
  82. data/test/{connection_test_mysql.rb → cases/connection_test_mysql.rb} +2 -2
  83. data/test/{copy_table_test_sqlite.rb → cases/copy_table_test_sqlite.rb} +13 -13
  84. data/test/{datatype_test_postgresql.rb → cases/datatype_test_postgresql.rb} +8 -8
  85. data/test/{date_time_test.rb → cases/date_time_test.rb} +5 -5
  86. data/test/{default_test_firebird.rb → cases/default_test_firebird.rb} +3 -3
  87. data/test/{defaults_test.rb → cases/defaults_test.rb} +8 -6
  88. data/test/{deprecated_finder_test.rb → cases/deprecated_finder_test.rb} +3 -3
  89. data/test/cases/dirty_test.rb +163 -0
  90. data/test/cases/finder_respond_to_test.rb +76 -0
  91. data/test/{finder_test.rb → cases/finder_test.rb} +266 -33
  92. data/test/{fixtures_test.rb → cases/fixtures_test.rb} +88 -72
  93. data/test/cases/helper.rb +47 -0
  94. data/test/{inheritance_test.rb → cases/inheritance_test.rb} +61 -17
  95. data/test/cases/invalid_date_test.rb +24 -0
  96. data/test/{json_serialization_test.rb → cases/json_serialization_test.rb} +36 -11
  97. data/test/{lifecycle_test.rb → cases/lifecycle_test.rb} +16 -13
  98. data/test/{locking_test.rb → cases/locking_test.rb} +17 -10
  99. data/test/{method_scoping_test.rb → cases/method_scoping_test.rb} +75 -39
  100. data/test/{migration_test.rb → cases/migration_test.rb} +420 -80
  101. data/test/{migration_test_firebird.rb → cases/migration_test_firebird.rb} +3 -3
  102. data/test/{mixin_test.rb → cases/mixin_test.rb} +7 -6
  103. data/test/{modules_test.rb → cases/modules_test.rb} +11 -6
  104. data/test/{multiple_db_test.rb → cases/multiple_db_test.rb} +5 -5
  105. data/test/cases/named_scope_test.rb +157 -0
  106. data/test/{pk_test.rb → cases/pk_test.rb} +10 -10
  107. data/test/{query_cache_test.rb → cases/query_cache_test.rb} +12 -10
  108. data/test/{readonly_test.rb → cases/readonly_test.rb} +11 -11
  109. data/test/{reflection_test.rb → cases/reflection_test.rb} +15 -14
  110. data/test/{reserved_word_test_mysql.rb → cases/reserved_word_test_mysql.rb} +4 -5
  111. data/test/{schema_authorization_test_postgresql.rb → cases/schema_authorization_test_postgresql.rb} +5 -5
  112. data/test/cases/schema_dumper_test.rb +138 -0
  113. data/test/cases/schema_test_postgresql.rb +102 -0
  114. data/test/{serialization_test.rb → cases/serialization_test.rb} +7 -7
  115. data/test/{synonym_test_oracle.rb → cases/synonym_test_oracle.rb} +5 -5
  116. data/test/{table_name_test_sqlserver.rb → cases/table_name_test_sqlserver.rb} +3 -3
  117. data/test/{threaded_connections_test.rb → cases/threaded_connections_test.rb} +7 -7
  118. data/test/{transactions_test.rb → cases/transactions_test.rb} +31 -5
  119. data/test/{unconnected_test.rb → cases/unconnected_test.rb} +2 -2
  120. data/test/{validations_test.rb → cases/validations_test.rb} +141 -39
  121. data/test/{xml_serialization_test.rb → cases/xml_serialization_test.rb} +12 -12
  122. data/test/config.rb +5 -0
  123. data/test/connections/native_db2/connection.rb +1 -1
  124. data/test/connections/native_firebird/connection.rb +1 -1
  125. data/test/connections/native_frontbase/connection.rb +1 -1
  126. data/test/connections/native_mysql/connection.rb +1 -1
  127. data/test/connections/native_openbase/connection.rb +1 -1
  128. data/test/connections/native_oracle/connection.rb +1 -1
  129. data/test/connections/native_postgresql/connection.rb +1 -3
  130. data/test/connections/native_sqlite/connection.rb +2 -2
  131. data/test/connections/native_sqlite3/connection.rb +2 -2
  132. data/test/connections/native_sqlite3/in_memory_connection.rb +3 -3
  133. data/test/connections/native_sybase/connection.rb +1 -1
  134. data/test/fixtures/author_addresses.yml +5 -0
  135. data/test/fixtures/authors.yml +2 -0
  136. data/test/fixtures/clubs.yml +6 -0
  137. data/test/fixtures/jobs.yml +7 -0
  138. data/test/fixtures/members.yml +4 -0
  139. data/test/fixtures/memberships.yml +20 -0
  140. data/test/fixtures/owners.yml +7 -0
  141. data/test/fixtures/people.yml +4 -1
  142. data/test/fixtures/pets.yml +14 -0
  143. data/test/fixtures/posts.yml +1 -0
  144. data/test/fixtures/price_estimates.yml +7 -0
  145. data/test/fixtures/readers.yml +5 -0
  146. data/test/fixtures/references.yml +17 -0
  147. data/test/fixtures/sponsors.yml +9 -0
  148. data/test/fixtures/subscribers.yml +7 -0
  149. data/test/fixtures/subscriptions.yml +12 -0
  150. data/test/fixtures/taggings.yml +4 -1
  151. data/test/fixtures/topics.yml +22 -2
  152. data/test/fixtures/warehouse-things.yml +3 -0
  153. data/test/{fixtures/migrations_with_decimal → migrations/decimal}/1_give_me_big_numbers.rb +0 -0
  154. data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/1_people_have_last_names.rb +1 -1
  155. data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/2_we_need_reminders.rb +1 -1
  156. data/test/{fixtures/migrations_with_duplicate → migrations/duplicate}/3_foo.rb +0 -0
  157. data/test/{fixtures/migrations → migrations/duplicate}/3_innocent_jointable.rb +0 -0
  158. data/test/migrations/duplicate_names/20080507052938_chunky.rb +7 -0
  159. data/test/migrations/duplicate_names/20080507053028_chunky.rb +7 -0
  160. data/test/{fixtures/migrations_with_duplicate → migrations/interleaved/pass_1}/3_innocent_jointable.rb +0 -0
  161. data/test/{fixtures/migrations → migrations/interleaved/pass_2}/1_people_have_last_names.rb +1 -1
  162. data/test/{fixtures/migrations_with_missing_versions/4_innocent_jointable.rb → migrations/interleaved/pass_2/3_innocent_jointable.rb} +0 -0
  163. data/test/{fixtures/migrations_with_missing_versions → migrations/interleaved/pass_3}/1_people_have_last_names.rb +1 -1
  164. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +8 -0
  165. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +12 -0
  166. data/test/{fixtures/migrations_with_missing_versions → migrations/missing}/1000_people_have_middle_names.rb +1 -1
  167. data/test/migrations/missing/1_people_have_last_names.rb +9 -0
  168. data/test/{fixtures/migrations_with_missing_versions → migrations/missing}/3_we_need_reminders.rb +1 -1
  169. data/test/migrations/missing/4_innocent_jointable.rb +12 -0
  170. data/test/migrations/valid/1_people_have_last_names.rb +9 -0
  171. data/test/{fixtures/migrations → migrations/valid}/2_we_need_reminders.rb +1 -1
  172. data/test/migrations/valid/3_innocent_jointable.rb +12 -0
  173. data/test/{fixtures → models}/author.rb +28 -4
  174. data/test/{fixtures → models}/auto_id.rb +0 -0
  175. data/test/{fixtures → models}/binary.rb +0 -0
  176. data/test/{fixtures → models}/book.rb +0 -0
  177. data/test/{fixtures → models}/categorization.rb +0 -0
  178. data/test/{fixtures → models}/category.rb +8 -5
  179. data/test/{fixtures → models}/citation.rb +0 -0
  180. data/test/models/club.rb +7 -0
  181. data/test/{fixtures → models}/column_name.rb +0 -0
  182. data/test/{fixtures → models}/comment.rb +5 -3
  183. data/test/{fixtures → models}/company.rb +15 -6
  184. data/test/{fixtures → models}/company_in_module.rb +5 -3
  185. data/test/{fixtures → models}/computer.rb +0 -1
  186. data/test/{fixtures → models}/contact.rb +1 -1
  187. data/test/{fixtures → models}/course.rb +0 -0
  188. data/test/{fixtures → models}/customer.rb +8 -8
  189. data/test/{fixtures → models}/default.rb +0 -0
  190. data/test/{fixtures → models}/developer.rb +14 -10
  191. data/test/{fixtures → models}/edge.rb +0 -0
  192. data/test/{fixtures → models}/entrant.rb +0 -0
  193. data/test/models/guid.rb +2 -0
  194. data/test/{fixtures → models}/item.rb +0 -0
  195. data/test/models/job.rb +5 -0
  196. data/test/{fixtures → models}/joke.rb +0 -0
  197. data/test/{fixtures → models}/keyboard.rb +0 -0
  198. data/test/{fixtures → models}/legacy_thing.rb +0 -0
  199. data/test/{fixtures → models}/matey.rb +0 -0
  200. data/test/models/member.rb +9 -0
  201. data/test/models/membership.rb +9 -0
  202. data/test/{fixtures → models}/minimalistic.rb +0 -0
  203. data/test/{fixtures → models}/mixed_case_monkey.rb +0 -0
  204. data/test/{fixtures → models}/movie.rb +0 -0
  205. data/test/{fixtures → models}/order.rb +2 -2
  206. data/test/models/owner.rb +4 -0
  207. data/test/{fixtures → models}/parrot.rb +0 -0
  208. data/test/models/person.rb +10 -0
  209. data/test/models/pet.rb +4 -0
  210. data/test/models/pirate.rb +9 -0
  211. data/test/{fixtures → models}/post.rb +23 -2
  212. data/test/models/price_estimate.rb +3 -0
  213. data/test/{fixtures → models}/project.rb +1 -0
  214. data/test/{fixtures → models}/reader.rb +0 -0
  215. data/test/models/reference.rb +4 -0
  216. data/test/{fixtures → models}/reply.rb +7 -5
  217. data/test/{fixtures → models}/ship.rb +0 -0
  218. data/test/models/sponsor.rb +4 -0
  219. data/test/{fixtures → models}/subject.rb +0 -0
  220. data/test/{fixtures → models}/subscriber.rb +2 -0
  221. data/test/models/subscription.rb +4 -0
  222. data/test/{fixtures → models}/tag.rb +0 -0
  223. data/test/{fixtures → models}/tagging.rb +0 -0
  224. data/test/{fixtures → models}/task.rb +0 -0
  225. data/test/{fixtures → models}/topic.rb +32 -4
  226. data/test/{fixtures → models}/treasure.rb +2 -0
  227. data/test/{fixtures → models}/vertex.rb +0 -0
  228. data/test/models/warehouse_thing.rb +5 -0
  229. data/test/schema/mysql_specific_schema.rb +12 -0
  230. data/test/schema/postgresql_specific_schema.rb +103 -0
  231. data/test/schema/schema.rb +421 -0
  232. data/test/schema/schema2.rb +6 -0
  233. data/test/schema/sqlite_specific_schema.rb +25 -0
  234. data/test/schema/sqlserver_specific_schema.rb +5 -0
  235. metadata +192 -176
  236. data/test/aaa_create_tables_test.rb +0 -72
  237. data/test/abstract_unit.rb +0 -84
  238. data/test/active_schema_test_mysql.rb +0 -46
  239. data/test/all.sh +0 -8
  240. data/test/association_inheritance_reload.rb +0 -14
  241. data/test/associations_test.rb +0 -2177
  242. data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +0 -1
  243. data/test/fixtures/bad_fixtures/attr_with_spaces +0 -1
  244. data/test/fixtures/bad_fixtures/blank_line +0 -3
  245. data/test/fixtures/bad_fixtures/duplicate_attributes +0 -3
  246. data/test/fixtures/bad_fixtures/missing_value +0 -1
  247. data/test/fixtures/db_definitions/db2.drop.sql +0 -33
  248. data/test/fixtures/db_definitions/db2.sql +0 -235
  249. data/test/fixtures/db_definitions/db22.drop.sql +0 -2
  250. data/test/fixtures/db_definitions/db22.sql +0 -5
  251. data/test/fixtures/db_definitions/firebird.drop.sql +0 -65
  252. data/test/fixtures/db_definitions/firebird.sql +0 -310
  253. data/test/fixtures/db_definitions/firebird2.drop.sql +0 -2
  254. data/test/fixtures/db_definitions/firebird2.sql +0 -6
  255. data/test/fixtures/db_definitions/frontbase.drop.sql +0 -33
  256. data/test/fixtures/db_definitions/frontbase.sql +0 -273
  257. data/test/fixtures/db_definitions/frontbase2.drop.sql +0 -1
  258. data/test/fixtures/db_definitions/frontbase2.sql +0 -4
  259. data/test/fixtures/db_definitions/openbase.drop.sql +0 -2
  260. data/test/fixtures/db_definitions/openbase.sql +0 -318
  261. data/test/fixtures/db_definitions/openbase2.drop.sql +0 -2
  262. data/test/fixtures/db_definitions/openbase2.sql +0 -7
  263. data/test/fixtures/db_definitions/oracle.drop.sql +0 -67
  264. data/test/fixtures/db_definitions/oracle.sql +0 -330
  265. data/test/fixtures/db_definitions/oracle2.drop.sql +0 -2
  266. data/test/fixtures/db_definitions/oracle2.sql +0 -6
  267. data/test/fixtures/db_definitions/postgresql.drop.sql +0 -44
  268. data/test/fixtures/db_definitions/postgresql.sql +0 -292
  269. data/test/fixtures/db_definitions/postgresql2.drop.sql +0 -2
  270. data/test/fixtures/db_definitions/postgresql2.sql +0 -4
  271. data/test/fixtures/db_definitions/schema.rb +0 -354
  272. data/test/fixtures/db_definitions/schema2.rb +0 -11
  273. data/test/fixtures/db_definitions/sqlite.drop.sql +0 -33
  274. data/test/fixtures/db_definitions/sqlite.sql +0 -219
  275. data/test/fixtures/db_definitions/sqlite2.drop.sql +0 -2
  276. data/test/fixtures/db_definitions/sqlite2.sql +0 -5
  277. data/test/fixtures/db_definitions/sybase.drop.sql +0 -35
  278. data/test/fixtures/db_definitions/sybase.sql +0 -222
  279. data/test/fixtures/db_definitions/sybase2.drop.sql +0 -4
  280. data/test/fixtures/db_definitions/sybase2.sql +0 -5
  281. data/test/fixtures/developers_projects/david_action_controller +0 -3
  282. data/test/fixtures/developers_projects/david_active_record +0 -3
  283. data/test/fixtures/developers_projects/jamis_active_record +0 -2
  284. data/test/fixtures/person.rb +0 -4
  285. data/test/fixtures/pirate.rb +0 -5
  286. data/test/fixtures/subscribers/first +0 -2
  287. data/test/fixtures/subscribers/second +0 -2
  288. data/test/schema_dumper_test.rb +0 -131
  289. data/test/schema_test_postgresql.rb +0 -64
@@ -1,4 +1,4 @@
1
- require "#{File.dirname(__FILE__)}/abstract_unit"
1
+ require "cases/helper"
2
2
 
3
3
  class Group < ActiveRecord::Base
4
4
  Group.table_name = 'group'
@@ -23,7 +23,7 @@ end
23
23
 
24
24
  # a suite of tests to ensure the ConnectionAdapters#MysqlAdapter can handle tables with
25
25
  # reserved word names (ie: group, order, values, etc...)
26
- class MysqlReservedWordTest < Test::Unit::TestCase
26
+ class MysqlReservedWordTest < ActiveRecord::TestCase
27
27
  def setup
28
28
  @connection = ActiveRecord::Base.connection
29
29
 
@@ -141,7 +141,7 @@ class MysqlReservedWordTest < Test::Unit::TestCase
141
141
  assert_nothing_raised { Group.table_exists? }
142
142
  assert_nothing_raised { Group.columns }
143
143
  end
144
-
144
+
145
145
  # Calculations
146
146
  def test_calculations_work_with_reserved_words
147
147
  assert_nothing_raised { Group.count }
@@ -156,8 +156,7 @@ class MysqlReservedWordTest < Test::Unit::TestCase
156
156
  private
157
157
  # custom fixture loader, uses Fixtures#create_fixtures and appends base_path to the current file's path
158
158
  def create_test_fixtures(*fixture_names)
159
- fixture_path = "./test/fixtures/reserved_words"
160
- Fixtures.create_fixtures(fixture_path, fixture_names)
159
+ Fixtures.create_fixtures(FIXTURES_ROOT + "/reserved_words", fixture_names)
161
160
  end
162
161
 
163
162
  # custom drop table, uses execute on connection to drop a table if it exists. note: escapes table_name
@@ -1,9 +1,9 @@
1
- require 'abstract_unit'
1
+ require "cases/helper"
2
2
 
3
3
  class SchemaThing < ActiveRecord::Base
4
4
  end
5
5
 
6
- class SchemaAuthorizationTest < Test::Unit::TestCase
6
+ class SchemaAuthorizationTest < ActiveRecord::TestCase
7
7
  self.use_transactional_fixtures = false
8
8
 
9
9
  TABLE_NAME = 'schema_things'
@@ -18,7 +18,7 @@ class SchemaAuthorizationTest < Test::Unit::TestCase
18
18
  @connection.execute "SET search_path TO '$user',public"
19
19
  set_session_auth
20
20
  USERS.each do |u|
21
- @connection.execute "CREATE ROLE #{u}"
21
+ @connection.execute "CREATE USER #{u}"
22
22
  @connection.execute "CREATE SCHEMA AUTHORIZATION #{u}"
23
23
  set_session_auth u
24
24
  @connection.execute "CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
@@ -28,11 +28,11 @@ class SchemaAuthorizationTest < Test::Unit::TestCase
28
28
  end
29
29
 
30
30
  def teardown
31
- set_session_auth
31
+ set_session_auth
32
32
  @connection.execute "RESET search_path"
33
33
  USERS.each do |u|
34
34
  @connection.execute "DROP SCHEMA #{u} CASCADE"
35
- @connection.execute "DROP ROLE #{u}"
35
+ @connection.execute "DROP USER #{u}"
36
36
  end
37
37
  end
38
38
 
@@ -0,0 +1,138 @@
1
+ require "cases/helper"
2
+ require 'active_record/schema_dumper'
3
+ require 'stringio'
4
+
5
+
6
+ class SchemaDumperTest < ActiveRecord::TestCase
7
+ def standard_dump
8
+ stream = StringIO.new
9
+ ActiveRecord::SchemaDumper.ignore_tables = []
10
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
11
+ stream.string
12
+ end
13
+
14
+ def test_schema_dump
15
+ output = standard_dump
16
+ assert_match %r{create_table "accounts"}, output
17
+ assert_match %r{create_table "authors"}, output
18
+ assert_no_match %r{create_table "schema_migrations"}, output
19
+ end
20
+
21
+ def test_schema_dump_excludes_sqlite_sequence
22
+ output = standard_dump
23
+ assert_no_match %r{create_table "sqlite_sequence"}, output
24
+ end
25
+
26
+ def assert_line_up(lines, pattern, required = false)
27
+ return assert(true) if lines.empty?
28
+ matches = lines.map { |line| line.match(pattern) }
29
+ assert matches.all? if required
30
+ matches.compact!
31
+ return assert(true) if matches.empty?
32
+ assert_equal 1, matches.map{ |match| match.offset(0).first }.uniq.length
33
+ end
34
+
35
+ def column_definition_lines(output = standard_dump)
36
+ output.scan(/^( *)create_table.*?\n(.*?)^\1end/m).map{ |m| m.last.split(/\n/) }
37
+ end
38
+
39
+ def test_types_line_up
40
+ column_definition_lines.each do |column_set|
41
+ next if column_set.empty?
42
+
43
+ lengths = column_set.map do |column|
44
+ if match = column.match(/t\.(?:integer|decimal|float|datetime|timestamp|time|date|text|binary|string|boolean)\s+"/)
45
+ match[0].length
46
+ end
47
+ end
48
+
49
+ assert_equal 1, lengths.uniq.length
50
+ end
51
+ end
52
+
53
+ def test_arguments_line_up
54
+ column_definition_lines.each do |column_set|
55
+ assert_line_up(column_set, /:default => /)
56
+ assert_line_up(column_set, /:limit => /)
57
+ assert_line_up(column_set, /:null => /)
58
+ end
59
+ end
60
+
61
+ def test_no_dump_errors
62
+ output = standard_dump
63
+ assert_no_match %r{\# Could not dump table}, output
64
+ end
65
+
66
+ def test_schema_dump_includes_not_null_columns
67
+ stream = StringIO.new
68
+
69
+ ActiveRecord::SchemaDumper.ignore_tables = [/^[^r]/]
70
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
71
+ output = stream.string
72
+ assert_match %r{:null => false}, output
73
+ end
74
+
75
+ def test_schema_dump_with_string_ignored_table
76
+ stream = StringIO.new
77
+
78
+ ActiveRecord::SchemaDumper.ignore_tables = ['accounts']
79
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
80
+ output = stream.string
81
+ assert_no_match %r{create_table "accounts"}, output
82
+ assert_match %r{create_table "authors"}, output
83
+ assert_no_match %r{create_table "schema_migrations"}, output
84
+ end
85
+
86
+ def test_schema_dump_with_regexp_ignored_table
87
+ stream = StringIO.new
88
+
89
+ ActiveRecord::SchemaDumper.ignore_tables = [/^account/]
90
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
91
+ output = stream.string
92
+ assert_no_match %r{create_table "accounts"}, output
93
+ assert_match %r{create_table "authors"}, output
94
+ assert_no_match %r{create_table "schema_migrations"}, output
95
+ end
96
+
97
+ def test_schema_dump_illegal_ignored_table_value
98
+ stream = StringIO.new
99
+ ActiveRecord::SchemaDumper.ignore_tables = [5]
100
+ assert_raise(StandardError) do
101
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
102
+ end
103
+ end
104
+
105
+ if current_adapter?(:MysqlAdapter)
106
+ def test_schema_dump_should_not_add_default_value_for_mysql_text_field
107
+ output = standard_dump
108
+ assert_match %r{t.text\s+"body",\s+:null => false$}, output
109
+ end
110
+
111
+ def test_mysql_schema_dump_should_honor_nonstandard_primary_keys
112
+ output = standard_dump
113
+ match = output.match(%r{create_table "movies"(.*)do})
114
+ assert_not_nil(match, "nonstandardpk table not found")
115
+ assert_match %r(:primary_key => "movieid"), match[1], "non-standard primary key not preserved"
116
+ end
117
+
118
+ def test_schema_dump_includes_length_for_mysql_blob_and_text_fields
119
+ output = standard_dump
120
+ assert_match %r{t.binary\s+"tiny_blob",\s+:limit => 255$}, output
121
+ assert_match %r{t.binary\s+"normal_blob"$}, output
122
+ assert_match %r{t.binary\s+"medium_blob",\s+:limit => 16777215$}, output
123
+ assert_match %r{t.binary\s+"long_blob",\s+:limit => 2147483647$}, output
124
+ assert_match %r{t.text\s+"tiny_text",\s+:limit => 255$}, output
125
+ assert_match %r{t.text\s+"normal_text"$}, output
126
+ assert_match %r{t.text\s+"medium_text",\s+:limit => 16777215$}, output
127
+ assert_match %r{t.text\s+"long_text",\s+:limit => 2147483647$}, output
128
+ end
129
+ end
130
+
131
+ def test_schema_dump_includes_decimal_options
132
+ stream = StringIO.new
133
+ ActiveRecord::SchemaDumper.ignore_tables = [/^[^n]/]
134
+ ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, stream)
135
+ output = stream.string
136
+ assert_match %r{:precision => 3,[[:space:]]+:scale => 2,[[:space:]]+:default => 2.78}, output
137
+ end
138
+ end
@@ -0,0 +1,102 @@
1
+ require "cases/helper"
2
+
3
+ class SchemaTest < ActiveRecord::TestCase
4
+ self.use_transactional_fixtures = false
5
+
6
+ SCHEMA_NAME = 'test_schema'
7
+ SCHEMA2_NAME = 'test_schema2'
8
+ TABLE_NAME = 'things'
9
+ INDEX_A_NAME = 'a_index_things_on_name'
10
+ INDEX_B_NAME = 'b_index_things_on_different_columns_in_each_schema'
11
+ INDEX_A_COLUMN = 'name'
12
+ INDEX_B_COLUMN_S1 = 'email'
13
+ INDEX_B_COLUMN_S2 = 'moment'
14
+ COLUMNS = [
15
+ 'id integer',
16
+ 'name character varying(50)',
17
+ 'email character varying(50)',
18
+ 'moment timestamp without time zone default now()'
19
+ ]
20
+
21
+ def setup
22
+ @connection = ActiveRecord::Base.connection
23
+ @connection.execute "CREATE SCHEMA #{SCHEMA_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
24
+ @connection.execute "CREATE SCHEMA #{SCHEMA2_NAME} CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
25
+ @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
26
+ @connection.execute "CREATE INDEX #{INDEX_A_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_A_COLUMN});"
27
+ @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S1});"
28
+ @connection.execute "CREATE INDEX #{INDEX_B_NAME} ON #{SCHEMA2_NAME}.#{TABLE_NAME} USING btree (#{INDEX_B_COLUMN_S2});"
29
+ end
30
+
31
+ def teardown
32
+ @connection.execute "DROP SCHEMA #{SCHEMA2_NAME} CASCADE"
33
+ @connection.execute "DROP SCHEMA #{SCHEMA_NAME} CASCADE"
34
+ end
35
+
36
+ def test_with_schema_prefixed_table_name
37
+ assert_nothing_raised do
38
+ assert_equal COLUMNS, columns("#{SCHEMA_NAME}.#{TABLE_NAME}")
39
+ end
40
+ end
41
+
42
+ def test_with_schema_search_path
43
+ assert_nothing_raised do
44
+ with_schema_search_path(SCHEMA_NAME) do
45
+ assert_equal COLUMNS, columns(TABLE_NAME)
46
+ end
47
+ end
48
+ end
49
+
50
+ def test_raise_on_unquoted_schema_name
51
+ assert_raise(ActiveRecord::StatementInvalid) do
52
+ with_schema_search_path '$user,public'
53
+ end
54
+ end
55
+
56
+ def test_without_schema_search_path
57
+ assert_raise(ActiveRecord::StatementInvalid) { columns(TABLE_NAME) }
58
+ end
59
+
60
+ def test_ignore_nil_schema_search_path
61
+ assert_nothing_raised { with_schema_search_path nil }
62
+ end
63
+
64
+ def test_dump_indexes_for_schema_one
65
+ do_dump_index_tests_for_schema(SCHEMA_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S1)
66
+ end
67
+
68
+ def test_dump_indexes_for_schema_two
69
+ do_dump_index_tests_for_schema(SCHEMA2_NAME, INDEX_A_COLUMN, INDEX_B_COLUMN_S2)
70
+ end
71
+
72
+ private
73
+ def columns(table_name)
74
+ @connection.send(:column_definitions, table_name).map do |name, type, default|
75
+ "#{name} #{type}" + (default ? " default #{default}" : '')
76
+ end
77
+ end
78
+
79
+ def with_schema_search_path(schema_search_path)
80
+ @connection.schema_search_path = schema_search_path
81
+ yield if block_given?
82
+ ensure
83
+ @connection.schema_search_path = "'$user', public"
84
+ end
85
+
86
+ def do_dump_index_tests_for_schema(this_schema_name, first_index_column_name, second_index_column_name)
87
+ with_schema_search_path(this_schema_name) do
88
+ indexes = @connection.indexes(TABLE_NAME).sort_by {|i| i.name}
89
+ assert_equal 2,indexes.size
90
+
91
+ do_dump_index_assertions_for_one_index(indexes[0], INDEX_A_NAME, first_index_column_name)
92
+ do_dump_index_assertions_for_one_index(indexes[1], INDEX_B_NAME, second_index_column_name)
93
+ end
94
+ end
95
+
96
+ def do_dump_index_assertions_for_one_index(this_index, this_index_name, this_index_column)
97
+ assert_equal TABLE_NAME, this_index.table
98
+ assert_equal 1, this_index.columns.size
99
+ assert_equal this_index_column, this_index.columns[0]
100
+ assert_equal this_index_name, this_index.name
101
+ end
102
+ end
@@ -1,9 +1,9 @@
1
- require 'abstract_unit'
2
- require 'fixtures/contact'
1
+ require "cases/helper"
2
+ require 'models/contact'
3
3
 
4
- class SerializationTest < Test::Unit::TestCase
4
+ class SerializationTest < ActiveRecord::TestCase
5
5
  FORMATS = [ :xml, :json ]
6
-
6
+
7
7
  def setup
8
8
  @contact_attributes = {
9
9
  :name => 'aaron stack',
@@ -16,12 +16,12 @@ class SerializationTest < Test::Unit::TestCase
16
16
 
17
17
  @contact = Contact.new(@contact_attributes)
18
18
  end
19
-
19
+
20
20
  def test_serialize_should_be_reversible
21
21
  for format in FORMATS
22
22
  @serialized = Contact.new.send("to_#{format}")
23
23
  contact = Contact.new.send("from_#{format}", @serialized)
24
-
24
+
25
25
  assert_equal @contact_attributes.keys.collect(&:to_s).sort, contact.attributes.keys.collect(&:to_s).sort, "For #{format}"
26
26
  end
27
27
  end
@@ -44,4 +44,4 @@ class SerializationTest < Test::Unit::TestCase
44
44
  assert_equal @contact_attributes[:awesome], contact.awesome, "For #{format}"
45
45
  end
46
46
  end
47
- end
47
+ end
@@ -1,17 +1,17 @@
1
- require 'abstract_unit'
2
- require 'fixtures/topic'
3
- require 'fixtures/subject'
1
+ require "cases/helper"
2
+ require 'models/topic'
3
+ require 'models/subject'
4
4
 
5
5
  # confirm that synonyms work just like tables; in this case
6
6
  # the "subjects" table in Oracle (defined in oci.sql) is just
7
7
  # a synonym to the "topics" table
8
8
 
9
- class TestOracleSynonym < Test::Unit::TestCase
9
+ class TestOracleSynonym < ActiveRecord::TestCase
10
10
 
11
11
  def test_oracle_synonym
12
12
  topic = Topic.new
13
13
  subject = Subject.new
14
14
  assert_equal(topic.attributes, subject.attributes)
15
15
  end
16
-
16
+
17
17
  end
@@ -1,12 +1,12 @@
1
- require 'abstract_unit'
2
- require "#{File.dirname(__FILE__)}/../lib/active_record/schema"
1
+ require "cases/helper"
2
+ require 'active_record/schema'
3
3
 
4
4
  if ActiveRecord::Base.connection.supports_migrations?
5
5
  class Order < ActiveRecord::Base
6
6
  self.table_name = '[order]'
7
7
  end
8
8
 
9
- class TableNameTest < Test::Unit::TestCase
9
+ class TableNameTest < ActiveRecord::TestCase
10
10
  self.use_transactional_fixtures = false
11
11
 
12
12
  # Ensures Model.columns works when using SQLServer escape characters.
@@ -1,9 +1,9 @@
1
- require 'abstract_unit'
2
- require 'fixtures/topic'
3
- require 'fixtures/reply'
1
+ require "cases/helper"
2
+ require 'models/topic'
3
+ require 'models/reply'
4
4
 
5
5
  unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
6
- class ThreadedConnectionsTest < Test::Unit::TestCase
6
+ class ThreadedConnectionsTest < ActiveRecord::TestCase
7
7
  self.use_transactional_fixtures = false
8
8
 
9
9
  fixtures :topics
@@ -13,7 +13,7 @@ unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
13
13
  @connections = []
14
14
  @allow_concurrency = ActiveRecord::Base.allow_concurrency
15
15
  end
16
-
16
+
17
17
  def teardown
18
18
  # clear the connection cache
19
19
  ActiveRecord::Base.send(:clear_all_cached_connections!)
@@ -22,11 +22,11 @@ unless %w(FrontBase).include? ActiveRecord::Base.connection.adapter_name
22
22
  # reestablish old connection
23
23
  ActiveRecord::Base.establish_connection(@connection)
24
24
  end
25
-
25
+
26
26
  def gather_connections(use_threaded_connections)
27
27
  ActiveRecord::Base.allow_concurrency = use_threaded_connections
28
28
  ActiveRecord::Base.establish_connection(@connection)
29
-
29
+
30
30
  5.times do
31
31
  Thread.new do
32
32
  Topic.find :first
@@ -1,9 +1,9 @@
1
- require 'abstract_unit'
2
- require 'fixtures/topic'
3
- require 'fixtures/reply'
4
- require 'fixtures/developer'
1
+ require "cases/helper"
2
+ require 'models/topic'
3
+ require 'models/reply'
4
+ require 'models/developer'
5
5
 
6
- class TransactionTest < Test::Unit::TestCase
6
+ class TransactionTest < ActiveRecord::TestCase
7
7
  self.use_transactional_fixtures = false
8
8
  fixtures :topics, :developers
9
9
 
@@ -179,6 +179,32 @@ class TransactionTest < Test::Unit::TestCase
179
179
  end
180
180
  end
181
181
 
182
+ def test_sqlite_add_column_in_transaction_raises_statement_invalid
183
+ return true unless current_adapter?(:SQLite3Adapter, :SQLiteAdapter)
184
+
185
+ # Test first if column creation/deletion works correctly when no
186
+ # transaction is in place.
187
+ #
188
+ # We go back to the connection for the column queries because
189
+ # Topic.columns is cached and won't report changes to the DB
190
+
191
+ assert_nothing_raised do
192
+ Topic.reset_column_information
193
+ Topic.connection.add_column('topics', 'stuff', :string)
194
+ assert Topic.column_names.include?('stuff')
195
+
196
+ Topic.reset_column_information
197
+ Topic.connection.remove_column('topics', 'stuff')
198
+ assert !Topic.column_names.include?('stuff')
199
+ end
200
+
201
+ # Test now inside a transaction: add_column should raise a StatementInvalid
202
+ Topic.transaction do
203
+ assert_raises(ActiveRecord::StatementInvalid) { Topic.connection.add_column('topics', 'stuff', :string) }
204
+ raise ActiveRecord::Rollback
205
+ end
206
+ end
207
+
182
208
  private
183
209
  def add_exception_raising_after_save_callback_to_topic
184
210
  Topic.class_eval { def after_save() raise "Make the transaction rollback" end }