activerecord_authorails 1.0.0

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 (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