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
@@ -0,0 +1,124 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/course'
3
+
4
+ class FirebirdMigrationTest < Test::Unit::TestCase
5
+ self.use_transactional_fixtures = false
6
+
7
+ def setup
8
+ # using Course connection for tests -- need a db that doesn't already have a BOOLEAN domain
9
+ @connection = Course.connection
10
+ @fireruby_connection = @connection.instance_variable_get(:@connection)
11
+ end
12
+
13
+ def teardown
14
+ @connection.drop_table :foo rescue nil
15
+ @connection.execute("DROP DOMAIN D_BOOLEAN") rescue nil
16
+ end
17
+
18
+ def test_create_table_with_custom_sequence_name
19
+ assert_nothing_raised do
20
+ @connection.create_table(:foo, :sequence => 'foo_custom_seq') do |f|
21
+ f.column :bar, :string
22
+ end
23
+ end
24
+ assert !sequence_exists?('foo_seq')
25
+ assert sequence_exists?('foo_custom_seq')
26
+
27
+ assert_nothing_raised { @connection.drop_table(:foo, :sequence => 'foo_custom_seq') }
28
+ assert !sequence_exists?('foo_custom_seq')
29
+ ensure
30
+ FireRuby::Generator.new('foo_custom_seq', @fireruby_connection).drop rescue nil
31
+ end
32
+
33
+ def test_create_table_without_sequence
34
+ assert_nothing_raised do
35
+ @connection.create_table(:foo, :sequence => false) do |f|
36
+ f.column :bar, :string
37
+ end
38
+ end
39
+ assert !sequence_exists?('foo_seq')
40
+ assert_nothing_raised { @connection.drop_table :foo }
41
+
42
+ assert_nothing_raised do
43
+ @connection.create_table(:foo, :id => false) do |f|
44
+ f.column :bar, :string
45
+ end
46
+ end
47
+ assert !sequence_exists?('foo_seq')
48
+ assert_nothing_raised { @connection.drop_table :foo }
49
+ end
50
+
51
+ def test_create_table_with_boolean_column
52
+ assert !boolean_domain_exists?
53
+ assert_nothing_raised do
54
+ @connection.create_table :foo do |f|
55
+ f.column :bar, :string
56
+ f.column :baz, :boolean
57
+ end
58
+ end
59
+ assert boolean_domain_exists?
60
+ end
61
+
62
+ def test_add_boolean_column
63
+ assert !boolean_domain_exists?
64
+ @connection.create_table :foo do |f|
65
+ f.column :bar, :string
66
+ end
67
+
68
+ assert_nothing_raised { @connection.add_column :foo, :baz, :boolean }
69
+ assert boolean_domain_exists?
70
+ assert_equal :boolean, @connection.columns(:foo).find { |c| c.name == "baz" }.type
71
+ end
72
+
73
+ def test_change_column_to_boolean
74
+ assert !boolean_domain_exists?
75
+ # Manually create table with a SMALLINT column, which can be changed to a BOOLEAN
76
+ @connection.execute "CREATE TABLE foo (bar SMALLINT)"
77
+ assert_equal :integer, @connection.columns(:foo).find { |c| c.name == "bar" }.type
78
+
79
+ assert_nothing_raised { @connection.change_column :foo, :bar, :boolean }
80
+ assert boolean_domain_exists?
81
+ assert_equal :boolean, @connection.columns(:foo).find { |c| c.name == "bar" }.type
82
+ end
83
+
84
+ def test_rename_table_with_data_and_index
85
+ @connection.create_table :foo do |f|
86
+ f.column :baz, :string, :limit => 50
87
+ end
88
+ 100.times { |i| @connection.execute "INSERT INTO foo VALUES (GEN_ID(foo_seq, 1), 'record #{i+1}')" }
89
+ @connection.add_index :foo, :baz
90
+
91
+ assert_nothing_raised { @connection.rename_table :foo, :bar }
92
+ assert !@connection.tables.include?("foo")
93
+ assert @connection.tables.include?("bar")
94
+ assert_equal "index_bar_on_baz", @connection.indexes("bar").first.name
95
+ assert_equal 100, FireRuby::Generator.new("bar_seq", @fireruby_connection).last
96
+ assert_equal 100, @connection.select_one("SELECT COUNT(*) FROM bar")["count"]
97
+ ensure
98
+ @connection.drop_table :bar rescue nil
99
+ end
100
+
101
+ def test_renaming_table_with_fk_constraint_raises_error
102
+ @connection.create_table :parent do |p|
103
+ p.column :name, :string
104
+ end
105
+ @connection.create_table :child do |c|
106
+ c.column :parent_id, :integer
107
+ end
108
+ @connection.execute "ALTER TABLE child ADD CONSTRAINT fk_child_parent FOREIGN KEY(parent_id) REFERENCES parent(id)"
109
+ assert_raise(ActiveRecord::ActiveRecordError) { @connection.rename_table :child, :descendant }
110
+ ensure
111
+ @connection.drop_table :child rescue nil
112
+ @connection.drop_table :descendant rescue nil
113
+ @connection.drop_table :parent rescue nil
114
+ end
115
+
116
+ private
117
+ def boolean_domain_exists?
118
+ !@connection.select_one("SELECT 1 FROM rdb$fields WHERE rdb$field_name = 'D_BOOLEAN'").nil?
119
+ end
120
+
121
+ def sequence_exists?(sequence_name)
122
+ FireRuby::Generator.exists?(sequence_name, @fireruby_connection)
123
+ end
124
+ end
@@ -0,0 +1,95 @@
1
+ require 'abstract_unit'
2
+
3
+ class Mixin < ActiveRecord::Base
4
+ end
5
+
6
+ # Let us control what Time.now returns for the TouchTest suite
7
+ class Time
8
+ @@forced_now_time = nil
9
+ cattr_accessor :forced_now_time
10
+
11
+ class << self
12
+ def now_with_forcing
13
+ if @@forced_now_time
14
+ @@forced_now_time
15
+ else
16
+ now_without_forcing
17
+ end
18
+ end
19
+ alias_method_chain :now, :forcing
20
+ end
21
+ end
22
+
23
+
24
+ class TouchTest < Test::Unit::TestCase
25
+ fixtures :mixins
26
+
27
+ def setup
28
+ Time.forced_now_time = Time.now
29
+ end
30
+
31
+ def teardown
32
+ Time.forced_now_time = nil
33
+ end
34
+
35
+ def test_time_mocking
36
+ five_minutes_ago = 5.minutes.ago
37
+ Time.forced_now_time = five_minutes_ago
38
+ assert_equal five_minutes_ago, Time.now
39
+
40
+ Time.forced_now_time = nil
41
+ assert_not_equal five_minutes_ago, Time.now
42
+ end
43
+
44
+ def test_update
45
+ stamped = Mixin.new
46
+
47
+ assert_nil stamped.updated_at
48
+ assert_nil stamped.created_at
49
+ stamped.save
50
+ assert_equal Time.now, stamped.updated_at
51
+ assert_equal Time.now, stamped.created_at
52
+ end
53
+
54
+ def test_create
55
+ obj = Mixin.create
56
+ assert_equal Time.now, obj.updated_at
57
+ assert_equal Time.now, obj.created_at
58
+ end
59
+
60
+ def test_many_updates
61
+ stamped = Mixin.new
62
+
63
+ assert_nil stamped.updated_at
64
+ assert_nil stamped.created_at
65
+ stamped.save
66
+ assert_equal Time.now, stamped.created_at
67
+ assert_equal Time.now, stamped.updated_at
68
+
69
+ old_updated_at = stamped.updated_at
70
+
71
+ Time.forced_now_time = 5.minutes.from_now
72
+ stamped.save
73
+
74
+ assert_equal Time.now, stamped.updated_at
75
+ assert_equal old_updated_at, stamped.created_at
76
+ end
77
+
78
+ def test_create_turned_off
79
+ Mixin.record_timestamps = false
80
+
81
+ mixin = Mixin.new
82
+
83
+ assert_nil mixin.updated_at
84
+ mixin.save
85
+ assert_nil mixin.updated_at
86
+
87
+ # Make sure Mixin.record_timestamps gets reset, even if this test fails,
88
+ # so that other tests do not fail because Mixin.record_timestamps == false
89
+ rescue Exception => e
90
+ raise e
91
+ ensure
92
+ Mixin.record_timestamps = true
93
+ end
94
+
95
+ end
data/test/modules_test.rb CHANGED
@@ -1,21 +1,34 @@
1
1
  require 'abstract_unit'
2
- # require File.dirname(__FILE__) + '/../dev-utils/eval_debugger'
3
2
  require 'fixtures/company_in_module'
4
3
 
5
4
  class ModulesTest < Test::Unit::TestCase
6
- def setup
7
- create_fixtures "accounts"
8
- create_fixtures "companies"
9
- end
5
+ fixtures :accounts, :companies, :projects, :developers
10
6
 
11
7
  def test_module_spanning_associations
12
- assert MyApplication::Business::Firm.find_first.has_clients?, "Firm should have clients"
13
- firm = MyApplication::Business::Firm.find_first
8
+ firm = MyApplication::Business::Firm.find(:first)
9
+ assert !firm.clients.empty?, "Firm should have clients"
14
10
  assert_nil firm.class.table_name.match('::'), "Firm shouldn't have the module appear in its table name"
15
- assert_equal 2, firm.clients_count, "Firm should have two clients"
11
+ end
12
+
13
+ def test_module_spanning_has_and_belongs_to_many_associations
14
+ project = MyApplication::Business::Project.find(:first)
15
+ project.developers << MyApplication::Business::Developer.create("name" => "John")
16
+ assert "John", project.developers.last.name
16
17
  end
17
18
 
18
19
  def test_associations_spanning_cross_modules
19
- assert MyApplication::Billing::Account.find(1).has_firm?, "37signals account should be able to backtrack"
20
+ account = MyApplication::Billing::Account.find(:first, :order => 'id')
21
+ assert_kind_of MyApplication::Business::Firm, account.firm
22
+ assert_kind_of MyApplication::Billing::Firm, account.qualified_billing_firm
23
+ assert_kind_of MyApplication::Billing::Firm, account.unqualified_billing_firm
24
+ assert_kind_of MyApplication::Billing::Nested::Firm, account.nested_qualified_billing_firm
25
+ assert_kind_of MyApplication::Billing::Nested::Firm, account.nested_unqualified_billing_firm
20
26
  end
21
- end
27
+
28
+ def test_find_account_and_include_company
29
+ account = MyApplication::Billing::Account.find(1, :include => :firm)
30
+ assert_kind_of MyApplication::Business::Firm, account.instance_variable_get('@firm')
31
+ assert_kind_of MyApplication::Business::Firm, account.firm
32
+ end
33
+
34
+ end
@@ -1,8 +1,12 @@
1
1
  require 'abstract_unit'
2
- require 'fixtures/course'
3
2
  require 'fixtures/entrant'
4
3
 
4
+ # So we can test whether Course.connection survives a reload.
5
+ require_dependency 'fixtures/course'
6
+
5
7
  class MultipleDbTest < Test::Unit::TestCase
8
+ self.use_transactional_fixtures = false
9
+
6
10
  def setup
7
11
  @courses = create_fixtures("courses") { Course.retrieve_connection }
8
12
  @entrants = create_fixtures("entrants")
@@ -35,12 +39,22 @@ class MultipleDbTest < Test::Unit::TestCase
35
39
 
36
40
  def test_associations
37
41
  c1 = Course.find(1)
38
- assert_equal 2, c1.entrants_count
42
+ assert_equal 2, c1.entrants.count
39
43
  e1 = Entrant.find(1)
40
44
  assert_equal e1.course.id, c1.id
41
45
  c2 = Course.find(2)
42
- assert_equal 1, c2.entrants_count
46
+ assert_equal 1, c2.entrants.count
43
47
  e3 = Entrant.find(3)
44
48
  assert_equal e3.course.id, c2.id
45
49
  end
50
+
51
+ def test_course_connection_should_survive_dependency_reload
52
+ assert Course.connection
53
+
54
+ Dependencies.clear
55
+ Object.send(:remove_const, :Course)
56
+ require_dependency 'fixtures/course'
57
+
58
+ assert Course.connection
59
+ end
46
60
  end
data/test/pk_test.rb CHANGED
@@ -1,57 +1,101 @@
1
- require 'abstract_unit'
1
+ require "#{File.dirname(__FILE__)}/abstract_unit"
2
2
  require 'fixtures/topic'
3
+ require 'fixtures/reply'
3
4
  require 'fixtures/subscriber'
4
5
  require 'fixtures/movie'
6
+ require 'fixtures/keyboard'
7
+ require 'fixtures/mixed_case_monkey'
5
8
 
6
9
  class PrimaryKeysTest < Test::Unit::TestCase
7
- def setup
8
- @topics = create_fixtures "topics"
9
- @subscribers = create_fixtures "subscribers"
10
- @movies = create_fixtures "movies"
11
- end
10
+ fixtures :topics, :subscribers, :movies, :mixed_case_monkeys
12
11
 
13
12
  def test_integer_key
14
13
  topic = Topic.find(1)
15
- assert_equal(@topics["first"]["author_name"], topic.author_name)
14
+ assert_equal(topics(:first).author_name, topic.author_name)
16
15
  topic = Topic.find(2)
17
- assert_equal(@topics["second"]["author_name"], topic.author_name)
16
+ assert_equal(topics(:second).author_name, topic.author_name)
18
17
 
19
18
  topic = Topic.new
20
19
  topic.title = "New Topic"
21
- topic.save
20
+ assert_equal(nil, topic.id)
21
+ assert_nothing_raised { topic.save! }
22
22
  id = topic.id
23
23
 
24
24
  topicReloaded = Topic.find(id)
25
25
  assert_equal("New Topic", topicReloaded.title)
26
26
  end
27
27
 
28
+ def test_customized_primary_key_auto_assigns_on_save
29
+ Keyboard.delete_all
30
+ keyboard = Keyboard.new(:name => 'HHKB')
31
+ assert_nothing_raised { keyboard.save! }
32
+ assert_equal keyboard.id, Keyboard.find_by_name('HHKB').id
33
+ end
34
+
35
+ def test_customized_primary_key_can_be_get_before_saving
36
+ keyboard = Keyboard.new
37
+ assert_nil keyboard.id
38
+ assert_nothing_raised { assert_nil keyboard.key_number }
39
+ end
40
+
41
+ def test_customized_string_primary_key_settable_before_save
42
+ subscriber = Subscriber.new
43
+ assert_nothing_raised { subscriber.id = 'webster123' }
44
+ assert_equal 'webster123', subscriber.id
45
+ assert_equal 'webster123', subscriber.nick
46
+ end
47
+
28
48
  def test_string_key
29
- subscriber = Subscriber.find(@subscribers["first"]["nick"])
30
- assert_equal(@subscribers["first"]["name"], subscriber.name)
31
- subscriber = Subscriber.find(@subscribers["second"]["nick"])
32
- assert_equal(@subscribers["second"]["name"], subscriber.name)
49
+ subscriber = Subscriber.find(subscribers(:first).nick)
50
+ assert_equal(subscribers(:first).name, subscriber.name)
51
+ subscriber = Subscriber.find(subscribers(:second).nick)
52
+ assert_equal(subscribers(:second).name, subscriber.name)
33
53
 
34
54
  subscriber = Subscriber.new
35
55
  subscriber.id = "jdoe"
56
+ assert_equal("jdoe", subscriber.id)
36
57
  subscriber.name = "John Doe"
37
- subscriber.save
58
+ assert_nothing_raised { subscriber.save! }
59
+ assert_equal("jdoe", subscriber.id)
38
60
 
39
61
  subscriberReloaded = Subscriber.find("jdoe")
40
62
  assert_equal("John Doe", subscriberReloaded.name)
41
63
  end
42
64
 
43
65
  def test_find_with_more_than_one_string_key
44
- assert_equal 2, Subscriber.find(@subscribers["first"]["nick"], @subscribers["second"]["nick"]).length
66
+ assert_equal 2, Subscriber.find(subscribers(:first).nick, subscribers(:second).nick).length
45
67
  end
46
68
 
47
69
  def test_primary_key_prefix
48
70
  ActiveRecord::Base.primary_key_prefix_type = :table_name
71
+ Topic.reset_primary_key
49
72
  assert_equal "topicid", Topic.primary_key
50
73
 
51
74
  ActiveRecord::Base.primary_key_prefix_type = :table_name_with_underscore
75
+ Topic.reset_primary_key
52
76
  assert_equal "topic_id", Topic.primary_key
53
77
 
54
78
  ActiveRecord::Base.primary_key_prefix_type = nil
79
+ Topic.reset_primary_key
55
80
  assert_equal "id", Topic.primary_key
56
81
  end
82
+
83
+ def test_delete_should_quote_pkey
84
+ assert_nothing_raised { MixedCaseMonkey.delete(1) }
85
+ end
86
+ def test_update_counters_should_quote_pkey_and_quote_counter_columns
87
+ assert_nothing_raised { MixedCaseMonkey.update_counters(1, :fleaCount => 99) }
88
+ end
89
+ def test_find_with_one_id_should_quote_pkey
90
+ assert_nothing_raised { MixedCaseMonkey.find(1) }
91
+ end
92
+ def test_find_with_multiple_ids_should_quote_pkey
93
+ assert_nothing_raised { MixedCaseMonkey.find([1,2]) }
94
+ end
95
+ def test_instance_update_should_quote_pkey
96
+ assert_nothing_raised { MixedCaseMonkey.find(1).save }
97
+ end
98
+ def test_instance_destroy_should_quote_pkey
99
+ assert_nothing_raised { MixedCaseMonkey.find(1).destroy }
100
+ end
57
101
  end
@@ -0,0 +1,104 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/topic'
3
+ require 'fixtures/reply'
4
+ require 'fixtures/task'
5
+ require 'fixtures/course'
6
+
7
+
8
+ class QueryCacheTest < Test::Unit::TestCase
9
+ fixtures :tasks, :topics
10
+
11
+ def test_find_queries
12
+ assert_queries(2) { Task.find(1); Task.find(1) }
13
+ end
14
+
15
+ def test_find_queries_with_cache
16
+ Task.cache do
17
+ assert_queries(1) { Task.find(1); Task.find(1) }
18
+ end
19
+ end
20
+
21
+ def test_count_queries_with_cache
22
+ Task.cache do
23
+ assert_queries(1) { Task.count; Task.count }
24
+ end
25
+ end
26
+
27
+ def test_query_cache_dups_results_correctly
28
+ Task.cache do
29
+ now = Time.now.utc
30
+ task = Task.find 1
31
+ assert_not_equal now, task.starting
32
+ task.starting = now
33
+ task.reload
34
+ assert_not_equal now, task.starting
35
+ end
36
+ end
37
+
38
+ def test_cache_is_flat
39
+ Task.cache do
40
+ Topic.columns # don't count this query
41
+ assert_queries(1) { Topic.find(1); Topic.find(1); }
42
+ end
43
+
44
+ ActiveRecord::Base.cache do
45
+ assert_queries(1) { Task.find(1); Task.find(1) }
46
+ end
47
+ end
48
+
49
+ def test_cache_does_not_wrap_string_results_in_arrays
50
+ Task.cache do
51
+ assert_instance_of String, Task.connection.select_value("SELECT count(*) AS count_all FROM tasks")
52
+ end
53
+ end
54
+ end
55
+
56
+ uses_mocha 'QueryCacheExpiryTest' do
57
+
58
+ class QueryCacheExpiryTest < Test::Unit::TestCase
59
+ fixtures :tasks
60
+
61
+ def test_find
62
+ Task.connection.expects(:clear_query_cache).times(1)
63
+
64
+ assert !Task.connection.query_cache_enabled
65
+ Task.cache do
66
+ assert Task.connection.query_cache_enabled
67
+ Task.find(1)
68
+
69
+ Task.uncached do
70
+ assert !Task.connection.query_cache_enabled
71
+ Task.find(1)
72
+ end
73
+
74
+ assert Task.connection.query_cache_enabled
75
+ end
76
+ assert !Task.connection.query_cache_enabled
77
+ end
78
+
79
+ def test_update
80
+ Task.connection.expects(:clear_query_cache).times(2)
81
+
82
+ Task.cache do
83
+ Task.find(1).save!
84
+ end
85
+ end
86
+
87
+ def test_destroy
88
+ Task.connection.expects(:clear_query_cache).times(2)
89
+
90
+ Task.cache do
91
+ Task.find(1).destroy
92
+ end
93
+ end
94
+
95
+ def test_insert
96
+ ActiveRecord::Base.connection.expects(:clear_query_cache).times(2)
97
+
98
+ Task.cache do
99
+ Task.create!
100
+ end
101
+ end
102
+ end
103
+
104
+ end
@@ -0,0 +1,107 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/post'
3
+ require 'fixtures/comment'
4
+ require 'fixtures/developer'
5
+ require 'fixtures/project'
6
+ require 'fixtures/reader'
7
+ require 'fixtures/person'
8
+
9
+ # Dummy class methods to test implicit association scoping.
10
+ def Comment.foo() find :first end
11
+ def Project.foo() find :first end
12
+
13
+
14
+ class ReadOnlyTest < Test::Unit::TestCase
15
+ fixtures :posts, :comments, :developers, :projects, :developers_projects
16
+
17
+ def test_cant_save_readonly_record
18
+ dev = Developer.find(1)
19
+ assert !dev.readonly?
20
+
21
+ dev.readonly!
22
+ assert dev.readonly?
23
+
24
+ assert_nothing_raised do
25
+ dev.name = 'Luscious forbidden fruit.'
26
+ assert !dev.save
27
+ dev.name = 'Forbidden.'
28
+ end
29
+ assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save }
30
+ assert_raise(ActiveRecord::ReadOnlyRecord) { dev.save! }
31
+ end
32
+
33
+
34
+ def test_find_with_readonly_option
35
+ Developer.find(:all).each { |d| assert !d.readonly? }
36
+ Developer.find(:all, :readonly => false).each { |d| assert !d.readonly? }
37
+ Developer.find(:all, :readonly => true).each { |d| assert d.readonly? }
38
+ end
39
+
40
+
41
+ def test_find_with_joins_option_implies_readonly
42
+ # Blank joins don't count.
43
+ Developer.find(:all, :joins => ' ').each { |d| assert !d.readonly? }
44
+ Developer.find(:all, :joins => ' ', :readonly => false).each { |d| assert !d.readonly? }
45
+
46
+ # Others do.
47
+ Developer.find(:all, :joins => ', projects').each { |d| assert d.readonly? }
48
+ Developer.find(:all, :joins => ', projects', :readonly => false).each { |d| assert !d.readonly? }
49
+ end
50
+
51
+
52
+ def test_habtm_find_readonly
53
+ dev = Developer.find(1)
54
+ assert !dev.projects.empty?
55
+ assert dev.projects.all?(&:readonly?)
56
+ assert dev.projects.find(:all).all?(&:readonly?)
57
+ assert dev.projects.find(:all, :readonly => true).all?(&:readonly?)
58
+ end
59
+
60
+ def test_has_many_find_readonly
61
+ post = Post.find(1)
62
+ assert !post.comments.empty?
63
+ assert !post.comments.any?(&:readonly?)
64
+ assert !post.comments.find(:all).any?(&:readonly?)
65
+ assert post.comments.find(:all, :readonly => true).all?(&:readonly?)
66
+ end
67
+
68
+ def test_has_many_with_through_is_not_implicitly_marked_readonly
69
+ assert people = Post.find(1).people
70
+ assert !people.any?(&:readonly?)
71
+ end
72
+
73
+ def test_readonly_scoping
74
+ Post.with_scope(:find => { :conditions => '1=1' }) do
75
+ assert !Post.find(1).readonly?
76
+ assert Post.find(1, :readonly => true).readonly?
77
+ assert !Post.find(1, :readonly => false).readonly?
78
+ end
79
+
80
+ Post.with_scope(:find => { :joins => ' ' }) do
81
+ assert !Post.find(1).readonly?
82
+ assert Post.find(1, :readonly => true).readonly?
83
+ assert !Post.find(1, :readonly => false).readonly?
84
+ end
85
+
86
+ # Oracle barfs on this because the join includes unqualified and
87
+ # conflicting column names
88
+ unless current_adapter?(:OracleAdapter)
89
+ Post.with_scope(:find => { :joins => ', developers' }) do
90
+ assert Post.find(1).readonly?
91
+ assert Post.find(1, :readonly => true).readonly?
92
+ assert !Post.find(1, :readonly => false).readonly?
93
+ end
94
+ end
95
+
96
+ Post.with_scope(:find => { :readonly => true }) do
97
+ assert Post.find(1).readonly?
98
+ assert Post.find(1, :readonly => true).readonly?
99
+ assert !Post.find(1, :readonly => false).readonly?
100
+ end
101
+ end
102
+
103
+ def test_association_collection_method_missing_scoping_not_readonly
104
+ assert !Developer.find(1).projects.foo.readonly?
105
+ assert !Post.find(1).comments.foo.readonly?
106
+ end
107
+ end