activerecord_authorails 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. data/CHANGELOG +3043 -0
  2. data/README +360 -0
  3. data/RUNNING_UNIT_TESTS +64 -0
  4. data/Rakefile +226 -0
  5. data/examples/associations.png +0 -0
  6. data/examples/associations.rb +87 -0
  7. data/examples/shared_setup.rb +15 -0
  8. data/examples/validation.rb +85 -0
  9. data/install.rb +30 -0
  10. data/lib/active_record.rb +85 -0
  11. data/lib/active_record/acts/list.rb +244 -0
  12. data/lib/active_record/acts/nested_set.rb +211 -0
  13. data/lib/active_record/acts/tree.rb +89 -0
  14. data/lib/active_record/aggregations.rb +191 -0
  15. data/lib/active_record/associations.rb +1637 -0
  16. data/lib/active_record/associations/association_collection.rb +190 -0
  17. data/lib/active_record/associations/association_proxy.rb +158 -0
  18. data/lib/active_record/associations/belongs_to_association.rb +56 -0
  19. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
  20. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +169 -0
  21. data/lib/active_record/associations/has_many_association.rb +210 -0
  22. data/lib/active_record/associations/has_many_through_association.rb +247 -0
  23. data/lib/active_record/associations/has_one_association.rb +80 -0
  24. data/lib/active_record/attribute_methods.rb +75 -0
  25. data/lib/active_record/base.rb +2164 -0
  26. data/lib/active_record/calculations.rb +270 -0
  27. data/lib/active_record/callbacks.rb +367 -0
  28. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +279 -0
  29. data/lib/active_record/connection_adapters/abstract/database_statements.rb +130 -0
  30. data/lib/active_record/connection_adapters/abstract/quoting.rb +58 -0
  31. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +343 -0
  32. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +310 -0
  33. data/lib/active_record/connection_adapters/abstract_adapter.rb +161 -0
  34. data/lib/active_record/connection_adapters/db2_adapter.rb +228 -0
  35. data/lib/active_record/connection_adapters/firebird_adapter.rb +728 -0
  36. data/lib/active_record/connection_adapters/frontbase_adapter.rb +861 -0
  37. data/lib/active_record/connection_adapters/mysql_adapter.rb +414 -0
  38. data/lib/active_record/connection_adapters/openbase_adapter.rb +350 -0
  39. data/lib/active_record/connection_adapters/oracle_adapter.rb +689 -0
  40. data/lib/active_record/connection_adapters/postgresql_adapter.rb +584 -0
  41. data/lib/active_record/connection_adapters/sqlite_adapter.rb +407 -0
  42. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +591 -0
  43. data/lib/active_record/connection_adapters/sybase_adapter.rb +662 -0
  44. data/lib/active_record/deprecated_associations.rb +104 -0
  45. data/lib/active_record/deprecated_finders.rb +44 -0
  46. data/lib/active_record/fixtures.rb +628 -0
  47. data/lib/active_record/locking/optimistic.rb +106 -0
  48. data/lib/active_record/locking/pessimistic.rb +77 -0
  49. data/lib/active_record/migration.rb +394 -0
  50. data/lib/active_record/observer.rb +178 -0
  51. data/lib/active_record/query_cache.rb +64 -0
  52. data/lib/active_record/reflection.rb +222 -0
  53. data/lib/active_record/schema.rb +58 -0
  54. data/lib/active_record/schema_dumper.rb +149 -0
  55. data/lib/active_record/timestamp.rb +51 -0
  56. data/lib/active_record/transactions.rb +136 -0
  57. data/lib/active_record/validations.rb +843 -0
  58. data/lib/active_record/vendor/db2.rb +362 -0
  59. data/lib/active_record/vendor/mysql.rb +1214 -0
  60. data/lib/active_record/vendor/simple.rb +693 -0
  61. data/lib/active_record/version.rb +9 -0
  62. data/lib/active_record/wrappers/yaml_wrapper.rb +15 -0
  63. data/lib/active_record/wrappings.rb +58 -0
  64. data/lib/active_record/xml_serialization.rb +308 -0
  65. data/test/aaa_create_tables_test.rb +59 -0
  66. data/test/abstract_unit.rb +77 -0
  67. data/test/active_schema_test_mysql.rb +31 -0
  68. data/test/adapter_test.rb +87 -0
  69. data/test/adapter_test_sqlserver.rb +81 -0
  70. data/test/aggregations_test.rb +95 -0
  71. data/test/all.sh +8 -0
  72. data/test/ar_schema_test.rb +33 -0
  73. data/test/association_inheritance_reload.rb +14 -0
  74. data/test/associations/callbacks_test.rb +126 -0
  75. data/test/associations/cascaded_eager_loading_test.rb +138 -0
  76. data/test/associations/eager_test.rb +393 -0
  77. data/test/associations/extension_test.rb +42 -0
  78. data/test/associations/join_model_test.rb +497 -0
  79. data/test/associations_test.rb +1809 -0
  80. data/test/attribute_methods_test.rb +49 -0
  81. data/test/base_test.rb +1586 -0
  82. data/test/binary_test.rb +37 -0
  83. data/test/calculations_test.rb +219 -0
  84. data/test/callbacks_test.rb +377 -0
  85. data/test/class_inheritable_attributes_test.rb +32 -0
  86. data/test/column_alias_test.rb +17 -0
  87. data/test/connection_test_firebird.rb +8 -0
  88. data/test/connections/native_db2/connection.rb +25 -0
  89. data/test/connections/native_firebird/connection.rb +26 -0
  90. data/test/connections/native_frontbase/connection.rb +27 -0
  91. data/test/connections/native_mysql/connection.rb +24 -0
  92. data/test/connections/native_openbase/connection.rb +21 -0
  93. data/test/connections/native_oracle/connection.rb +27 -0
  94. data/test/connections/native_postgresql/connection.rb +23 -0
  95. data/test/connections/native_sqlite/connection.rb +34 -0
  96. data/test/connections/native_sqlite3/connection.rb +34 -0
  97. data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
  98. data/test/connections/native_sqlserver/connection.rb +23 -0
  99. data/test/connections/native_sqlserver_odbc/connection.rb +25 -0
  100. data/test/connections/native_sybase/connection.rb +23 -0
  101. data/test/copy_table_sqlite.rb +64 -0
  102. data/test/datatype_test_postgresql.rb +52 -0
  103. data/test/default_test_firebird.rb +16 -0
  104. data/test/defaults_test.rb +60 -0
  105. data/test/deprecated_associations_test.rb +396 -0
  106. data/test/deprecated_finder_test.rb +151 -0
  107. data/test/empty_date_time_test.rb +25 -0
  108. data/test/finder_test.rb +504 -0
  109. data/test/fixtures/accounts.yml +28 -0
  110. data/test/fixtures/author.rb +99 -0
  111. data/test/fixtures/author_favorites.yml +4 -0
  112. data/test/fixtures/authors.yml +7 -0
  113. data/test/fixtures/auto_id.rb +4 -0
  114. data/test/fixtures/bad_fixtures/attr_with_numeric_first_char +1 -0
  115. data/test/fixtures/bad_fixtures/attr_with_spaces +1 -0
  116. data/test/fixtures/bad_fixtures/blank_line +3 -0
  117. data/test/fixtures/bad_fixtures/duplicate_attributes +3 -0
  118. data/test/fixtures/bad_fixtures/missing_value +1 -0
  119. data/test/fixtures/binary.rb +2 -0
  120. data/test/fixtures/categories.yml +14 -0
  121. data/test/fixtures/categories/special_categories.yml +9 -0
  122. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  123. data/test/fixtures/categories_ordered.yml +7 -0
  124. data/test/fixtures/categories_posts.yml +23 -0
  125. data/test/fixtures/categorization.rb +5 -0
  126. data/test/fixtures/categorizations.yml +17 -0
  127. data/test/fixtures/category.rb +20 -0
  128. data/test/fixtures/column_name.rb +3 -0
  129. data/test/fixtures/comment.rb +23 -0
  130. data/test/fixtures/comments.yml +59 -0
  131. data/test/fixtures/companies.yml +55 -0
  132. data/test/fixtures/company.rb +107 -0
  133. data/test/fixtures/company_in_module.rb +59 -0
  134. data/test/fixtures/computer.rb +3 -0
  135. data/test/fixtures/computers.yml +4 -0
  136. data/test/fixtures/course.rb +3 -0
  137. data/test/fixtures/courses.yml +7 -0
  138. data/test/fixtures/customer.rb +55 -0
  139. data/test/fixtures/customers.yml +17 -0
  140. data/test/fixtures/db_definitions/db2.drop.sql +32 -0
  141. data/test/fixtures/db_definitions/db2.sql +231 -0
  142. data/test/fixtures/db_definitions/db22.drop.sql +2 -0
  143. data/test/fixtures/db_definitions/db22.sql +5 -0
  144. data/test/fixtures/db_definitions/firebird.drop.sql +63 -0
  145. data/test/fixtures/db_definitions/firebird.sql +304 -0
  146. data/test/fixtures/db_definitions/firebird2.drop.sql +2 -0
  147. data/test/fixtures/db_definitions/firebird2.sql +6 -0
  148. data/test/fixtures/db_definitions/frontbase.drop.sql +32 -0
  149. data/test/fixtures/db_definitions/frontbase.sql +268 -0
  150. data/test/fixtures/db_definitions/frontbase2.drop.sql +1 -0
  151. data/test/fixtures/db_definitions/frontbase2.sql +4 -0
  152. data/test/fixtures/db_definitions/mysql.drop.sql +32 -0
  153. data/test/fixtures/db_definitions/mysql.sql +234 -0
  154. data/test/fixtures/db_definitions/mysql2.drop.sql +2 -0
  155. data/test/fixtures/db_definitions/mysql2.sql +5 -0
  156. data/test/fixtures/db_definitions/openbase.drop.sql +2 -0
  157. data/test/fixtures/db_definitions/openbase.sql +302 -0
  158. data/test/fixtures/db_definitions/openbase2.drop.sql +2 -0
  159. data/test/fixtures/db_definitions/openbase2.sql +7 -0
  160. data/test/fixtures/db_definitions/oracle.drop.sql +65 -0
  161. data/test/fixtures/db_definitions/oracle.sql +325 -0
  162. data/test/fixtures/db_definitions/oracle2.drop.sql +2 -0
  163. data/test/fixtures/db_definitions/oracle2.sql +6 -0
  164. data/test/fixtures/db_definitions/postgresql.drop.sql +37 -0
  165. data/test/fixtures/db_definitions/postgresql.sql +263 -0
  166. data/test/fixtures/db_definitions/postgresql2.drop.sql +2 -0
  167. data/test/fixtures/db_definitions/postgresql2.sql +5 -0
  168. data/test/fixtures/db_definitions/schema.rb +60 -0
  169. data/test/fixtures/db_definitions/sqlite.drop.sql +32 -0
  170. data/test/fixtures/db_definitions/sqlite.sql +215 -0
  171. data/test/fixtures/db_definitions/sqlite2.drop.sql +2 -0
  172. data/test/fixtures/db_definitions/sqlite2.sql +5 -0
  173. data/test/fixtures/db_definitions/sqlserver.drop.sql +34 -0
  174. data/test/fixtures/db_definitions/sqlserver.sql +243 -0
  175. data/test/fixtures/db_definitions/sqlserver2.drop.sql +2 -0
  176. data/test/fixtures/db_definitions/sqlserver2.sql +5 -0
  177. data/test/fixtures/db_definitions/sybase.drop.sql +34 -0
  178. data/test/fixtures/db_definitions/sybase.sql +218 -0
  179. data/test/fixtures/db_definitions/sybase2.drop.sql +4 -0
  180. data/test/fixtures/db_definitions/sybase2.sql +5 -0
  181. data/test/fixtures/default.rb +2 -0
  182. data/test/fixtures/developer.rb +52 -0
  183. data/test/fixtures/developers.yml +21 -0
  184. data/test/fixtures/developers_projects.yml +17 -0
  185. data/test/fixtures/developers_projects/david_action_controller +3 -0
  186. data/test/fixtures/developers_projects/david_active_record +3 -0
  187. data/test/fixtures/developers_projects/jamis_active_record +2 -0
  188. data/test/fixtures/edge.rb +5 -0
  189. data/test/fixtures/edges.yml +6 -0
  190. data/test/fixtures/entrant.rb +3 -0
  191. data/test/fixtures/entrants.yml +14 -0
  192. data/test/fixtures/fk_test_has_fk.yml +3 -0
  193. data/test/fixtures/fk_test_has_pk.yml +2 -0
  194. data/test/fixtures/flowers.jpg +0 -0
  195. data/test/fixtures/funny_jokes.yml +10 -0
  196. data/test/fixtures/joke.rb +6 -0
  197. data/test/fixtures/keyboard.rb +3 -0
  198. data/test/fixtures/legacy_thing.rb +3 -0
  199. data/test/fixtures/legacy_things.yml +3 -0
  200. data/test/fixtures/migrations/1_people_have_last_names.rb +9 -0
  201. data/test/fixtures/migrations/2_we_need_reminders.rb +12 -0
  202. data/test/fixtures/migrations/3_innocent_jointable.rb +12 -0
  203. data/test/fixtures/migrations_with_decimal/1_give_me_big_numbers.rb +15 -0
  204. data/test/fixtures/migrations_with_duplicate/1_people_have_last_names.rb +9 -0
  205. data/test/fixtures/migrations_with_duplicate/2_we_need_reminders.rb +12 -0
  206. data/test/fixtures/migrations_with_duplicate/3_foo.rb +7 -0
  207. data/test/fixtures/migrations_with_duplicate/3_innocent_jointable.rb +12 -0
  208. data/test/fixtures/migrations_with_missing_versions/1000_people_have_middle_names.rb +9 -0
  209. data/test/fixtures/migrations_with_missing_versions/1_people_have_last_names.rb +9 -0
  210. data/test/fixtures/migrations_with_missing_versions/3_we_need_reminders.rb +12 -0
  211. data/test/fixtures/migrations_with_missing_versions/4_innocent_jointable.rb +12 -0
  212. data/test/fixtures/mixed_case_monkey.rb +3 -0
  213. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  214. data/test/fixtures/mixin.rb +63 -0
  215. data/test/fixtures/mixins.yml +127 -0
  216. data/test/fixtures/movie.rb +5 -0
  217. data/test/fixtures/movies.yml +7 -0
  218. data/test/fixtures/naked/csv/accounts.csv +1 -0
  219. data/test/fixtures/naked/yml/accounts.yml +1 -0
  220. data/test/fixtures/naked/yml/companies.yml +1 -0
  221. data/test/fixtures/naked/yml/courses.yml +1 -0
  222. data/test/fixtures/order.rb +4 -0
  223. data/test/fixtures/people.yml +3 -0
  224. data/test/fixtures/person.rb +4 -0
  225. data/test/fixtures/post.rb +58 -0
  226. data/test/fixtures/posts.yml +48 -0
  227. data/test/fixtures/project.rb +27 -0
  228. data/test/fixtures/projects.yml +7 -0
  229. data/test/fixtures/reader.rb +4 -0
  230. data/test/fixtures/readers.yml +4 -0
  231. data/test/fixtures/reply.rb +37 -0
  232. data/test/fixtures/subject.rb +4 -0
  233. data/test/fixtures/subscriber.rb +6 -0
  234. data/test/fixtures/subscribers/first +2 -0
  235. data/test/fixtures/subscribers/second +2 -0
  236. data/test/fixtures/tag.rb +7 -0
  237. data/test/fixtures/tagging.rb +6 -0
  238. data/test/fixtures/taggings.yml +18 -0
  239. data/test/fixtures/tags.yml +7 -0
  240. data/test/fixtures/task.rb +3 -0
  241. data/test/fixtures/tasks.yml +7 -0
  242. data/test/fixtures/topic.rb +25 -0
  243. data/test/fixtures/topics.yml +22 -0
  244. data/test/fixtures/vertex.rb +9 -0
  245. data/test/fixtures/vertices.yml +4 -0
  246. data/test/fixtures_test.rb +401 -0
  247. data/test/inheritance_test.rb +205 -0
  248. data/test/lifecycle_test.rb +137 -0
  249. data/test/locking_test.rb +190 -0
  250. data/test/method_scoping_test.rb +416 -0
  251. data/test/migration_test.rb +768 -0
  252. data/test/migration_test_firebird.rb +124 -0
  253. data/test/mixin_nested_set_test.rb +196 -0
  254. data/test/mixin_test.rb +550 -0
  255. data/test/modules_test.rb +34 -0
  256. data/test/multiple_db_test.rb +60 -0
  257. data/test/pk_test.rb +104 -0
  258. data/test/readonly_test.rb +107 -0
  259. data/test/reflection_test.rb +159 -0
  260. data/test/schema_authorization_test_postgresql.rb +75 -0
  261. data/test/schema_dumper_test.rb +96 -0
  262. data/test/schema_test_postgresql.rb +64 -0
  263. data/test/synonym_test_oracle.rb +17 -0
  264. data/test/table_name_test_sqlserver.rb +23 -0
  265. data/test/threaded_connections_test.rb +48 -0
  266. data/test/transactions_test.rb +230 -0
  267. data/test/unconnected_test.rb +32 -0
  268. data/test/validations_test.rb +1097 -0
  269. data/test/xml_serialization_test.rb +125 -0
  270. metadata +365 -0
@@ -0,0 +1,104 @@
1
+ module ActiveRecord
2
+ module Associations # :nodoc:
3
+ module ClassMethods
4
+ def deprecated_collection_count_method(collection_name)# :nodoc:
5
+ module_eval <<-"end_eval", __FILE__, __LINE__
6
+ def #{collection_name}_count(force_reload = false)
7
+ unless has_attribute?(:#{collection_name}_count)
8
+ ActiveSupport::Deprecation.warn :#{collection_name}_count
9
+ end
10
+ #{collection_name}.reload if force_reload
11
+ #{collection_name}.size
12
+ end
13
+ end_eval
14
+ end
15
+
16
+ def deprecated_add_association_relation(association_name)# :nodoc:
17
+ module_eval <<-"end_eval", __FILE__, __LINE__
18
+ def add_#{association_name}(*items)
19
+ #{association_name}.concat(items)
20
+ end
21
+ deprecate :add_#{association_name} => "use #{association_name}.concat instead"
22
+ end_eval
23
+ end
24
+
25
+ def deprecated_remove_association_relation(association_name)# :nodoc:
26
+ module_eval <<-"end_eval", __FILE__, __LINE__
27
+ def remove_#{association_name}(*items)
28
+ #{association_name}.delete(items)
29
+ end
30
+ deprecate :remove_#{association_name} => "use #{association_name}.delete instead"
31
+ end_eval
32
+ end
33
+
34
+ def deprecated_has_collection_method(collection_name)# :nodoc:
35
+ module_eval <<-"end_eval", __FILE__, __LINE__
36
+ def has_#{collection_name}?(force_reload = false)
37
+ !#{collection_name}(force_reload).empty?
38
+ end
39
+ deprecate :has_#{collection_name}? => "use !#{collection_name}.empty? instead"
40
+ end_eval
41
+ end
42
+
43
+ def deprecated_find_in_collection_method(collection_name)# :nodoc:
44
+ module_eval <<-"end_eval", __FILE__, __LINE__
45
+ def find_in_#{collection_name}(association_id)
46
+ #{collection_name}.find(association_id)
47
+ end
48
+ deprecate :find_in_#{collection_name} => "use #{collection_name}.find instead"
49
+ end_eval
50
+ end
51
+
52
+ def deprecated_find_all_in_collection_method(collection_name)# :nodoc:
53
+ module_eval <<-"end_eval", __FILE__, __LINE__
54
+ def find_all_in_#{collection_name}(runtime_conditions = nil, orderings = nil, limit = nil, joins = nil)
55
+ ActiveSupport::Deprecation.silence do
56
+ #{collection_name}.find_all(runtime_conditions, orderings, limit, joins)
57
+ end
58
+ end
59
+ deprecate :find_all_in_#{collection_name} => "use #{collection_name}.find(:all, ...) instead"
60
+ end_eval
61
+ end
62
+
63
+ def deprecated_collection_create_method(collection_name)# :nodoc:
64
+ module_eval <<-"end_eval", __FILE__, __LINE__
65
+ def create_in_#{collection_name}(attributes = {})
66
+ #{collection_name}.create(attributes)
67
+ end
68
+ deprecate :create_in_#{collection_name} => "use #{collection_name}.create instead"
69
+ end_eval
70
+ end
71
+
72
+ def deprecated_collection_build_method(collection_name)# :nodoc:
73
+ module_eval <<-"end_eval", __FILE__, __LINE__
74
+ def build_to_#{collection_name}(attributes = {})
75
+ #{collection_name}.build(attributes)
76
+ end
77
+ deprecate :build_to_#{collection_name} => "use #{collection_name}.build instead"
78
+ end_eval
79
+ end
80
+
81
+ def deprecated_association_comparison_method(association_name, association_class_name) # :nodoc:
82
+ module_eval <<-"end_eval", __FILE__, __LINE__
83
+ def #{association_name}?(comparison_object, force_reload = false)
84
+ if comparison_object.kind_of?(#{association_class_name})
85
+ #{association_name}(force_reload) == comparison_object
86
+ else
87
+ raise "Comparison object is a #{association_class_name}, should have been \#{comparison_object.class.name}"
88
+ end
89
+ end
90
+ deprecate :#{association_name}? => :==
91
+ end_eval
92
+ end
93
+
94
+ def deprecated_has_association_method(association_name) # :nodoc:
95
+ module_eval <<-"end_eval", __FILE__, __LINE__
96
+ def has_#{association_name}?(force_reload = false)
97
+ !#{association_name}(force_reload).nil?
98
+ end
99
+ deprecate :has_#{association_name}? => "use !#{association_name} insead"
100
+ end_eval
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,44 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ # This method is deprecated in favor of find with the :conditions option.
5
+ #
6
+ # Works like find, but the record matching +id+ must also meet the +conditions+.
7
+ # +RecordNotFound+ is raised if no record can be found matching the +id+ or meeting the condition.
8
+ # Example:
9
+ # Person.find_on_conditions 5, "first_name LIKE '%dav%' AND last_name = 'heinemeier'"
10
+ def find_on_conditions(ids, conditions) # :nodoc:
11
+ find(ids, :conditions => conditions)
12
+ end
13
+ deprecate :find_on_conditions => "use find(ids, :conditions => conditions)"
14
+
15
+ # This method is deprecated in favor of find(:first, options).
16
+ #
17
+ # Returns the object for the first record responding to the conditions in +conditions+,
18
+ # such as "group = 'master'". If more than one record is returned from the query, it's the first that'll
19
+ # be used to create the object. In such cases, it might be beneficial to also specify
20
+ # +orderings+, like "income DESC, name", to control exactly which record is to be used. Example:
21
+ # Employee.find_first "income > 50000", "income DESC, name"
22
+ def find_first(conditions = nil, orderings = nil, joins = nil) # :nodoc:
23
+ find(:first, :conditions => conditions, :order => orderings, :joins => joins)
24
+ end
25
+ deprecate :find_first => "use find(:first, ...)"
26
+
27
+ # This method is deprecated in favor of find(:all, options).
28
+ #
29
+ # Returns an array of all the objects that could be instantiated from the associated
30
+ # table in the database. The +conditions+ can be used to narrow the selection of objects (WHERE-part),
31
+ # such as by "color = 'red'", and arrangement of the selection can be done through +orderings+ (ORDER BY-part),
32
+ # such as by "last_name, first_name DESC". A maximum of returned objects and their offset can be specified in
33
+ # +limit+ with either just a single integer as the limit or as an array with the first element as the limit,
34
+ # the second as the offset. Examples:
35
+ # Project.find_all "category = 'accounts'", "last_accessed DESC", 15
36
+ # Project.find_all ["category = ?", category_name], "created ASC", [15, 20]
37
+ def find_all(conditions = nil, orderings = nil, limit = nil, joins = nil) # :nodoc:
38
+ limit, offset = limit.is_a?(Array) ? limit : [ limit, nil ]
39
+ find(:all, :conditions => conditions, :order => orderings, :joins => joins, :limit => limit, :offset => offset)
40
+ end
41
+ deprecate :find_all => "use find(:all, ...)"
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,628 @@
1
+ require 'erb'
2
+ require 'yaml'
3
+ require 'csv'
4
+
5
+ module YAML #:nodoc:
6
+ class Omap #:nodoc:
7
+ def keys; map { |k, v| k } end
8
+ def values; map { |k, v| v } end
9
+ end
10
+ end
11
+
12
+ class FixtureClassNotFound < ActiveRecord::ActiveRecordError #:nodoc:
13
+ end
14
+
15
+ # Fixtures are a way of organizing data that you want to test against; in short, sample data. They come in 3 flavours:
16
+ #
17
+ # 1. YAML fixtures
18
+ # 2. CSV fixtures
19
+ # 3. Single-file fixtures
20
+ #
21
+ # = YAML fixtures
22
+ #
23
+ # This type of fixture is in YAML format and the preferred default. YAML is a file format which describes data structures
24
+ # in a non-verbose, humanly-readable format. It ships with Ruby 1.8.1+.
25
+ #
26
+ # Unlike single-file fixtures, YAML fixtures are stored in a single file per model, which are placed in the directory appointed
27
+ # by <tt>Test::Unit::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
28
+ # put your files in <your-rails-app>/test/fixtures/). The fixture file ends with the .yml file extension (Rails example:
29
+ # "<your-rails-app>/test/fixtures/web_sites.yml"). The format of a YAML fixture file looks like this:
30
+ #
31
+ # rubyonrails:
32
+ # id: 1
33
+ # name: Ruby on Rails
34
+ # url: http://www.rubyonrails.org
35
+ #
36
+ # google:
37
+ # id: 2
38
+ # name: Google
39
+ # url: http://www.google.com
40
+ #
41
+ # This YAML fixture file includes two fixtures. Each YAML fixture (ie. record) is given a name and is followed by an
42
+ # indented list of key/value pairs in the "key: value" format. Records are separated by a blank line for your viewing
43
+ # pleasure.
44
+ #
45
+ # Note that YAML fixtures are unordered. If you want ordered fixtures, use the omap YAML type. See http://yaml.org/type/omap.html
46
+ # for the specification. You will need ordered fixtures when you have foreign key constraints on keys in the same table.
47
+ # This is commonly needed for tree structures. Example:
48
+ #
49
+ # --- !omap
50
+ # - parent:
51
+ # id: 1
52
+ # parent_id: NULL
53
+ # title: Parent
54
+ # - child:
55
+ # id: 2
56
+ # parent_id: 1
57
+ # title: Child
58
+ #
59
+ # = CSV fixtures
60
+ #
61
+ # Fixtures can also be kept in the Comma Separated Value format. Akin to YAML fixtures, CSV fixtures are stored
62
+ # in a single file, but instead end with the .csv file extension (Rails example: "<your-rails-app>/test/fixtures/web_sites.csv")
63
+ #
64
+ # The format of this type of fixture file is much more compact than the others, but also a little harder to read by us
65
+ # humans. The first line of the CSV file is a comma-separated list of field names. The rest of the file is then comprised
66
+ # of the actual data (1 per line). Here's an example:
67
+ #
68
+ # id, name, url
69
+ # 1, Ruby On Rails, http://www.rubyonrails.org
70
+ # 2, Google, http://www.google.com
71
+ #
72
+ # Should you have a piece of data with a comma character in it, you can place double quotes around that value. If you
73
+ # need to use a double quote character, you must escape it with another double quote.
74
+ #
75
+ # Another unique attribute of the CSV fixture is that it has *no* fixture name like the other two formats. Instead, the
76
+ # fixture names are automatically generated by deriving the class name of the fixture file and adding an incrementing
77
+ # number to the end. In our example, the 1st fixture would be called "web_site_1" and the 2nd one would be called
78
+ # "web_site_2".
79
+ #
80
+ # Most databases and spreadsheets support exporting to CSV format, so this is a great format for you to choose if you
81
+ # have existing data somewhere already.
82
+ #
83
+ # = Single-file fixtures
84
+ #
85
+ # This type of fixtures was the original format for Active Record that has since been deprecated in favor of the YAML and CSV formats.
86
+ # Fixtures for this format are created by placing text files in a sub-directory (with the name of the model) to the directory
87
+ # appointed by <tt>Test::Unit::TestCase.fixture_path=(path)</tt> (this is automatically configured for Rails, so you can just
88
+ # put your files in <your-rails-app>/test/fixtures/<your-model-name>/ -- like <your-rails-app>/test/fixtures/web_sites/ for the WebSite
89
+ # model).
90
+ #
91
+ # Each text file placed in this directory represents a "record". Usually these types of fixtures are named without
92
+ # extensions, but if you are on a Windows machine, you might consider adding .txt as the extension. Here's what the
93
+ # above example might look like:
94
+ #
95
+ # web_sites/google
96
+ # web_sites/yahoo.txt
97
+ # web_sites/ruby-on-rails
98
+ #
99
+ # The file format of a standard fixture is simple. Each line is a property (or column in db speak) and has the syntax
100
+ # of "name => value". Here's an example of the ruby-on-rails fixture above:
101
+ #
102
+ # id => 1
103
+ # name => Ruby on Rails
104
+ # url => http://www.rubyonrails.org
105
+ #
106
+ # = Using Fixtures
107
+ #
108
+ # Since fixtures are a testing construct, we use them in our unit and functional tests. There are two ways to use the
109
+ # fixtures, but first let's take a look at a sample unit test found:
110
+ #
111
+ # require 'web_site'
112
+ #
113
+ # class WebSiteTest < Test::Unit::TestCase
114
+ # def test_web_site_count
115
+ # assert_equal 2, WebSite.count
116
+ # end
117
+ # end
118
+ #
119
+ # As it stands, unless we pre-load the web_site table in our database with two records, this test will fail. Here's the
120
+ # easiest way to add fixtures to the database:
121
+ #
122
+ # ...
123
+ # class WebSiteTest < Test::Unit::TestCase
124
+ # fixtures :web_sites # add more by separating the symbols with commas
125
+ # ...
126
+ #
127
+ # By adding a "fixtures" method to the test case and passing it a list of symbols (only one is shown here tho), we trigger
128
+ # the testing environment to automatically load the appropriate fixtures into the database before each test.
129
+ # To ensure consistent data, the environment deletes the fixtures before running the load.
130
+ #
131
+ # In addition to being available in the database, the fixtures are also loaded into a hash stored in an instance variable
132
+ # of the test case. It is named after the symbol... so, in our example, there would be a hash available called
133
+ # @web_sites. This is where the "fixture name" comes into play.
134
+ #
135
+ # On top of that, each record is automatically "found" (using Model.find(id)) and placed in the instance variable of its name.
136
+ # So for the YAML fixtures, we'd get @rubyonrails and @google, which could be interrogated using regular Active Record semantics:
137
+ #
138
+ # # test if the object created from the fixture data has the same attributes as the data itself
139
+ # def test_find
140
+ # assert_equal @web_sites["rubyonrails"]["name"], @rubyonrails.name
141
+ # end
142
+ #
143
+ # As seen above, the data hash created from the YAML fixtures would have @web_sites["rubyonrails"]["url"] return
144
+ # "http://www.rubyonrails.org" and @web_sites["google"]["name"] would return "Google". The same fixtures, but loaded
145
+ # from a CSV fixture file, would be accessible via @web_sites["web_site_1"]["name"] == "Ruby on Rails" and have the individual
146
+ # fixtures available as instance variables @web_site_1 and @web_site_2.
147
+ #
148
+ # If you do not wish to use instantiated fixtures (usually for performance reasons) there are two options.
149
+ #
150
+ # - to completely disable instantiated fixtures:
151
+ # self.use_instantiated_fixtures = false
152
+ #
153
+ # - to keep the fixture instance (@web_sites) available, but do not automatically 'find' each instance:
154
+ # self.use_instantiated_fixtures = :no_instances
155
+ #
156
+ # Even if auto-instantiated fixtures are disabled, you can still access them
157
+ # by name via special dynamic methods. Each method has the same name as the
158
+ # model, and accepts the name of the fixture to instantiate:
159
+ #
160
+ # fixtures :web_sites
161
+ #
162
+ # def test_find
163
+ # assert_equal "Ruby on Rails", web_sites(:rubyonrails).name
164
+ # end
165
+ #
166
+ # = Dynamic fixtures with ERb
167
+ #
168
+ # Some times you don't care about the content of the fixtures as much as you care about the volume. In these cases, you can
169
+ # mix ERb in with your YAML or CSV fixtures to create a bunch of fixtures for load testing, like:
170
+ #
171
+ # <% for i in 1..1000 %>
172
+ # fix_<%= i %>:
173
+ # id: <%= i %>
174
+ # name: guy_<%= 1 %>
175
+ # <% end %>
176
+ #
177
+ # This will create 1000 very simple YAML fixtures.
178
+ #
179
+ # Using ERb, you can also inject dynamic values into your fixtures with inserts like <%= Date.today.strftime("%Y-%m-%d") %>.
180
+ # This is however a feature to be used with some caution. The point of fixtures are that they're stable units of predictable
181
+ # sample data. If you feel that you need to inject dynamic values, then perhaps you should reexamine whether your application
182
+ # is properly testable. Hence, dynamic values in fixtures are to be considered a code smell.
183
+ #
184
+ # = Transactional fixtures
185
+ #
186
+ # TestCases can use begin+rollback to isolate their changes to the database instead of having to delete+insert for every test case.
187
+ # They can also turn off auto-instantiation of fixture data since the feature is costly and often unused.
188
+ #
189
+ # class FooTest < Test::Unit::TestCase
190
+ # self.use_transactional_fixtures = true
191
+ # self.use_instantiated_fixtures = false
192
+ #
193
+ # fixtures :foos
194
+ #
195
+ # def test_godzilla
196
+ # assert !Foo.find(:all).empty?
197
+ # Foo.destroy_all
198
+ # assert Foo.find(:all).empty?
199
+ # end
200
+ #
201
+ # def test_godzilla_aftermath
202
+ # assert !Foo.find(:all).empty?
203
+ # end
204
+ # end
205
+ #
206
+ # If you preload your test database with all fixture data (probably in the Rakefile task) and use transactional fixtures,
207
+ # then you may omit all fixtures declarations in your test cases since all the data's already there and every case rolls back its changes.
208
+ #
209
+ # In order to use instantiated fixtures with preloaded data, set +self.pre_loaded_fixtures+ to true. This will provide
210
+ # access to fixture data for every table that has been loaded through fixtures (depending on the value of +use_instantiated_fixtures+)
211
+ #
212
+ # When *not* to use transactional fixtures:
213
+ # 1. You're testing whether a transaction works correctly. Nested transactions don't commit until all parent transactions commit,
214
+ # particularly, the fixtures transaction which is begun in setup and rolled back in teardown. Thus, you won't be able to verify
215
+ # the results of your transaction until Active Record supports nested transactions or savepoints (in progress.)
216
+ # 2. Your database does not support transactions. Every Active Record database supports transactions except MySQL MyISAM.
217
+ # Use InnoDB, MaxDB, or NDB instead.
218
+ class Fixtures < YAML::Omap
219
+ DEFAULT_FILTER_RE = /\.ya?ml$/
220
+
221
+ def self.instantiate_fixtures(object, table_name, fixtures, load_instances=true)
222
+ object.instance_variable_set "@#{table_name.to_s.gsub('.','_')}", fixtures
223
+ if load_instances
224
+ ActiveRecord::Base.silence do
225
+ fixtures.each do |name, fixture|
226
+ begin
227
+ object.instance_variable_set "@#{name}", fixture.find
228
+ rescue FixtureClassNotFound
229
+ nil
230
+ end
231
+ end
232
+ end
233
+ end
234
+ end
235
+
236
+ def self.instantiate_all_loaded_fixtures(object, load_instances=true)
237
+ all_loaded_fixtures.each do |table_name, fixtures|
238
+ Fixtures.instantiate_fixtures(object, table_name, fixtures, load_instances)
239
+ end
240
+ end
241
+
242
+ cattr_accessor :all_loaded_fixtures
243
+ self.all_loaded_fixtures = {}
244
+
245
+ def self.create_fixtures(fixtures_directory, table_names, class_names = {})
246
+ table_names = [table_names].flatten.map { |n| n.to_s }
247
+ connection = block_given? ? yield : ActiveRecord::Base.connection
248
+ ActiveRecord::Base.silence do
249
+ fixtures_map = {}
250
+ fixtures = table_names.map do |table_name|
251
+ fixtures_map[table_name] = Fixtures.new(connection, File.split(table_name.to_s).last, class_names[table_name.to_sym], File.join(fixtures_directory, table_name.to_s))
252
+ end
253
+ all_loaded_fixtures.merge! fixtures_map
254
+
255
+ connection.transaction(Thread.current['open_transactions'] == 0) do
256
+ fixtures.reverse.each { |fixture| fixture.delete_existing_fixtures }
257
+ fixtures.each { |fixture| fixture.insert_fixtures }
258
+
259
+ # Cap primary key sequences to max(pk).
260
+ if connection.respond_to?(:reset_pk_sequence!)
261
+ table_names.each do |table_name|
262
+ connection.reset_pk_sequence!(table_name)
263
+ end
264
+ end
265
+ end
266
+
267
+ return fixtures.size > 1 ? fixtures : fixtures.first
268
+ end
269
+ end
270
+
271
+
272
+ attr_reader :table_name
273
+
274
+ def initialize(connection, table_name, class_name, fixture_path, file_filter = DEFAULT_FILTER_RE)
275
+ @connection, @table_name, @fixture_path, @file_filter = connection, table_name, fixture_path, file_filter
276
+ @class_name = class_name ||
277
+ (ActiveRecord::Base.pluralize_table_names ? @table_name.singularize.camelize : @table_name.camelize)
278
+ @table_name = ActiveRecord::Base.table_name_prefix + @table_name + ActiveRecord::Base.table_name_suffix
279
+ @table_name = class_name.table_name if class_name.respond_to?(:table_name)
280
+ @connection = class_name.connection if class_name.respond_to?(:connection)
281
+ read_fixture_files
282
+ end
283
+
284
+ def delete_existing_fixtures
285
+ @connection.delete "DELETE FROM #{@table_name}", 'Fixture Delete'
286
+ end
287
+
288
+ def insert_fixtures
289
+ values.each do |fixture|
290
+ @connection.execute "INSERT INTO #{@table_name} (#{fixture.key_list}) VALUES (#{fixture.value_list})", 'Fixture Insert'
291
+ end
292
+ end
293
+
294
+ private
295
+
296
+ def read_fixture_files
297
+ if File.file?(yaml_file_path)
298
+ # YAML fixtures
299
+ yaml_string = ""
300
+ Dir["#{@fixture_path}/**/*.yml"].select {|f| test(?f,f) }.each do |subfixture_path|
301
+ yaml_string << IO.read(subfixture_path)
302
+ end
303
+ yaml_string << IO.read(yaml_file_path)
304
+
305
+ begin
306
+ yaml = YAML::load(erb_render(yaml_string))
307
+ rescue Exception=>boom
308
+ raise Fixture::FormatError, "a YAML error occurred parsing #{yaml_file_path}. Please note that YAML must be consistently indented using spaces. Tabs are not allowed. Please have a look at http://www.yaml.org/faq.html\nThe exact error was:\n #{boom.class}: #{boom}"
309
+ end
310
+
311
+ if yaml
312
+ # If the file is an ordered map, extract its children.
313
+ yaml_value =
314
+ if yaml.respond_to?(:type_id) && yaml.respond_to?(:value)
315
+ yaml.value
316
+ else
317
+ [yaml]
318
+ end
319
+
320
+ yaml_value.each do |fixture|
321
+ fixture.each do |name, data|
322
+ unless data
323
+ raise Fixture::FormatError, "Bad data for #{@class_name} fixture named #{name} (nil)"
324
+ end
325
+
326
+ self[name] = Fixture.new(data, @class_name)
327
+ end
328
+ end
329
+ end
330
+ elsif File.file?(csv_file_path)
331
+ # CSV fixtures
332
+ reader = CSV::Reader.create(erb_render(IO.read(csv_file_path)))
333
+ header = reader.shift
334
+ i = 0
335
+ reader.each do |row|
336
+ data = {}
337
+ row.each_with_index { |cell, j| data[header[j].to_s.strip] = cell.to_s.strip }
338
+ self["#{Inflector::underscore(@class_name)}_#{i+=1}"]= Fixture.new(data, @class_name)
339
+ end
340
+ elsif File.file?(deprecated_yaml_file_path)
341
+ raise Fixture::FormatError, ".yml extension required: rename #{deprecated_yaml_file_path} to #{yaml_file_path}"
342
+ else
343
+ # Standard fixtures
344
+ Dir.entries(@fixture_path).each do |file|
345
+ path = File.join(@fixture_path, file)
346
+ if File.file?(path) and file !~ @file_filter
347
+ self[file] = Fixture.new(path, @class_name)
348
+ end
349
+ end
350
+ end
351
+ end
352
+
353
+ def yaml_file_path
354
+ "#{@fixture_path}.yml"
355
+ end
356
+
357
+ def deprecated_yaml_file_path
358
+ "#{@fixture_path}.yaml"
359
+ end
360
+
361
+ def csv_file_path
362
+ @fixture_path + ".csv"
363
+ end
364
+
365
+ def yaml_fixtures_key(path)
366
+ File.basename(@fixture_path).split(".").first
367
+ end
368
+
369
+ def erb_render(fixture_content)
370
+ ERB.new(fixture_content).result
371
+ end
372
+ end
373
+
374
+ class Fixture #:nodoc:
375
+ include Enumerable
376
+ class FixtureError < StandardError#:nodoc:
377
+ end
378
+ class FormatError < FixtureError#:nodoc:
379
+ end
380
+
381
+ def initialize(fixture, class_name)
382
+ case fixture
383
+ when Hash, YAML::Omap
384
+ @fixture = fixture
385
+ when String
386
+ @fixture = read_fixture_file(fixture)
387
+ else
388
+ raise ArgumentError, "Bad fixture argument #{fixture.inspect} during creation of #{class_name} fixture"
389
+ end
390
+
391
+ @class_name = class_name
392
+ end
393
+
394
+ def each
395
+ @fixture.each { |item| yield item }
396
+ end
397
+
398
+ def [](key)
399
+ @fixture[key]
400
+ end
401
+
402
+ def to_hash
403
+ @fixture
404
+ end
405
+
406
+ def key_list
407
+ columns = @fixture.keys.collect{ |column_name| ActiveRecord::Base.connection.quote_column_name(column_name) }
408
+ columns.join(", ")
409
+ end
410
+
411
+ def value_list
412
+ klass = @class_name.constantize rescue nil
413
+
414
+ list = @fixture.inject([]) do |fixtures, (key, value)|
415
+ col = klass.columns_hash[key] if klass.kind_of?(ActiveRecord::Base)
416
+ fixtures << ActiveRecord::Base.connection.quote(value, col).gsub('[^\]\\n', "\n").gsub('[^\]\\r', "\r")
417
+ end
418
+ list * ', '
419
+ end
420
+
421
+ def find
422
+ klass = @class_name.is_a?(Class) ? @class_name : Object.const_get(@class_name) rescue nil
423
+ if klass
424
+ klass.find(self[klass.primary_key])
425
+ else
426
+ raise FixtureClassNotFound, "The class #{@class_name.inspect} was not found."
427
+ end
428
+ end
429
+
430
+ private
431
+ def read_fixture_file(fixture_file_path)
432
+ IO.readlines(fixture_file_path).inject({}) do |fixture, line|
433
+ # Mercifully skip empty lines.
434
+ next if line =~ /^\s*$/
435
+
436
+ # Use the same regular expression for attributes as Active Record.
437
+ unless md = /^\s*([a-zA-Z][-_\w]*)\s*=>\s*(.+)\s*$/.match(line)
438
+ raise FormatError, "#{fixture_file_path}: fixture format error at '#{line}'. Expecting 'key => value'."
439
+ end
440
+ key, value = md.captures
441
+
442
+ # Disallow duplicate keys to catch typos.
443
+ raise FormatError, "#{fixture_file_path}: duplicate '#{key}' in fixture." if fixture[key]
444
+ fixture[key] = value.strip
445
+ fixture
446
+ end
447
+ end
448
+ end
449
+
450
+ module Test #:nodoc:
451
+ module Unit #:nodoc:
452
+ class TestCase #:nodoc:
453
+ cattr_accessor :fixture_path
454
+ class_inheritable_accessor :fixture_table_names
455
+ class_inheritable_accessor :fixture_class_names
456
+ class_inheritable_accessor :use_transactional_fixtures
457
+ class_inheritable_accessor :use_instantiated_fixtures # true, false, or :no_instances
458
+ class_inheritable_accessor :pre_loaded_fixtures
459
+
460
+ self.fixture_table_names = []
461
+ self.use_transactional_fixtures = false
462
+ self.use_instantiated_fixtures = true
463
+ self.pre_loaded_fixtures = false
464
+
465
+ self.fixture_class_names = {}
466
+
467
+ @@already_loaded_fixtures = {}
468
+ self.fixture_class_names = {}
469
+
470
+ def self.set_fixture_class(class_names = {})
471
+ self.fixture_class_names = self.fixture_class_names.merge(class_names)
472
+ end
473
+
474
+ def self.fixtures(*table_names)
475
+ table_names = table_names.flatten.map { |n| n.to_s }
476
+ self.fixture_table_names |= table_names
477
+ require_fixture_classes(table_names)
478
+ setup_fixture_accessors(table_names)
479
+ end
480
+
481
+ def self.require_fixture_classes(table_names=nil)
482
+ (table_names || fixture_table_names).each do |table_name|
483
+ file_name = table_name.to_s
484
+ file_name = file_name.singularize if ActiveRecord::Base.pluralize_table_names
485
+ begin
486
+ require_dependency file_name
487
+ rescue LoadError
488
+ # Let's hope the developer has included it himself
489
+ end
490
+ end
491
+ end
492
+
493
+ def self.setup_fixture_accessors(table_names=nil)
494
+ (table_names || fixture_table_names).each do |table_name|
495
+ table_name = table_name.to_s.tr('.','_')
496
+ define_method(table_name) do |fixture, *optionals|
497
+ force_reload = optionals.shift
498
+ @fixture_cache[table_name] ||= Hash.new
499
+ @fixture_cache[table_name][fixture] = nil if force_reload
500
+ if @loaded_fixtures[table_name][fixture.to_s]
501
+ @fixture_cache[table_name][fixture] ||= @loaded_fixtures[table_name][fixture.to_s].find
502
+ else
503
+ raise StandardError, "No fixture with name '#{fixture}' found for table '#{table_name}'"
504
+ end
505
+ end
506
+ end
507
+ end
508
+
509
+ def self.uses_transaction(*methods)
510
+ @uses_transaction = [] unless defined?(@uses_transaction)
511
+ @uses_transaction.concat methods.map(&:to_s)
512
+ end
513
+
514
+ def self.uses_transaction?(method)
515
+ @uses_transaction = [] unless defined?(@uses_transaction)
516
+ @uses_transaction.include?(method.to_s)
517
+ end
518
+
519
+ def use_transactional_fixtures?
520
+ use_transactional_fixtures &&
521
+ !self.class.uses_transaction?(method_name)
522
+ end
523
+
524
+ def setup_with_fixtures
525
+ return unless defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
526
+
527
+ if pre_loaded_fixtures && !use_transactional_fixtures
528
+ raise RuntimeError, 'pre_loaded_fixtures requires use_transactional_fixtures'
529
+ end
530
+
531
+ @fixture_cache = Hash.new
532
+
533
+ # Load fixtures once and begin transaction.
534
+ if use_transactional_fixtures?
535
+ if @@already_loaded_fixtures[self.class]
536
+ @loaded_fixtures = @@already_loaded_fixtures[self.class]
537
+ else
538
+ load_fixtures
539
+ @@already_loaded_fixtures[self.class] = @loaded_fixtures
540
+ end
541
+ ActiveRecord::Base.send :increment_open_transactions
542
+ ActiveRecord::Base.connection.begin_db_transaction
543
+
544
+ # Load fixtures for every test.
545
+ else
546
+ @@already_loaded_fixtures[self.class] = nil
547
+ load_fixtures
548
+ end
549
+
550
+ # Instantiate fixtures for every test if requested.
551
+ instantiate_fixtures if use_instantiated_fixtures
552
+ end
553
+
554
+ alias_method :setup, :setup_with_fixtures
555
+
556
+ def teardown_with_fixtures
557
+ return unless defined?(ActiveRecord::Base) && !ActiveRecord::Base.configurations.blank?
558
+
559
+ # Rollback changes if a transaction is active.
560
+ if use_transactional_fixtures? && Thread.current['open_transactions'] != 0
561
+ ActiveRecord::Base.connection.rollback_db_transaction
562
+ Thread.current['open_transactions'] = 0
563
+ end
564
+ ActiveRecord::Base.verify_active_connections!
565
+ end
566
+
567
+ alias_method :teardown, :teardown_with_fixtures
568
+
569
+ def self.method_added(method)
570
+ case method.to_s
571
+ when 'setup'
572
+ unless method_defined?(:setup_without_fixtures)
573
+ alias_method :setup_without_fixtures, :setup
574
+ define_method(:setup) do
575
+ setup_with_fixtures
576
+ setup_without_fixtures
577
+ end
578
+ end
579
+ when 'teardown'
580
+ unless method_defined?(:teardown_without_fixtures)
581
+ alias_method :teardown_without_fixtures, :teardown
582
+ define_method(:teardown) do
583
+ teardown_without_fixtures
584
+ teardown_with_fixtures
585
+ end
586
+ end
587
+ end
588
+ end
589
+
590
+ private
591
+ def load_fixtures
592
+ @loaded_fixtures = {}
593
+ fixtures = Fixtures.create_fixtures(fixture_path, fixture_table_names, fixture_class_names)
594
+ unless fixtures.nil?
595
+ if fixtures.instance_of?(Fixtures)
596
+ @loaded_fixtures[fixtures.table_name] = fixtures
597
+ else
598
+ fixtures.each { |f| @loaded_fixtures[f.table_name] = f }
599
+ end
600
+ end
601
+ end
602
+
603
+ # for pre_loaded_fixtures, only require the classes once. huge speed improvement
604
+ @@required_fixture_classes = false
605
+
606
+ def instantiate_fixtures
607
+ if pre_loaded_fixtures
608
+ raise RuntimeError, 'Load fixtures before instantiating them.' if Fixtures.all_loaded_fixtures.empty?
609
+ unless @@required_fixture_classes
610
+ self.class.require_fixture_classes Fixtures.all_loaded_fixtures.keys
611
+ @@required_fixture_classes = true
612
+ end
613
+ Fixtures.instantiate_all_loaded_fixtures(self, load_instances?)
614
+ else
615
+ raise RuntimeError, 'Load fixtures before instantiating them.' if @loaded_fixtures.nil?
616
+ @loaded_fixtures.each do |table_name, fixtures|
617
+ Fixtures.instantiate_fixtures(self, table_name, fixtures, load_instances?)
618
+ end
619
+ end
620
+ end
621
+
622
+ def load_instances?
623
+ use_instantiated_fixtures != :no_instances
624
+ end
625
+ end
626
+
627
+ end
628
+ end