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,52 @@
1
+ require 'abstract_unit'
2
+
3
+ class PostgresqlDatatype < ActiveRecord::Base
4
+ end
5
+
6
+ class PGDataTypeTest < Test::Unit::TestCase
7
+ self.use_transactional_fixtures = false
8
+
9
+ TABLE_NAME = 'postgresql_datatypes'
10
+ COLUMNS = [
11
+ 'id SERIAL PRIMARY KEY',
12
+ 'commission_by_quarter INTEGER[]',
13
+ 'nicknames TEXT[]'
14
+ ]
15
+
16
+ def setup
17
+ @connection = ActiveRecord::Base.connection
18
+ @connection.execute "CREATE TABLE #{TABLE_NAME} (#{COLUMNS.join(',')})"
19
+ @connection.execute "INSERT INTO #{TABLE_NAME} (commission_by_quarter, nicknames) VALUES ( '{35000,21000,18000,17000}', '{foo,bar,baz}' )"
20
+ @first = PostgresqlDatatype.find( 1 )
21
+ end
22
+
23
+ def teardown
24
+ @connection.execute "DROP TABLE #{TABLE_NAME}"
25
+ end
26
+
27
+ def test_data_type_of_array_types
28
+ assert_equal :string, @first.column_for_attribute("commission_by_quarter").type
29
+ assert_equal :string, @first.column_for_attribute("nicknames").type
30
+ end
31
+
32
+ def test_array_values
33
+ assert_equal '{35000,21000,18000,17000}', @first.commission_by_quarter
34
+ assert_equal '{foo,bar,baz}', @first.nicknames
35
+ end
36
+
37
+ def test_update_integer_array
38
+ new_value = '{32800,95000,29350,17000}'
39
+ assert @first.commission_by_quarter = new_value
40
+ assert @first.save
41
+ assert @first.reload
42
+ assert_equal @first.commission_by_quarter, new_value
43
+ end
44
+
45
+ def test_update_text_array
46
+ new_value = '{robby,robert,rob,robbie}'
47
+ assert @first.nicknames = new_value
48
+ assert @first.save
49
+ assert @first.reload
50
+ assert_equal @first.nicknames, new_value
51
+ end
52
+ end
@@ -0,0 +1,16 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/default'
3
+
4
+ class DefaultTest < Test::Unit::TestCase
5
+ def test_default_timestamp
6
+ default = Default.new
7
+ assert_instance_of(Time, default.default_timestamp)
8
+ assert_equal(:datetime, default.column_for_attribute(:default_timestamp).type)
9
+
10
+ # Variance should be small; increase if required -- e.g., if test db is on
11
+ # remote host and clocks aren't synchronized.
12
+ t1 = Time.new
13
+ accepted_variance = 1.0
14
+ assert_in_delta(t1.to_f, default.default_timestamp.to_f, accepted_variance)
15
+ end
16
+ end
@@ -0,0 +1,60 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/default'
3
+ require 'fixtures/entrant'
4
+
5
+ class DefaultTest < Test::Unit::TestCase
6
+ def test_nil_defaults_for_not_null_columns
7
+ column_defaults =
8
+ if current_adapter?(:MysqlAdapter)
9
+ { 'id' => nil, 'name' => '', 'course_id' => nil }
10
+ else
11
+ { 'id' => nil, 'name' => nil, 'course_id' => nil }
12
+ end
13
+
14
+ column_defaults.each do |name, default|
15
+ column = Entrant.columns_hash[name]
16
+ assert !column.null, "#{name} column should be NOT NULL"
17
+ assert_equal default, column.default, "#{name} column should be DEFAULT #{default.inspect}"
18
+ end
19
+ end
20
+
21
+ if current_adapter?(:MysqlAdapter)
22
+ # MySQL uses an implicit default 0 rather than NULL unless in strict mode.
23
+ # We use an implicit NULL so schema.rb is compatible with other databases.
24
+ def test_mysql_integer_not_null_defaults
25
+ klass = Class.new(ActiveRecord::Base)
26
+ klass.table_name = 'test_integer_not_null_default_zero'
27
+ klass.connection.create_table klass.table_name do |t|
28
+ t.column :zero, :integer, :null => false, :default => 0
29
+ t.column :omit, :integer, :null => false
30
+ end
31
+
32
+ assert_equal 0, klass.columns_hash['zero'].default
33
+ assert !klass.columns_hash['zero'].null
34
+ assert_equal nil, klass.columns_hash['omit'].default
35
+ assert !klass.columns_hash['omit'].null
36
+
37
+ assert_raise(ActiveRecord::StatementInvalid) { klass.create! }
38
+
39
+ assert_nothing_raised do
40
+ instance = klass.create!(:omit => 1)
41
+ assert_equal 0, instance.zero
42
+ assert_equal 1, instance.omit
43
+ end
44
+ ensure
45
+ klass.connection.drop_table(klass.table_name) rescue nil
46
+ end
47
+ end
48
+
49
+ if current_adapter?(:PostgreSQLAdapter, :SQLServerAdapter, :FirebirdAdapter, :OpenBaseAdapter, :OracleAdapter)
50
+ def test_default_integers
51
+ default = Default.new
52
+ assert_instance_of Fixnum, default.positive_integer
53
+ assert_equal 1, default.positive_integer
54
+ assert_instance_of Fixnum, default.negative_integer
55
+ assert_equal -1, default.negative_integer
56
+ assert_instance_of BigDecimal, default.decimal_number
57
+ assert_equal BigDecimal.new("2.78"), default.decimal_number
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,396 @@
1
+ require 'abstract_unit'
2
+ require 'fixtures/developer'
3
+ require 'fixtures/project'
4
+ require 'fixtures/company'
5
+ require 'fixtures/topic'
6
+ require 'fixtures/reply'
7
+
8
+ # Can't declare new classes in test case methods, so tests before that
9
+ bad_collection_keys = false
10
+ begin
11
+ class Car < ActiveRecord::Base; has_many :wheels, :name => "wheels"; end
12
+ rescue ArgumentError
13
+ bad_collection_keys = true
14
+ end
15
+ raise "ActiveRecord should have barked on bad collection keys" unless bad_collection_keys
16
+
17
+
18
+ class DeprecatedAssociationWarningsTest < Test::Unit::TestCase
19
+ def test_deprecation_warnings
20
+ assert_deprecated('find_first') { Firm.find_first }
21
+ assert_deprecated('find_all') { Firm.find_all }
22
+ assert_deprecated('has_account?') { Firm.find(:first).has_account? }
23
+ assert_deprecated('has_clients?') { Firm.find(:first).has_clients? }
24
+ end
25
+ end
26
+
27
+ class DeprecatedAssociationsTest < Test::Unit::TestCase
28
+ fixtures :accounts, :companies, :developers, :projects, :topics,
29
+ :developers_projects
30
+
31
+ def setup
32
+ @firm = companies(:first_firm)
33
+ end
34
+
35
+ def test_has_many_find
36
+ assert_equal 2, @firm.clients.length
37
+ end
38
+
39
+ def test_has_many_orders
40
+ assert_equal "Summit", @firm.clients.first.name
41
+ end
42
+
43
+ def test_has_many_class_name
44
+ assert_equal "Microsoft", @firm.clients_sorted_desc.first.name
45
+ end
46
+
47
+ def test_has_many_foreign_key
48
+ assert_equal "Microsoft", @firm.clients_of_firm.first.name
49
+ end
50
+
51
+ def test_has_many_conditions
52
+ assert_equal "Microsoft", @firm.clients_like_ms.first.name
53
+ end
54
+
55
+ def test_has_many_sql
56
+ assert_equal "Microsoft", @firm.clients_using_sql.first.name
57
+ assert_equal 1, @firm.clients_using_sql.count
58
+ assert_equal 1, @firm.clients_using_sql.count
59
+ end
60
+
61
+ def test_has_many_counter_sql
62
+ assert_equal 1, @firm.clients_using_counter_sql.count
63
+ end
64
+
65
+ def test_has_many_queries
66
+ assert !@firm.clients.loaded?
67
+ assert_deprecated 'has_clients?' do
68
+ assert_queries(1) { assert @firm.has_clients? }
69
+ end
70
+ assert !@firm.clients.loaded?
71
+ assert_deprecated 'clients_count' do
72
+ assert_queries(1) { assert_equal 2, @firm.clients_count }
73
+ end
74
+ assert !@firm.clients.loaded?
75
+ assert_queries(1) { @firm.clients.size }
76
+ assert !@firm.clients.loaded?
77
+ assert_queries(0) { @firm.clients }
78
+ assert !@firm.clients.loaded?
79
+ assert_queries(1) { @firm.clients.reload }
80
+ assert @firm.clients.loaded?
81
+ assert_queries(0) { @firm.clients.size }
82
+ assert_queries(1) { @firm.clients.count }
83
+ end
84
+
85
+ def test_has_many_dependence
86
+ count = Client.count
87
+ Firm.find(:first).destroy
88
+ assert_equal count - 2, Client.count
89
+ end
90
+
91
+ uses_transaction :test_has_many_dependence_with_transaction_support_on_failure
92
+ def test_has_many_dependence_with_transaction_support_on_failure
93
+ count = Client.count
94
+
95
+ clients = @firm.clients
96
+ clients.last.instance_eval { def before_destroy() raise "Trigger rollback" end }
97
+
98
+ @firm.destroy rescue "do nothing"
99
+
100
+ assert_equal count, Client.count
101
+ end
102
+
103
+ def test_has_one_dependence
104
+ num_accounts = Account.count
105
+ assert_not_nil @firm.account
106
+ @firm.destroy
107
+ assert_equal num_accounts - 1, Account.count
108
+ end
109
+
110
+ def test_has_one_dependence_with_missing_association
111
+ Account.destroy_all
112
+ assert_nil @firm.account
113
+ @firm.destroy
114
+ end
115
+
116
+ def test_belongs_to
117
+ client = companies(:second_client)
118
+ assert_deprecated('has_firm?') do
119
+ assert companies(:second_client).has_firm?, "Microsoft should have a firm"
120
+ end
121
+ assert_equal companies(:first_firm), client.firm, "Microsoft should have a firm"
122
+ end
123
+
124
+ def test_belongs_to_with_different_class_name
125
+ assert_equal @firm, companies(:second_client).firm_with_other_name
126
+ end
127
+
128
+ def test_belongs_to_with_condition
129
+ assert_equal @firm, companies(:second_client).firm_with_condition
130
+ end
131
+
132
+ def test_belongs_to_equality
133
+ assert_equal @firm, companies(:second_client).firm, 'Microsoft should have 37signals as firm'
134
+ end
135
+
136
+ def test_has_one
137
+ assert_equal accounts(:signals37), @firm.account
138
+ assert_deprecated 'has_account?' do
139
+ assert @firm.has_account?, "37signals should have an account"
140
+ end
141
+ assert_deprecated 'firm?' do
142
+ assert accounts(:signals37).firm?(@firm), "37signals account should be able to backtrack"
143
+ end
144
+ assert_deprecated 'has_firm?' do
145
+ assert accounts(:signals37).has_firm?, "37signals account should be able to backtrack"
146
+ end
147
+
148
+ assert_nil accounts(:unknown).firm, "Unknown isn't linked"
149
+ end
150
+
151
+ def test_has_many_dependence_on_account
152
+ num_accounts = Account.count
153
+ @firm.destroy
154
+ assert_equal num_accounts - 1, Account.count
155
+ end
156
+
157
+ def test_find_in
158
+ assert_deprecated 'find_in_clients' do
159
+ assert_equal companies(:first_client), @firm.find_in_clients(2)
160
+ assert_raises(ActiveRecord::RecordNotFound) { @firm.find_in_clients(6) }
161
+ end
162
+ end
163
+
164
+ def test_force_reload
165
+ ActiveSupport::Deprecation.silence do
166
+ firm = Firm.new("name" => "A New Firm, Inc")
167
+ firm.save
168
+ firm.clients.each {|c|} # forcing to load all clients
169
+ assert firm.clients.empty?, "New firm shouldn't have client objects"
170
+ assert !firm.has_clients?, "New firm shouldn't have clients"
171
+ assert_equal 0, firm.clients_count, "New firm should have 0 clients"
172
+
173
+ client = Client.new("name" => "TheClient.com", "firm_id" => firm.id)
174
+ client.save
175
+
176
+ assert firm.clients.empty?, "New firm should have cached no client objects"
177
+ assert !firm.has_clients?, "New firm should have cached a no-clients response"
178
+ assert_equal 0, firm.clients_count, "New firm should have cached 0 clients count"
179
+
180
+ assert !firm.clients(true).empty?, "New firm should have reloaded client objects"
181
+ assert firm.has_clients?(true), "New firm should have reloaded with a have-clients response"
182
+ assert_equal 1, firm.clients_count(true), "New firm should have reloaded clients count"
183
+ end
184
+ end
185
+
186
+ def test_included_in_collection
187
+ assert @firm.clients.include?(Client.find(2))
188
+ end
189
+
190
+ def test_build_to_collection
191
+ count = @firm.clients_of_firm.count
192
+ new_client = nil
193
+ assert_deprecated 'build_to_clients_of_firm' do
194
+ new_client = @firm.build_to_clients_of_firm("name" => "Another Client")
195
+ end
196
+ assert_equal "Another Client", new_client.name
197
+ assert new_client.save
198
+
199
+ assert_equal @firm, new_client.firm
200
+ assert_equal count + 1, @firm.clients_of_firm.count
201
+ end
202
+
203
+ def test_create_in_collection
204
+ assert_deprecated 'create_in_clients_of_firm' do
205
+ assert_equal @firm.create_in_clients_of_firm("name" => "Another Client"), @firm.clients_of_firm(true).last
206
+ end
207
+ end
208
+
209
+ def test_has_and_belongs_to_many
210
+ david = Developer.find(1)
211
+ assert_deprecated 'has_projects?' do
212
+ assert david.has_projects?
213
+ end
214
+ assert_deprecated 'projects_count' do
215
+ assert_equal 2, david.projects_count
216
+ end
217
+
218
+ active_record = Project.find(1)
219
+ assert_deprecated 'has_developers?' do
220
+ assert active_record.has_developers?
221
+ end
222
+ assert_deprecated 'developers_count' do
223
+ assert_equal 3, active_record.developers_count
224
+ end
225
+ assert active_record.developers.include?(david)
226
+ end
227
+
228
+ def test_has_and_belongs_to_many_removing
229
+ david = Developer.find(1)
230
+ active_record = Project.find(1)
231
+
232
+ assert_deprecated do
233
+ david.remove_projects(active_record)
234
+ assert_equal 1, david.projects_count
235
+ assert_equal 2, active_record.developers_count
236
+ end
237
+ end
238
+
239
+ def test_has_and_belongs_to_many_zero
240
+ david = Developer.find(1)
241
+ assert_deprecated do
242
+ david.remove_projects Project.find_all
243
+ assert_equal 0, david.projects_count
244
+ assert !david.has_projects?
245
+ end
246
+ end
247
+
248
+ def test_has_and_belongs_to_many_adding
249
+ jamis = Developer.find(2)
250
+ action_controller = Project.find(2)
251
+
252
+ assert_deprecated do
253
+ jamis.add_projects(action_controller)
254
+ assert_equal 2, jamis.projects_count
255
+ assert_equal 2, action_controller.developers_count
256
+ end
257
+ end
258
+
259
+ def test_has_and_belongs_to_many_adding_from_the_project
260
+ jamis = Developer.find(2)
261
+ action_controller = Project.find(2)
262
+
263
+ assert_deprecated do
264
+ action_controller.add_developers(jamis)
265
+ assert_equal 2, jamis.projects_count
266
+ assert_equal 2, action_controller.developers_count
267
+ end
268
+ end
269
+
270
+ def test_has_and_belongs_to_many_adding_a_collection
271
+ aredridel = Developer.new("name" => "Aredridel")
272
+ aredridel.save
273
+
274
+ assert_deprecated do
275
+ aredridel.add_projects([ Project.find(1), Project.find(2) ])
276
+ assert_equal 2, aredridel.projects_count
277
+ end
278
+ end
279
+
280
+ def test_belongs_to_counter
281
+ topic = Topic.create("title" => "Apple", "content" => "hello world")
282
+ assert_equal 0, topic.send(:read_attribute, "replies_count"), "No replies yet"
283
+
284
+ reply = assert_deprecated { topic.create_in_replies("title" => "I'm saying no!", "content" => "over here") }
285
+ assert_equal 1, Topic.find(topic.id).send(:read_attribute, "replies_count"), "First reply created"
286
+
287
+ reply.destroy
288
+ assert_equal 0, Topic.find(topic.id).send(:read_attribute, "replies_count"), "First reply deleted"
289
+ end
290
+
291
+ def test_natural_assignment_of_has_one
292
+ apple = Firm.create("name" => "Apple")
293
+ citibank = Account.create("credit_limit" => 10)
294
+ apple.account = citibank
295
+ assert_equal apple.id, citibank.firm_id
296
+ end
297
+
298
+ def test_natural_assignment_of_belongs_to
299
+ apple = Firm.create("name" => "Apple")
300
+ citibank = Account.create("credit_limit" => 10)
301
+ citibank.firm = apple
302
+ assert_equal apple.id, citibank.firm_id
303
+ end
304
+
305
+ def test_natural_assignment_of_has_many
306
+ apple = Firm.create("name" => "Apple")
307
+ natural = Client.create("name" => "Natural Company")
308
+ apple.clients << natural
309
+ assert_equal apple.id, natural.firm_id
310
+ assert_equal Client.find(natural.id), Firm.find(apple.id).clients.find(natural.id)
311
+ apple.clients.delete natural
312
+ assert_raises(ActiveRecord::RecordNotFound) {
313
+ Firm.find(apple.id).clients.find(natural.id)
314
+ }
315
+ end
316
+
317
+ def test_natural_adding_of_has_and_belongs_to_many
318
+ rails = Project.create("name" => "Rails")
319
+ ap = Project.create("name" => "Action Pack")
320
+ john = Developer.create("name" => "John")
321
+ mike = Developer.create("name" => "Mike")
322
+ rails.developers << john
323
+ rails.developers << mike
324
+
325
+ assert_equal Developer.find(john.id), Project.find(rails.id).developers.find(john.id)
326
+ assert_equal Developer.find(mike.id), Project.find(rails.id).developers.find(mike.id)
327
+ assert_equal Project.find(rails.id), Developer.find(mike.id).projects.find(rails.id)
328
+ assert_equal Project.find(rails.id), Developer.find(john.id).projects.find(rails.id)
329
+ ap.developers << john
330
+ assert_equal Developer.find(john.id), Project.find(ap.id).developers.find(john.id)
331
+ assert_equal Project.find(ap.id), Developer.find(john.id).projects.find(ap.id)
332
+
333
+ ap.developers.delete john
334
+ assert_raises(ActiveRecord::RecordNotFound) {
335
+ Project.find(ap.id).developers.find(john.id)
336
+ }
337
+ assert_raises(ActiveRecord::RecordNotFound) {
338
+ Developer.find(john.id).projects.find(ap.id)
339
+ }
340
+ end
341
+
342
+ def test_storing_in_pstore
343
+ require "pstore"
344
+ require "tmpdir"
345
+ apple = Firm.create("name" => "Apple")
346
+ natural = Client.new("name" => "Natural Company")
347
+ apple.clients << natural
348
+
349
+ db = PStore.new(File.join(Dir.tmpdir, "ar-pstore-association-test"))
350
+ db.transaction do
351
+ db["apple"] = apple
352
+ end
353
+
354
+ db = PStore.new(File.join(Dir.tmpdir, "ar-pstore-association-test"))
355
+ db.transaction do
356
+ assert_equal "Natural Company", db["apple"].clients.first.name
357
+ end
358
+ end
359
+
360
+ def test_has_many_find_all
361
+ assert_deprecated 'find_all_in_clients' do
362
+ assert_equal 2, @firm.find_all_in_clients("#{QUOTED_TYPE} = 'Client'").length
363
+ assert_equal 1, @firm.find_all_in_clients("name = 'Summit'").length
364
+ end
365
+ end
366
+
367
+ def test_has_one
368
+ assert_equal Account.find(1), @firm.account, "37signals should have an account"
369
+ assert_equal @firm, Account.find(1).firm, "37signals account should be able to backtrack"
370
+ assert_nil Account.find(2).firm, "Unknown isn't linked"
371
+ end
372
+
373
+ def test_has_one_build
374
+ firm = Firm.new("name" => "GlobalMegaCorp")
375
+ assert firm.save
376
+
377
+ account = firm.build_account(:credit_limit => 1000)
378
+ assert account.save
379
+ assert_equal account, firm.account
380
+ end
381
+
382
+ def test_has_one_failing_build_association
383
+ firm = Firm.new("name" => "GlobalMegaCorp")
384
+ firm.save
385
+
386
+ account = firm.build_account
387
+ assert !account.save
388
+ assert_equal "can't be empty", account.errors.on("credit_limit")
389
+ end
390
+
391
+ def test_has_one_create
392
+ firm = Firm.new("name" => "GlobalMegaCorp")
393
+ firm.save
394
+ assert_equal firm.create_account("credit_limit" => 1000), firm.account
395
+ end
396
+ end