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,151 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/company'
3
+ require 'fixtures/topic'
4
+ require 'fixtures/reply'
5
+ require 'fixtures/entrant'
6
+ require 'fixtures/developer'
7
+
8
+ class DeprecatedFinderTest < Test::Unit::TestCase
9
+ fixtures :companies, :topics, :entrants, :developers
10
+
11
+ def test_find_all_with_limit
12
+ entrants = assert_deprecated { Entrant.find_all nil, "id ASC", 2 }
13
+ assert_equal 2, entrants.size
14
+ assert_equal entrants(:first), entrants.first
15
+ end
16
+
17
+ def test_find_all_with_prepared_limit_and_offset
18
+ entrants = assert_deprecated { Entrant.find_all nil, "id ASC", [2, 1] }
19
+ assert_equal 2, entrants.size
20
+ assert_equal entrants(:second), entrants.first
21
+ end
22
+
23
+ def test_find_first
24
+ first = assert_deprecated { Topic.find_first "title = 'The First Topic'" }
25
+ assert_equal topics(:first), first
26
+ end
27
+
28
+ def test_find_first_failing
29
+ first = assert_deprecated { Topic.find_first "title = 'The First Topic!'" }
30
+ assert_nil first
31
+ end
32
+
33
+ def test_deprecated_find_on_conditions
34
+ assert_deprecated 'find_on_conditions' do
35
+ assert Topic.find_on_conditions(1, ["approved = ?", false])
36
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find_on_conditions(1, ["approved = ?", true]) }
37
+ end
38
+ end
39
+
40
+ def test_condition_interpolation
41
+ assert_deprecated do
42
+ assert_kind_of Firm, Company.find_first(["name = '%s'", "37signals"])
43
+ assert_nil Company.find_first(["name = '%s'", "37signals!"])
44
+ assert_nil Company.find_first(["name = '%s'", "37signals!' OR 1=1"])
45
+ assert_kind_of Time, Topic.find_first(["id = %d", 1]).written_on
46
+ end
47
+ end
48
+
49
+ def test_bind_variables
50
+ assert_deprecated do
51
+ assert_kind_of Firm, Company.find_first(["name = ?", "37signals"])
52
+ assert_nil Company.find_first(["name = ?", "37signals!"])
53
+ assert_nil Company.find_first(["name = ?", "37signals!' OR 1=1"])
54
+ assert_kind_of Time, Topic.find_first(["id = ?", 1]).written_on
55
+ assert_raises(ActiveRecord::PreparedStatementInvalid) {
56
+ Company.find_first(["id=? AND name = ?", 2])
57
+ }
58
+ assert_raises(ActiveRecord::PreparedStatementInvalid) {
59
+ Company.find_first(["id=?", 2, 3, 4])
60
+ }
61
+ end
62
+ end
63
+
64
+ def test_bind_variables_with_quotes
65
+ Company.create("name" => "37signals' go'es agains")
66
+ assert_deprecated do
67
+ assert_not_nil Company.find_first(["name = ?", "37signals' go'es agains"])
68
+ end
69
+ end
70
+
71
+ def test_named_bind_variables_with_quotes
72
+ Company.create("name" => "37signals' go'es agains")
73
+ assert_deprecated do
74
+ assert_not_nil Company.find_first(["name = :name", {:name => "37signals' go'es agains"}])
75
+ end
76
+ end
77
+
78
+ def test_named_bind_variables
79
+ assert_equal '1', bind(':a', :a => 1) # ' ruby-mode
80
+ assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode
81
+
82
+ assert_deprecated do
83
+ assert_kind_of Firm, Company.find_first(["name = :name", { :name => "37signals" }])
84
+ assert_nil Company.find_first(["name = :name", { :name => "37signals!" }])
85
+ assert_nil Company.find_first(["name = :name", { :name => "37signals!' OR 1=1" }])
86
+ assert_kind_of Time, Topic.find_first(["id = :id", { :id => 1 }]).written_on
87
+ end
88
+ end
89
+
90
+ def test_count
91
+ assert_equal(0, Entrant.count(:conditions => "id > 3"))
92
+ assert_equal(1, Entrant.count(:conditions => ["id > ?", 2]))
93
+ assert_equal(2, Entrant.count(:conditions => ["id > ?", 1]))
94
+ end
95
+
96
+ def test_count_by_sql
97
+ assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
98
+ assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
99
+ assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1]))
100
+ end
101
+
102
+ def test_find_all_with_limit
103
+ assert_deprecated do
104
+ first_five_developers = Developer.find_all nil, 'id ASC', 5
105
+ assert_equal 5, first_five_developers.length
106
+ assert_equal 'David', first_five_developers.first.name
107
+ assert_equal 'fixture_5', first_five_developers.last.name
108
+
109
+ no_developers = Developer.find_all nil, 'id ASC', 0
110
+ assert_equal 0, no_developers.length
111
+
112
+ assert_equal first_five_developers, Developer.find_all(nil, 'id ASC', [5])
113
+ assert_equal no_developers, Developer.find_all(nil, 'id ASC', [0])
114
+ end
115
+ end
116
+
117
+ def test_find_all_with_limit_and_offset
118
+ assert_deprecated do
119
+ first_three_developers = Developer.find_all nil, 'id ASC', [3, 0]
120
+ second_three_developers = Developer.find_all nil, 'id ASC', [3, 3]
121
+ last_two_developers = Developer.find_all nil, 'id ASC', [2, 8]
122
+
123
+ assert_equal 3, first_three_developers.length
124
+ assert_equal 3, second_three_developers.length
125
+ assert_equal 2, last_two_developers.length
126
+
127
+ assert_equal 'David', first_three_developers.first.name
128
+ assert_equal 'fixture_4', second_three_developers.first.name
129
+ assert_equal 'fixture_9', last_two_developers.first.name
130
+ end
131
+ end
132
+
133
+ def test_find_all_by_one_attribute_with_options
134
+ assert_not_deprecated do
135
+ topics = Topic.find_all_by_content("Have a nice day", "id DESC")
136
+ assert topics(:first), topics.last
137
+
138
+ topics = Topic.find_all_by_content("Have a nice day", "id DESC")
139
+ assert topics(:first), topics.first
140
+ end
141
+ end
142
+
143
+ protected
144
+ def bind(statement, *vars)
145
+ if vars.first.is_a?(Hash)
146
+ ActiveRecord::Base.send(:replace_named_bind_variables, statement, vars.first)
147
+ else
148
+ ActiveRecord::Base.send(:replace_bind_variables, statement, vars)
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,25 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/topic'
3
+ require 'fixtures/task'
4
+
5
+ class EmptyDateTimeTest < Test::Unit::TestCase
6
+ def test_assign_empty_date_time
7
+ task = Task.new
8
+ task.starting = ''
9
+ task.ending = nil
10
+ assert_nil task.starting
11
+ assert_nil task.ending
12
+ end
13
+
14
+ def test_assign_empty_date
15
+ topic = Topic.new
16
+ topic.last_read = ''
17
+ assert_nil topic.last_read
18
+ end
19
+
20
+ def test_assign_empty_time
21
+ topic = Topic.new
22
+ topic.bonus_time = ''
23
+ assert_nil topic.bonus_time
24
+ end
25
+ end
@@ -0,0 +1,504 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/company'
3
+ require 'fixtures/topic'
4
+ require 'fixtures/reply'
5
+ require 'fixtures/entrant'
6
+ require 'fixtures/developer'
7
+ require 'fixtures/post'
8
+
9
+ class FinderTest < Test::Unit::TestCase
10
+ fixtures :companies, :topics, :entrants, :developers, :developers_projects, :posts, :accounts
11
+
12
+ def test_find
13
+ assert_equal(topics(:first).title, Topic.find(1).title)
14
+ end
15
+
16
+ # find should handle strings that come from URLs
17
+ # (example: Category.find(params[:id]))
18
+ def test_find_with_string
19
+ assert_equal(Topic.find(1).title,Topic.find("1").title)
20
+ end
21
+
22
+ def test_exists
23
+ assert Topic.exists?(1)
24
+ assert Topic.exists?("1")
25
+ assert Topic.exists?(:author_name => "David")
26
+ assert Topic.exists?(:author_name => "Mary", :approved => true)
27
+ assert Topic.exists?(["parent_id = ?", 1])
28
+ assert !Topic.exists?(45)
29
+ assert !Topic.exists?("foo")
30
+ assert_raise(NoMethodError) { Topic.exists?([1,2]) }
31
+ end
32
+
33
+ def test_find_by_array_of_one_id
34
+ assert_kind_of(Array, Topic.find([ 1 ]))
35
+ assert_equal(1, Topic.find([ 1 ]).length)
36
+ end
37
+
38
+ def test_find_by_ids
39
+ assert_equal(2, Topic.find(1, 2).length)
40
+ assert_equal(topics(:second).title, Topic.find([ 2 ]).first.title)
41
+ end
42
+
43
+ def test_find_an_empty_array
44
+ assert_equal [], Topic.find([])
45
+ end
46
+
47
+ def test_find_by_ids_missing_one
48
+ assert_raises(ActiveRecord::RecordNotFound) {
49
+ Topic.find(1, 2, 45)
50
+ }
51
+ end
52
+
53
+ def test_find_all_with_limit
54
+ entrants = Entrant.find(:all, :order => "id ASC", :limit => 2)
55
+
56
+ assert_equal(2, entrants.size)
57
+ assert_equal(entrants(:first).name, entrants.first.name)
58
+ end
59
+
60
+ def test_find_all_with_prepared_limit_and_offset
61
+ entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 1)
62
+
63
+ assert_equal(2, entrants.size)
64
+ assert_equal(entrants(:second).name, entrants.first.name)
65
+
66
+ entrants = Entrant.find(:all, :order => "id ASC", :limit => 2, :offset => 2)
67
+ assert_equal(1, entrants.size)
68
+ assert_equal(entrants(:third).name, entrants.first.name)
69
+ end
70
+
71
+ def test_find_all_with_limit_and_offset_and_multiple_orderings
72
+ developers = Developer.find(:all, :order => "salary ASC, id DESC", :limit => 3, :offset => 1)
73
+ assert_equal ["David", "fixture_10", "fixture_9"], developers.collect {|d| d.name}
74
+ end
75
+
76
+ def test_find_with_limit_and_condition
77
+ developers = Developer.find(:all, :order => "id DESC", :conditions => "salary = 100000", :limit => 3, :offset =>7)
78
+ assert_equal(1, developers.size)
79
+ assert_equal("fixture_3", developers.first.name)
80
+ end
81
+
82
+ def test_find_with_entire_select_statement
83
+ topics = Topic.find_by_sql "SELECT * FROM topics WHERE author_name = 'Mary'"
84
+
85
+ assert_equal(1, topics.size)
86
+ assert_equal(topics(:second).title, topics.first.title)
87
+ end
88
+
89
+ def test_find_with_prepared_select_statement
90
+ topics = Topic.find_by_sql ["SELECT * FROM topics WHERE author_name = ?", "Mary"]
91
+
92
+ assert_equal(1, topics.size)
93
+ assert_equal(topics(:second).title, topics.first.title)
94
+ end
95
+
96
+ def test_find_by_sql_with_sti_on_joined_table
97
+ accounts = Account.find_by_sql("SELECT * FROM accounts INNER JOIN companies ON companies.id = accounts.firm_id")
98
+ assert_equal [Account], accounts.collect(&:class).uniq
99
+ end
100
+
101
+ def test_find_first
102
+ first = Topic.find(:first, :conditions => "title = 'The First Topic'")
103
+ assert_equal(topics(:first).title, first.title)
104
+ end
105
+
106
+ def test_find_first_failing
107
+ first = Topic.find(:first, :conditions => "title = 'The First Topic!'")
108
+ assert_nil(first)
109
+ end
110
+
111
+ def test_unexisting_record_exception_handling
112
+ assert_raises(ActiveRecord::RecordNotFound) {
113
+ Topic.find(1).parent
114
+ }
115
+
116
+ Topic.find(2).topic
117
+ end
118
+
119
+ def test_find_only_some_columns
120
+ topic = Topic.find(1, :select => "author_name")
121
+ assert_raises(NoMethodError) { topic.title }
122
+ assert_equal "David", topic.author_name
123
+ assert !topic.attribute_present?("title")
124
+ assert !topic.respond_to?("title")
125
+ assert topic.attribute_present?("author_name")
126
+ assert topic.respond_to?("author_name")
127
+ end
128
+
129
+ def test_find_on_array_conditions
130
+ assert Topic.find(1, :conditions => ["approved = ?", false])
131
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => ["approved = ?", true]) }
132
+ end
133
+
134
+ def test_find_on_hash_conditions
135
+ assert Topic.find(1, :conditions => { :approved => false })
136
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :approved => true }) }
137
+ end
138
+
139
+ def test_find_on_hash_conditions_with_range
140
+ assert_equal [1,2], Topic.find(:all, :conditions => { :id => 1..2 }).map(&:id).sort
141
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :id => 2..3 }) }
142
+ end
143
+
144
+ def test_find_on_hash_conditions_with_multiple_ranges
145
+ assert_equal [1,2,3], Comment.find(:all, :conditions => { :id => 1..3, :post_id => 1..2 }).map(&:id).sort
146
+ assert_equal [1], Comment.find(:all, :conditions => { :id => 1..1, :post_id => 1..10 }).map(&:id).sort
147
+ end
148
+
149
+ def test_find_on_multiple_hash_conditions
150
+ assert Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => false })
151
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) }
152
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "HHC", :replies_count => 1, :approved => false }) }
153
+ assert_raises(ActiveRecord::RecordNotFound) { Topic.find(1, :conditions => { :author_name => "David", :title => "The First Topic", :replies_count => 1, :approved => true }) }
154
+ end
155
+
156
+ def test_condition_array_interpolation
157
+ assert_kind_of Firm, Company.find(:first, :conditions => ["name = '%s'", "37signals"])
158
+ assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!"])
159
+ assert_nil Company.find(:first, :conditions => ["name = '%s'", "37signals!' OR 1=1"])
160
+ assert_kind_of Time, Topic.find(:first, :conditions => ["id = %d", 1]).written_on
161
+ end
162
+
163
+ def test_condition_hash_interpolation
164
+ assert_kind_of Firm, Company.find(:first, :conditions => { :name => "37signals"})
165
+ assert_nil Company.find(:first, :conditions => { :name => "37signals!"})
166
+ assert_kind_of Time, Topic.find(:first, :conditions => {:id => 1}).written_on
167
+ end
168
+
169
+ def test_hash_condition_find_malformed
170
+ assert_raises(ActiveRecord::StatementInvalid) {
171
+ Company.find(:first, :conditions => { :id => 2, :dhh => true })
172
+ }
173
+ end
174
+
175
+ def test_hash_condition_find_with_escaped_characters
176
+ Company.create("name" => "Ain't noth'n like' \#stuff")
177
+ assert Company.find(:first, :conditions => { :name => "Ain't noth'n like' \#stuff" })
178
+ end
179
+
180
+ def test_hash_condition_find_with_array
181
+ p1, p2 = Post.find(:all, :limit => 2, :order => 'id asc')
182
+ assert_equal [p1, p2], Post.find(:all, :conditions => { :id => [p1, p2] }, :order => 'id asc')
183
+ assert_equal [p1, p2], Post.find(:all, :conditions => { :id => [p1, p2.id] }, :order => 'id asc')
184
+ end
185
+
186
+ def test_hash_condition_find_with_nil
187
+ topic = Topic.find(:first, :conditions => { :last_read => nil } )
188
+ assert_not_nil topic
189
+ assert_nil topic.last_read
190
+ end
191
+
192
+ def test_bind_variables
193
+ assert_kind_of Firm, Company.find(:first, :conditions => ["name = ?", "37signals"])
194
+ assert_nil Company.find(:first, :conditions => ["name = ?", "37signals!"])
195
+ assert_nil Company.find(:first, :conditions => ["name = ?", "37signals!' OR 1=1"])
196
+ assert_kind_of Time, Topic.find(:first, :conditions => ["id = ?", 1]).written_on
197
+ assert_raises(ActiveRecord::PreparedStatementInvalid) {
198
+ Company.find(:first, :conditions => ["id=? AND name = ?", 2])
199
+ }
200
+ assert_raises(ActiveRecord::PreparedStatementInvalid) {
201
+ Company.find(:first, :conditions => ["id=?", 2, 3, 4])
202
+ }
203
+ end
204
+
205
+ def test_bind_variables_with_quotes
206
+ Company.create("name" => "37signals' go'es agains")
207
+ assert Company.find(:first, :conditions => ["name = ?", "37signals' go'es agains"])
208
+ end
209
+
210
+ def test_named_bind_variables_with_quotes
211
+ Company.create("name" => "37signals' go'es agains")
212
+ assert Company.find(:first, :conditions => ["name = :name", {:name => "37signals' go'es agains"}])
213
+ end
214
+
215
+ def test_bind_arity
216
+ assert_nothing_raised { bind '' }
217
+ assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '', 1 }
218
+
219
+ assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '?' }
220
+ assert_nothing_raised { bind '?', 1 }
221
+ assert_raises(ActiveRecord::PreparedStatementInvalid) { bind '?', 1, 1 }
222
+ end
223
+
224
+ def test_named_bind_variables
225
+ assert_equal '1', bind(':a', :a => 1) # ' ruby-mode
226
+ assert_equal '1 1', bind(':a :a', :a => 1) # ' ruby-mode
227
+
228
+ assert_kind_of Firm, Company.find(:first, :conditions => ["name = :name", { :name => "37signals" }])
229
+ assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!" }])
230
+ assert_nil Company.find(:first, :conditions => ["name = :name", { :name => "37signals!' OR 1=1" }])
231
+ assert_kind_of Time, Topic.find(:first, :conditions => ["id = :id", { :id => 1 }]).written_on
232
+ end
233
+
234
+ def test_bind_enumerable
235
+ assert_equal '1,2,3', bind('?', [1, 2, 3])
236
+ assert_equal %('a','b','c'), bind('?', %w(a b c))
237
+
238
+ assert_equal '1,2,3', bind(':a', :a => [1, 2, 3])
239
+ assert_equal %('a','b','c'), bind(':a', :a => %w(a b c)) # '
240
+
241
+ require 'set'
242
+ assert_equal '1,2,3', bind('?', Set.new([1, 2, 3]))
243
+ assert_equal %('a','b','c'), bind('?', Set.new(%w(a b c)))
244
+
245
+ assert_equal '1,2,3', bind(':a', :a => Set.new([1, 2, 3]))
246
+ assert_equal %('a','b','c'), bind(':a', :a => Set.new(%w(a b c))) # '
247
+ end
248
+
249
+ def test_bind_empty_enumerable
250
+ quoted_nil = ActiveRecord::Base.connection.quote(nil)
251
+ assert_equal quoted_nil, bind('?', [])
252
+ assert_equal " in (#{quoted_nil})", bind(' in (?)', [])
253
+ assert_equal "foo in (#{quoted_nil})", bind('foo in (?)', [])
254
+ end
255
+
256
+ def test_bind_string
257
+ assert_equal "''", bind('?', '')
258
+ end
259
+
260
+ def test_bind_record
261
+ o = Struct.new(:quoted_id).new(1)
262
+ assert_equal '1', bind('?', o)
263
+
264
+ os = [o] * 3
265
+ assert_equal '1,1,1', bind('?', os)
266
+ end
267
+
268
+ def test_string_sanitation
269
+ assert_not_equal "'something ' 1=1'", ActiveRecord::Base.sanitize("something ' 1=1")
270
+ assert_equal "'something; select table'", ActiveRecord::Base.sanitize("something; select table")
271
+ end
272
+
273
+ def test_count
274
+ assert_equal(0, Entrant.count(:conditions => "id > 3"))
275
+ assert_equal(1, Entrant.count(:conditions => ["id > ?", 2]))
276
+ assert_equal(2, Entrant.count(:conditions => ["id > ?", 1]))
277
+ end
278
+
279
+ def test_count_by_sql
280
+ assert_equal(0, Entrant.count_by_sql("SELECT COUNT(*) FROM entrants WHERE id > 3"))
281
+ assert_equal(1, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 2]))
282
+ assert_equal(2, Entrant.count_by_sql(["SELECT COUNT(*) FROM entrants WHERE id > ?", 1]))
283
+ end
284
+
285
+ def test_find_by_one_attribute
286
+ assert_equal topics(:first), Topic.find_by_title("The First Topic")
287
+ assert_nil Topic.find_by_title("The First Topic!")
288
+ end
289
+
290
+ def test_find_by_one_attribute_with_order_option
291
+ assert_equal accounts(:signals37), Account.find_by_credit_limit(50, :order => 'id')
292
+ assert_equal accounts(:rails_core_account), Account.find_by_credit_limit(50, :order => 'id DESC')
293
+ end
294
+
295
+ def test_find_by_one_attribute_with_conditions
296
+ assert_equal accounts(:rails_core_account), Account.find_by_credit_limit(50, :conditions => ['firm_id = ?', 6])
297
+ end
298
+
299
+ def test_find_by_one_attribute_with_several_options
300
+ assert_equal accounts(:unknown), Account.find_by_credit_limit(50, :order => 'id DESC', :conditions => ['id != ?', 3])
301
+ end
302
+
303
+ def test_find_by_one_missing_attribute
304
+ assert_raises(NoMethodError) { Topic.find_by_undertitle("The First Topic!") }
305
+ end
306
+
307
+ def test_find_by_invalid_method_syntax
308
+ assert_raises(NoMethodError) { Topic.fail_to_find_by_title("The First Topic") }
309
+ assert_raises(NoMethodError) { Topic.find_by_title?("The First Topic") }
310
+ assert_raises(NoMethodError) { Topic.fail_to_find_or_create_by_title("Nonexistent Title") }
311
+ assert_raises(NoMethodError) { Topic.find_or_create_by_title?("Nonexistent Title") }
312
+ end
313
+
314
+ def test_find_by_two_attributes
315
+ assert_equal topics(:first), Topic.find_by_title_and_author_name("The First Topic", "David")
316
+ assert_nil Topic.find_by_title_and_author_name("The First Topic", "Mary")
317
+ end
318
+
319
+ def test_find_all_by_one_attribute
320
+ topics = Topic.find_all_by_content("Have a nice day")
321
+ assert_equal 2, topics.size
322
+ assert topics.include?(topics(:first))
323
+
324
+ assert_equal [], Topic.find_all_by_title("The First Topic!!")
325
+ end
326
+
327
+ def test_find_all_by_one_attribute_with_options
328
+ topics = Topic.find_all_by_content("Have a nice day", :order => "id DESC")
329
+ assert topics(:first), topics.last
330
+
331
+ topics = Topic.find_all_by_content("Have a nice day", :order => "id")
332
+ assert topics(:first), topics.first
333
+ end
334
+
335
+ def test_find_all_by_array_attribute
336
+ assert_equal 2, Topic.find_all_by_title(["The First Topic", "The Second Topic's of the day"]).size
337
+ end
338
+
339
+ def test_find_all_by_boolean_attribute
340
+ topics = Topic.find_all_by_approved(false)
341
+ assert_equal 1, topics.size
342
+ assert topics.include?(topics(:first))
343
+
344
+ topics = Topic.find_all_by_approved(true)
345
+ assert_equal 1, topics.size
346
+ assert topics.include?(topics(:second))
347
+ end
348
+
349
+ def test_find_by_nil_attribute
350
+ topic = Topic.find_by_last_read nil
351
+ assert_not_nil topic
352
+ assert_nil topic.last_read
353
+ end
354
+
355
+ def test_find_all_by_nil_attribute
356
+ topics = Topic.find_all_by_last_read nil
357
+ assert_equal 1, topics.size
358
+ assert_nil topics[0].last_read
359
+ end
360
+
361
+ def test_find_by_nil_and_not_nil_attributes
362
+ topic = Topic.find_by_last_read_and_author_name nil, "Mary"
363
+ assert_equal "Mary", topic.author_name
364
+ end
365
+
366
+ def test_find_all_by_nil_and_not_nil_attributes
367
+ topics = Topic.find_all_by_last_read_and_author_name nil, "Mary"
368
+ assert_equal 1, topics.size
369
+ assert_equal "Mary", topics[0].author_name
370
+ end
371
+
372
+ def test_find_or_create_from_one_attribute
373
+ number_of_companies = Company.count
374
+ sig38 = Company.find_or_create_by_name("38signals")
375
+ assert_equal number_of_companies + 1, Company.count
376
+ assert_equal sig38, Company.find_or_create_by_name("38signals")
377
+ assert !sig38.new_record?
378
+ end
379
+
380
+ def test_find_or_create_from_two_attributes
381
+ number_of_topics = Topic.count
382
+ another = Topic.find_or_create_by_title_and_author_name("Another topic","John")
383
+ assert_equal number_of_topics + 1, Topic.count
384
+ assert_equal another, Topic.find_or_create_by_title_and_author_name("Another topic", "John")
385
+ assert !another.new_record?
386
+ end
387
+
388
+ def test_find_or_initialize_from_one_attribute
389
+ sig38 = Company.find_or_initialize_by_name("38signals")
390
+ assert_equal "38signals", sig38.name
391
+ assert sig38.new_record?
392
+ end
393
+
394
+ def test_find_or_initialize_from_two_attributes
395
+ another = Topic.find_or_initialize_by_title_and_author_name("Another topic","John")
396
+ assert_equal "Another topic", another.title
397
+ assert_equal "John", another.author_name
398
+ assert another.new_record?
399
+ end
400
+
401
+ def test_find_with_bad_sql
402
+ assert_raises(ActiveRecord::StatementInvalid) { Topic.find_by_sql "select 1 from badtable" }
403
+ end
404
+
405
+ def test_find_with_invalid_params
406
+ assert_raises(ArgumentError) { Topic.find :first, :join => "It should be `joins'" }
407
+ assert_raises(ArgumentError) { Topic.find :first, :conditions => '1 = 1', :join => "It should be `joins'" }
408
+ end
409
+
410
+ def test_find_all_with_limit
411
+ first_five_developers = Developer.find :all, :order => 'id ASC', :limit => 5
412
+ assert_equal 5, first_five_developers.length
413
+ assert_equal 'David', first_five_developers.first.name
414
+ assert_equal 'fixture_5', first_five_developers.last.name
415
+
416
+ no_developers = Developer.find :all, :order => 'id ASC', :limit => 0
417
+ assert_equal 0, no_developers.length
418
+ end
419
+
420
+ def test_find_all_with_limit_and_offset
421
+ first_three_developers = Developer.find :all, :order => 'id ASC', :limit => 3, :offset => 0
422
+ second_three_developers = Developer.find :all, :order => 'id ASC', :limit => 3, :offset => 3
423
+ last_two_developers = Developer.find :all, :order => 'id ASC', :limit => 2, :offset => 8
424
+
425
+ assert_equal 3, first_three_developers.length
426
+ assert_equal 3, second_three_developers.length
427
+ assert_equal 2, last_two_developers.length
428
+
429
+ assert_equal 'David', first_three_developers.first.name
430
+ assert_equal 'fixture_4', second_three_developers.first.name
431
+ assert_equal 'fixture_9', last_two_developers.first.name
432
+ end
433
+
434
+ def test_find_all_with_limit_and_offset_and_multiple_order_clauses
435
+ first_three_posts = Post.find :all, :order => 'author_id, id', :limit => 3, :offset => 0
436
+ second_three_posts = Post.find :all, :order => ' author_id,id ', :limit => 3, :offset => 3
437
+ last_posts = Post.find :all, :order => ' author_id, id ', :limit => 3, :offset => 6
438
+
439
+ assert_equal [[0,3],[1,1],[1,2]], first_three_posts.map { |p| [p.author_id, p.id] }
440
+ assert_equal [[1,4],[1,5],[1,6]], second_three_posts.map { |p| [p.author_id, p.id] }
441
+ assert_equal [[2,7]], last_posts.map { |p| [p.author_id, p.id] }
442
+ end
443
+
444
+ def test_find_all_with_join
445
+ developers_on_project_one = Developer.find(
446
+ :all,
447
+ :joins => 'LEFT JOIN developers_projects ON developers.id = developers_projects.developer_id',
448
+ :conditions => 'project_id=1'
449
+ )
450
+ assert_equal 3, developers_on_project_one.length
451
+ developer_names = developers_on_project_one.map { |d| d.name }
452
+ assert developer_names.include?('David')
453
+ assert developer_names.include?('Jamis')
454
+ end
455
+
456
+ def test_find_by_id_with_conditions_with_or
457
+ assert_nothing_raised do
458
+ Post.find([1,2,3],
459
+ :conditions => "posts.id <= 3 OR posts.#{QUOTED_TYPE} = 'Post'")
460
+ end
461
+ end
462
+
463
+ # http://dev.rubyonrails.org/ticket/6778
464
+ def test_find_ignores_previously_inserted_record
465
+ post = Post.create!(:title => 'test', :body => 'it out')
466
+ assert_equal [], Post.find_all_by_id(nil)
467
+ end
468
+
469
+ def test_find_by_empty_ids
470
+ assert_equal [], Post.find([])
471
+ end
472
+
473
+ def test_find_by_empty_in_condition
474
+ assert_equal [], Post.find(:all, :conditions => ['id in (?)', []])
475
+ end
476
+
477
+ def test_find_by_records
478
+ p1, p2 = Post.find(:all, :limit => 2, :order => 'id asc')
479
+ assert_equal [p1, p2], Post.find(:all, :conditions => ['id in (?)', [p1, p2]], :order => 'id asc')
480
+ assert_equal [p1, p2], Post.find(:all, :conditions => ['id in (?)', [p1, p2.id]], :order => 'id asc')
481
+ end
482
+
483
+ def test_select_value
484
+ assert_equal "37signals", Company.connection.select_value("SELECT name FROM companies WHERE id = 1")
485
+ assert_nil Company.connection.select_value("SELECT name FROM companies WHERE id = -1")
486
+ # make sure we didn't break count...
487
+ assert_equal 0, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = 'Halliburton'")
488
+ assert_equal 1, Company.count_by_sql("SELECT COUNT(*) FROM companies WHERE name = '37signals'")
489
+ end
490
+
491
+ def test_select_values
492
+ assert_equal ["1","2","3","4","5","6","7","8","9"], Company.connection.select_values("SELECT id FROM companies ORDER BY id").map! { |i| i.to_s }
493
+ assert_equal ["37signals","Summit","Microsoft", "Flamboyant Software", "Ex Nihilo", "RailsCore", "Leetsoft", "Jadedpixel", "Odegy"], Company.connection.select_values("SELECT name FROM companies ORDER BY id")
494
+ end
495
+
496
+ protected
497
+ def bind(statement, *vars)
498
+ if vars.first.is_a?(Hash)
499
+ ActiveRecord::Base.send(:replace_named_bind_variables, statement, vars.first)
500
+ else
501
+ ActiveRecord::Base.send(:replace_bind_variables, statement, vars)
502
+ end
503
+ end
504
+ end