activerecord 1.0.0 → 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.

Files changed (311) hide show
  1. data/CHANGELOG +4928 -3
  2. data/README +45 -46
  3. data/RUNNING_UNIT_TESTS +8 -11
  4. data/Rakefile +247 -0
  5. data/install.rb +8 -38
  6. data/lib/active_record/aggregations.rb +64 -49
  7. data/lib/active_record/associations/association_collection.rb +217 -47
  8. data/lib/active_record/associations/association_proxy.rb +159 -0
  9. data/lib/active_record/associations/belongs_to_association.rb +56 -0
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
  11. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +155 -37
  12. data/lib/active_record/associations/has_many_association.rb +145 -75
  13. data/lib/active_record/associations/has_many_through_association.rb +283 -0
  14. data/lib/active_record/associations/has_one_association.rb +96 -0
  15. data/lib/active_record/associations.rb +1537 -304
  16. data/lib/active_record/attribute_methods.rb +328 -0
  17. data/lib/active_record/base.rb +2001 -588
  18. data/lib/active_record/calculations.rb +269 -0
  19. data/lib/active_record/callbacks.rb +169 -165
  20. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +308 -0
  21. data/lib/active_record/connection_adapters/abstract/database_statements.rb +171 -0
  22. data/lib/active_record/connection_adapters/abstract/query_cache.rb +87 -0
  23. data/lib/active_record/connection_adapters/abstract/quoting.rb +69 -0
  24. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +472 -0
  25. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +306 -0
  26. data/lib/active_record/connection_adapters/abstract_adapter.rb +125 -279
  27. data/lib/active_record/connection_adapters/mysql_adapter.rb +442 -77
  28. data/lib/active_record/connection_adapters/postgresql_adapter.rb +805 -135
  29. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
  30. data/lib/active_record/connection_adapters/sqlite_adapter.rb +353 -69
  31. data/lib/active_record/fixtures.rb +946 -100
  32. data/lib/active_record/locking/optimistic.rb +144 -0
  33. data/lib/active_record/locking/pessimistic.rb +77 -0
  34. data/lib/active_record/migration.rb +417 -0
  35. data/lib/active_record/observer.rb +142 -32
  36. data/lib/active_record/query_cache.rb +23 -0
  37. data/lib/active_record/reflection.rb +163 -70
  38. data/lib/active_record/schema.rb +58 -0
  39. data/lib/active_record/schema_dumper.rb +171 -0
  40. data/lib/active_record/serialization.rb +98 -0
  41. data/lib/active_record/serializers/json_serializer.rb +71 -0
  42. data/lib/active_record/serializers/xml_serializer.rb +315 -0
  43. data/lib/active_record/timestamp.rb +41 -0
  44. data/lib/active_record/transactions.rb +87 -57
  45. data/lib/active_record/validations.rb +909 -122
  46. data/lib/active_record/vendor/db2.rb +362 -0
  47. data/lib/active_record/vendor/mysql.rb +126 -29
  48. data/lib/active_record/version.rb +9 -0
  49. data/lib/active_record.rb +35 -7
  50. data/lib/activerecord.rb +1 -0
  51. data/test/aaa_create_tables_test.rb +72 -0
  52. data/test/abstract_unit.rb +73 -5
  53. data/test/active_schema_test_mysql.rb +43 -0
  54. data/test/adapter_test.rb +105 -0
  55. data/test/adapter_test_sqlserver.rb +95 -0
  56. data/test/aggregations_test.rb +110 -16
  57. data/test/all.sh +2 -2
  58. data/test/ar_schema_test.rb +33 -0
  59. data/test/association_inheritance_reload.rb +14 -0
  60. data/test/associations/ar_joins_test.rb +0 -0
  61. data/test/associations/callbacks_test.rb +147 -0
  62. data/test/associations/cascaded_eager_loading_test.rb +110 -0
  63. data/test/associations/eager_singularization_test.rb +145 -0
  64. data/test/associations/eager_test.rb +442 -0
  65. data/test/associations/extension_test.rb +47 -0
  66. data/test/associations/inner_join_association_test.rb +88 -0
  67. data/test/associations/join_model_test.rb +553 -0
  68. data/test/associations_test.rb +1930 -267
  69. data/test/attribute_methods_test.rb +146 -0
  70. data/test/base_test.rb +1316 -84
  71. data/test/binary_test.rb +32 -0
  72. data/test/calculations_test.rb +251 -0
  73. data/test/callbacks_test.rb +400 -0
  74. data/test/class_inheritable_attributes_test.rb +3 -4
  75. data/test/column_alias_test.rb +17 -0
  76. data/test/connection_test_firebird.rb +8 -0
  77. data/test/connection_test_mysql.rb +30 -0
  78. data/test/connections/native_db2/connection.rb +25 -0
  79. data/test/connections/native_firebird/connection.rb +26 -0
  80. data/test/connections/native_frontbase/connection.rb +27 -0
  81. data/test/connections/native_mysql/connection.rb +21 -18
  82. data/test/connections/native_openbase/connection.rb +21 -0
  83. data/test/connections/native_oracle/connection.rb +27 -0
  84. data/test/connections/native_postgresql/connection.rb +17 -18
  85. data/test/connections/native_sqlite/connection.rb +17 -16
  86. data/test/connections/native_sqlite3/connection.rb +25 -0
  87. data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
  88. data/test/connections/native_sybase/connection.rb +23 -0
  89. data/test/copy_table_test_sqlite.rb +69 -0
  90. data/test/datatype_test_postgresql.rb +203 -0
  91. data/test/date_time_test.rb +37 -0
  92. data/test/default_test_firebird.rb +16 -0
  93. data/test/defaults_test.rb +67 -0
  94. data/test/deprecated_finder_test.rb +30 -0
  95. data/test/finder_test.rb +607 -32
  96. data/test/fixtures/accounts.yml +28 -0
  97. data/test/fixtures/all/developers.yml +0 -0
  98. data/test/fixtures/all/people.csv +0 -0
  99. data/test/fixtures/all/tasks.yml +0 -0
  100. data/test/fixtures/author.rb +107 -0
  101. data/test/fixtures/author_favorites.yml +4 -0
  102. data/test/fixtures/authors.yml +7 -0
  103. data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
  104. data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
  105. data/test/fixtures/bad_fixtures/blank_line +3 -0
  106. data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
  107. data/test/fixtures/bad_fixtures/missing_value +1 -0
  108. data/test/fixtures/binaries.yml +132 -0
  109. data/test/fixtures/binary.rb +2 -0
  110. data/test/fixtures/book.rb +4 -0
  111. data/test/fixtures/books.yml +7 -0
  112. data/test/fixtures/categories/special_categories.yml +9 -0
  113. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  114. data/test/fixtures/categories.yml +14 -0
  115. data/test/fixtures/categories_ordered.yml +7 -0
  116. data/test/fixtures/categories_posts.yml +23 -0
  117. data/test/fixtures/categorization.rb +5 -0
  118. data/test/fixtures/categorizations.yml +17 -0
  119. data/test/fixtures/category.rb +26 -0
  120. data/test/fixtures/citation.rb +6 -0
  121. data/test/fixtures/comment.rb +23 -0
  122. data/test/fixtures/comments.yml +59 -0
  123. data/test/fixtures/companies.yml +55 -0
  124. data/test/fixtures/company.rb +81 -4
  125. data/test/fixtures/company_in_module.rb +32 -6
  126. data/test/fixtures/computer.rb +4 -0
  127. data/test/fixtures/computers.yml +4 -0
  128. data/test/fixtures/contact.rb +16 -0
  129. data/test/fixtures/courses.yml +7 -0
  130. data/test/fixtures/customer.rb +28 -3
  131. data/test/fixtures/customers.yml +17 -0
  132. data/test/fixtures/db_definitions/db2.drop.sql +33 -0
  133. data/test/fixtures/db_definitions/db2.sql +235 -0
  134. data/test/fixtures/db_definitions/db22.drop.sql +2 -0
  135. data/test/fixtures/db_definitions/db22.sql +5 -0
  136. data/test/fixtures/db_definitions/firebird.drop.sql +65 -0
  137. data/test/fixtures/db_definitions/firebird.sql +310 -0
  138. data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
  139. data/test/fixtures/db_definitions/firebird2.sql +6 -0
  140. data/test/fixtures/db_definitions/frontbase.drop.sql +33 -0
  141. data/test/fixtures/db_definitions/frontbase.sql +273 -0
  142. data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
  143. data/test/fixtures/db_definitions/frontbase2.sql +4 -0
  144. data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
  145. data/test/fixtures/db_definitions/openbase.sql +318 -0
  146. data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
  147. data/test/fixtures/db_definitions/openbase2.sql +7 -0
  148. data/test/fixtures/db_definitions/oracle.drop.sql +67 -0
  149. data/test/fixtures/db_definitions/oracle.sql +330 -0
  150. data/test/fixtures/db_definitions/oracle2.drop.sql +2 -0
  151. data/test/fixtures/db_definitions/oracle2.sql +6 -0
  152. data/test/fixtures/db_definitions/postgresql.drop.sql +44 -0
  153. data/test/fixtures/db_definitions/postgresql.sql +217 -38
  154. data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
  155. data/test/fixtures/db_definitions/postgresql2.sql +2 -2
  156. data/test/fixtures/db_definitions/schema.rb +354 -0
  157. data/test/fixtures/db_definitions/schema2.rb +11 -0
  158. data/test/fixtures/db_definitions/sqlite.drop.sql +33 -0
  159. data/test/fixtures/db_definitions/sqlite.sql +139 -5
  160. data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
  161. data/test/fixtures/db_definitions/sqlite2.sql +1 -0
  162. data/test/fixtures/db_definitions/sybase.drop.sql +35 -0
  163. data/test/fixtures/db_definitions/sybase.sql +222 -0
  164. data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
  165. data/test/fixtures/db_definitions/sybase2.sql +5 -0
  166. data/test/fixtures/developer.rb +70 -6
  167. data/test/fixtures/developers.yml +21 -0
  168. data/test/fixtures/developers_projects/david_action_controller +2 -1
  169. data/test/fixtures/developers_projects/david_active_record +2 -1
  170. data/test/fixtures/developers_projects.yml +17 -0
  171. data/test/fixtures/edge.rb +5 -0
  172. data/test/fixtures/edges.yml +6 -0
  173. data/test/fixtures/entrants.yml +14 -0
  174. data/test/fixtures/example.log +1 -0
  175. data/test/fixtures/fk_test_has_fk.yml +3 -0
  176. data/test/fixtures/fk_test_has_pk.yml +2 -0
  177. data/test/fixtures/flowers.jpg +0 -0
  178. data/test/fixtures/funny_jokes.yml +10 -0
  179. data/test/fixtures/item.rb +7 -0
  180. data/test/fixtures/items.yml +4 -0
  181. data/test/fixtures/joke.rb +3 -0
  182. data/test/fixtures/keyboard.rb +3 -0
  183. data/test/fixtures/legacy_thing.rb +3 -0
  184. data/test/fixtures/legacy_things.yml +3 -0
  185. data/test/fixtures/matey.rb +4 -0
  186. data/test/fixtures/mateys.yml +4 -0
  187. data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
  188. data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
  189. data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
  190. data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
  191. data/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +9 -0
  192. data/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +12 -0
  193. data/test/fixtures/migrations_with_duplicate/3_foo.rb +7 -0
  194. data/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +12 -0
  195. data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
  196. data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
  197. data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
  198. data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
  199. data/test/fixtures/minimalistic.rb +2 -0
  200. data/test/fixtures/minimalistics.yml +2 -0
  201. data/test/fixtures/mixed_case_monkey.rb +3 -0
  202. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  203. data/test/fixtures/mixins.yml +29 -0
  204. data/test/fixtures/movies.yml +7 -0
  205. data/test/fixtures/naked/csv/accounts.csv +1 -0
  206. data/test/fixtures/naked/yml/accounts.yml +1 -0
  207. data/test/fixtures/naked/yml/companies.yml +1 -0
  208. data/test/fixtures/naked/yml/courses.yml +1 -0
  209. data/test/fixtures/order.rb +4 -0
  210. data/test/fixtures/parrot.rb +13 -0
  211. data/test/fixtures/parrots.yml +27 -0
  212. data/test/fixtures/parrots_pirates.yml +7 -0
  213. data/test/fixtures/people.yml +3 -0
  214. data/test/fixtures/person.rb +4 -0
  215. data/test/fixtures/pirate.rb +5 -0
  216. data/test/fixtures/pirates.yml +9 -0
  217. data/test/fixtures/post.rb +59 -0
  218. data/test/fixtures/posts.yml +48 -0
  219. data/test/fixtures/project.rb +27 -2
  220. data/test/fixtures/projects.yml +7 -0
  221. data/test/fixtures/reader.rb +4 -0
  222. data/test/fixtures/readers.yml +4 -0
  223. data/test/fixtures/reply.rb +18 -2
  224. data/test/fixtures/reserved_words/distinct.yml +5 -0
  225. data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
  226. data/test/fixtures/reserved_words/group.yml +14 -0
  227. data/test/fixtures/reserved_words/select.yml +8 -0
  228. data/test/fixtures/reserved_words/values.yml +7 -0
  229. data/test/fixtures/ship.rb +3 -0
  230. data/test/fixtures/ships.yml +5 -0
  231. data/test/fixtures/subject.rb +4 -0
  232. data/test/fixtures/subscriber.rb +4 -3
  233. data/test/fixtures/tag.rb +7 -0
  234. data/test/fixtures/tagging.rb +10 -0
  235. data/test/fixtures/taggings.yml +25 -0
  236. data/test/fixtures/tags.yml +7 -0
  237. data/test/fixtures/task.rb +3 -0
  238. data/test/fixtures/tasks.yml +7 -0
  239. data/test/fixtures/topic.rb +20 -3
  240. data/test/fixtures/topics.yml +22 -0
  241. data/test/fixtures/treasure.rb +4 -0
  242. data/test/fixtures/treasures.yml +10 -0
  243. data/test/fixtures/vertex.rb +9 -0
  244. data/test/fixtures/vertices.yml +4 -0
  245. data/test/fixtures_test.rb +574 -8
  246. data/test/inheritance_test.rb +113 -27
  247. data/test/json_serialization_test.rb +180 -0
  248. data/test/lifecycle_test.rb +56 -29
  249. data/test/locking_test.rb +273 -0
  250. data/test/method_scoping_test.rb +416 -0
  251. data/test/migration_test.rb +933 -0
  252. data/test/migration_test_firebird.rb +124 -0
  253. data/test/mixin_test.rb +95 -0
  254. data/test/modules_test.rb +23 -10
  255. data/test/multiple_db_test.rb +17 -3
  256. data/test/pk_test.rb +59 -15
  257. data/test/query_cache_test.rb +104 -0
  258. data/test/readonly_test.rb +107 -0
  259. data/test/reflection_test.rb +124 -27
  260. data/test/reserved_word_test_mysql.rb +177 -0
  261. data/test/schema_authorization_test_postgresql.rb +75 -0
  262. data/test/schema_dumper_test.rb +131 -0
  263. data/test/schema_test_postgresql.rb +64 -0
  264. data/test/serialization_test.rb +47 -0
  265. data/test/synonym_test_oracle.rb +17 -0
  266. data/test/table_name_test_sqlserver.rb +23 -0
  267. data/test/threaded_connections_test.rb +48 -0
  268. data/test/transactions_test.rb +227 -29
  269. data/test/unconnected_test.rb +14 -6
  270. data/test/validations_test.rb +1293 -32
  271. data/test/xml_serialization_test.rb +202 -0
  272. metadata +347 -143
  273. data/dev-utils/eval_debugger.rb +0 -9
  274. data/examples/associations.rb +0 -87
  275. data/examples/shared_setup.rb +0 -15
  276. data/examples/validation.rb +0 -88
  277. data/lib/active_record/deprecated_associations.rb +0 -70
  278. data/lib/active_record/support/class_attribute_accessors.rb +0 -43
  279. data/lib/active_record/support/class_inheritable_attributes.rb +0 -37
  280. data/lib/active_record/support/clean_logger.rb +0 -10
  281. data/lib/active_record/support/inflector.rb +0 -70
  282. data/lib/active_record/vendor/simple.rb +0 -702
  283. data/lib/active_record/wrappers/yaml_wrapper.rb +0 -15
  284. data/lib/active_record/wrappings.rb +0 -59
  285. data/rakefile +0 -122
  286. data/test/deprecated_associations_test.rb +0 -336
  287. data/test/fixtures/accounts/signals37 +0 -3
  288. data/test/fixtures/accounts/unknown +0 -2
  289. data/test/fixtures/companies/first_client +0 -6
  290. data/test/fixtures/companies/first_firm +0 -4
  291. data/test/fixtures/companies/second_client +0 -6
  292. data/test/fixtures/courses/java +0 -2
  293. data/test/fixtures/courses/ruby +0 -2
  294. data/test/fixtures/customers/david +0 -6
  295. data/test/fixtures/db_definitions/mysql.sql +0 -96
  296. data/test/fixtures/db_definitions/mysql2.sql +0 -4
  297. data/test/fixtures/developers/david +0 -2
  298. data/test/fixtures/developers/jamis +0 -2
  299. data/test/fixtures/entrants/first +0 -3
  300. data/test/fixtures/entrants/second +0 -3
  301. data/test/fixtures/entrants/third +0 -3
  302. data/test/fixtures/fixture_database.sqlite +0 -0
  303. data/test/fixtures/fixture_database_2.sqlite +0 -0
  304. data/test/fixtures/movies/first +0 -2
  305. data/test/fixtures/movies/second +0 -2
  306. data/test/fixtures/projects/action_controller +0 -2
  307. data/test/fixtures/projects/active_record +0 -2
  308. data/test/fixtures/topics/first +0 -9
  309. data/test/fixtures/topics/second +0 -8
  310. data/test/inflector_test.rb +0 -104
  311. data/test/thread_safety_test.rb +0 -33
data/lib/active_record.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2004 David Heinemeier Hansson
2
+ # Copyright (c) 2004-2007 David Heinemeier Hansson
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -21,28 +21,56 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #++
23
23
 
24
- $:.unshift(File.dirname(__FILE__))
24
+ $:.unshift(File.dirname(__FILE__)) unless
25
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
25
26
 
26
- require 'active_record/support/clean_logger'
27
+ unless defined? ActiveSupport
28
+ active_support_path = File.dirname(__FILE__) + "/../../activesupport/lib"
29
+ if File.exist?(active_support_path)
30
+ $:.unshift active_support_path
31
+ require 'active_support'
32
+ else
33
+ require 'rubygems'
34
+ gem 'activesupport'
35
+ require 'active_support'
36
+ end
37
+ end
27
38
 
28
39
  require 'active_record/base'
29
40
  require 'active_record/observer'
41
+ require 'active_record/query_cache'
30
42
  require 'active_record/validations'
31
43
  require 'active_record/callbacks'
44
+ require 'active_record/reflection'
32
45
  require 'active_record/associations'
33
46
  require 'active_record/aggregations'
34
47
  require 'active_record/transactions'
35
- require 'active_record/reflection'
48
+ require 'active_record/timestamp'
49
+ require 'active_record/locking/optimistic'
50
+ require 'active_record/locking/pessimistic'
51
+ require 'active_record/migration'
52
+ require 'active_record/schema'
53
+ require 'active_record/calculations'
54
+ require 'active_record/serialization'
55
+ require 'active_record/attribute_methods'
36
56
 
37
57
  ActiveRecord::Base.class_eval do
58
+ extend ActiveRecord::QueryCache
38
59
  include ActiveRecord::Validations
60
+ include ActiveRecord::Locking::Optimistic
61
+ include ActiveRecord::Locking::Pessimistic
39
62
  include ActiveRecord::Callbacks
63
+ include ActiveRecord::Observing
64
+ include ActiveRecord::Timestamp
40
65
  include ActiveRecord::Associations
41
66
  include ActiveRecord::Aggregations
42
67
  include ActiveRecord::Transactions
43
68
  include ActiveRecord::Reflection
69
+ include ActiveRecord::Calculations
70
+ include ActiveRecord::Serialization
71
+ include ActiveRecord::AttributeMethods
44
72
  end
45
73
 
46
- require 'active_record/connection_adapters/mysql_adapter'
47
- require 'active_record/connection_adapters/postgresql_adapter'
48
- require 'active_record/connection_adapters/sqlite_adapter'
74
+ require 'active_record/connection_adapters/abstract_adapter'
75
+
76
+ require 'active_record/schema_dumper'
@@ -0,0 +1 @@
1
+ require 'active_record'
@@ -0,0 +1,72 @@
1
+ # The filename begins with "aaa" to ensure this is the first test.
2
+ require 'abstract_unit'
3
+
4
+ class AAACreateTablesTest < Test::Unit::TestCase
5
+ self.use_transactional_fixtures = false
6
+
7
+ def setup
8
+ @base_path = "#{File.dirname(__FILE__)}/fixtures/db_definitions"
9
+ end
10
+
11
+ def test_drop_and_create_main_tables
12
+ recreate ActiveRecord::Base unless use_migrations?
13
+ assert true
14
+ end
15
+
16
+ def test_load_schema
17
+ if ActiveRecord::Base.connection.supports_migrations?
18
+ eval(File.read("#{File.dirname(__FILE__)}/fixtures/db_definitions/schema.rb"))
19
+ else
20
+ recreate ActiveRecord::Base, '3'
21
+ end
22
+ assert true
23
+ end
24
+
25
+ def test_drop_and_create_courses_table
26
+ if Course.connection.supports_migrations?
27
+ eval(File.read("#{File.dirname(__FILE__)}/fixtures/db_definitions/schema2.rb"))
28
+ end
29
+ recreate Course, '2' unless use_migrations_for_courses?
30
+ assert true
31
+ end
32
+
33
+ private
34
+ def use_migrations?
35
+ unittest_sql_filename = ActiveRecord::Base.connection.adapter_name.downcase + ".sql"
36
+ not File.exists? "#{@base_path}/#{unittest_sql_filename}"
37
+ end
38
+
39
+ def use_migrations_for_courses?
40
+ unittest2_sql_filename = ActiveRecord::Base.connection.adapter_name.downcase + "2.sql"
41
+ not File.exists? "#{@base_path}/#{unittest2_sql_filename}"
42
+ end
43
+
44
+ def recreate(base, suffix = nil)
45
+ connection = base.connection
46
+ adapter_name = connection.adapter_name.downcase + suffix.to_s
47
+ execute_sql_file "#{@base_path}/#{adapter_name}.drop.sql", connection
48
+ execute_sql_file "#{@base_path}/#{adapter_name}.sql", connection
49
+ end
50
+
51
+ def execute_sql_file(path, connection)
52
+ # OpenBase has a different format for sql files
53
+ if current_adapter?(:OpenBaseAdapter) then
54
+ File.read(path).split("go").each_with_index do |sql, i|
55
+ begin
56
+ # OpenBase does not support comments embedded in sql
57
+ connection.execute(sql,"SQL statement ##{i}") unless sql.blank?
58
+ rescue ActiveRecord::StatementInvalid
59
+ #$stderr.puts "warning: #{$!}"
60
+ end
61
+ end
62
+ else
63
+ File.read(path).split(';').each_with_index do |sql, i|
64
+ begin
65
+ connection.execute("\n\n-- statement ##{i}\n#{sql}\n") unless sql.blank?
66
+ rescue ActiveRecord::StatementInvalid
67
+ #$stderr.puts "warning: #{$!}"
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,16 +1,84 @@
1
1
  $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ $:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
2
3
 
3
4
  require 'test/unit'
4
5
  require 'active_record'
5
6
  require 'active_record/fixtures'
7
+ require 'active_support/test_case'
6
8
  require 'connection'
7
9
 
10
+ # Show backtraces for deprecated behavior for quicker cleanup.
11
+ ActiveSupport::Deprecation.debug = true
12
+
13
+
14
+ QUOTED_TYPE = ActiveRecord::Base.connection.quote_column_name('type') unless Object.const_defined?(:QUOTED_TYPE)
15
+
8
16
  class Test::Unit::TestCase #:nodoc:
9
- def create_fixtures(*table_names)
10
- if block_given?
11
- Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names) { yield }
17
+ self.fixture_path = File.dirname(__FILE__) + "/fixtures/"
18
+ self.use_instantiated_fixtures = false
19
+ self.use_transactional_fixtures = (ENV['AR_NO_TX_FIXTURES'] != "yes")
20
+
21
+ def create_fixtures(*table_names, &block)
22
+ Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names, {}, &block)
23
+ end
24
+
25
+ def assert_date_from_db(expected, actual, message = nil)
26
+ # SQL Server doesn't have a separate column type just for dates,
27
+ # so the time is in the string and incorrectly formatted
28
+ if current_adapter?(:SQLServerAdapter)
29
+ assert_equal expected.strftime("%Y/%m/%d 00:00:00"), actual.strftime("%Y/%m/%d 00:00:00")
30
+ elsif current_adapter?(:SybaseAdapter)
31
+ assert_equal expected.to_s, actual.to_date.to_s, message
12
32
  else
13
- Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures/", table_names)
33
+ assert_equal expected.to_s, actual.to_s, message
34
+ end
35
+ end
36
+
37
+ def assert_queries(num = 1)
38
+ $query_count = 0
39
+ yield
40
+ ensure
41
+ assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
42
+ end
43
+
44
+ def assert_no_queries(&block)
45
+ assert_queries(0, &block)
46
+ end
47
+ end
48
+
49
+ def current_adapter?(*types)
50
+ types.any? do |type|
51
+ ActiveRecord::ConnectionAdapters.const_defined?(type) &&
52
+ ActiveRecord::Base.connection.is_a?(ActiveRecord::ConnectionAdapters.const_get(type))
53
+ end
54
+ end
55
+
56
+ def uses_mocha(test_name)
57
+ require 'rubygems'
58
+ require 'mocha'
59
+ yield
60
+ rescue LoadError
61
+ $stderr.puts "Skipping #{test_name} tests. `gem install mocha` and try again."
62
+ end
63
+
64
+ ActiveRecord::Base.connection.class.class_eval do
65
+ unless defined? IGNORED_SQL
66
+ IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/]
67
+
68
+ def execute_with_counting(sql, name = nil, &block)
69
+ $query_count ||= 0
70
+ $query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
71
+ execute_without_counting(sql, name, &block)
14
72
  end
73
+
74
+ alias_method_chain :execute, :counting
15
75
  end
16
- end
76
+ end
77
+
78
+ # Make with_scope public for tests
79
+ class << ActiveRecord::Base
80
+ public :with_scope, :with_exclusive_scope
81
+ end
82
+
83
+ #ActiveRecord::Base.logger = Logger.new(STDOUT)
84
+ #ActiveRecord::Base.colorize_logging = false
@@ -0,0 +1,43 @@
1
+ require 'abstract_unit'
2
+
3
+ class ActiveSchemaTest < Test::Unit::TestCase
4
+ def setup
5
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.class_eval do
6
+ alias_method :real_execute, :execute
7
+ def execute(sql, name = nil) return sql end
8
+ end
9
+ end
10
+
11
+ def teardown
12
+ ActiveRecord::ConnectionAdapters::MysqlAdapter.send(:alias_method, :execute, :real_execute)
13
+ end
14
+
15
+ def test_drop_table
16
+ assert_equal "DROP TABLE `people`", drop_table(:people)
17
+ end
18
+
19
+ if current_adapter?(:MysqlAdapter)
20
+ def test_create_mysql_database_with_encoding
21
+ assert_equal "CREATE DATABASE `matt` DEFAULT CHARACTER SET `utf8`", create_database(:matt)
22
+ assert_equal "CREATE DATABASE `aimonetti` DEFAULT CHARACTER SET `latin1`", create_database(:aimonetti, {:charset => 'latin1'})
23
+ assert_equal "CREATE DATABASE `matt_aimonetti` DEFAULT CHARACTER SET `big5` COLLATE `big5_chinese_ci`", create_database(:matt_aimonetti, {:charset => :big5, :collation => :big5_chinese_ci})
24
+ end
25
+ end
26
+
27
+ def test_add_column
28
+ assert_equal "ALTER TABLE `people` ADD `last_name` varchar(255)", add_column(:people, :last_name, :string)
29
+ end
30
+
31
+ def test_add_column_with_limit
32
+ assert_equal "ALTER TABLE `people` ADD `key` varchar(32)", add_column(:people, :key, :string, :limit => 32)
33
+ end
34
+
35
+ def test_drop_table_with_specific_database
36
+ assert_equal "DROP TABLE `otherdb`.`people`", drop_table('otherdb.people')
37
+ end
38
+
39
+ private
40
+ def method_missing(method_symbol, *arguments)
41
+ ActiveRecord::Base.connection.send(method_symbol, *arguments)
42
+ end
43
+ end
@@ -0,0 +1,105 @@
1
+ require 'abstract_unit'
2
+
3
+ class AdapterTest < Test::Unit::TestCase
4
+ def setup
5
+ @connection = ActiveRecord::Base.connection
6
+ end
7
+
8
+ def test_tables
9
+ if @connection.respond_to?(:tables)
10
+ tables = @connection.tables
11
+ assert tables.include?("accounts")
12
+ assert tables.include?("authors")
13
+ assert tables.include?("tasks")
14
+ assert tables.include?("topics")
15
+ else
16
+ warn "#{@connection.class} does not respond to #tables"
17
+ end
18
+ end
19
+
20
+ def test_indexes
21
+ idx_name = "accounts_idx"
22
+
23
+ if @connection.respond_to?(:indexes)
24
+ indexes = @connection.indexes("accounts")
25
+ assert indexes.empty?
26
+
27
+ @connection.add_index :accounts, :firm_id, :name => idx_name
28
+ indexes = @connection.indexes("accounts")
29
+ assert_equal "accounts", indexes.first.table
30
+ # OpenBase does not have the concept of a named index
31
+ # Indexes are merely properties of columns.
32
+ assert_equal idx_name, indexes.first.name unless current_adapter?(:OpenBaseAdapter)
33
+ assert !indexes.first.unique
34
+ assert_equal ["firm_id"], indexes.first.columns
35
+ else
36
+ warn "#{@connection.class} does not respond to #indexes"
37
+ end
38
+
39
+ ensure
40
+ @connection.remove_index(:accounts, :name => idx_name) rescue nil
41
+ end
42
+
43
+ def test_current_database
44
+ if @connection.respond_to?(:current_database)
45
+ assert_equal ENV['ARUNIT_DB_NAME'] || "activerecord_unittest", @connection.current_database
46
+ end
47
+ end
48
+
49
+ if current_adapter?(:MysqlAdapter)
50
+ def test_charset
51
+ assert_not_nil @connection.charset
52
+ assert_not_equal 'character_set_database', @connection.charset
53
+ assert_equal @connection.show_variable('character_set_database'), @connection.charset
54
+ end
55
+
56
+ def test_collation
57
+ assert_not_nil @connection.collation
58
+ assert_not_equal 'collation_database', @connection.collation
59
+ assert_equal @connection.show_variable('collation_database'), @connection.collation
60
+ end
61
+
62
+ def test_show_nonexistent_variable_returns_nil
63
+ assert_nil @connection.show_variable('foo_bar_baz')
64
+ end
65
+ end
66
+
67
+ def test_table_alias
68
+ def @connection.test_table_alias_length() 10; end
69
+ class << @connection
70
+ alias_method :old_table_alias_length, :table_alias_length
71
+ alias_method :table_alias_length, :test_table_alias_length
72
+ end
73
+
74
+ assert_equal 'posts', @connection.table_alias_for('posts')
75
+ assert_equal 'posts_comm', @connection.table_alias_for('posts_comments')
76
+ assert_equal 'dbo_posts', @connection.table_alias_for('dbo.posts')
77
+
78
+ class << @connection
79
+ alias_method :table_alias_length, :old_table_alias_length
80
+ end
81
+ end
82
+
83
+ # test resetting sequences in odd tables in postgreSQL
84
+ if ActiveRecord::Base.connection.respond_to?(:reset_pk_sequence!)
85
+ require 'fixtures/movie'
86
+ require 'fixtures/subscriber'
87
+
88
+ def test_reset_empty_table_with_custom_pk
89
+ Movie.delete_all
90
+ Movie.connection.reset_pk_sequence! 'movies'
91
+ assert_equal 1, Movie.create(:name => 'fight club').id
92
+ end
93
+
94
+ if ActiveRecord::Base.connection.adapter_name != "FrontBase"
95
+ def test_reset_table_with_non_integer_pk
96
+ Subscriber.delete_all
97
+ Subscriber.connection.reset_pk_sequence! 'subscribers'
98
+ sub = Subscriber.new(:name => 'robert drake')
99
+ sub.id = 'bob drake'
100
+ assert_nothing_raised { sub.save! }
101
+ end
102
+ end
103
+ end
104
+
105
+ end
@@ -0,0 +1,95 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/default'
3
+ require 'fixtures/post'
4
+ require 'fixtures/task'
5
+
6
+ class SqlServerAdapterTest < Test::Unit::TestCase
7
+ class TableWithRealColumn < ActiveRecord::Base; end
8
+
9
+ fixtures :posts, :tasks
10
+
11
+ def setup
12
+ @connection = ActiveRecord::Base.connection
13
+ end
14
+
15
+ def teardown
16
+ @connection.execute("SET LANGUAGE us_english") rescue nil
17
+ end
18
+
19
+ def test_real_column_has_float_type
20
+ assert_equal :float, TableWithRealColumn.columns_hash["real_number"].type
21
+ end
22
+
23
+ # SQL Server 2000 has a bug where some unambiguous date formats are not
24
+ # correctly identified if the session language is set to german
25
+ def test_date_insertion_when_language_is_german
26
+ @connection.execute("SET LANGUAGE deutsch")
27
+
28
+ assert_nothing_raised do
29
+ Task.create(:starting => Time.utc(2000, 1, 31, 5, 42, 0), :ending => Date.new(2006, 12, 31))
30
+ end
31
+ end
32
+
33
+ def test_indexes_with_descending_order
34
+ # Make sure we have an index with descending order
35
+ @connection.execute "CREATE INDEX idx_credit_limit ON accounts (credit_limit DESC)" rescue nil
36
+ assert_equal ["credit_limit"], @connection.indexes('accounts').first.columns
37
+ ensure
38
+ @connection.execute "DROP INDEX accounts.idx_credit_limit"
39
+ end
40
+
41
+ def test_execute_without_block_closes_statement
42
+ assert_all_statements_used_are_closed do
43
+ @connection.execute("SELECT 1")
44
+ end
45
+ end
46
+
47
+ def test_execute_with_block_closes_statement
48
+ assert_all_statements_used_are_closed do
49
+ @connection.execute("SELECT 1") do |sth|
50
+ assert !sth.finished?, "Statement should still be alive within block"
51
+ end
52
+ end
53
+ end
54
+
55
+ def test_insert_with_identity_closes_statement
56
+ assert_all_statements_used_are_closed do
57
+ @connection.insert("INSERT INTO accounts ([id], [firm_id],[credit_limit]) values (999, 1, 50)")
58
+ end
59
+ end
60
+
61
+ def test_insert_without_identity_closes_statement
62
+ assert_all_statements_used_are_closed do
63
+ @connection.insert("INSERT INTO accounts ([firm_id],[credit_limit]) values (1, 50)")
64
+ end
65
+ end
66
+
67
+ def test_active_closes_statement
68
+ assert_all_statements_used_are_closed do
69
+ @connection.active?
70
+ end
71
+ end
72
+
73
+ def assert_all_statements_used_are_closed(&block)
74
+ existing_handles = []
75
+ ObjectSpace.each_object(DBI::StatementHandle) {|handle| existing_handles << handle}
76
+ GC.disable
77
+
78
+ yield
79
+
80
+ used_handles = []
81
+ ObjectSpace.each_object(DBI::StatementHandle) {|handle| used_handles << handle unless existing_handles.include? handle}
82
+
83
+ assert_block "No statements were used within given block" do
84
+ used_handles.size > 0
85
+ end
86
+
87
+ ObjectSpace.each_object(DBI::StatementHandle) do |handle|
88
+ assert_block "Statement should have been closed within given block" do
89
+ handle.finished?
90
+ end
91
+ end
92
+ ensure
93
+ GC.enable
94
+ end
95
+ end
@@ -1,34 +1,128 @@
1
1
  require 'abstract_unit'
2
- # require File.dirname(__FILE__) + '/../dev-utils/eval_debugger'
3
2
  require 'fixtures/customer'
4
3
 
5
4
  class AggregationsTest < Test::Unit::TestCase
6
- def setup
7
- @customers = create_fixtures "customers"
8
- @david = Customer.find(1)
9
- end
5
+ fixtures :customers
10
6
 
11
7
  def test_find_single_value_object
12
- assert_equal 50, @david.balance.amount
13
- assert_kind_of Money, @david.balance
14
- assert_equal 300, @david.balance.exchange_to("DKK").amount
8
+ assert_equal 50, customers(:david).balance.amount
9
+ assert_kind_of Money, customers(:david).balance
10
+ assert_equal 300, customers(:david).balance.exchange_to("DKK").amount
15
11
  end
16
12
 
17
13
  def test_find_multiple_value_object
18
- assert_equal @customers["david"]["address_street"], @david.address.street
14
+ assert_equal customers(:david).address_street, customers(:david).address.street
19
15
  assert(
20
- @david.address.close_to?(Address.new("Different Street", @customers["david"]["address_city"], @customers["david"]["address_country"]))
16
+ customers(:david).address.close_to?(Address.new("Different Street", customers(:david).address_city, customers(:david).address_country))
21
17
  )
22
18
  end
23
19
 
24
20
  def test_change_single_value_object
25
- @david.balance = Money.new(100)
26
- @david.save
27
- assert_equal 100, Customer.find(1).balance.amount
21
+ customers(:david).balance = Money.new(100)
22
+ customers(:david).save
23
+ assert_equal 100, customers(:david).reload.balance.amount
28
24
  end
29
25
 
30
26
  def test_immutable_value_objects
31
- @david.balance = Money.new(100)
32
- assert_raises(TypeError) { @david.balance.instance_eval { @amount = 20 } }
27
+ customers(:david).balance = Money.new(100)
28
+ assert_raises(TypeError) { customers(:david).balance.instance_eval { @amount = 20 } }
33
29
  end
34
- end
30
+
31
+ def test_inferred_mapping
32
+ assert_equal "35.544623640962634", customers(:david).gps_location.latitude
33
+ assert_equal "-105.9309951055148", customers(:david).gps_location.longitude
34
+
35
+ customers(:david).gps_location = GpsLocation.new("39x-110")
36
+
37
+ assert_equal "39", customers(:david).gps_location.latitude
38
+ assert_equal "-110", customers(:david).gps_location.longitude
39
+
40
+ customers(:david).save
41
+
42
+ customers(:david).reload
43
+
44
+ assert_equal "39", customers(:david).gps_location.latitude
45
+ assert_equal "-110", customers(:david).gps_location.longitude
46
+ end
47
+
48
+ def test_reloaded_instance_refreshes_aggregations
49
+ assert_equal "35.544623640962634", customers(:david).gps_location.latitude
50
+ assert_equal "-105.9309951055148", customers(:david).gps_location.longitude
51
+
52
+ Customer.update_all("gps_location = '24x113'")
53
+ customers(:david).reload
54
+ assert_equal '24x113', customers(:david)['gps_location']
55
+
56
+ assert_equal GpsLocation.new('24x113'), customers(:david).gps_location
57
+ end
58
+
59
+ def test_gps_equality
60
+ assert GpsLocation.new('39x110') == GpsLocation.new('39x110')
61
+ end
62
+
63
+ def test_gps_inequality
64
+ assert GpsLocation.new('39x110') != GpsLocation.new('39x111')
65
+ end
66
+
67
+ def test_allow_nil_gps_is_nil
68
+ assert_equal nil, customers(:zaphod).gps_location
69
+ end
70
+
71
+ def test_allow_nil_gps_set_to_nil
72
+ customers(:david).gps_location = nil
73
+ customers(:david).save
74
+ customers(:david).reload
75
+ assert_equal nil, customers(:david).gps_location
76
+ end
77
+
78
+ def test_allow_nil_set_address_attributes_to_nil
79
+ customers(:zaphod).address = nil
80
+ assert_equal nil, customers(:zaphod).attributes[:address_street]
81
+ assert_equal nil, customers(:zaphod).attributes[:address_city]
82
+ assert_equal nil, customers(:zaphod).attributes[:address_country]
83
+ end
84
+
85
+ def test_allow_nil_address_set_to_nil
86
+ customers(:zaphod).address = nil
87
+ customers(:zaphod).save
88
+ customers(:zaphod).reload
89
+ assert_equal nil, customers(:zaphod).address
90
+ end
91
+
92
+ def test_nil_raises_error_when_allow_nil_is_false
93
+ assert_raises(NoMethodError) { customers(:david).balance = nil }
94
+ end
95
+
96
+ def test_allow_nil_address_loaded_when_only_some_attributes_are_nil
97
+ customers(:zaphod).address_street = nil
98
+ customers(:zaphod).save
99
+ customers(:zaphod).reload
100
+ assert_kind_of Address, customers(:zaphod).address
101
+ assert customers(:zaphod).address.street.nil?
102
+ end
103
+
104
+ def test_nil_assignment_results_in_nil
105
+ customers(:david).gps_location = GpsLocation.new('39x111')
106
+ assert_not_equal nil, customers(:david).gps_location
107
+ customers(:david).gps_location = nil
108
+ assert_equal nil, customers(:david).gps_location
109
+ end
110
+ end
111
+
112
+ class OverridingAggregationsTest < Test::Unit::TestCase
113
+ class Name; end
114
+ class DifferentName; end
115
+
116
+ class Person < ActiveRecord::Base
117
+ composed_of :composed_of, :mapping => %w(person_first_name first_name)
118
+ end
119
+
120
+ class DifferentPerson < Person
121
+ composed_of :composed_of, :class_name => 'DifferentName', :mapping => %w(different_person_first_name first_name)
122
+ end
123
+
124
+ def test_composed_of_aggregation_redefinition_reflections_should_differ_and_not_inherited
125
+ assert_not_equal Person.reflect_on_aggregation(:composed_of),
126
+ DifferentPerson.reflect_on_aggregation(:composed_of)
127
+ end
128
+ end
data/test/all.sh CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/bin/sh
2
2
 
3
3
  if [ -z "$1" ]; then
4
- echo "Usage: $0 connections/<db_library>" 1>&2
4
+ echo "Usage: $0 <database>" 1>&2
5
5
  exit 1
6
6
  fi
7
7
 
8
- ruby -I $1 -e 'Dir.foreach(".") { |file| require file if file =~ /_test.rb$/ }'
8
+ ruby -I connections/native_$1 -e 'Dir["**/*_test.rb"].each { |path| require path }'
@@ -0,0 +1,33 @@
1
+ require 'abstract_unit'
2
+ require "#{File.dirname(__FILE__)}/../lib/active_record/schema"
3
+
4
+ if ActiveRecord::Base.connection.supports_migrations?
5
+
6
+ class ActiveRecordSchemaTest < Test::Unit::TestCase
7
+ self.use_transactional_fixtures = false
8
+
9
+ def setup
10
+ @connection = ActiveRecord::Base.connection
11
+ end
12
+
13
+ def teardown
14
+ @connection.drop_table :fruits rescue nil
15
+ end
16
+
17
+ def test_schema_define
18
+ ActiveRecord::Schema.define(:version => 7) do
19
+ create_table :fruits do |t|
20
+ t.column :color, :string
21
+ t.column :fruit_size, :string # NOTE: "size" is reserved in Oracle
22
+ t.column :texture, :string
23
+ t.column :flavor, :string
24
+ end
25
+ end
26
+
27
+ assert_nothing_raised { @connection.select_all "SELECT * FROM fruits" }
28
+ assert_nothing_raised { @connection.select_all "SELECT * FROM schema_info" }
29
+ assert_equal 7, @connection.select_one("SELECT version FROM schema_info")['version'].to_i
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,14 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/company'
3
+
4
+ class AssociationInheritanceReloadTest < Test::Unit::TestCase
5
+ fixtures :companies
6
+
7
+ def test_set_attributes
8
+ assert_equal ["errors.add_on_empty('name', \"can't be empty\")"], Firm.read_inheritable_attribute("validate"), "Second run"
9
+ # ActiveRecord::Base.reset_column_information_and_inheritable_attributes_for_all_subclasses
10
+ remove_subclass_of(ActiveRecord::Base)
11
+ load 'fixtures/company.rb'
12
+ assert_equal ["errors.add_on_empty('name', \"can't be empty\")"], Firm.read_inheritable_attribute("validate"), "Second run"
13
+ end
14
+ end
File without changes