activerecord_csi 2.3.5.p6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. data/CHANGELOG +5858 -0
  2. data/README +351 -0
  3. data/RUNNING_UNIT_TESTS +36 -0
  4. data/Rakefile +270 -0
  5. data/examples/associations.png +0 -0
  6. data/examples/performance.rb +162 -0
  7. data/install.rb +30 -0
  8. data/lib/active_record/aggregations.rb +261 -0
  9. data/lib/active_record/association_preload.rb +389 -0
  10. data/lib/active_record/associations/association_collection.rb +475 -0
  11. data/lib/active_record/associations/association_proxy.rb +278 -0
  12. data/lib/active_record/associations/belongs_to_association.rb +76 -0
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +53 -0
  14. data/lib/active_record/associations/has_and_belongs_to_many_association.rb +143 -0
  15. data/lib/active_record/associations/has_many_association.rb +122 -0
  16. data/lib/active_record/associations/has_many_through_association.rb +266 -0
  17. data/lib/active_record/associations/has_one_association.rb +133 -0
  18. data/lib/active_record/associations/has_one_through_association.rb +37 -0
  19. data/lib/active_record/associations.rb +2241 -0
  20. data/lib/active_record/attribute_methods.rb +388 -0
  21. data/lib/active_record/autosave_association.rb +364 -0
  22. data/lib/active_record/base.rb +3171 -0
  23. data/lib/active_record/batches.rb +81 -0
  24. data/lib/active_record/calculations.rb +311 -0
  25. data/lib/active_record/callbacks.rb +360 -0
  26. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +371 -0
  27. data/lib/active_record/connection_adapters/abstract/connection_specification.rb +139 -0
  28. data/lib/active_record/connection_adapters/abstract/database_statements.rb +289 -0
  29. data/lib/active_record/connection_adapters/abstract/query_cache.rb +94 -0
  30. data/lib/active_record/connection_adapters/abstract/quoting.rb +69 -0
  31. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +722 -0
  32. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +434 -0
  33. data/lib/active_record/connection_adapters/abstract_adapter.rb +241 -0
  34. data/lib/active_record/connection_adapters/mysql_adapter.rb +630 -0
  35. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1113 -0
  36. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -0
  37. data/lib/active_record/connection_adapters/sqlite_adapter.rb +453 -0
  38. data/lib/active_record/dirty.rb +183 -0
  39. data/lib/active_record/dynamic_finder_match.rb +41 -0
  40. data/lib/active_record/dynamic_scope_match.rb +25 -0
  41. data/lib/active_record/fixtures.rb +996 -0
  42. data/lib/active_record/i18n_interpolation_deprecation.rb +26 -0
  43. data/lib/active_record/locale/en.yml +58 -0
  44. data/lib/active_record/locking/optimistic.rb +148 -0
  45. data/lib/active_record/locking/pessimistic.rb +55 -0
  46. data/lib/active_record/migration.rb +566 -0
  47. data/lib/active_record/named_scope.rb +192 -0
  48. data/lib/active_record/nested_attributes.rb +392 -0
  49. data/lib/active_record/observer.rb +197 -0
  50. data/lib/active_record/query_cache.rb +33 -0
  51. data/lib/active_record/reflection.rb +320 -0
  52. data/lib/active_record/schema.rb +51 -0
  53. data/lib/active_record/schema_dumper.rb +182 -0
  54. data/lib/active_record/serialization.rb +101 -0
  55. data/lib/active_record/serializers/json_serializer.rb +91 -0
  56. data/lib/active_record/serializers/xml_serializer.rb +357 -0
  57. data/lib/active_record/session_store.rb +326 -0
  58. data/lib/active_record/test_case.rb +66 -0
  59. data/lib/active_record/timestamp.rb +71 -0
  60. data/lib/active_record/transactions.rb +235 -0
  61. data/lib/active_record/validations.rb +1135 -0
  62. data/lib/active_record/version.rb +9 -0
  63. data/lib/active_record.rb +84 -0
  64. data/lib/activerecord.rb +2 -0
  65. data/test/assets/example.log +1 -0
  66. data/test/assets/flowers.jpg +0 -0
  67. data/test/cases/aaa_create_tables_test.rb +24 -0
  68. data/test/cases/active_schema_test_mysql.rb +100 -0
  69. data/test/cases/active_schema_test_postgresql.rb +24 -0
  70. data/test/cases/adapter_test.rb +145 -0
  71. data/test/cases/aggregations_test.rb +167 -0
  72. data/test/cases/ar_schema_test.rb +32 -0
  73. data/test/cases/associations/belongs_to_associations_test.rb +425 -0
  74. data/test/cases/associations/callbacks_test.rb +161 -0
  75. data/test/cases/associations/cascaded_eager_loading_test.rb +131 -0
  76. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -0
  77. data/test/cases/associations/eager_load_nested_include_test.rb +130 -0
  78. data/test/cases/associations/eager_singularization_test.rb +145 -0
  79. data/test/cases/associations/eager_test.rb +834 -0
  80. data/test/cases/associations/extension_test.rb +62 -0
  81. data/test/cases/associations/habtm_join_table_test.rb +56 -0
  82. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +822 -0
  83. data/test/cases/associations/has_many_associations_test.rb +1134 -0
  84. data/test/cases/associations/has_many_through_associations_test.rb +346 -0
  85. data/test/cases/associations/has_one_associations_test.rb +330 -0
  86. data/test/cases/associations/has_one_through_associations_test.rb +209 -0
  87. data/test/cases/associations/inner_join_association_test.rb +93 -0
  88. data/test/cases/associations/join_model_test.rb +712 -0
  89. data/test/cases/associations_test.rb +262 -0
  90. data/test/cases/attribute_methods_test.rb +305 -0
  91. data/test/cases/autosave_association_test.rb +1142 -0
  92. data/test/cases/base_test.rb +2154 -0
  93. data/test/cases/batches_test.rb +61 -0
  94. data/test/cases/binary_test.rb +30 -0
  95. data/test/cases/calculations_test.rb +348 -0
  96. data/test/cases/callbacks_observers_test.rb +38 -0
  97. data/test/cases/callbacks_test.rb +438 -0
  98. data/test/cases/class_inheritable_attributes_test.rb +32 -0
  99. data/test/cases/column_alias_test.rb +17 -0
  100. data/test/cases/column_definition_test.rb +70 -0
  101. data/test/cases/connection_pool_test.rb +25 -0
  102. data/test/cases/connection_test_firebird.rb +8 -0
  103. data/test/cases/connection_test_mysql.rb +64 -0
  104. data/test/cases/copy_table_test_sqlite.rb +80 -0
  105. data/test/cases/database_statements_test.rb +12 -0
  106. data/test/cases/datatype_test_postgresql.rb +204 -0
  107. data/test/cases/date_time_test.rb +37 -0
  108. data/test/cases/default_test_firebird.rb +16 -0
  109. data/test/cases/defaults_test.rb +111 -0
  110. data/test/cases/deprecated_finder_test.rb +30 -0
  111. data/test/cases/dirty_test.rb +316 -0
  112. data/test/cases/finder_respond_to_test.rb +76 -0
  113. data/test/cases/finder_test.rb +1066 -0
  114. data/test/cases/fixtures_test.rb +656 -0
  115. data/test/cases/helper.rb +68 -0
  116. data/test/cases/i18n_test.rb +46 -0
  117. data/test/cases/inheritance_test.rb +262 -0
  118. data/test/cases/invalid_date_test.rb +24 -0
  119. data/test/cases/json_serialization_test.rb +205 -0
  120. data/test/cases/lifecycle_test.rb +193 -0
  121. data/test/cases/locking_test.rb +304 -0
  122. data/test/cases/method_scoping_test.rb +704 -0
  123. data/test/cases/migration_test.rb +1523 -0
  124. data/test/cases/migration_test_firebird.rb +124 -0
  125. data/test/cases/mixin_test.rb +96 -0
  126. data/test/cases/modules_test.rb +81 -0
  127. data/test/cases/multiple_db_test.rb +85 -0
  128. data/test/cases/named_scope_test.rb +361 -0
  129. data/test/cases/nested_attributes_test.rb +581 -0
  130. data/test/cases/pk_test.rb +119 -0
  131. data/test/cases/pooled_connections_test.rb +103 -0
  132. data/test/cases/query_cache_test.rb +123 -0
  133. data/test/cases/readonly_test.rb +107 -0
  134. data/test/cases/reflection_test.rb +194 -0
  135. data/test/cases/reload_models_test.rb +22 -0
  136. data/test/cases/repair_helper.rb +50 -0
  137. data/test/cases/reserved_word_test_mysql.rb +176 -0
  138. data/test/cases/sanitize_test.rb +25 -0
  139. data/test/cases/schema_authorization_test_postgresql.rb +75 -0
  140. data/test/cases/schema_dumper_test.rb +211 -0
  141. data/test/cases/schema_test_postgresql.rb +178 -0
  142. data/test/cases/serialization_test.rb +47 -0
  143. data/test/cases/synonym_test_oracle.rb +17 -0
  144. data/test/cases/timestamp_test.rb +75 -0
  145. data/test/cases/transactions_test.rb +522 -0
  146. data/test/cases/unconnected_test.rb +32 -0
  147. data/test/cases/validations_i18n_test.rb +955 -0
  148. data/test/cases/validations_test.rb +1640 -0
  149. data/test/cases/xml_serialization_test.rb +240 -0
  150. data/test/config.rb +5 -0
  151. data/test/connections/jdbc_jdbcderby/connection.rb +18 -0
  152. data/test/connections/jdbc_jdbch2/connection.rb +18 -0
  153. data/test/connections/jdbc_jdbchsqldb/connection.rb +18 -0
  154. data/test/connections/jdbc_jdbcmysql/connection.rb +26 -0
  155. data/test/connections/jdbc_jdbcpostgresql/connection.rb +26 -0
  156. data/test/connections/jdbc_jdbcsqlite3/connection.rb +25 -0
  157. data/test/connections/native_db2/connection.rb +25 -0
  158. data/test/connections/native_firebird/connection.rb +26 -0
  159. data/test/connections/native_frontbase/connection.rb +27 -0
  160. data/test/connections/native_mysql/connection.rb +25 -0
  161. data/test/connections/native_openbase/connection.rb +21 -0
  162. data/test/connections/native_oracle/connection.rb +27 -0
  163. data/test/connections/native_postgresql/connection.rb +25 -0
  164. data/test/connections/native_sqlite/connection.rb +25 -0
  165. data/test/connections/native_sqlite3/connection.rb +25 -0
  166. data/test/connections/native_sqlite3/in_memory_connection.rb +18 -0
  167. data/test/connections/native_sybase/connection.rb +23 -0
  168. data/test/fixtures/accounts.yml +29 -0
  169. data/test/fixtures/all/developers.yml +0 -0
  170. data/test/fixtures/all/people.csv +0 -0
  171. data/test/fixtures/all/tasks.yml +0 -0
  172. data/test/fixtures/author_addresses.yml +5 -0
  173. data/test/fixtures/author_favorites.yml +4 -0
  174. data/test/fixtures/authors.yml +9 -0
  175. data/test/fixtures/binaries.yml +132 -0
  176. data/test/fixtures/books.yml +7 -0
  177. data/test/fixtures/categories/special_categories.yml +9 -0
  178. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  179. data/test/fixtures/categories.yml +14 -0
  180. data/test/fixtures/categories_ordered.yml +7 -0
  181. data/test/fixtures/categories_posts.yml +23 -0
  182. data/test/fixtures/categorizations.yml +17 -0
  183. data/test/fixtures/clubs.yml +6 -0
  184. data/test/fixtures/comments.yml +59 -0
  185. data/test/fixtures/companies.yml +56 -0
  186. data/test/fixtures/computers.yml +4 -0
  187. data/test/fixtures/courses.yml +7 -0
  188. data/test/fixtures/customers.yml +26 -0
  189. data/test/fixtures/developers.yml +21 -0
  190. data/test/fixtures/developers_projects.yml +17 -0
  191. data/test/fixtures/edges.yml +6 -0
  192. data/test/fixtures/entrants.yml +14 -0
  193. data/test/fixtures/fixture_database.sqlite3 +0 -0
  194. data/test/fixtures/fixture_database_2.sqlite3 +0 -0
  195. data/test/fixtures/fk_test_has_fk.yml +3 -0
  196. data/test/fixtures/fk_test_has_pk.yml +2 -0
  197. data/test/fixtures/funny_jokes.yml +10 -0
  198. data/test/fixtures/items.yml +4 -0
  199. data/test/fixtures/jobs.yml +7 -0
  200. data/test/fixtures/legacy_things.yml +3 -0
  201. data/test/fixtures/mateys.yml +4 -0
  202. data/test/fixtures/member_types.yml +6 -0
  203. data/test/fixtures/members.yml +6 -0
  204. data/test/fixtures/memberships.yml +20 -0
  205. data/test/fixtures/minimalistics.yml +2 -0
  206. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  207. data/test/fixtures/mixins.yml +29 -0
  208. data/test/fixtures/movies.yml +7 -0
  209. data/test/fixtures/naked/csv/accounts.csv +1 -0
  210. data/test/fixtures/naked/yml/accounts.yml +1 -0
  211. data/test/fixtures/naked/yml/companies.yml +1 -0
  212. data/test/fixtures/naked/yml/courses.yml +1 -0
  213. data/test/fixtures/organizations.yml +5 -0
  214. data/test/fixtures/owners.yml +7 -0
  215. data/test/fixtures/parrots.yml +27 -0
  216. data/test/fixtures/parrots_pirates.yml +7 -0
  217. data/test/fixtures/people.yml +15 -0
  218. data/test/fixtures/pets.yml +14 -0
  219. data/test/fixtures/pirates.yml +9 -0
  220. data/test/fixtures/posts.yml +52 -0
  221. data/test/fixtures/price_estimates.yml +7 -0
  222. data/test/fixtures/projects.yml +7 -0
  223. data/test/fixtures/readers.yml +9 -0
  224. data/test/fixtures/references.yml +17 -0
  225. data/test/fixtures/reserved_words/distinct.yml +5 -0
  226. data/test/fixtures/reserved_words/distincts_selects.yml +11 -0
  227. data/test/fixtures/reserved_words/group.yml +14 -0
  228. data/test/fixtures/reserved_words/select.yml +8 -0
  229. data/test/fixtures/reserved_words/values.yml +7 -0
  230. data/test/fixtures/ships.yml +5 -0
  231. data/test/fixtures/sponsors.yml +9 -0
  232. data/test/fixtures/subscribers.yml +7 -0
  233. data/test/fixtures/subscriptions.yml +12 -0
  234. data/test/fixtures/taggings.yml +28 -0
  235. data/test/fixtures/tags.yml +7 -0
  236. data/test/fixtures/tasks.yml +7 -0
  237. data/test/fixtures/topics.yml +42 -0
  238. data/test/fixtures/toys.yml +4 -0
  239. data/test/fixtures/treasures.yml +10 -0
  240. data/test/fixtures/vertices.yml +4 -0
  241. data/test/fixtures/warehouse-things.yml +3 -0
  242. data/test/migrations/broken/100_migration_that_raises_exception.rb +10 -0
  243. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -0
  244. data/test/migrations/duplicate/1_people_have_last_names.rb +9 -0
  245. data/test/migrations/duplicate/2_we_need_reminders.rb +12 -0
  246. data/test/migrations/duplicate/3_foo.rb +7 -0
  247. data/test/migrations/duplicate/3_innocent_jointable.rb +12 -0
  248. data/test/migrations/duplicate_names/20080507052938_chunky.rb +7 -0
  249. data/test/migrations/duplicate_names/20080507053028_chunky.rb +7 -0
  250. data/test/migrations/interleaved/pass_1/3_innocent_jointable.rb +12 -0
  251. data/test/migrations/interleaved/pass_2/1_people_have_last_names.rb +9 -0
  252. data/test/migrations/interleaved/pass_2/3_innocent_jointable.rb +12 -0
  253. data/test/migrations/interleaved/pass_3/1_people_have_last_names.rb +9 -0
  254. data/test/migrations/interleaved/pass_3/2_i_raise_on_down.rb +8 -0
  255. data/test/migrations/interleaved/pass_3/3_innocent_jointable.rb +12 -0
  256. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -0
  257. data/test/migrations/missing/1_people_have_last_names.rb +9 -0
  258. data/test/migrations/missing/3_we_need_reminders.rb +12 -0
  259. data/test/migrations/missing/4_innocent_jointable.rb +12 -0
  260. data/test/migrations/valid/1_people_have_last_names.rb +9 -0
  261. data/test/migrations/valid/2_we_need_reminders.rb +12 -0
  262. data/test/migrations/valid/3_innocent_jointable.rb +12 -0
  263. data/test/models/author.rb +146 -0
  264. data/test/models/auto_id.rb +4 -0
  265. data/test/models/binary.rb +2 -0
  266. data/test/models/bird.rb +3 -0
  267. data/test/models/book.rb +4 -0
  268. data/test/models/categorization.rb +5 -0
  269. data/test/models/category.rb +34 -0
  270. data/test/models/citation.rb +6 -0
  271. data/test/models/club.rb +13 -0
  272. data/test/models/column_name.rb +3 -0
  273. data/test/models/comment.rb +29 -0
  274. data/test/models/company.rb +171 -0
  275. data/test/models/company_in_module.rb +61 -0
  276. data/test/models/computer.rb +3 -0
  277. data/test/models/contact.rb +16 -0
  278. data/test/models/contract.rb +5 -0
  279. data/test/models/course.rb +3 -0
  280. data/test/models/customer.rb +73 -0
  281. data/test/models/default.rb +2 -0
  282. data/test/models/developer.rb +101 -0
  283. data/test/models/edge.rb +5 -0
  284. data/test/models/entrant.rb +3 -0
  285. data/test/models/essay.rb +3 -0
  286. data/test/models/event.rb +3 -0
  287. data/test/models/guid.rb +2 -0
  288. data/test/models/item.rb +7 -0
  289. data/test/models/job.rb +5 -0
  290. data/test/models/joke.rb +3 -0
  291. data/test/models/keyboard.rb +3 -0
  292. data/test/models/legacy_thing.rb +3 -0
  293. data/test/models/matey.rb +4 -0
  294. data/test/models/member.rb +12 -0
  295. data/test/models/member_detail.rb +5 -0
  296. data/test/models/member_type.rb +3 -0
  297. data/test/models/membership.rb +9 -0
  298. data/test/models/minimalistic.rb +2 -0
  299. data/test/models/mixed_case_monkey.rb +3 -0
  300. data/test/models/movie.rb +5 -0
  301. data/test/models/order.rb +4 -0
  302. data/test/models/organization.rb +6 -0
  303. data/test/models/owner.rb +5 -0
  304. data/test/models/parrot.rb +16 -0
  305. data/test/models/person.rb +16 -0
  306. data/test/models/pet.rb +5 -0
  307. data/test/models/pirate.rb +70 -0
  308. data/test/models/post.rb +100 -0
  309. data/test/models/price_estimate.rb +3 -0
  310. data/test/models/project.rb +30 -0
  311. data/test/models/reader.rb +4 -0
  312. data/test/models/reference.rb +4 -0
  313. data/test/models/reply.rb +46 -0
  314. data/test/models/ship.rb +10 -0
  315. data/test/models/ship_part.rb +5 -0
  316. data/test/models/sponsor.rb +4 -0
  317. data/test/models/subject.rb +4 -0
  318. data/test/models/subscriber.rb +8 -0
  319. data/test/models/subscription.rb +4 -0
  320. data/test/models/tag.rb +7 -0
  321. data/test/models/tagging.rb +10 -0
  322. data/test/models/task.rb +3 -0
  323. data/test/models/topic.rb +80 -0
  324. data/test/models/toy.rb +6 -0
  325. data/test/models/treasure.rb +8 -0
  326. data/test/models/vertex.rb +9 -0
  327. data/test/models/warehouse_thing.rb +5 -0
  328. data/test/schema/mysql_specific_schema.rb +24 -0
  329. data/test/schema/postgresql_specific_schema.rb +114 -0
  330. data/test/schema/schema.rb +493 -0
  331. data/test/schema/schema2.rb +6 -0
  332. data/test/schema/sqlite_specific_schema.rb +25 -0
  333. metadata +420 -0
@@ -0,0 +1,361 @@
1
+ require "cases/helper"
2
+ require 'models/post'
3
+ require 'models/topic'
4
+ require 'models/comment'
5
+ require 'models/reply'
6
+ require 'models/author'
7
+ require 'models/developer'
8
+
9
+ class NamedScopeTest < ActiveRecord::TestCase
10
+ fixtures :posts, :authors, :topics, :comments, :author_addresses
11
+
12
+ def test_implements_enumerable
13
+ assert !Topic.find(:all).empty?
14
+
15
+ assert_equal Topic.find(:all), Topic.base
16
+ assert_equal Topic.find(:all), Topic.base.to_a
17
+ assert_equal Topic.find(:first), Topic.base.first
18
+ assert_equal Topic.find(:all), Topic.base.map { |i| i }
19
+ end
20
+
21
+ def test_found_items_are_cached
22
+ Topic.columns
23
+ all_posts = Topic.base
24
+
25
+ assert_queries(1) do
26
+ all_posts.collect
27
+ all_posts.collect
28
+ end
29
+ end
30
+
31
+ def test_reload_expires_cache_of_found_items
32
+ all_posts = Topic.base
33
+ all_posts.inspect
34
+
35
+ new_post = Topic.create!
36
+ assert !all_posts.include?(new_post)
37
+ assert all_posts.reload.include?(new_post)
38
+ end
39
+
40
+ def test_delegates_finds_and_calculations_to_the_base_class
41
+ assert !Topic.find(:all).empty?
42
+
43
+ assert_equal Topic.find(:all), Topic.base.find(:all)
44
+ assert_equal Topic.find(:first), Topic.base.find(:first)
45
+ assert_equal Topic.count, Topic.base.count
46
+ assert_equal Topic.average(:replies_count), Topic.base.average(:replies_count)
47
+ end
48
+
49
+ def test_scope_should_respond_to_own_methods_and_methods_of_the_proxy
50
+ assert Topic.approved.respond_to?(:proxy_found)
51
+ assert Topic.approved.respond_to?(:count)
52
+ assert Topic.approved.respond_to?(:length)
53
+ end
54
+
55
+ def test_respond_to_respects_include_private_parameter
56
+ assert !Topic.approved.respond_to?(:load_found)
57
+ assert Topic.approved.respond_to?(:load_found, true)
58
+ end
59
+
60
+ def test_subclasses_inherit_scopes
61
+ assert Topic.scopes.include?(:base)
62
+
63
+ assert Reply.scopes.include?(:base)
64
+ assert_equal Reply.find(:all), Reply.base
65
+ end
66
+
67
+ def test_scopes_with_options_limit_finds_to_those_matching_the_criteria_specified
68
+ assert !Topic.find(:all, :conditions => {:approved => true}).empty?
69
+
70
+ assert_equal Topic.find(:all, :conditions => {:approved => true}), Topic.approved
71
+ assert_equal Topic.count(:conditions => {:approved => true}), Topic.approved.count
72
+ end
73
+
74
+ def test_scopes_with_string_name_can_be_composed
75
+ # NOTE that scopes defined with a string as a name worked on their own
76
+ # but when called on another scope the other scope was completely replaced
77
+ assert_equal Topic.replied.approved, Topic.replied.approved_as_string
78
+ end
79
+
80
+ def test_scopes_can_be_specified_with_deep_hash_conditions
81
+ assert_equal Topic.replied.approved, Topic.replied.approved_as_hash_condition
82
+ end
83
+
84
+ def test_scopes_are_composable
85
+ assert_equal (approved = Topic.find(:all, :conditions => {:approved => true})), Topic.approved
86
+ assert_equal (replied = Topic.find(:all, :conditions => 'replies_count > 0')), Topic.replied
87
+ assert !(approved == replied)
88
+ assert !(approved & replied).empty?
89
+
90
+ assert_equal approved & replied, Topic.approved.replied
91
+ end
92
+
93
+ def test_procedural_scopes
94
+ topics_written_before_the_third = Topic.find(:all, :conditions => ['written_on < ?', topics(:third).written_on])
95
+ topics_written_before_the_second = Topic.find(:all, :conditions => ['written_on < ?', topics(:second).written_on])
96
+ assert_not_equal topics_written_before_the_second, topics_written_before_the_third
97
+
98
+ assert_equal topics_written_before_the_third, Topic.written_before(topics(:third).written_on)
99
+ assert_equal topics_written_before_the_second, Topic.written_before(topics(:second).written_on)
100
+ end
101
+
102
+ def test_procedural_scopes_returning_nil
103
+ all_topics = Topic.find(:all)
104
+
105
+ assert_equal all_topics, Topic.written_before(nil)
106
+ end
107
+
108
+ def test_scopes_with_joins
109
+ address = author_addresses(:david_address)
110
+ posts_with_authors_at_address = Post.find(
111
+ :all, :joins => 'JOIN authors ON authors.id = posts.author_id',
112
+ :conditions => [ 'authors.author_address_id = ?', address.id ]
113
+ )
114
+ assert_equal posts_with_authors_at_address, Post.with_authors_at_address(address)
115
+ end
116
+
117
+ def test_scopes_with_joins_respects_custom_select
118
+ address = author_addresses(:david_address)
119
+ posts_with_authors_at_address_titles = Post.find(:all,
120
+ :select => 'title',
121
+ :joins => 'JOIN authors ON authors.id = posts.author_id',
122
+ :conditions => [ 'authors.author_address_id = ?', address.id ]
123
+ )
124
+ assert_equal posts_with_authors_at_address_titles, Post.with_authors_at_address(address).find(:all, :select => 'title')
125
+ end
126
+
127
+ def test_extensions
128
+ assert_equal 1, Topic.anonymous_extension.one
129
+ assert_equal 2, Topic.named_extension.two
130
+ end
131
+
132
+ def test_multiple_extensions
133
+ assert_equal 2, Topic.multiple_extensions.extension_two
134
+ assert_equal 1, Topic.multiple_extensions.extension_one
135
+ end
136
+
137
+ def test_has_many_associations_have_access_to_named_scopes
138
+ assert_not_equal Post.containing_the_letter_a, authors(:david).posts
139
+ assert !Post.containing_the_letter_a.empty?
140
+
141
+ assert_equal authors(:david).posts & Post.containing_the_letter_a, authors(:david).posts.containing_the_letter_a
142
+ end
143
+
144
+ def test_has_many_through_associations_have_access_to_named_scopes
145
+ assert_not_equal Comment.containing_the_letter_e, authors(:david).comments
146
+ assert !Comment.containing_the_letter_e.empty?
147
+
148
+ assert_equal authors(:david).comments & Comment.containing_the_letter_e, authors(:david).comments.containing_the_letter_e
149
+ end
150
+
151
+ def test_named_scopes_honor_current_scopes_from_when_defined
152
+ assert !Post.ranked_by_comments.limit(5).empty?
153
+ assert !authors(:david).posts.ranked_by_comments.limit(5).empty?
154
+ assert_not_equal Post.ranked_by_comments.limit(5), authors(:david).posts.ranked_by_comments.limit(5)
155
+ assert_not_equal Post.top(5), authors(:david).posts.top(5)
156
+ assert_equal authors(:david).posts.ranked_by_comments.limit(5), authors(:david).posts.top(5)
157
+ assert_equal Post.ranked_by_comments.limit(5), Post.top(5)
158
+ end
159
+
160
+ def test_active_records_have_scope_named__all__
161
+ assert !Topic.find(:all).empty?
162
+
163
+ assert_equal Topic.find(:all), Topic.base
164
+ end
165
+
166
+ def test_active_records_have_scope_named__scoped__
167
+ assert !Topic.find(:all, scope = {:conditions => "content LIKE '%Have%'"}).empty?
168
+
169
+ assert_equal Topic.find(:all, scope), Topic.scoped(scope)
170
+ end
171
+
172
+ def test_proxy_options
173
+ expected_proxy_options = { :conditions => { :approved => true } }
174
+ assert_equal expected_proxy_options, Topic.approved.proxy_options
175
+ end
176
+
177
+ def test_first_and_last_should_support_find_options
178
+ assert_equal Topic.base.first(:order => 'title'), Topic.base.find(:first, :order => 'title')
179
+ assert_equal Topic.base.last(:order => 'title'), Topic.base.find(:last, :order => 'title')
180
+ end
181
+
182
+ def test_first_and_last_should_allow_integers_for_limit
183
+ assert_equal Topic.base.first(2), Topic.base.to_a.first(2)
184
+ assert_equal Topic.base.last(2), Topic.base.to_a.last(2)
185
+ end
186
+
187
+ def test_first_and_last_should_not_use_query_when_results_are_loaded
188
+ topics = Topic.base
189
+ topics.reload # force load
190
+ assert_no_queries do
191
+ topics.first
192
+ topics.last
193
+ end
194
+ end
195
+
196
+ def test_first_and_last_find_options_should_use_query_when_results_are_loaded
197
+ topics = Topic.base
198
+ topics.reload # force load
199
+ assert_queries(2) do
200
+ topics.first(:order => 'title')
201
+ topics.last(:order => 'title')
202
+ end
203
+ end
204
+
205
+ def test_empty_should_not_load_results
206
+ topics = Topic.base
207
+ assert_queries(2) do
208
+ topics.empty? # use count query
209
+ topics.collect # force load
210
+ topics.empty? # use loaded (no query)
211
+ end
212
+ end
213
+
214
+ def test_any_should_not_load_results
215
+ topics = Topic.base
216
+ assert_queries(2) do
217
+ topics.any? # use count query
218
+ topics.collect # force load
219
+ topics.any? # use loaded (no query)
220
+ end
221
+ end
222
+
223
+ def test_any_should_call_proxy_found_if_using_a_block
224
+ topics = Topic.base
225
+ assert_queries(1) do
226
+ topics.expects(:empty?).never
227
+ topics.any? { true }
228
+ end
229
+ end
230
+
231
+ def test_any_should_not_fire_query_if_named_scope_loaded
232
+ topics = Topic.base
233
+ topics.collect # force load
234
+ assert_no_queries { assert topics.any? }
235
+ end
236
+
237
+ def test_should_build_with_proxy_options
238
+ topic = Topic.approved.build({})
239
+ assert topic.approved
240
+ end
241
+
242
+ def test_should_build_new_with_proxy_options
243
+ topic = Topic.approved.new
244
+ assert topic.approved
245
+ end
246
+
247
+ def test_should_create_with_proxy_options
248
+ topic = Topic.approved.create({})
249
+ assert topic.approved
250
+ end
251
+
252
+ def test_should_create_with_bang_with_proxy_options
253
+ topic = Topic.approved.create!({})
254
+ assert topic.approved
255
+ end
256
+
257
+ def test_should_build_with_proxy_options_chained
258
+ topic = Topic.approved.by_lifo.build({})
259
+ assert topic.approved
260
+ assert_equal 'lifo', topic.author_name
261
+ end
262
+
263
+ def test_find_all_should_behave_like_select
264
+ assert_equal Topic.base.select(&:approved), Topic.base.find_all(&:approved)
265
+ end
266
+
267
+ def test_rand_should_select_a_random_object_from_proxy
268
+ assert Topic.approved.rand.is_a?(Topic)
269
+ end
270
+
271
+ def test_should_use_where_in_query_for_named_scope
272
+ assert_equal Developer.find_all_by_name('Jamis').to_set, Developer.find_all_by_id(Developer.jamises).to_set
273
+ end
274
+
275
+ def test_size_should_use_count_when_results_are_not_loaded
276
+ topics = Topic.base
277
+ assert_queries(1) do
278
+ assert_sql(/COUNT/i) { topics.size }
279
+ end
280
+ end
281
+
282
+ def test_size_should_use_length_when_results_are_loaded
283
+ topics = Topic.base
284
+ topics.reload # force load
285
+ assert_no_queries do
286
+ topics.size # use loaded (no query)
287
+ end
288
+ end
289
+
290
+ def test_chaining_with_duplicate_joins
291
+ join = "INNER JOIN comments ON comments.post_id = posts.id"
292
+ post = Post.find(1)
293
+ assert_equal post.comments.size, Post.scoped(:joins => join).scoped(:joins => join, :conditions => "posts.id = #{post.id}").size
294
+ end
295
+
296
+ def test_chaining_should_use_latest_conditions_when_creating
297
+ post = Topic.rejected.new
298
+ assert !post.approved?
299
+
300
+ post = Topic.rejected.approved.new
301
+ assert post.approved?
302
+
303
+ post = Topic.approved.rejected.new
304
+ assert !post.approved?
305
+
306
+ post = Topic.approved.rejected.approved.new
307
+ assert post.approved?
308
+ end
309
+
310
+ def test_chaining_should_use_latest_conditions_when_searching
311
+ # Normal hash conditions
312
+ assert_equal Topic.all(:conditions => {:approved => true}), Topic.rejected.approved.all
313
+ assert_equal Topic.all(:conditions => {:approved => false}), Topic.approved.rejected.all
314
+
315
+ # Nested hash conditions with same keys
316
+ assert_equal [posts(:sti_comments)], Post.with_special_comments.with_very_special_comments.all
317
+
318
+ # Nested hash conditions with different keys
319
+ assert_equal [posts(:sti_comments)], Post.with_special_comments.with_post(4).all.uniq
320
+ end
321
+
322
+ def test_named_scopes_batch_finders
323
+ assert_equal 3, Topic.approved.count
324
+
325
+ assert_queries(4) do
326
+ Topic.approved.find_each(:batch_size => 1) {|t| assert t.approved? }
327
+ end
328
+
329
+ assert_queries(2) do
330
+ Topic.approved.find_in_batches(:batch_size => 2) do |group|
331
+ group.each {|t| assert t.approved? }
332
+ end
333
+ end
334
+ end
335
+
336
+ def test_table_names_for_chaining_scopes_with_and_without_table_name_included
337
+ assert_nothing_raised do
338
+ Comment.for_first_post.for_first_author.all
339
+ end
340
+ end
341
+ end
342
+
343
+ class DynamicScopeMatchTest < ActiveRecord::TestCase
344
+ def test_scoped_by_no_match
345
+ assert_nil ActiveRecord::DynamicScopeMatch.match("not_scoped_at_all")
346
+ end
347
+
348
+ def test_scoped_by
349
+ match = ActiveRecord::DynamicScopeMatch.match("scoped_by_age_and_sex_and_location")
350
+ assert_not_nil match
351
+ assert match.scope?
352
+ assert_equal %w(age sex location), match.attribute_names
353
+ end
354
+ end
355
+
356
+ class DynamicScopeTest < ActiveRecord::TestCase
357
+ def test_dynamic_scope
358
+ assert_equal Post.scoped_by_author_id(1).find(1), Post.find(1)
359
+ assert_equal Post.scoped_by_author_id_and_title(1, "Welcome to the weblog").first, Post.find(:first, :conditions => { :author_id => 1, :title => "Welcome to the weblog"})
360
+ end
361
+ end