ibm_db 3.0.5 → 4.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 (580) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -0
  3. data/LICENSE +1 -1
  4. data/MANIFEST +14 -14
  5. data/ParameterizedQueries README +6 -6
  6. data/README +208 -225
  7. data/ext/Makefile.nt32 +181 -181
  8. data/ext/Makefile.nt32.191 +212 -212
  9. data/ext/extconf.rb +291 -291
  10. data/ext/ibm_db.c +11887 -11887
  11. data/ext/ruby_ibm_db.h +241 -241
  12. data/ext/ruby_ibm_db_cli.c +866 -866
  13. data/ext/ruby_ibm_db_cli.h +500 -500
  14. data/init.rb +41 -41
  15. data/lib/IBM_DB.rb +27 -27
  16. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +3452 -3177
  17. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +5 -2
  18. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  19. data/test/active_record/connection_adapters/fake_adapter.rb +49 -46
  20. data/test/assets/example.log +1 -1
  21. data/test/assets/test.txt +1 -1
  22. data/test/cases/adapter_test.rb +351 -276
  23. data/test/cases/adapters/mysql2/active_schema_test.rb +193 -0
  24. data/test/cases/adapters/mysql2/bind_parameter_test.rb +50 -0
  25. data/test/cases/adapters/mysql2/boolean_test.rb +100 -0
  26. data/test/cases/adapters/mysql2/case_sensitivity_test.rb +63 -0
  27. data/test/cases/adapters/mysql2/charset_collation_test.rb +54 -0
  28. data/test/cases/adapters/mysql2/connection_test.rb +210 -0
  29. data/test/cases/adapters/mysql2/datetime_precision_quoting_test.rb +45 -0
  30. data/test/cases/adapters/mysql2/enum_test.rb +26 -0
  31. data/test/cases/adapters/mysql2/explain_test.rb +21 -0
  32. data/test/cases/adapters/mysql2/json_test.rb +195 -0
  33. data/test/cases/adapters/mysql2/mysql2_adapter_test.rb +83 -0
  34. data/test/cases/adapters/mysql2/reserved_word_test.rb +152 -0
  35. data/test/cases/adapters/mysql2/schema_migrations_test.rb +59 -0
  36. data/test/cases/adapters/mysql2/schema_test.rb +126 -0
  37. data/test/cases/adapters/mysql2/sp_test.rb +36 -0
  38. data/test/cases/adapters/mysql2/sql_types_test.rb +14 -0
  39. data/test/cases/adapters/mysql2/table_options_test.rb +42 -0
  40. data/test/cases/adapters/mysql2/unsigned_type_test.rb +66 -0
  41. data/test/cases/adapters/postgresql/active_schema_test.rb +98 -0
  42. data/test/cases/adapters/postgresql/array_test.rb +339 -0
  43. data/test/cases/adapters/postgresql/bit_string_test.rb +82 -0
  44. data/test/cases/adapters/postgresql/bytea_test.rb +134 -0
  45. data/test/cases/adapters/postgresql/case_insensitive_test.rb +26 -0
  46. data/test/cases/adapters/postgresql/change_schema_test.rb +38 -0
  47. data/test/cases/adapters/postgresql/cidr_test.rb +25 -0
  48. data/test/cases/adapters/postgresql/citext_test.rb +78 -0
  49. data/test/cases/adapters/postgresql/collation_test.rb +53 -0
  50. data/test/cases/adapters/postgresql/composite_test.rb +132 -0
  51. data/test/cases/adapters/postgresql/connection_test.rb +257 -0
  52. data/test/cases/adapters/postgresql/datatype_test.rb +92 -0
  53. data/test/cases/adapters/postgresql/domain_test.rb +47 -0
  54. data/test/cases/adapters/postgresql/enum_test.rb +91 -0
  55. data/test/cases/adapters/postgresql/explain_test.rb +20 -0
  56. data/test/cases/adapters/postgresql/extension_migration_test.rb +63 -0
  57. data/test/cases/adapters/postgresql/full_text_test.rb +44 -0
  58. data/test/cases/adapters/postgresql/geometric_test.rb +378 -0
  59. data/test/cases/adapters/postgresql/hstore_test.rb +382 -0
  60. data/test/cases/adapters/postgresql/infinity_test.rb +69 -0
  61. data/test/cases/adapters/postgresql/integer_test.rb +25 -0
  62. data/test/cases/adapters/postgresql/json_test.rb +237 -0
  63. data/test/cases/adapters/postgresql/ltree_test.rb +53 -0
  64. data/test/cases/adapters/postgresql/money_test.rb +96 -0
  65. data/test/cases/adapters/postgresql/network_test.rb +94 -0
  66. data/test/cases/adapters/postgresql/numbers_test.rb +49 -0
  67. data/test/cases/adapters/postgresql/postgresql_adapter_test.rb +405 -0
  68. data/test/cases/adapters/postgresql/prepared_statements_test.rb +22 -0
  69. data/test/cases/adapters/postgresql/quoting_test.rb +44 -0
  70. data/test/cases/adapters/postgresql/range_test.rb +343 -0
  71. data/test/cases/adapters/postgresql/referential_integrity_test.rb +111 -0
  72. data/test/cases/adapters/postgresql/rename_table_test.rb +34 -0
  73. data/test/cases/adapters/postgresql/schema_authorization_test.rb +119 -0
  74. data/test/cases/adapters/postgresql/schema_test.rb +597 -0
  75. data/test/cases/adapters/postgresql/serial_test.rb +154 -0
  76. data/test/cases/adapters/postgresql/statement_pool_test.rb +41 -0
  77. data/test/cases/adapters/postgresql/timestamp_test.rb +90 -0
  78. data/test/cases/adapters/postgresql/type_lookup_test.rb +33 -0
  79. data/test/cases/adapters/postgresql/utils_test.rb +62 -0
  80. data/test/cases/adapters/postgresql/uuid_test.rb +294 -0
  81. data/test/cases/adapters/postgresql/xml_test.rb +54 -0
  82. data/test/cases/adapters/sqlite3/collation_test.rb +53 -0
  83. data/test/cases/adapters/sqlite3/copy_table_test.rb +98 -0
  84. data/test/cases/adapters/sqlite3/explain_test.rb +21 -0
  85. data/test/cases/adapters/sqlite3/quoting_test.rb +101 -0
  86. data/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb +441 -0
  87. data/test/cases/adapters/sqlite3/sqlite3_create_folder_test.rb +24 -0
  88. data/test/cases/adapters/sqlite3/statement_pool_test.rb +20 -0
  89. data/test/cases/aggregations_test.rb +168 -158
  90. data/test/cases/ar_schema_test.rb +146 -161
  91. data/test/cases/associations/association_scope_test.rb +16 -21
  92. data/test/cases/associations/belongs_to_associations_test.rb +1141 -1029
  93. data/test/cases/associations/bidirectional_destroy_dependencies_test.rb +41 -0
  94. data/test/cases/associations/callbacks_test.rb +190 -192
  95. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -188
  96. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -36
  97. data/test/cases/associations/eager_load_nested_include_test.rb +126 -128
  98. data/test/cases/associations/eager_singularization_test.rb +148 -148
  99. data/test/cases/associations/eager_test.rb +1514 -1429
  100. data/test/cases/associations/extension_test.rb +87 -82
  101. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +1004 -972
  102. data/test/cases/associations/has_many_associations_test.rb +2501 -2182
  103. data/test/cases/associations/has_many_through_associations_test.rb +1271 -1204
  104. data/test/cases/associations/has_one_associations_test.rb +707 -610
  105. data/test/cases/associations/has_one_through_associations_test.rb +383 -380
  106. data/test/cases/associations/inner_join_association_test.rb +139 -139
  107. data/test/cases/associations/inverse_associations_test.rb +733 -706
  108. data/test/cases/associations/join_model_test.rb +777 -754
  109. data/test/cases/associations/left_outer_join_association_test.rb +88 -0
  110. data/test/cases/associations/nested_through_associations_test.rb +579 -579
  111. data/test/cases/associations/required_test.rb +102 -82
  112. data/test/cases/associations_test.rb +385 -380
  113. data/test/cases/attribute_decorators_test.rb +125 -125
  114. data/test/cases/attribute_methods/read_test.rb +60 -60
  115. data/test/cases/attribute_methods_test.rb +1009 -952
  116. data/test/cases/attribute_set_test.rb +270 -210
  117. data/test/cases/attribute_test.rb +246 -180
  118. data/test/cases/attributes_test.rb +253 -136
  119. data/test/cases/autosave_association_test.rb +1708 -1595
  120. data/test/cases/base_test.rb +1713 -1664
  121. data/test/cases/batches_test.rb +489 -212
  122. data/test/cases/binary_test.rb +44 -52
  123. data/test/cases/bind_parameter_test.rb +110 -100
  124. data/test/cases/cache_key_test.rb +25 -0
  125. data/test/cases/calculations_test.rb +798 -646
  126. data/test/cases/callbacks_test.rb +636 -543
  127. data/test/cases/clone_test.rb +40 -40
  128. data/test/cases/coders/json_test.rb +15 -0
  129. data/test/cases/coders/yaml_column_test.rb +63 -63
  130. data/test/cases/collection_cache_key_test.rb +115 -0
  131. data/test/cases/column_alias_test.rb +17 -17
  132. data/test/cases/column_definition_test.rb +92 -123
  133. data/test/cases/comment_test.rb +143 -0
  134. data/test/cases/connection_adapters/adapter_leasing_test.rb +56 -54
  135. data/test/cases/connection_adapters/connection_handler_test.rb +160 -53
  136. data/test/cases/connection_adapters/connection_specification_test.rb +12 -12
  137. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +255 -293
  138. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +69 -65
  139. data/test/cases/connection_adapters/quoting_test.rb +13 -13
  140. data/test/cases/connection_adapters/schema_cache_test.rb +61 -56
  141. data/test/cases/connection_adapters/type_lookup_test.rb +118 -110
  142. data/test/cases/connection_management_test.rb +112 -122
  143. data/test/cases/connection_pool_test.rb +521 -346
  144. data/test/cases/connection_specification/resolver_test.rb +131 -116
  145. data/test/cases/core_test.rb +112 -112
  146. data/test/cases/counter_cache_test.rb +214 -209
  147. data/test/cases/custom_locking_test.rb +17 -17
  148. data/test/cases/database_statements_test.rb +34 -19
  149. data/test/cases/{invalid_date_test.rb → date_test.rb} +44 -32
  150. data/test/cases/date_time_precision_test.rb +106 -0
  151. data/test/cases/date_time_test.rb +61 -61
  152. data/test/cases/defaults_test.rb +218 -223
  153. data/test/cases/dirty_test.rb +763 -785
  154. data/test/cases/disconnected_test.rb +30 -28
  155. data/test/cases/dup_test.rb +157 -157
  156. data/test/cases/enum_test.rb +444 -290
  157. data/test/cases/errors_test.rb +16 -0
  158. data/test/cases/explain_subscriber_test.rb +64 -64
  159. data/test/cases/explain_test.rb +87 -76
  160. data/test/cases/finder_respond_to_test.rb +60 -60
  161. data/test/cases/finder_test.rb +1294 -1169
  162. data/test/cases/fixture_set/file_test.rb +156 -138
  163. data/test/cases/fixtures_test.rb +988 -908
  164. data/test/cases/forbidden_attributes_protection_test.rb +165 -99
  165. data/test/cases/habtm_destroy_order_test.rb +61 -61
  166. data/test/cases/helper.rb +204 -210
  167. data/test/cases/hot_compatibility_test.rb +142 -54
  168. data/test/cases/i18n_test.rb +45 -45
  169. data/test/cases/inheritance_test.rb +606 -375
  170. data/test/cases/integration_test.rb +155 -139
  171. data/test/cases/invalid_connection_test.rb +24 -22
  172. data/test/cases/invertible_migration_test.rb +387 -295
  173. data/test/cases/json_serialization_test.rb +311 -302
  174. data/test/cases/locking_test.rb +493 -477
  175. data/test/cases/log_subscriber_test.rb +225 -136
  176. data/test/cases/migration/change_schema_test.rb +458 -512
  177. data/test/cases/migration/change_table_test.rb +256 -224
  178. data/test/cases/migration/column_attributes_test.rb +176 -192
  179. data/test/cases/migration/column_positioning_test.rb +56 -56
  180. data/test/cases/migration/columns_test.rb +310 -304
  181. data/test/cases/migration/command_recorder_test.rb +350 -305
  182. data/test/cases/migration/compatibility_test.rb +118 -0
  183. data/test/cases/migration/create_join_table_test.rb +157 -148
  184. data/test/cases/migration/foreign_key_test.rb +360 -328
  185. data/test/cases/migration/helper.rb +39 -39
  186. data/test/cases/migration/index_test.rb +218 -216
  187. data/test/cases/migration/logger_test.rb +36 -36
  188. data/test/cases/migration/pending_migrations_test.rb +52 -53
  189. data/test/cases/migration/references_foreign_key_test.rb +216 -169
  190. data/test/cases/migration/references_index_test.rb +101 -101
  191. data/test/cases/migration/references_statements_test.rb +136 -116
  192. data/test/cases/migration/rename_table_test.rb +93 -93
  193. data/test/cases/migration_test.rb +1157 -959
  194. data/test/cases/migrator_test.rb +470 -388
  195. data/test/cases/mixin_test.rb +68 -70
  196. data/test/cases/modules_test.rb +172 -173
  197. data/test/cases/multiparameter_attributes_test.rb +372 -350
  198. data/test/cases/multiple_db_test.rb +122 -115
  199. data/test/cases/nested_attributes_test.rb +1098 -1070
  200. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -144
  201. data/test/cases/persistence_test.rb +1001 -909
  202. data/test/cases/pooled_connections_test.rb +81 -81
  203. data/test/cases/primary_keys_test.rb +376 -237
  204. data/test/cases/query_cache_test.rb +446 -326
  205. data/test/cases/quoting_test.rb +202 -156
  206. data/test/cases/readonly_test.rb +119 -118
  207. data/test/cases/reaper_test.rb +85 -85
  208. data/test/cases/reflection_test.rb +509 -463
  209. data/test/cases/relation/delegation_test.rb +63 -68
  210. data/test/cases/relation/merging_test.rb +157 -161
  211. data/test/cases/relation/mutation_test.rb +183 -165
  212. data/test/cases/relation/or_test.rb +92 -0
  213. data/test/cases/relation/predicate_builder_test.rb +16 -14
  214. data/test/cases/relation/record_fetch_warning_test.rb +40 -0
  215. data/test/cases/relation/where_chain_test.rb +105 -181
  216. data/test/cases/relation/where_clause_test.rb +182 -0
  217. data/test/cases/relation/where_test.rb +322 -300
  218. data/test/cases/relation_test.rb +328 -319
  219. data/test/cases/relations_test.rb +2026 -1815
  220. data/test/cases/reload_models_test.rb +22 -22
  221. data/test/cases/result_test.rb +90 -80
  222. data/test/cases/sanitize_test.rb +176 -83
  223. data/test/cases/schema_dumper_test.rb +457 -463
  224. data/test/cases/schema_loading_test.rb +52 -0
  225. data/test/cases/scoping/default_scoping_test.rb +528 -454
  226. data/test/cases/scoping/named_scoping_test.rb +561 -524
  227. data/test/cases/scoping/relation_scoping_test.rb +400 -357
  228. data/test/cases/secure_token_test.rb +32 -0
  229. data/test/cases/serialization_test.rb +104 -104
  230. data/test/cases/serialized_attribute_test.rb +364 -277
  231. data/test/cases/statement_cache_test.rb +136 -98
  232. data/test/cases/store_test.rb +195 -194
  233. data/test/cases/suppressor_test.rb +63 -0
  234. data/test/cases/tasks/database_tasks_test.rb +462 -398
  235. data/test/cases/tasks/mysql_rake_test.rb +345 -324
  236. data/test/cases/tasks/postgresql_rake_test.rb +304 -250
  237. data/test/cases/tasks/sqlite_rake_test.rb +220 -193
  238. data/test/cases/test_case.rb +131 -123
  239. data/test/cases/test_fixtures_test.rb +36 -0
  240. data/test/cases/time_precision_test.rb +102 -0
  241. data/test/cases/timestamp_test.rb +501 -467
  242. data/test/cases/touch_later_test.rb +121 -0
  243. data/test/cases/transaction_callbacks_test.rb +518 -452
  244. data/test/cases/transaction_isolation_test.rb +106 -106
  245. data/test/cases/transactions_test.rb +834 -817
  246. data/test/cases/type/adapter_specific_registry_test.rb +133 -0
  247. data/test/cases/type/date_time_test.rb +14 -0
  248. data/test/cases/type/integer_test.rb +27 -121
  249. data/test/cases/type/string_test.rb +22 -36
  250. data/test/cases/type/type_map_test.rb +177 -177
  251. data/test/cases/type_test.rb +39 -0
  252. data/test/cases/types_test.rb +24 -141
  253. data/test/cases/unconnected_test.rb +33 -33
  254. data/test/cases/validations/absence_validation_test.rb +73 -0
  255. data/test/cases/validations/association_validation_test.rb +97 -86
  256. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -84
  257. data/test/cases/validations/i18n_validation_test.rb +86 -90
  258. data/test/cases/validations/length_validation_test.rb +79 -47
  259. data/test/cases/validations/presence_validation_test.rb +103 -68
  260. data/test/cases/validations/uniqueness_validation_test.rb +548 -457
  261. data/test/cases/validations_repair_helper.rb +19 -23
  262. data/test/cases/validations_test.rb +194 -165
  263. data/test/cases/view_test.rb +216 -119
  264. data/test/cases/yaml_serialization_test.rb +121 -126
  265. data/test/config.example.yml +97 -0
  266. data/test/config.rb +5 -5
  267. data/test/fixtures/accounts.yml +29 -29
  268. data/test/fixtures/admin/accounts.yml +2 -2
  269. data/test/fixtures/admin/users.yml +10 -10
  270. data/test/fixtures/author_addresses.original +11 -0
  271. data/test/fixtures/author_addresses.yml +17 -17
  272. data/test/fixtures/author_favorites.yml +3 -3
  273. data/test/fixtures/authors.original +17 -0
  274. data/test/fixtures/authors.yml +23 -23
  275. data/test/fixtures/bad_posts.yml +9 -0
  276. data/test/fixtures/binaries.yml +133 -133
  277. data/test/fixtures/books.yml +31 -11
  278. data/test/fixtures/bulbs.yml +5 -5
  279. data/test/fixtures/cars.yml +9 -9
  280. data/test/fixtures/categories.yml +19 -19
  281. data/test/fixtures/categories/special_categories.yml +9 -9
  282. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -4
  283. data/test/fixtures/categories_ordered.yml +7 -7
  284. data/test/fixtures/categories_posts.yml +31 -31
  285. data/test/fixtures/categorizations.yml +23 -23
  286. data/test/fixtures/clubs.yml +8 -8
  287. data/test/fixtures/collections.yml +3 -3
  288. data/test/fixtures/colleges.yml +3 -3
  289. data/test/fixtures/comments.yml +65 -65
  290. data/test/fixtures/companies.yml +67 -67
  291. data/test/fixtures/computers.yml +10 -10
  292. data/test/fixtures/content.yml +3 -0
  293. data/test/fixtures/content_positions.yml +3 -0
  294. data/test/fixtures/courses.yml +8 -8
  295. data/test/fixtures/customers.yml +25 -25
  296. data/test/fixtures/dashboards.yml +6 -6
  297. data/test/fixtures/dead_parrots.yml +5 -0
  298. data/test/fixtures/developers.yml +22 -22
  299. data/test/fixtures/developers_projects.yml +16 -16
  300. data/test/fixtures/dog_lovers.yml +7 -7
  301. data/test/fixtures/dogs.yml +4 -4
  302. data/test/fixtures/doubloons.yml +3 -3
  303. data/test/fixtures/edges.yml +5 -5
  304. data/test/fixtures/entrants.yml +14 -14
  305. data/test/fixtures/essays.yml +6 -6
  306. data/test/fixtures/faces.yml +11 -11
  307. data/test/fixtures/fk_test_has_fk.yml +3 -3
  308. data/test/fixtures/fk_test_has_pk.yml +1 -1
  309. data/test/fixtures/friendships.yml +4 -4
  310. data/test/fixtures/funny_jokes.yml +10 -10
  311. data/test/fixtures/interests.yml +33 -33
  312. data/test/fixtures/items.yml +3 -3
  313. data/test/fixtures/jobs.yml +7 -7
  314. data/test/fixtures/legacy_things.yml +3 -3
  315. data/test/fixtures/live_parrots.yml +4 -0
  316. data/test/fixtures/mateys.yml +4 -4
  317. data/test/fixtures/member_details.yml +8 -8
  318. data/test/fixtures/member_types.yml +6 -6
  319. data/test/fixtures/members.yml +11 -11
  320. data/test/fixtures/memberships.yml +34 -34
  321. data/test/fixtures/men.yml +5 -5
  322. data/test/fixtures/minimalistics.yml +2 -2
  323. data/test/fixtures/minivans.yml +5 -5
  324. data/test/fixtures/mixed_case_monkeys.yml +6 -6
  325. data/test/fixtures/mixins.yml +29 -29
  326. data/test/fixtures/movies.yml +7 -7
  327. data/test/fixtures/naked/yml/accounts.yml +1 -1
  328. data/test/fixtures/naked/yml/companies.yml +1 -1
  329. data/test/fixtures/naked/yml/courses.yml +1 -1
  330. data/test/fixtures/naked/yml/parrots.yml +2 -0
  331. data/test/fixtures/naked/yml/trees.yml +3 -0
  332. data/test/fixtures/nodes.yml +29 -0
  333. data/test/fixtures/organizations.yml +5 -5
  334. data/test/fixtures/other_comments.yml +6 -0
  335. data/test/fixtures/other_dogs.yml +2 -0
  336. data/test/fixtures/other_posts.yml +7 -0
  337. data/test/fixtures/other_topics.yml +42 -42
  338. data/test/fixtures/owners.yml +9 -9
  339. data/test/fixtures/parrots.yml +27 -27
  340. data/test/fixtures/parrots_pirates.yml +7 -7
  341. data/test/fixtures/people.yml +24 -24
  342. data/test/fixtures/peoples_treasures.yml +3 -3
  343. data/test/fixtures/pets.yml +19 -19
  344. data/test/fixtures/pirates.yml +15 -12
  345. data/test/fixtures/posts.yml +80 -80
  346. data/test/fixtures/price_estimates.yml +16 -7
  347. data/test/fixtures/products.yml +4 -4
  348. data/test/fixtures/projects.yml +7 -7
  349. data/test/fixtures/ratings.yml +14 -14
  350. data/test/fixtures/readers.yml +11 -11
  351. data/test/fixtures/references.yml +17 -17
  352. data/test/fixtures/reserved_words/distinct.yml +5 -5
  353. data/test/fixtures/reserved_words/distinct_select.yml +11 -11
  354. data/test/fixtures/reserved_words/group.yml +14 -14
  355. data/test/fixtures/reserved_words/select.yml +8 -8
  356. data/test/fixtures/reserved_words/values.yml +7 -7
  357. data/test/fixtures/ships.yml +6 -6
  358. data/test/fixtures/speedometers.yml +8 -8
  359. data/test/fixtures/sponsors.yml +12 -12
  360. data/test/fixtures/string_key_objects.yml +7 -7
  361. data/test/fixtures/subscribers.yml +10 -10
  362. data/test/fixtures/subscriptions.yml +12 -12
  363. data/test/fixtures/taggings.yml +78 -78
  364. data/test/fixtures/tags.yml +11 -11
  365. data/test/fixtures/tasks.yml +7 -7
  366. data/test/fixtures/teapots.yml +3 -3
  367. data/test/fixtures/to_be_linked/accounts.yml +2 -2
  368. data/test/fixtures/to_be_linked/users.yml +10 -10
  369. data/test/fixtures/topics.yml +49 -49
  370. data/test/fixtures/toys.yml +14 -14
  371. data/test/fixtures/traffic_lights.yml +9 -9
  372. data/test/fixtures/treasures.yml +10 -10
  373. data/test/fixtures/trees.yml +3 -0
  374. data/test/fixtures/uuid_children.yml +3 -3
  375. data/test/fixtures/uuid_parents.yml +2 -2
  376. data/test/fixtures/variants.yml +4 -4
  377. data/test/fixtures/vegetables.yml +19 -19
  378. data/test/fixtures/vertices.yml +3 -3
  379. data/test/fixtures/warehouse_things.yml +2 -2
  380. data/test/fixtures/zines.yml +5 -5
  381. data/test/migrations/10_urban/9_add_expressions.rb +11 -11
  382. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -15
  383. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -12
  384. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -9
  385. data/test/migrations/missing/1_people_have_last_names.rb +9 -9
  386. data/test/migrations/missing/3_we_need_reminders.rb +12 -12
  387. data/test/migrations/missing/4_innocent_jointable.rb +12 -12
  388. data/test/migrations/rename/1_we_need_things.rb +11 -11
  389. data/test/migrations/rename/2_rename_things.rb +9 -9
  390. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -9
  391. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -9
  392. data/test/migrations/to_copy2/1_create_articles.rb +7 -7
  393. data/test/migrations/to_copy2/2_create_comments.rb +7 -7
  394. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -9
  395. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -9
  396. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -9
  397. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -7
  398. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -7
  399. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -9
  400. data/test/migrations/valid/2_we_need_reminders.rb +12 -12
  401. data/test/migrations/valid/3_innocent_jointable.rb +12 -12
  402. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -9
  403. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -12
  404. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -12
  405. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -9
  406. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -12
  407. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -12
  408. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -8
  409. data/test/models/admin.rb +5 -5
  410. data/test/models/admin/account.rb +3 -3
  411. data/test/models/admin/randomly_named_c1.rb +6 -2
  412. data/test/models/admin/user.rb +40 -40
  413. data/test/models/aircraft.rb +5 -4
  414. data/test/models/arunit2_model.rb +3 -3
  415. data/test/models/author.rb +209 -212
  416. data/test/models/auto_id.rb +4 -4
  417. data/test/models/autoloadable/extra_firm.rb +2 -2
  418. data/test/models/binary.rb +2 -2
  419. data/test/models/bird.rb +12 -12
  420. data/test/models/book.rb +23 -18
  421. data/test/models/boolean.rb +2 -2
  422. data/test/models/bulb.rb +52 -51
  423. data/test/models/cake_designer.rb +3 -3
  424. data/test/models/car.rb +29 -26
  425. data/test/models/carrier.rb +2 -2
  426. data/test/models/cat.rb +10 -0
  427. data/test/models/categorization.rb +19 -19
  428. data/test/models/category.rb +35 -35
  429. data/test/models/chef.rb +8 -7
  430. data/test/models/citation.rb +3 -3
  431. data/test/models/club.rb +25 -23
  432. data/test/models/college.rb +10 -10
  433. data/test/models/column.rb +3 -3
  434. data/test/models/column_name.rb +3 -3
  435. data/test/models/comment.rb +76 -64
  436. data/test/models/company.rb +230 -228
  437. data/test/models/company_in_module.rb +98 -98
  438. data/test/models/computer.rb +3 -3
  439. data/test/models/contact.rb +41 -41
  440. data/test/models/content.rb +40 -0
  441. data/test/models/contract.rb +20 -20
  442. data/test/models/country.rb +7 -7
  443. data/test/models/course.rb +6 -6
  444. data/test/models/customer.rb +83 -77
  445. data/test/models/customer_carrier.rb +14 -14
  446. data/test/models/dashboard.rb +3 -3
  447. data/test/models/default.rb +2 -2
  448. data/test/models/department.rb +4 -4
  449. data/test/models/developer.rb +274 -255
  450. data/test/models/dog.rb +5 -5
  451. data/test/models/dog_lover.rb +5 -5
  452. data/test/models/doubloon.rb +12 -12
  453. data/test/models/drink_designer.rb +3 -3
  454. data/test/models/edge.rb +5 -5
  455. data/test/models/electron.rb +5 -5
  456. data/test/models/engine.rb +4 -4
  457. data/test/models/entrant.rb +3 -3
  458. data/test/models/essay.rb +5 -5
  459. data/test/models/event.rb +3 -3
  460. data/test/models/eye.rb +37 -37
  461. data/test/models/face.rb +9 -9
  462. data/test/models/friendship.rb +6 -6
  463. data/test/models/guid.rb +2 -2
  464. data/test/models/guitar.rb +4 -0
  465. data/test/models/hotel.rb +11 -9
  466. data/test/models/image.rb +3 -3
  467. data/test/models/interest.rb +5 -5
  468. data/test/models/invoice.rb +4 -4
  469. data/test/models/item.rb +7 -7
  470. data/test/models/job.rb +7 -7
  471. data/test/models/joke.rb +7 -7
  472. data/test/models/keyboard.rb +3 -3
  473. data/test/models/legacy_thing.rb +3 -3
  474. data/test/models/lesson.rb +11 -11
  475. data/test/models/line_item.rb +3 -3
  476. data/test/models/liquid.rb +4 -4
  477. data/test/models/man.rb +11 -11
  478. data/test/models/matey.rb +4 -4
  479. data/test/models/member.rb +42 -41
  480. data/test/models/member_detail.rb +8 -7
  481. data/test/models/member_type.rb +3 -3
  482. data/test/models/membership.rb +35 -35
  483. data/test/models/mentor.rb +3 -0
  484. data/test/models/minimalistic.rb +2 -2
  485. data/test/models/minivan.rb +9 -9
  486. data/test/models/mixed_case_monkey.rb +3 -3
  487. data/test/models/mocktail_designer.rb +2 -0
  488. data/test/models/molecule.rb +6 -6
  489. data/test/models/movie.rb +5 -5
  490. data/test/models/node.rb +5 -0
  491. data/test/models/non_primary_key.rb +2 -0
  492. data/test/models/notification.rb +3 -0
  493. data/test/models/order.rb +4 -4
  494. data/test/models/organization.rb +14 -14
  495. data/test/models/other_dog.rb +5 -0
  496. data/test/models/owner.rb +37 -34
  497. data/test/models/parrot.rb +28 -29
  498. data/test/models/person.rb +142 -143
  499. data/test/models/personal_legacy_thing.rb +4 -4
  500. data/test/models/pet.rb +18 -15
  501. data/test/models/pet_treasure.rb +6 -0
  502. data/test/models/pirate.rb +92 -92
  503. data/test/models/possession.rb +3 -3
  504. data/test/models/post.rb +273 -264
  505. data/test/models/price_estimate.rb +4 -4
  506. data/test/models/professor.rb +5 -5
  507. data/test/models/project.rb +40 -31
  508. data/test/models/publisher.rb +2 -2
  509. data/test/models/publisher/article.rb +4 -4
  510. data/test/models/publisher/magazine.rb +3 -3
  511. data/test/models/randomly_named_c1.rb +1 -1
  512. data/test/models/rating.rb +4 -4
  513. data/test/models/reader.rb +23 -23
  514. data/test/models/recipe.rb +3 -0
  515. data/test/models/record.rb +2 -2
  516. data/test/models/reference.rb +22 -22
  517. data/test/models/reply.rb +61 -61
  518. data/test/models/ship.rb +39 -33
  519. data/test/models/ship_part.rb +8 -8
  520. data/test/models/shop.rb +17 -17
  521. data/test/models/shop_account.rb +6 -6
  522. data/test/models/speedometer.rb +6 -6
  523. data/test/models/sponsor.rb +7 -7
  524. data/test/models/string_key_object.rb +3 -3
  525. data/test/models/student.rb +4 -4
  526. data/test/models/subject.rb +16 -16
  527. data/test/models/subscriber.rb +8 -8
  528. data/test/models/subscription.rb +4 -4
  529. data/test/models/tag.rb +13 -7
  530. data/test/models/tagging.rb +13 -13
  531. data/test/models/task.rb +5 -5
  532. data/test/models/topic.rb +118 -124
  533. data/test/models/toy.rb +6 -6
  534. data/test/models/traffic_light.rb +4 -4
  535. data/test/models/treasure.rb +14 -14
  536. data/test/models/treaty.rb +7 -7
  537. data/test/models/tree.rb +3 -0
  538. data/test/models/tuning_peg.rb +4 -0
  539. data/test/models/tyre.rb +11 -11
  540. data/test/models/user.rb +14 -0
  541. data/test/models/uuid_child.rb +3 -3
  542. data/test/models/uuid_item.rb +6 -0
  543. data/test/models/uuid_parent.rb +3 -3
  544. data/test/models/vegetables.rb +24 -24
  545. data/test/models/vehicle.rb +6 -6
  546. data/test/models/vertex.rb +9 -9
  547. data/test/models/warehouse_thing.rb +5 -5
  548. data/test/models/wheel.rb +3 -3
  549. data/test/models/without_table.rb +3 -3
  550. data/test/models/zine.rb +3 -3
  551. data/test/schema/mysql2_specific_schema.rb +68 -58
  552. data/test/schema/oracle_specific_schema.rb +40 -43
  553. data/test/schema/postgresql_specific_schema.rb +114 -202
  554. data/test/schema/schema.rb +1057 -952
  555. data/test/schema/schema.rb.original +1057 -0
  556. data/test/schema/sqlite_specific_schema.rb +18 -22
  557. data/test/support/config.rb +43 -43
  558. data/test/support/connection.rb +23 -22
  559. data/test/support/connection_helper.rb +14 -14
  560. data/test/support/ddl_helper.rb +8 -8
  561. data/test/support/schema_dumping_helper.rb +20 -20
  562. data/test/support/yaml_compatibility_fixtures/rails_4_1.yml +22 -0
  563. data/test/support/yaml_compatibility_fixtures/rails_4_2_0.yml +182 -0
  564. metadata +129 -24
  565. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +0 -26
  566. data/test/cases/attribute_methods/serialization_test.rb +0 -29
  567. data/test/cases/migration/change_schema_test - Copy.rb +0 -448
  568. data/test/cases/migration/foreign_key_test - Changed.rb +0 -325
  569. data/test/cases/migration/table_and_index_test.rb +0 -24
  570. data/test/cases/relation/where_test2.rb +0 -36
  571. data/test/cases/type/decimal_test.rb +0 -56
  572. data/test/cases/type/unsigned_integer_test.rb +0 -18
  573. data/test/cases/xml_serialization_test.rb +0 -457
  574. data/test/connections/native_ibm_db/connection.rb +0 -44
  575. data/test/fixtures/naked/csv/accounts.csv +0 -1
  576. data/test/schema/i5/ibm_db_specific_schema.rb +0 -137
  577. data/test/schema/ids/ibm_db_specific_schema.rb +0 -140
  578. data/test/schema/luw/ibm_db_specific_schema.rb +0 -137
  579. data/test/schema/mysql_specific_schema.rb +0 -70
  580. data/test/schema/zOS/ibm_db_specific_schema.rb +0 -208
@@ -1,180 +1,246 @@
1
- require 'cases/helper'
2
- require 'minitest/mock'
3
-
4
- module ActiveRecord
5
- class AttributeTest < ActiveRecord::TestCase
6
- setup do
7
- @type = Minitest::Mock.new
8
- end
9
-
10
- teardown do
11
- assert @type.verify
12
- end
13
-
14
- test "from_database + read type casts from database" do
15
- @type.expect(:type_cast_from_database, 'type cast from database', ['a value'])
16
- attribute = Attribute.from_database(nil, 'a value', @type)
17
-
18
- type_cast_value = attribute.value
19
-
20
- assert_equal 'type cast from database', type_cast_value
21
- end
22
-
23
- test "from_user + read type casts from user" do
24
- @type.expect(:type_cast_from_user, 'type cast from user', ['a value'])
25
- attribute = Attribute.from_user(nil, 'a value', @type)
26
-
27
- type_cast_value = attribute.value
28
-
29
- assert_equal 'type cast from user', type_cast_value
30
- end
31
-
32
- test "reading memoizes the value" do
33
- @type.expect(:type_cast_from_database, 'from the database', ['whatever'])
34
- attribute = Attribute.from_database(nil, 'whatever', @type)
35
-
36
- type_cast_value = attribute.value
37
- second_read = attribute.value
38
-
39
- assert_equal 'from the database', type_cast_value
40
- assert_same type_cast_value, second_read
41
- end
42
-
43
- test "reading memoizes falsy values" do
44
- @type.expect(:type_cast_from_database, false, ['whatever'])
45
- attribute = Attribute.from_database(nil, 'whatever', @type)
46
-
47
- attribute.value
48
- attribute.value
49
- end
50
-
51
- test "read_before_typecast returns the given value" do
52
- attribute = Attribute.from_database(nil, 'raw value', @type)
53
-
54
- raw_value = attribute.value_before_type_cast
55
-
56
- assert_equal 'raw value', raw_value
57
- end
58
-
59
- test "from_database + read_for_database type casts to and from database" do
60
- @type.expect(:type_cast_from_database, 'read from database', ['whatever'])
61
- @type.expect(:type_cast_for_database, 'ready for database', ['read from database'])
62
- attribute = Attribute.from_database(nil, 'whatever', @type)
63
-
64
- type_cast_for_database = attribute.value_for_database
65
-
66
- assert_equal 'ready for database', type_cast_for_database
67
- end
68
-
69
- test "from_user + read_for_database type casts from the user to the database" do
70
- @type.expect(:type_cast_from_user, 'read from user', ['whatever'])
71
- @type.expect(:type_cast_for_database, 'ready for database', ['read from user'])
72
- attribute = Attribute.from_user(nil, 'whatever', @type)
73
-
74
- type_cast_for_database = attribute.value_for_database
75
-
76
- assert_equal 'ready for database', type_cast_for_database
77
- end
78
-
79
- test "duping dups the value" do
80
- @type.expect(:type_cast_from_database, 'type cast', ['a value'])
81
- attribute = Attribute.from_database(nil, 'a value', @type)
82
-
83
- value_from_orig = attribute.value
84
- value_from_clone = attribute.dup.value
85
- value_from_orig << ' foo'
86
-
87
- assert_equal 'type cast foo', value_from_orig
88
- assert_equal 'type cast', value_from_clone
89
- end
90
-
91
- test "duping does not dup the value if it is not dupable" do
92
- @type.expect(:type_cast_from_database, false, ['a value'])
93
- attribute = Attribute.from_database(nil, 'a value', @type)
94
-
95
- assert_same attribute.value, attribute.dup.value
96
- end
97
-
98
- test "duping does not eagerly type cast if we have not yet type cast" do
99
- attribute = Attribute.from_database(nil, 'a value', @type)
100
- attribute.dup
101
- end
102
-
103
- class MyType
104
- def type_cast_from_user(value)
105
- value + " from user"
106
- end
107
-
108
- def type_cast_from_database(value)
109
- value + " from database"
110
- end
111
- end
112
-
113
- test "with_value_from_user returns a new attribute with the value from the user" do
114
- old = Attribute.from_database(nil, "old", MyType.new)
115
- new = old.with_value_from_user("new")
116
-
117
- assert_equal "old from database", old.value
118
- assert_equal "new from user", new.value
119
- end
120
-
121
- test "with_value_from_database returns a new attribute with the value from the database" do
122
- old = Attribute.from_user(nil, "old", MyType.new)
123
- new = old.with_value_from_database("new")
124
-
125
- assert_equal "old from user", old.value
126
- assert_equal "new from database", new.value
127
- end
128
-
129
- test "uninitialized attributes yield their name if a block is given to value" do
130
- block = proc { |name| name.to_s + "!" }
131
- foo = Attribute.uninitialized(:foo, nil)
132
- bar = Attribute.uninitialized(:bar, nil)
133
-
134
- assert_equal "foo!", foo.value(&block)
135
- assert_equal "bar!", bar.value(&block)
136
- end
137
-
138
- test "uninitialized attributes have no value" do
139
- assert_nil Attribute.uninitialized(:foo, nil).value
140
- end
141
-
142
- test "attributes equal other attributes with the same constructor arguments" do
143
- first = Attribute.from_database(:foo, 1, Type::Integer.new)
144
- second = Attribute.from_database(:foo, 1, Type::Integer.new)
145
- assert_equal first, second
146
- end
147
-
148
- test "attributes do not equal attributes with different names" do
149
- first = Attribute.from_database(:foo, 1, Type::Integer.new)
150
- second = Attribute.from_database(:bar, 1, Type::Integer.new)
151
- assert_not_equal first, second
152
- end
153
-
154
- test "attributes do not equal attributes with different types" do
155
- first = Attribute.from_database(:foo, 1, Type::Integer.new)
156
- second = Attribute.from_database(:foo, 1, Type::Float.new)
157
- assert_not_equal first, second
158
- end
159
-
160
- test "attributes do not equal attributes with different values" do
161
- first = Attribute.from_database(:foo, 1, Type::Integer.new)
162
- second = Attribute.from_database(:foo, 2, Type::Integer.new)
163
- assert_not_equal first, second
164
- end
165
-
166
- test "attributes do not equal attributes of other classes" do
167
- first = Attribute.from_database(:foo, 1, Type::Integer.new)
168
- second = Attribute.from_user(:foo, 1, Type::Integer.new)
169
- assert_not_equal first, second
170
- end
171
-
172
- test "an attribute can not be mutated if it has not been read,
173
- and skips expensive calculations" do
174
- type_which_raises_from_all_methods = Object.new
175
- attribute = Attribute.from_database(:foo, "bar", type_which_raises_from_all_methods)
176
-
177
- assert_not attribute.changed_in_place_from?("bar")
178
- end
179
- end
180
- end
1
+ require 'cases/helper'
2
+
3
+ module ActiveRecord
4
+ class AttributeTest < ActiveRecord::TestCase
5
+ setup do
6
+ @type = Minitest::Mock.new
7
+ end
8
+
9
+ teardown do
10
+ assert @type.verify
11
+ end
12
+
13
+ test "from_database + read type casts from database" do
14
+ @type.expect(:deserialize, 'type cast from database', ['a value'])
15
+ attribute = Attribute.from_database(nil, 'a value', @type)
16
+
17
+ type_cast_value = attribute.value
18
+
19
+ assert_equal 'type cast from database', type_cast_value
20
+ end
21
+
22
+ test "from_user + read type casts from user" do
23
+ @type.expect(:cast, 'type cast from user', ['a value'])
24
+ attribute = Attribute.from_user(nil, 'a value', @type)
25
+
26
+ type_cast_value = attribute.value
27
+
28
+ assert_equal 'type cast from user', type_cast_value
29
+ end
30
+
31
+ test "reading memoizes the value" do
32
+ @type.expect(:deserialize, 'from the database', ['whatever'])
33
+ attribute = Attribute.from_database(nil, 'whatever', @type)
34
+
35
+ type_cast_value = attribute.value
36
+ second_read = attribute.value
37
+
38
+ assert_equal 'from the database', type_cast_value
39
+ assert_same type_cast_value, second_read
40
+ end
41
+
42
+ test "reading memoizes falsy values" do
43
+ @type.expect(:deserialize, false, ['whatever'])
44
+ attribute = Attribute.from_database(nil, 'whatever', @type)
45
+
46
+ attribute.value
47
+ attribute.value
48
+ end
49
+
50
+ test "read_before_typecast returns the given value" do
51
+ attribute = Attribute.from_database(nil, 'raw value', @type)
52
+
53
+ raw_value = attribute.value_before_type_cast
54
+
55
+ assert_equal 'raw value', raw_value
56
+ end
57
+
58
+ test "from_database + read_for_database type casts to and from database" do
59
+ @type.expect(:deserialize, 'read from database', ['whatever'])
60
+ @type.expect(:serialize, 'ready for database', ['read from database'])
61
+ attribute = Attribute.from_database(nil, 'whatever', @type)
62
+
63
+ serialize = attribute.value_for_database
64
+
65
+ assert_equal 'ready for database', serialize
66
+ end
67
+
68
+ test "from_user + read_for_database type casts from the user to the database" do
69
+ @type.expect(:cast, 'read from user', ['whatever'])
70
+ @type.expect(:serialize, 'ready for database', ['read from user'])
71
+ attribute = Attribute.from_user(nil, 'whatever', @type)
72
+
73
+ serialize = attribute.value_for_database
74
+
75
+ assert_equal 'ready for database', serialize
76
+ end
77
+
78
+ test "duping dups the value" do
79
+ @type.expect(:deserialize, 'type cast', ['a value'])
80
+ attribute = Attribute.from_database(nil, 'a value', @type)
81
+
82
+ value_from_orig = attribute.value
83
+ value_from_clone = attribute.dup.value
84
+ value_from_orig << ' foo'
85
+
86
+ assert_equal 'type cast foo', value_from_orig
87
+ assert_equal 'type cast', value_from_clone
88
+ end
89
+
90
+ test "duping does not dup the value if it is not dupable" do
91
+ @type.expect(:deserialize, false, ['a value'])
92
+ attribute = Attribute.from_database(nil, 'a value', @type)
93
+
94
+ assert_same attribute.value, attribute.dup.value
95
+ end
96
+
97
+ test "duping does not eagerly type cast if we have not yet type cast" do
98
+ attribute = Attribute.from_database(nil, 'a value', @type)
99
+ attribute.dup
100
+ end
101
+
102
+ class MyType
103
+ def cast(value)
104
+ value + " from user"
105
+ end
106
+
107
+ def deserialize(value)
108
+ value + " from database"
109
+ end
110
+
111
+ def assert_valid_value(*)
112
+ end
113
+ end
114
+
115
+ test "with_value_from_user returns a new attribute with the value from the user" do
116
+ old = Attribute.from_database(nil, "old", MyType.new)
117
+ new = old.with_value_from_user("new")
118
+
119
+ assert_equal "old from database", old.value
120
+ assert_equal "new from user", new.value
121
+ end
122
+
123
+ test "with_value_from_database returns a new attribute with the value from the database" do
124
+ old = Attribute.from_user(nil, "old", MyType.new)
125
+ new = old.with_value_from_database("new")
126
+
127
+ assert_equal "old from user", old.value
128
+ assert_equal "new from database", new.value
129
+ end
130
+
131
+ test "uninitialized attributes yield their name if a block is given to value" do
132
+ block = proc { |name| name.to_s + "!" }
133
+ foo = Attribute.uninitialized(:foo, nil)
134
+ bar = Attribute.uninitialized(:bar, nil)
135
+
136
+ assert_equal "foo!", foo.value(&block)
137
+ assert_equal "bar!", bar.value(&block)
138
+ end
139
+
140
+ test "uninitialized attributes have no value" do
141
+ assert_nil Attribute.uninitialized(:foo, nil).value
142
+ end
143
+
144
+ test "attributes equal other attributes with the same constructor arguments" do
145
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
146
+ second = Attribute.from_database(:foo, 1, Type::Integer.new)
147
+ assert_equal first, second
148
+ end
149
+
150
+ test "attributes do not equal attributes with different names" do
151
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
152
+ second = Attribute.from_database(:bar, 1, Type::Integer.new)
153
+ assert_not_equal first, second
154
+ end
155
+
156
+ test "attributes do not equal attributes with different types" do
157
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
158
+ second = Attribute.from_database(:foo, 1, Type::Float.new)
159
+ assert_not_equal first, second
160
+ end
161
+
162
+ test "attributes do not equal attributes with different values" do
163
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
164
+ second = Attribute.from_database(:foo, 2, Type::Integer.new)
165
+ assert_not_equal first, second
166
+ end
167
+
168
+ test "attributes do not equal attributes of other classes" do
169
+ first = Attribute.from_database(:foo, 1, Type::Integer.new)
170
+ second = Attribute.from_user(:foo, 1, Type::Integer.new)
171
+ assert_not_equal first, second
172
+ end
173
+
174
+ test "an attribute has not been read by default" do
175
+ attribute = Attribute.from_database(:foo, 1, Type::Value.new)
176
+ assert_not attribute.has_been_read?
177
+ end
178
+
179
+ test "an attribute has been read when its value is calculated" do
180
+ attribute = Attribute.from_database(:foo, 1, Type::Value.new)
181
+ attribute.value
182
+ assert attribute.has_been_read?
183
+ end
184
+
185
+ test "an attribute is not changed if it hasn't been assigned or mutated" do
186
+ attribute = Attribute.from_database(:foo, 1, Type::Value.new)
187
+
188
+ refute attribute.changed?
189
+ end
190
+
191
+ test "an attribute is changed if it's been assigned a new value" do
192
+ attribute = Attribute.from_database(:foo, 1, Type::Value.new)
193
+ changed = attribute.with_value_from_user(2)
194
+
195
+ assert changed.changed?
196
+ end
197
+
198
+ test "an attribute is not changed if it's assigned the same value" do
199
+ attribute = Attribute.from_database(:foo, 1, Type::Value.new)
200
+ unchanged = attribute.with_value_from_user(1)
201
+
202
+ refute unchanged.changed?
203
+ end
204
+
205
+ test "an attribute can not be mutated if it has not been read,
206
+ and skips expensive calculations" do
207
+ type_which_raises_from_all_methods = Object.new
208
+ attribute = Attribute.from_database(:foo, "bar", type_which_raises_from_all_methods)
209
+
210
+ assert_not attribute.changed_in_place?
211
+ end
212
+
213
+ test "an attribute is changed if it has been mutated" do
214
+ attribute = Attribute.from_database(:foo, "bar", Type::String.new)
215
+ attribute.value << "!"
216
+
217
+ assert attribute.changed_in_place?
218
+ assert attribute.changed?
219
+ end
220
+
221
+ test "an attribute can forget its changes" do
222
+ attribute = Attribute.from_database(:foo, "bar", Type::String.new)
223
+ changed = attribute.with_value_from_user("foo")
224
+ forgotten = changed.forgetting_assignment
225
+
226
+ assert changed.changed? # sanity check
227
+ refute forgotten.changed?
228
+ end
229
+
230
+ test "with_value_from_user validates the value" do
231
+ type = Type::Value.new
232
+ type.define_singleton_method(:assert_valid_value) do |value|
233
+ if value == 1
234
+ raise ArgumentError
235
+ end
236
+ end
237
+
238
+ attribute = Attribute.from_database(:foo, 1, type)
239
+ assert_equal 1, attribute.value
240
+ assert_equal 2, attribute.with_value_from_user(2).value
241
+ assert_raises ArgumentError do
242
+ attribute.with_value_from_user(1)
243
+ end
244
+ end
245
+ end
246
+ end
@@ -1,136 +1,253 @@
1
- require 'cases/helper'
2
-
3
- class OverloadedType < ActiveRecord::Base
4
- attribute :overloaded_float, Type::Integer.new
5
- attribute :overloaded_string_with_limit, Type::String.new(limit: 50)
6
- attribute :non_existent_decimal, Type::Decimal.new
7
- attribute :string_with_default, Type::String.new, default: 'the overloaded default'
8
- end
9
-
10
- class ChildOfOverloadedType < OverloadedType
11
- end
12
-
13
- class GrandchildOfOverloadedType < ChildOfOverloadedType
14
- attribute :overloaded_float, Type::Float.new
15
- end
16
-
17
- class UnoverloadedType < ActiveRecord::Base
18
- self.table_name = 'overloaded_types'
19
- end
20
-
21
- module ActiveRecord
22
- class CustomPropertiesTest < ActiveRecord::TestCase
23
- test "overloading types" do
24
- data = OverloadedType.new
25
-
26
- data.overloaded_float = "1.1"
27
- data.unoverloaded_float = "1.1"
28
-
29
- assert_equal 1, data.overloaded_float
30
- assert_equal 1.1, data.unoverloaded_float
31
- end
32
-
33
- test "overloaded properties save" do
34
- data = OverloadedType.new
35
-
36
- data.overloaded_float = "2.2"
37
- data.save!
38
- data.reload
39
-
40
- assert_equal 2, data.overloaded_float
41
- assert_kind_of Fixnum, OverloadedType.last.overloaded_float
42
- assert_equal 2.0, UnoverloadedType.last.overloaded_float
43
- assert_kind_of Float, UnoverloadedType.last.overloaded_float
44
- end
45
-
46
- test "properties assigned in constructor" do
47
- data = OverloadedType.new(overloaded_float: '3.3')
48
-
49
- assert_equal 3, data.overloaded_float
50
- end
51
-
52
- test "overloaded properties with limit" do
53
- assert_equal 50, OverloadedType.columns_hash['overloaded_string_with_limit'].limit
54
- assert_equal 255, UnoverloadedType.columns_hash['overloaded_string_with_limit'].limit
55
- end
56
-
57
- test "nonexistent attribute" do
58
- data = OverloadedType.new(non_existent_decimal: 1)
59
-
60
- assert_equal BigDecimal.new(1), data.non_existent_decimal
61
- assert_raise ActiveRecord::UnknownAttributeError do
62
- UnoverloadedType.new(non_existent_decimal: 1)
63
- end
64
- end
65
-
66
- test "changing defaults" do
67
- data = OverloadedType.new
68
- unoverloaded_data = UnoverloadedType.new
69
-
70
- assert_equal 'the overloaded default', data.string_with_default
71
- assert_equal 'the original default', unoverloaded_data.string_with_default
72
- end
73
-
74
- test "defaults are not touched on the columns" do
75
- assert_equal 'the original default', OverloadedType.columns_hash['string_with_default'].default
76
- end
77
-
78
- test "children inherit custom properties" do
79
- data = ChildOfOverloadedType.new(overloaded_float: '4.4')
80
-
81
- assert_equal 4, data.overloaded_float
82
- end
83
-
84
- test "children can override parents" do
85
- data = GrandchildOfOverloadedType.new(overloaded_float: '4.4')
86
-
87
- assert_equal 4.4, data.overloaded_float
88
- end
89
-
90
- test "overloading properties does not change column order" do
91
- column_names = OverloadedType.column_names
92
- assert_equal %w(id overloaded_float unoverloaded_float overloaded_string_with_limit string_with_default non_existent_decimal), column_names
93
- end
94
-
95
- test "caches are cleared" do
96
- klass = Class.new(OverloadedType)
97
-
98
- assert_equal 6, klass.columns.length
99
- assert_not klass.columns_hash.key?('wibble')
100
- assert_equal 6, klass.column_types.length
101
- assert_equal 6, klass.column_defaults.length
102
- assert_not klass.column_names.include?('wibble')
103
- assert_equal 5, klass.content_columns.length
104
-
105
- klass.attribute :wibble, Type::Value.new
106
-
107
- assert_equal 7, klass.columns.length
108
- assert klass.columns_hash.key?('wibble')
109
- assert_equal 7, klass.column_types.length
110
- assert_equal 7, klass.column_defaults.length
111
- assert klass.column_names.include?('wibble')
112
- assert_equal 6, klass.content_columns.length
113
- end
114
-
115
- test "non string/integers use custom types for queries" do
116
- klass = Class.new(OverloadedType)
117
- type = Type::Value.new
118
- def type.cast_value(value)
119
- !!value
120
- end
121
-
122
- def type.type_cast_for_database(value)
123
- if value
124
- "Y"
125
- else
126
- "N"
127
- end
128
- end
129
-
130
- klass.attribute(:string_with_default, type, default: false)
131
- klass.create!(string_with_default: true)
132
-
133
- assert_equal 1, klass.where(string_with_default: true).count
134
- end
135
- end
136
- end
1
+ require 'cases/helper'
2
+
3
+ class OverloadedType < ActiveRecord::Base
4
+ attribute :overloaded_float, :integer
5
+ attribute :overloaded_string_with_limit, :string, limit: 50
6
+ attribute :non_existent_decimal, :decimal
7
+ attribute :string_with_default, :string, default: 'the overloaded default'
8
+ end
9
+
10
+ class ChildOfOverloadedType < OverloadedType
11
+ end
12
+
13
+ class GrandchildOfOverloadedType < ChildOfOverloadedType
14
+ attribute :overloaded_float, :float
15
+ end
16
+
17
+ class UnoverloadedType < ActiveRecord::Base
18
+ self.table_name = 'overloaded_types'
19
+ end
20
+
21
+ module ActiveRecord
22
+ class CustomPropertiesTest < ActiveRecord::TestCase
23
+ test "overloading types" do
24
+ data = OverloadedType.new
25
+
26
+ data.overloaded_float = "1.1"
27
+ data.unoverloaded_float = "1.1"
28
+
29
+ assert_equal 1, data.overloaded_float
30
+ assert_equal 1.1, data.unoverloaded_float
31
+ end
32
+
33
+ test "overloaded properties save" do
34
+ data = OverloadedType.new
35
+
36
+ data.overloaded_float = "2.2"
37
+ data.save!
38
+ data.reload
39
+
40
+ assert_equal 2, data.overloaded_float
41
+ assert_kind_of Integer, OverloadedType.last.overloaded_float
42
+ assert_equal 2.0, UnoverloadedType.last.overloaded_float
43
+ assert_kind_of Float, UnoverloadedType.last.overloaded_float
44
+ end
45
+
46
+ test "properties assigned in constructor" do
47
+ data = OverloadedType.new(overloaded_float: '3.3')
48
+
49
+ assert_equal 3, data.overloaded_float
50
+ end
51
+
52
+ test "overloaded properties with limit" do
53
+ assert_equal 50, OverloadedType.type_for_attribute('overloaded_string_with_limit').limit
54
+ assert_equal 255, UnoverloadedType.type_for_attribute('overloaded_string_with_limit').limit
55
+ end
56
+
57
+ test "nonexistent attribute" do
58
+ data = OverloadedType.new(non_existent_decimal: 1)
59
+
60
+ assert_equal BigDecimal.new(1), data.non_existent_decimal
61
+ assert_raise ActiveRecord::UnknownAttributeError do
62
+ UnoverloadedType.new(non_existent_decimal: 1)
63
+ end
64
+ end
65
+
66
+ test "model with nonexistent attribute with default value can be saved" do
67
+ klass = Class.new(OverloadedType) do
68
+ attribute :non_existent_string_with_default, :string, default: 'nonexistent'
69
+ end
70
+
71
+ model = klass.new
72
+ assert model.save
73
+ end
74
+
75
+ test "changing defaults" do
76
+ data = OverloadedType.new
77
+ unoverloaded_data = UnoverloadedType.new
78
+
79
+ assert_equal 'the overloaded default', data.string_with_default
80
+ assert_equal 'the original default', unoverloaded_data.string_with_default
81
+ end
82
+
83
+ test "defaults are not touched on the columns" do
84
+ assert_equal 'the original default', OverloadedType.columns_hash['string_with_default'].default
85
+ end
86
+
87
+ test "children inherit custom properties" do
88
+ data = ChildOfOverloadedType.new(overloaded_float: '4.4')
89
+
90
+ assert_equal 4, data.overloaded_float
91
+ end
92
+
93
+ test "children can override parents" do
94
+ data = GrandchildOfOverloadedType.new(overloaded_float: '4.4')
95
+
96
+ assert_equal 4.4, data.overloaded_float
97
+ end
98
+
99
+ test "overloading properties does not attribute method order" do
100
+ attribute_names = OverloadedType.attribute_names
101
+ assert_equal %w(id overloaded_float unoverloaded_float overloaded_string_with_limit string_with_default non_existent_decimal), attribute_names
102
+ end
103
+
104
+ test "caches are cleared" do
105
+ klass = Class.new(OverloadedType)
106
+
107
+ assert_equal 6, klass.attribute_types.length
108
+ assert_equal 6, klass.column_defaults.length
109
+ assert_not klass.attribute_types.include?('wibble')
110
+
111
+ klass.attribute :wibble, Type::Value.new
112
+
113
+ assert_equal 7, klass.attribute_types.length
114
+ assert_equal 7, klass.column_defaults.length
115
+ assert klass.attribute_types.include?('wibble')
116
+ end
117
+
118
+ test "the given default value is cast from user" do
119
+ custom_type = Class.new(Type::Value) do
120
+ def cast(*)
121
+ "from user"
122
+ end
123
+
124
+ def deserialize(*)
125
+ "from database"
126
+ end
127
+ end
128
+
129
+ klass = Class.new(OverloadedType) do
130
+ attribute :wibble, custom_type.new, default: "default"
131
+ end
132
+ model = klass.new
133
+
134
+ assert_equal "from user", model.wibble
135
+ end
136
+
137
+ test "procs for default values" do
138
+ klass = Class.new(OverloadedType) do
139
+ @@counter = 0
140
+ attribute :counter, :integer, default: -> { @@counter += 1 }
141
+ end
142
+
143
+ assert_equal 1, klass.new.counter
144
+ assert_equal 2, klass.new.counter
145
+ end
146
+
147
+ test "procs are memoized before type casting" do
148
+ klass = Class.new(OverloadedType) do
149
+ @@counter = 0
150
+ attribute :counter, :integer, default: -> { @@counter += 1 }
151
+ end
152
+
153
+ model = klass.new
154
+ assert_equal 1, model.counter_before_type_cast
155
+ assert_equal 1, model.counter_before_type_cast
156
+ end
157
+
158
+ test "user provided defaults are persisted even if unchanged" do
159
+ model = OverloadedType.create!
160
+
161
+ assert_equal "the overloaded default", model.reload.string_with_default
162
+ end
163
+
164
+ if current_adapter?(:PostgreSQLAdapter)
165
+ test "array types can be specified" do
166
+ klass = Class.new(OverloadedType) do
167
+ attribute :my_array, :string, limit: 50, array: true
168
+ attribute :my_int_array, :integer, array: true
169
+ end
170
+
171
+ string_array = ConnectionAdapters::PostgreSQL::OID::Array.new(
172
+ Type::String.new(limit: 50))
173
+ int_array = ConnectionAdapters::PostgreSQL::OID::Array.new(
174
+ Type::Integer.new)
175
+ assert_not_equal string_array, int_array
176
+ assert_equal string_array, klass.type_for_attribute("my_array")
177
+ assert_equal int_array, klass.type_for_attribute("my_int_array")
178
+ end
179
+
180
+ test "range types can be specified" do
181
+ klass = Class.new(OverloadedType) do
182
+ attribute :my_range, :string, limit: 50, range: true
183
+ attribute :my_int_range, :integer, range: true
184
+ end
185
+
186
+ string_range = ConnectionAdapters::PostgreSQL::OID::Range.new(
187
+ Type::String.new(limit: 50))
188
+ int_range = ConnectionAdapters::PostgreSQL::OID::Range.new(
189
+ Type::Integer.new)
190
+ assert_not_equal string_range, int_range
191
+ assert_equal string_range, klass.type_for_attribute("my_range")
192
+ assert_equal int_range, klass.type_for_attribute("my_int_range")
193
+ end
194
+ end
195
+
196
+ test "attributes added after subclasses load are inherited" do
197
+ parent = Class.new(ActiveRecord::Base) do
198
+ self.table_name = "topics"
199
+ end
200
+
201
+ child = Class.new(parent)
202
+ child.new # => force a schema load
203
+
204
+ parent.attribute(:foo, Type::Value.new)
205
+
206
+ assert_equal(:bar, child.new(foo: :bar).foo)
207
+ end
208
+
209
+ test "attributes not backed by database columns are not dirty when unchanged" do
210
+ refute OverloadedType.new.non_existent_decimal_changed?
211
+ end
212
+
213
+ test "attributes not backed by database columns are always initialized" do
214
+ OverloadedType.create!
215
+ model = OverloadedType.first
216
+
217
+ assert_nil model.non_existent_decimal
218
+ model.non_existent_decimal = "123"
219
+ assert_equal 123, model.non_existent_decimal
220
+ end
221
+
222
+ test "attributes not backed by database columns return the default on models loaded from database" do
223
+ child = Class.new(OverloadedType) do
224
+ attribute :non_existent_decimal, :decimal, default: 123
225
+ end
226
+ child.create!
227
+ model = child.first
228
+
229
+ assert_equal 123, model.non_existent_decimal
230
+ end
231
+
232
+ test "attributes not backed by database columns properly interact with mutation and dirty" do
233
+ child = Class.new(ActiveRecord::Base) do
234
+ self.table_name = "topics"
235
+ attribute :foo, :string, default: "lol"
236
+ end
237
+ child.create!
238
+ model = child.first
239
+
240
+ assert_equal "lol", model.foo
241
+
242
+ model.foo << "asdf"
243
+ assert_equal "lolasdf", model.foo
244
+ assert model.foo_changed?
245
+
246
+ model.reload
247
+ assert_equal "lol", model.foo
248
+
249
+ model.foo = "lol"
250
+ refute model.changed?
251
+ end
252
+ end
253
+ end