ibm_db 3.0.0-x86-mingw32 → 3.0.1-x86-mingw32

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 (465) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +4 -0
  3. data/MANIFEST +14 -14
  4. data/README +225 -225
  5. data/ext/Makefile.nt32 +181 -181
  6. data/ext/Makefile.nt32.191 +212 -212
  7. data/ext/OLD/extconf.rb +264 -0
  8. data/ext/{extconf_MacOS.rb → OLD/extconf_MacOS.rb} +269 -269
  9. data/ext/extconf.rb +291 -264
  10. data/ext/ibm_db.c +2 -2
  11. data/ext/ruby_ibm_db.h +241 -241
  12. data/ext/ruby_ibm_db_cli.h +500 -500
  13. data/init.rb +41 -41
  14. data/lib/IBM_DB.rb +27 -27
  15. data/lib/active_record/connection_adapters/ibm_db_adapter.rb +4 -4
  16. data/lib/active_record/connection_adapters/ibmdb_adapter.rb +1 -1
  17. data/lib/active_record/vendor/db2-i5-zOS.yaml +328 -328
  18. data/lib/mswin32/ibm_db.rb +115 -115
  19. data/test/active_record/connection_adapters/fake_adapter.rb +46 -0
  20. data/test/assets/example.log +1 -0
  21. data/test/assets/flowers.jpg +0 -0
  22. data/test/assets/test.txt +1 -0
  23. data/test/cases/adapter_test.rb +261 -207
  24. data/test/cases/aggregations_test.rb +158 -0
  25. data/test/cases/ar_schema_test.rb +161 -0
  26. data/test/cases/associations/association_scope_test.rb +21 -0
  27. data/test/cases/associations/belongs_to_associations_test.rb +1029 -711
  28. data/test/cases/associations/callbacks_test.rb +192 -0
  29. data/test/cases/associations/cascaded_eager_loading_test.rb +188 -181
  30. data/test/cases/associations/deprecated_counter_cache_on_has_many_through_test.rb +26 -0
  31. data/test/cases/associations/eager_load_includes_full_sti_class_test.rb +36 -0
  32. data/test/cases/associations/eager_load_nested_include_test.rb +128 -0
  33. data/test/cases/associations/eager_singularization_test.rb +148 -0
  34. data/test/cases/associations/eager_test.rb +1411 -0
  35. data/test/cases/associations/extension_test.rb +82 -0
  36. data/test/cases/associations/has_and_belongs_to_many_associations_test.rb +932 -851
  37. data/test/cases/associations/has_many_associations_test.rb +2162 -0
  38. data/test/cases/associations/has_many_through_associations_test.rb +1204 -0
  39. data/test/cases/associations/has_one_associations_test.rb +610 -0
  40. data/test/cases/associations/has_one_through_associations_test.rb +380 -0
  41. data/test/cases/associations/inner_join_association_test.rb +139 -0
  42. data/test/cases/associations/inverse_associations_test.rb +693 -0
  43. data/test/cases/associations/join_model_test.rb +754 -743
  44. data/test/cases/associations/nested_through_associations_test.rb +579 -0
  45. data/test/cases/associations/required_test.rb +82 -0
  46. data/test/cases/associations_test.rb +380 -0
  47. data/test/cases/attribute_decorators_test.rb +125 -0
  48. data/test/cases/attribute_methods/read_test.rb +60 -0
  49. data/test/cases/attribute_methods/serialization_test.rb +29 -0
  50. data/test/cases/attribute_methods_test.rb +952 -822
  51. data/test/cases/attribute_set_test.rb +200 -0
  52. data/test/cases/attribute_test.rb +180 -0
  53. data/test/cases/attributes_test.rb +136 -0
  54. data/test/cases/autosave_association_test.rb +1595 -0
  55. data/test/cases/base_test.rb +1638 -2133
  56. data/test/cases/batches_test.rb +212 -0
  57. data/test/cases/binary_test.rb +52 -0
  58. data/test/cases/bind_parameter_test.rb +100 -0
  59. data/test/cases/calculations_test.rb +646 -482
  60. data/test/cases/callbacks_test.rb +543 -0
  61. data/test/cases/clone_test.rb +40 -0
  62. data/test/cases/coders/yaml_column_test.rb +63 -0
  63. data/test/cases/column_alias_test.rb +17 -0
  64. data/test/cases/column_definition_test.rb +123 -0
  65. data/test/cases/connection_adapters/adapter_leasing_test.rb +54 -0
  66. data/test/cases/connection_adapters/connection_handler_test.rb +53 -0
  67. data/test/cases/connection_adapters/connection_specification_test.rb +12 -0
  68. data/test/cases/connection_adapters/merge_and_resolve_default_url_config_test.rb +293 -0
  69. data/test/cases/connection_adapters/mysql_type_lookup_test.rb +65 -0
  70. data/test/cases/connection_adapters/quoting_test.rb +13 -0
  71. data/test/cases/connection_adapters/schema_cache_test.rb +56 -0
  72. data/test/cases/connection_adapters/type_lookup_test.rb +110 -0
  73. data/test/cases/connection_management_test.rb +122 -0
  74. data/test/cases/connection_pool_test.rb +346 -0
  75. data/test/cases/connection_specification/resolver_test.rb +116 -0
  76. data/test/cases/core_test.rb +112 -0
  77. data/test/cases/counter_cache_test.rb +209 -0
  78. data/test/cases/custom_locking_test.rb +17 -0
  79. data/test/cases/database_statements_test.rb +19 -0
  80. data/test/cases/date_time_test.rb +61 -0
  81. data/test/cases/defaults_test.rb +223 -0
  82. data/test/cases/dirty_test.rb +775 -0
  83. data/test/cases/disconnected_test.rb +28 -0
  84. data/test/cases/dup_test.rb +157 -0
  85. data/test/cases/enum_test.rb +290 -0
  86. data/test/cases/explain_subscriber_test.rb +64 -0
  87. data/test/cases/explain_test.rb +76 -0
  88. data/test/cases/finder_respond_to_test.rb +60 -0
  89. data/test/cases/finder_test.rb +1166 -0
  90. data/test/cases/fixture_set/file_test.rb +138 -0
  91. data/test/cases/fixtures_test.rb +897 -0
  92. data/test/cases/forbidden_attributes_protection_test.rb +99 -0
  93. data/test/cases/habtm_destroy_order_test.rb +61 -0
  94. data/test/cases/helper.rb +210 -0
  95. data/test/cases/hot_compatibility_test.rb +54 -0
  96. data/test/cases/i18n_test.rb +45 -0
  97. data/test/cases/inheritance_test.rb +375 -0
  98. data/test/cases/integration_test.rb +139 -0
  99. data/test/cases/invalid_connection_test.rb +22 -0
  100. data/test/cases/invalid_date_test.rb +32 -0
  101. data/test/cases/invertible_migration_test.rb +295 -0
  102. data/test/cases/json_serialization_test.rb +302 -0
  103. data/test/cases/locking_test.rb +477 -0
  104. data/test/cases/log_subscriber_test.rb +136 -0
  105. data/test/cases/migration/change_schema_test - Copy.rb +448 -0
  106. data/test/cases/migration/change_schema_test.rb +472 -0
  107. data/test/cases/migration/change_table_test.rb +224 -0
  108. data/test/cases/migration/column_attributes_test.rb +192 -0
  109. data/test/cases/migration/column_positioning_test.rb +56 -0
  110. data/test/cases/migration/columns_test.rb +304 -0
  111. data/test/cases/migration/command_recorder_test.rb +305 -0
  112. data/test/cases/migration/create_join_table_test.rb +148 -0
  113. data/test/cases/migration/foreign_key_test - Changed.rb +325 -0
  114. data/test/cases/migration/foreign_key_test.rb +360 -0
  115. data/test/cases/migration/helper.rb +39 -0
  116. data/test/cases/migration/index_test.rb +216 -0
  117. data/test/cases/migration/logger_test.rb +36 -0
  118. data/test/cases/migration/pending_migrations_test.rb +53 -0
  119. data/test/cases/migration/references_foreign_key_test.rb +214 -0
  120. data/test/cases/migration/references_index_test.rb +101 -0
  121. data/test/cases/migration/references_statements_test.rb +116 -0
  122. data/test/cases/migration/rename_table_test.rb +93 -0
  123. data/test/cases/migration/table_and_index_test.rb +24 -0
  124. data/test/cases/migration_test.rb +959 -2408
  125. data/test/cases/migrator_test.rb +388 -0
  126. data/test/cases/mixin_test.rb +70 -0
  127. data/test/cases/modules_test.rb +173 -0
  128. data/test/cases/multiparameter_attributes_test.rb +350 -0
  129. data/test/cases/multiple_db_test.rb +115 -0
  130. data/test/cases/nested_attributes_test.rb +1057 -0
  131. data/test/cases/nested_attributes_with_callbacks_test.rb +144 -0
  132. data/test/cases/persistence_test.rb +909 -642
  133. data/test/cases/pooled_connections_test.rb +81 -0
  134. data/test/cases/primary_keys_test.rb +237 -0
  135. data/test/cases/query_cache_test.rb +326 -257
  136. data/test/cases/quoting_test.rb +156 -0
  137. data/test/cases/readonly_test.rb +118 -0
  138. data/test/cases/reaper_test.rb +85 -0
  139. data/test/cases/reflection_test.rb +454 -0
  140. data/test/cases/relation/delegation_test.rb +68 -0
  141. data/test/cases/relation/merging_test.rb +161 -0
  142. data/test/cases/relation/mutation_test.rb +165 -0
  143. data/test/cases/relation/predicate_builder_test.rb +14 -0
  144. data/test/cases/relation/where_chain_test.rb +181 -0
  145. data/test/cases/relation/where_test.rb +300 -0
  146. data/test/cases/relation/where_test2.rb +36 -0
  147. data/test/cases/relation_test.rb +297 -0
  148. data/test/cases/relations_test.rb +1815 -1182
  149. data/test/cases/reload_models_test.rb +22 -0
  150. data/test/cases/result_test.rb +80 -0
  151. data/test/cases/sanitize_test.rb +83 -0
  152. data/test/cases/schema_dumper_test.rb +463 -256
  153. data/test/cases/scoping/default_scoping_test.rb +454 -0
  154. data/test/cases/scoping/named_scoping_test.rb +524 -0
  155. data/test/cases/scoping/relation_scoping_test.rb +357 -0
  156. data/test/cases/serialization_test.rb +104 -0
  157. data/test/cases/serialized_attribute_test.rb +277 -0
  158. data/test/cases/statement_cache_test.rb +98 -0
  159. data/test/cases/store_test.rb +194 -0
  160. data/test/cases/tasks/database_tasks_test.rb +396 -0
  161. data/test/cases/tasks/mysql_rake_test.rb +311 -0
  162. data/test/cases/tasks/postgresql_rake_test.rb +245 -0
  163. data/test/cases/tasks/sqlite_rake_test.rb +193 -0
  164. data/test/cases/test_case.rb +123 -0
  165. data/test/cases/timestamp_test.rb +468 -0
  166. data/test/cases/transaction_callbacks_test.rb +452 -300
  167. data/test/cases/transaction_isolation_test.rb +106 -0
  168. data/test/cases/transactions_test.rb +817 -0
  169. data/test/cases/type/decimal_test.rb +51 -0
  170. data/test/cases/type/integer_test.rb +121 -0
  171. data/test/cases/type/string_test.rb +36 -0
  172. data/test/cases/type/type_map_test.rb +177 -0
  173. data/test/cases/type/unsigned_integer_test.rb +18 -0
  174. data/test/cases/types_test.rb +141 -0
  175. data/test/cases/unconnected_test.rb +33 -0
  176. data/test/cases/validations/association_validation_test.rb +86 -0
  177. data/test/cases/validations/i18n_generate_message_validation_test.rb +84 -0
  178. data/test/cases/validations/i18n_validation_test.rb +90 -0
  179. data/test/cases/validations/length_validation_test.rb +47 -0
  180. data/test/cases/validations/presence_validation_test.rb +68 -0
  181. data/test/cases/validations/uniqueness_validation_test.rb +434 -299
  182. data/test/cases/validations_repair_helper.rb +23 -0
  183. data/test/cases/validations_test.rb +165 -0
  184. data/test/cases/view_test.rb +113 -0
  185. data/test/cases/xml_serialization_test.rb +457 -408
  186. data/test/cases/yaml_serialization_test.rb +86 -0
  187. data/test/config.rb +5 -0
  188. data/test/config.yml +154 -154
  189. data/test/connections/native_ibm_db/connection.rb +43 -43
  190. data/test/fixtures/accounts.yml +29 -0
  191. data/test/fixtures/admin/accounts.yml +2 -0
  192. data/test/fixtures/admin/randomly_named_a9.yml +7 -0
  193. data/test/fixtures/admin/randomly_named_b0.yml +7 -0
  194. data/test/fixtures/admin/users.yml +10 -0
  195. data/test/fixtures/all/admin +1 -0
  196. data/test/fixtures/all/developers.yml +0 -0
  197. data/test/fixtures/all/people.yml +0 -0
  198. data/test/fixtures/all/tasks.yml +0 -0
  199. data/test/fixtures/author_addresses.yml +18 -0
  200. data/test/fixtures/author_favorites.yml +4 -0
  201. data/test/fixtures/authors.yml +23 -0
  202. data/test/fixtures/binaries.yml +133 -0
  203. data/test/fixtures/books.yml +11 -0
  204. data/test/fixtures/bulbs.yml +5 -0
  205. data/test/fixtures/cars.yml +9 -0
  206. data/test/fixtures/categories.yml +19 -0
  207. data/test/fixtures/categories/special_categories.yml +9 -0
  208. data/test/fixtures/categories/subsubdir/arbitrary_filename.yml +4 -0
  209. data/test/fixtures/categories_ordered.yml +7 -0
  210. data/test/fixtures/categories_posts.yml +31 -0
  211. data/test/fixtures/categorizations.yml +23 -0
  212. data/test/fixtures/clubs.yml +8 -0
  213. data/test/fixtures/collections.yml +3 -0
  214. data/test/fixtures/colleges.yml +3 -0
  215. data/test/fixtures/comments.yml +65 -0
  216. data/test/fixtures/companies.yml +67 -0
  217. data/test/fixtures/computers.yml +10 -0
  218. data/test/fixtures/courses.yml +8 -0
  219. data/test/fixtures/customers.yml +26 -0
  220. data/test/fixtures/dashboards.yml +6 -0
  221. data/test/fixtures/developers.yml +22 -0
  222. data/test/fixtures/developers_projects.yml +17 -0
  223. data/test/fixtures/dog_lovers.yml +7 -0
  224. data/test/fixtures/dogs.yml +4 -0
  225. data/test/fixtures/doubloons.yml +3 -0
  226. data/test/fixtures/edges.yml +5 -0
  227. data/test/fixtures/entrants.yml +14 -0
  228. data/test/fixtures/essays.yml +6 -0
  229. data/test/fixtures/faces.yml +11 -0
  230. data/test/fixtures/fk_test_has_fk.yml +3 -0
  231. data/test/fixtures/fk_test_has_pk.yml +2 -0
  232. data/test/fixtures/friendships.yml +4 -0
  233. data/test/fixtures/funny_jokes.yml +10 -0
  234. data/test/fixtures/interests.yml +33 -0
  235. data/test/fixtures/items.yml +3 -0
  236. data/test/fixtures/jobs.yml +7 -0
  237. data/test/fixtures/legacy_things.yml +3 -0
  238. data/test/fixtures/mateys.yml +4 -0
  239. data/test/fixtures/member_details.yml +8 -0
  240. data/test/fixtures/member_types.yml +6 -0
  241. data/test/fixtures/members.yml +11 -0
  242. data/test/fixtures/memberships.yml +34 -0
  243. data/test/fixtures/men.yml +5 -0
  244. data/test/fixtures/minimalistics.yml +2 -0
  245. data/test/fixtures/minivans.yml +5 -0
  246. data/test/fixtures/mixed_case_monkeys.yml +6 -0
  247. data/test/fixtures/mixins.yml +29 -0
  248. data/test/fixtures/movies.yml +7 -0
  249. data/test/fixtures/naked/csv/accounts.csv +1 -0
  250. data/test/fixtures/naked/yml/accounts.yml +1 -0
  251. data/test/fixtures/naked/yml/companies.yml +1 -0
  252. data/test/fixtures/naked/yml/courses.yml +1 -0
  253. data/test/fixtures/organizations.yml +5 -0
  254. data/test/fixtures/other_topics.yml +42 -0
  255. data/test/fixtures/owners.yml +9 -0
  256. data/test/fixtures/parrots.yml +27 -0
  257. data/test/fixtures/parrots_pirates.yml +7 -0
  258. data/test/fixtures/people.yml +24 -0
  259. data/test/fixtures/peoples_treasures.yml +3 -0
  260. data/test/fixtures/pets.yml +19 -0
  261. data/test/fixtures/pirates.yml +12 -0
  262. data/test/fixtures/posts.yml +80 -0
  263. data/test/fixtures/price_estimates.yml +7 -0
  264. data/test/fixtures/products.yml +4 -0
  265. data/test/fixtures/projects.yml +7 -0
  266. data/test/fixtures/randomly_named_a9.yml +7 -0
  267. data/test/fixtures/ratings.yml +14 -0
  268. data/test/fixtures/readers.yml +11 -0
  269. data/test/fixtures/references.yml +17 -0
  270. data/test/fixtures/reserved_words/distinct.yml +5 -0
  271. data/test/fixtures/reserved_words/distinct_select.yml +11 -0
  272. data/test/fixtures/reserved_words/group.yml +14 -0
  273. data/test/fixtures/reserved_words/select.yml +8 -0
  274. data/test/fixtures/reserved_words/values.yml +7 -0
  275. data/test/fixtures/ships.yml +6 -0
  276. data/test/fixtures/speedometers.yml +8 -0
  277. data/test/fixtures/sponsors.yml +12 -0
  278. data/test/fixtures/string_key_objects.yml +7 -0
  279. data/test/fixtures/subscribers.yml +11 -0
  280. data/test/fixtures/subscriptions.yml +12 -0
  281. data/test/fixtures/taggings.yml +78 -0
  282. data/test/fixtures/tags.yml +11 -0
  283. data/test/fixtures/tasks.yml +7 -0
  284. data/test/fixtures/teapots.yml +3 -0
  285. data/test/fixtures/to_be_linked/accounts.yml +2 -0
  286. data/test/fixtures/to_be_linked/users.yml +10 -0
  287. data/test/fixtures/topics.yml +49 -0
  288. data/test/fixtures/toys.yml +14 -0
  289. data/test/fixtures/traffic_lights.yml +10 -0
  290. data/test/fixtures/treasures.yml +10 -0
  291. data/test/fixtures/uuid_children.yml +3 -0
  292. data/test/fixtures/uuid_parents.yml +2 -0
  293. data/test/fixtures/variants.yml +4 -0
  294. data/test/fixtures/vegetables.yml +20 -0
  295. data/test/fixtures/vertices.yml +4 -0
  296. data/test/fixtures/warehouse_things.yml +3 -0
  297. data/test/fixtures/zines.yml +5 -0
  298. data/test/ibm_db_test.rb +24 -24
  299. data/test/migrations/10_urban/9_add_expressions.rb +11 -0
  300. data/test/migrations/decimal/1_give_me_big_numbers.rb +15 -0
  301. data/test/migrations/magic/1_currencies_have_symbols.rb +12 -0
  302. data/test/migrations/missing/1000_people_have_middle_names.rb +9 -0
  303. data/test/migrations/missing/1_people_have_last_names.rb +9 -0
  304. data/test/migrations/missing/3_we_need_reminders.rb +12 -0
  305. data/test/migrations/missing/4_innocent_jointable.rb +12 -0
  306. data/test/migrations/rename/1_we_need_things.rb +11 -0
  307. data/test/migrations/rename/2_rename_things.rb +9 -0
  308. data/test/migrations/to_copy/1_people_have_hobbies.rb +9 -0
  309. data/test/migrations/to_copy/2_people_have_descriptions.rb +9 -0
  310. data/test/migrations/to_copy2/1_create_articles.rb +7 -0
  311. data/test/migrations/to_copy2/2_create_comments.rb +7 -0
  312. data/test/migrations/to_copy_with_name_collision/1_people_have_hobbies.rb +9 -0
  313. data/test/migrations/to_copy_with_timestamps/20090101010101_people_have_hobbies.rb +9 -0
  314. data/test/migrations/to_copy_with_timestamps/20090101010202_people_have_descriptions.rb +9 -0
  315. data/test/migrations/to_copy_with_timestamps2/20090101010101_create_articles.rb +7 -0
  316. data/test/migrations/to_copy_with_timestamps2/20090101010202_create_comments.rb +7 -0
  317. data/test/migrations/valid/1_valid_people_have_last_names.rb +9 -0
  318. data/test/migrations/valid/2_we_need_reminders.rb +12 -0
  319. data/test/migrations/valid/3_innocent_jointable.rb +12 -0
  320. data/test/migrations/valid_with_subdirectories/1_valid_people_have_last_names.rb +9 -0
  321. data/test/migrations/valid_with_subdirectories/sub/2_we_need_reminders.rb +12 -0
  322. data/test/migrations/valid_with_subdirectories/sub1/3_innocent_jointable.rb +12 -0
  323. data/test/migrations/valid_with_timestamps/20100101010101_valid_with_timestamps_people_have_last_names.rb +9 -0
  324. data/test/migrations/valid_with_timestamps/20100201010101_valid_with_timestamps_we_need_reminders.rb +12 -0
  325. data/test/migrations/valid_with_timestamps/20100301010101_valid_with_timestamps_innocent_jointable.rb +12 -0
  326. data/test/migrations/version_check/20131219224947_migration_version_check.rb +8 -0
  327. data/test/models/admin.rb +5 -0
  328. data/test/models/admin/account.rb +3 -0
  329. data/test/models/admin/randomly_named_c1.rb +3 -0
  330. data/test/models/admin/user.rb +40 -0
  331. data/test/models/aircraft.rb +4 -0
  332. data/test/models/arunit2_model.rb +3 -0
  333. data/test/models/author.rb +212 -0
  334. data/test/models/auto_id.rb +4 -0
  335. data/test/models/autoloadable/extra_firm.rb +2 -0
  336. data/test/models/binary.rb +2 -0
  337. data/test/models/bird.rb +12 -0
  338. data/test/models/book.rb +18 -0
  339. data/test/models/boolean.rb +2 -0
  340. data/test/models/bulb.rb +51 -0
  341. data/test/models/cake_designer.rb +3 -0
  342. data/test/models/car.rb +26 -0
  343. data/test/models/carrier.rb +2 -0
  344. data/test/models/categorization.rb +19 -0
  345. data/test/models/category.rb +35 -0
  346. data/test/models/chef.rb +3 -0
  347. data/test/models/citation.rb +3 -0
  348. data/test/models/club.rb +23 -0
  349. data/test/models/college.rb +10 -0
  350. data/test/models/column.rb +3 -0
  351. data/test/models/column_name.rb +3 -0
  352. data/test/models/comment.rb +64 -0
  353. data/test/models/company.rb +225 -0
  354. data/test/models/company_in_module.rb +98 -0
  355. data/test/models/computer.rb +3 -0
  356. data/test/models/contact.rb +41 -0
  357. data/test/models/contract.rb +20 -0
  358. data/test/models/country.rb +7 -0
  359. data/test/models/course.rb +6 -0
  360. data/test/models/customer.rb +77 -0
  361. data/test/models/customer_carrier.rb +14 -0
  362. data/test/models/dashboard.rb +3 -0
  363. data/test/models/default.rb +2 -0
  364. data/test/models/department.rb +4 -0
  365. data/test/models/developer.rb +252 -0
  366. data/test/models/dog.rb +5 -0
  367. data/test/models/dog_lover.rb +5 -0
  368. data/test/models/doubloon.rb +12 -0
  369. data/test/models/drink_designer.rb +3 -0
  370. data/test/models/edge.rb +5 -0
  371. data/test/models/electron.rb +5 -0
  372. data/test/models/engine.rb +4 -0
  373. data/test/models/entrant.rb +3 -0
  374. data/test/models/essay.rb +5 -0
  375. data/test/models/event.rb +3 -0
  376. data/test/models/eye.rb +37 -0
  377. data/test/models/face.rb +9 -0
  378. data/test/models/friendship.rb +6 -0
  379. data/test/models/guid.rb +2 -0
  380. data/test/models/hotel.rb +6 -0
  381. data/test/models/image.rb +3 -0
  382. data/test/models/interest.rb +5 -0
  383. data/test/models/invoice.rb +4 -0
  384. data/test/models/item.rb +7 -0
  385. data/test/models/job.rb +7 -0
  386. data/test/models/joke.rb +7 -0
  387. data/test/models/keyboard.rb +3 -0
  388. data/test/models/legacy_thing.rb +3 -0
  389. data/test/models/lesson.rb +11 -0
  390. data/test/models/line_item.rb +3 -0
  391. data/test/models/liquid.rb +4 -0
  392. data/test/models/man.rb +11 -0
  393. data/test/models/matey.rb +4 -0
  394. data/test/models/member.rb +41 -0
  395. data/test/models/member_detail.rb +7 -0
  396. data/test/models/member_type.rb +3 -0
  397. data/test/models/membership.rb +35 -0
  398. data/test/models/minimalistic.rb +2 -0
  399. data/test/models/minivan.rb +9 -0
  400. data/test/models/mixed_case_monkey.rb +3 -0
  401. data/test/models/molecule.rb +6 -0
  402. data/test/models/movie.rb +5 -0
  403. data/test/models/order.rb +4 -0
  404. data/test/models/organization.rb +14 -0
  405. data/test/models/owner.rb +34 -0
  406. data/test/models/parrot.rb +29 -0
  407. data/test/models/person.rb +143 -0
  408. data/test/models/personal_legacy_thing.rb +4 -0
  409. data/test/models/pet.rb +15 -0
  410. data/test/models/pirate.rb +92 -0
  411. data/test/models/possession.rb +3 -0
  412. data/test/models/post.rb +264 -0
  413. data/test/models/price_estimate.rb +4 -0
  414. data/test/models/professor.rb +5 -0
  415. data/test/models/project.rb +29 -0
  416. data/test/models/publisher.rb +2 -0
  417. data/test/models/publisher/article.rb +4 -0
  418. data/test/models/publisher/magazine.rb +3 -0
  419. data/test/models/randomly_named_c1.rb +3 -0
  420. data/test/models/rating.rb +4 -0
  421. data/test/models/reader.rb +23 -0
  422. data/test/models/record.rb +2 -0
  423. data/test/models/reference.rb +22 -0
  424. data/test/models/reply.rb +61 -0
  425. data/test/models/ship.rb +33 -0
  426. data/test/models/ship_part.rb +8 -0
  427. data/test/models/shop.rb +17 -0
  428. data/test/models/shop_account.rb +6 -0
  429. data/test/models/speedometer.rb +6 -0
  430. data/test/models/sponsor.rb +7 -0
  431. data/test/models/string_key_object.rb +3 -0
  432. data/test/models/student.rb +4 -0
  433. data/test/models/subject.rb +16 -0
  434. data/test/models/subscriber.rb +8 -0
  435. data/test/models/subscription.rb +4 -0
  436. data/test/models/tag.rb +7 -0
  437. data/test/models/tagging.rb +13 -0
  438. data/test/models/task.rb +5 -0
  439. data/test/models/topic.rb +124 -0
  440. data/test/models/toy.rb +6 -0
  441. data/test/models/traffic_light.rb +4 -0
  442. data/test/models/treasure.rb +14 -0
  443. data/test/models/treaty.rb +7 -0
  444. data/test/models/tyre.rb +11 -0
  445. data/test/models/uuid_child.rb +3 -0
  446. data/test/models/uuid_parent.rb +3 -0
  447. data/test/models/vegetables.rb +24 -0
  448. data/test/models/vehicle.rb +7 -0
  449. data/test/models/vertex.rb +9 -0
  450. data/test/models/warehouse_thing.rb +5 -5
  451. data/test/models/wheel.rb +3 -0
  452. data/test/models/without_table.rb +3 -0
  453. data/test/models/zine.rb +3 -0
  454. data/test/schema/mysql2_specific_schema.rb +58 -0
  455. data/test/schema/mysql_specific_schema.rb +70 -0
  456. data/test/schema/oracle_specific_schema.rb +43 -0
  457. data/test/schema/postgresql_specific_schema.rb +202 -0
  458. data/test/schema/schema.rb +938 -751
  459. data/test/schema/sqlite_specific_schema.rb +22 -0
  460. data/test/support/config.rb +43 -0
  461. data/test/support/connection.rb +22 -0
  462. data/test/support/connection_helper.rb +14 -0
  463. data/test/support/ddl_helper.rb +8 -0
  464. data/test/support/schema_dumping_helper.rb +20 -0
  465. metadata +444 -18
@@ -0,0 +1,23 @@
1
+ module ActiveRecord
2
+ module ValidationsRepairHelper
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ def repair_validations(*model_classes)
7
+ teardown do
8
+ model_classes.each do |k|
9
+ k.clear_validators!
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ def repair_validations(*model_classes)
16
+ yield if block_given?
17
+ ensure
18
+ model_classes.each do |k|
19
+ k.clear_validators!
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,165 @@
1
+ # encoding: utf-8
2
+ require "cases/helper"
3
+ require 'models/topic'
4
+ require 'models/reply'
5
+ require 'models/person'
6
+ require 'models/developer'
7
+ require 'models/computer'
8
+ require 'models/parrot'
9
+ require 'models/company'
10
+
11
+ class ValidationsTest < ActiveRecord::TestCase
12
+ fixtures :topics, :developers
13
+
14
+ # Most of the tests mess with the validations of Topic, so lets repair it all the time.
15
+ # Other classes we mess with will be dealt with in the specific tests
16
+ repair_validations(Topic)
17
+
18
+ def test_valid_uses_create_context_when_new
19
+ r = WrongReply.new
20
+ r.title = "Wrong Create"
21
+ assert_not r.valid?
22
+ assert r.errors[:title].any?, "A reply with a bad title should mark that attribute as invalid"
23
+ assert_equal ["is Wrong Create"], r.errors[:title], "A reply with a bad content should contain an error"
24
+ end
25
+
26
+ def test_valid_uses_update_context_when_persisted
27
+ r = WrongReply.new
28
+ r.title = "Bad"
29
+ r.content = "Good"
30
+ assert r.save, "First validation should be successful"
31
+
32
+ r.title = "Wrong Update"
33
+ assert_not r.valid?, "Second validation should fail"
34
+
35
+ assert r.errors[:title].any?, "A reply with a bad title should mark that attribute as invalid"
36
+ assert_equal ["is Wrong Update"], r.errors[:title], "A reply with a bad content should contain an error"
37
+ end
38
+
39
+ def test_valid_using_special_context
40
+ r = WrongReply.new(:title => "Valid title")
41
+ assert !r.valid?(:special_case)
42
+ assert_equal "Invalid", r.errors[:author_name].join
43
+
44
+ r.author_name = "secret"
45
+ r.content = "Good"
46
+ assert r.valid?(:special_case)
47
+
48
+ r.author_name = nil
49
+ assert_not r.valid?(:special_case)
50
+ assert_equal "Invalid", r.errors[:author_name].join
51
+
52
+ r.author_name = "secret"
53
+ assert r.valid?(:special_case)
54
+ end
55
+
56
+ def test_validate
57
+ r = WrongReply.new
58
+
59
+ r.validate
60
+ assert_empty r.errors[:author_name]
61
+
62
+ r.validate(:special_case)
63
+ assert_not_empty r.errors[:author_name]
64
+
65
+ r.author_name = "secret"
66
+
67
+ r.validate(:special_case)
68
+ assert_empty r.errors[:author_name]
69
+ end
70
+
71
+ def test_invalid_record_exception
72
+ assert_raise(ActiveRecord::RecordInvalid) { WrongReply.create! }
73
+ assert_raise(ActiveRecord::RecordInvalid) { WrongReply.new.save! }
74
+
75
+ r = WrongReply.new
76
+ invalid = assert_raise ActiveRecord::RecordInvalid do
77
+ r.save!
78
+ end
79
+ assert_equal r, invalid.record
80
+ end
81
+
82
+ def test_validate_with_bang
83
+ assert_raise(ActiveRecord::RecordInvalid) do
84
+ WrongReply.new.validate!
85
+ end
86
+ end
87
+
88
+ def test_validate_with_bang_and_context
89
+ assert_raise(ActiveRecord::RecordInvalid) do
90
+ WrongReply.new.validate!(:special_case)
91
+ end
92
+ r = WrongReply.new(:title => "Valid title", :author_name => "secret", :content => "Good")
93
+ assert r.validate!(:special_case)
94
+ end
95
+
96
+ def test_exception_on_create_bang_many
97
+ assert_raise(ActiveRecord::RecordInvalid) do
98
+ WrongReply.create!([ { "title" => "OK" }, { "title" => "Wrong Create" }])
99
+ end
100
+ end
101
+
102
+ def test_exception_on_create_bang_with_block
103
+ assert_raise(ActiveRecord::RecordInvalid) do
104
+ WrongReply.create!({ "title" => "OK" }) do |r|
105
+ r.content = nil
106
+ end
107
+ end
108
+ end
109
+
110
+ def test_exception_on_create_bang_many_with_block
111
+ assert_raise(ActiveRecord::RecordInvalid) do
112
+ WrongReply.create!([{ "title" => "OK" }, { "title" => "Wrong Create" }]) do |r|
113
+ r.content = nil
114
+ end
115
+ end
116
+ end
117
+
118
+ def test_save_without_validation
119
+ reply = WrongReply.new
120
+ assert !reply.save
121
+ assert reply.save(:validate => false)
122
+ end
123
+
124
+ def test_validates_acceptance_of_with_non_existent_table
125
+ Object.const_set :IncorporealModel, Class.new(ActiveRecord::Base)
126
+
127
+ assert_nothing_raised ActiveRecord::StatementInvalid do
128
+ IncorporealModel.validates_acceptance_of(:incorporeal_column)
129
+ end
130
+ end
131
+
132
+ def test_throw_away_typing
133
+ d = Developer.new("name" => "David", "salary" => "100,000")
134
+ assert !d.valid?
135
+ assert_equal 100, d.salary
136
+ assert_equal "100,000", d.salary_before_type_cast
137
+ end
138
+
139
+ def test_validates_acceptance_of_as_database_column
140
+ Topic.validates_acceptance_of(:approved)
141
+ topic = Topic.create("approved" => true)
142
+ assert topic["approved"]
143
+ end
144
+
145
+ def test_validators
146
+ assert_equal 1, Parrot.validators.size
147
+ assert_equal 1, Company.validators.size
148
+ assert_equal 1, Parrot.validators_on(:name).size
149
+ assert_equal 1, Company.validators_on(:name).size
150
+ end
151
+
152
+ def test_numericality_validation_with_mutation
153
+ Topic.class_eval do
154
+ attribute :wibble, ActiveRecord::Type::String.new
155
+ validates_numericality_of :wibble, only_integer: true
156
+ end
157
+
158
+ topic = Topic.new(wibble: '123-4567')
159
+ topic.wibble.gsub!('-', '')
160
+
161
+ assert topic.valid?
162
+ ensure
163
+ Topic.reset_column_information
164
+ end
165
+ end
@@ -0,0 +1,113 @@
1
+ require "cases/helper"
2
+ require "models/book"
3
+
4
+ module ViewBehavior
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ fixtures :books
9
+ end
10
+
11
+ class Ebook < ActiveRecord::Base
12
+ self.primary_key = "id"
13
+ end
14
+
15
+ def setup
16
+ super
17
+ @connection = ActiveRecord::Base.connection
18
+ create_view "ebooks", <<-SQL
19
+ SELECT id, name, status FROM books WHERE format = 'ebook'
20
+ SQL
21
+ end
22
+
23
+ def teardown
24
+ super
25
+ drop_view "ebooks"
26
+ end
27
+
28
+ def test_reading
29
+ books = Ebook.all
30
+ assert_equal [books(:rfr).id], books.map(&:id)
31
+ assert_equal ["Ruby for Rails"], books.map(&:name)
32
+ end
33
+
34
+ def test_table_exists
35
+ view_name = Ebook.table_name
36
+ assert @connection.table_exists?(view_name), "'#{view_name}' table should exist"
37
+ end
38
+
39
+ def test_column_definitions
40
+ assert_equal([["id", :integer],
41
+ ["name", :string],
42
+ ["status", :integer]], Ebook.columns.map { |c| [c.name, c.type] })
43
+ end
44
+
45
+ def test_attributes
46
+ assert_equal({"id" => 2, "name" => "Ruby for Rails", "status" => 0},
47
+ Ebook.first.attributes)
48
+ end
49
+
50
+ def test_does_not_assume_id_column_as_primary_key
51
+ model = Class.new(ActiveRecord::Base) do
52
+ self.table_name = "ebooks"
53
+ end
54
+ assert_nil model.primary_key
55
+ end
56
+ end
57
+
58
+ if ActiveRecord::Base.connection.supports_views?
59
+ class ViewWithPrimaryKeyTest < ActiveRecord::TestCase
60
+ include ViewBehavior
61
+
62
+ private
63
+ def create_view(name, query)
64
+ @connection.execute "CREATE VIEW #{name} AS #{query}"
65
+ end
66
+
67
+ def drop_view(name)
68
+ @connection.execute "DROP VIEW #{name}" if @connection.table_exists? name
69
+ end
70
+ end
71
+
72
+ class ViewWithoutPrimaryKeyTest < ActiveRecord::TestCase
73
+ fixtures :books
74
+
75
+ class Paperback < ActiveRecord::Base; end
76
+
77
+ setup do
78
+ @connection = ActiveRecord::Base.connection
79
+ @connection.execute <<-SQL
80
+ CREATE VIEW paperbacks
81
+ AS SELECT name, status FROM books WHERE format = 'paperback'
82
+ SQL
83
+ end
84
+
85
+ teardown do
86
+ @connection.execute "DROP VIEW paperbacks" if @connection.table_exists? "paperbacks"
87
+ end
88
+
89
+ def test_reading
90
+ books = Paperback.all
91
+ assert_equal ["Agile Web Development with Rails"], books.map(&:name)
92
+ end
93
+
94
+ def test_table_exists
95
+ view_name = Paperback.table_name
96
+ assert @connection.table_exists?(view_name), "'#{view_name}' table should exist"
97
+ end
98
+
99
+ def test_column_definitions
100
+ assert_equal([["name", :string],
101
+ ["status", :integer]], Paperback.columns.map { |c| [c.name, c.type] })
102
+ end
103
+
104
+ def test_attributes
105
+ assert_equal({"name" => "Agile Web Development with Rails", "status" => 0},
106
+ Paperback.first.attributes)
107
+ end
108
+
109
+ def test_does_not_have_a_primary_key
110
+ assert_nil Paperback.primary_key
111
+ end
112
+ end
113
+ end
@@ -1,408 +1,457 @@
1
- require "cases/helper"
2
- require 'models/contact'
3
- require 'models/post'
4
- require 'models/author'
5
- require 'models/comment'
6
- require 'models/company_in_module'
7
- require 'models/toy'
8
- require 'models/topic'
9
- require 'models/reply'
10
- require 'models/company'
11
-
12
- class XmlSerializationTest < ActiveRecord::TestCase
13
- def test_should_serialize_default_root
14
- @xml = Contact.new.to_xml
15
- assert_match %r{^<contact>}, @xml
16
- assert_match %r{</contact>$}, @xml
17
- end
18
-
19
- def test_should_serialize_default_root_with_namespace
20
- @xml = Contact.new.to_xml :namespace=>"http://xml.rubyonrails.org/contact"
21
- assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, @xml
22
- assert_match %r{</contact>$}, @xml
23
- end
24
-
25
- def test_should_serialize_custom_root
26
- @xml = Contact.new.to_xml :root => 'xml_contact'
27
- assert_match %r{^<xml-contact>}, @xml
28
- assert_match %r{</xml-contact>$}, @xml
29
- end
30
-
31
- def test_should_allow_undasherized_tags
32
- @xml = Contact.new.to_xml :root => 'xml_contact', :dasherize => false
33
- assert_match %r{^<xml_contact>}, @xml
34
- assert_match %r{</xml_contact>$}, @xml
35
- assert_match %r{<created_at}, @xml
36
- end
37
-
38
- def test_should_allow_camelized_tags
39
- @xml = Contact.new.to_xml :root => 'xml_contact', :camelize => true
40
- assert_match %r{^<XmlContact>}, @xml
41
- assert_match %r{</XmlContact>$}, @xml
42
- assert_match %r{<CreatedAt}, @xml
43
- end
44
-
45
- def test_should_allow_skipped_types
46
- @xml = Contact.new(:age => 25).to_xml :skip_types => true
47
- assert %r{<age>25</age>}.match(@xml)
48
- end
49
-
50
- def test_should_include_yielded_additions
51
- @xml = Contact.new.to_xml do |xml|
52
- xml.creator "David"
53
- end
54
- assert_match %r{<creator>David</creator>}, @xml
55
- end
56
-
57
- def test_to_xml_with_block
58
- value = "Rockin' the block"
59
- xml = Contact.new.to_xml(:skip_instruct => true) do |_xml|
60
- _xml.tag! "arbitrary-element", value
61
- end
62
- assert_equal "<contact>", xml.first(9)
63
- assert xml.include?(%(<arbitrary-element>#{value}</arbitrary-element>))
64
- end
65
-
66
- def test_should_skip_instruct_for_included_records
67
- @contact = Contact.new
68
- @contact.alternative = Contact.new(:name => 'Copa Cabana')
69
- @xml = @contact.to_xml(:include => [ :alternative ])
70
- assert_equal @xml.index('<?xml '), 0
71
- assert_nil @xml.index('<?xml ', 1)
72
- end
73
- end
74
-
75
- class DefaultXmlSerializationTest < ActiveRecord::TestCase
76
- def setup
77
- @xml = Contact.new(:name => 'aaron stack', :age => 25, :avatar => 'binarydata', :created_at => Time.utc(2006, 8, 1), :awesome => false, :preferences => { :gem => 'ruby' }).to_xml
78
- end
79
-
80
- def test_should_serialize_string
81
- assert_match %r{<name>aaron stack</name>}, @xml
82
- end
83
-
84
- def test_should_serialize_integer
85
- assert_match %r{<age type="integer">25</age>}, @xml
86
- end
87
-
88
- def test_should_serialize_binary
89
- assert_match %r{YmluYXJ5ZGF0YQ==\n</avatar>}, @xml
90
- assert_match %r{<avatar(.*)(type="binary")}, @xml
91
- assert_match %r{<avatar(.*)(encoding="base64")}, @xml
92
- end
93
-
94
- def test_should_serialize_datetime
95
- assert_match %r{<created-at type=\"datetime\">2006-08-01T00:00:00Z</created-at>}, @xml
96
- end
97
-
98
- def test_should_serialize_boolean
99
- assert_match %r{<awesome type=\"boolean\">false</awesome>}, @xml
100
- end
101
-
102
- def test_should_serialize_hash
103
- assert_match %r{<preferences>\s*<gem>ruby</gem>\s*</preferences>}m, @xml
104
- end
105
- end
106
-
107
- class DefaultXmlSerializationTimezoneTest < ActiveRecord::TestCase
108
- def test_should_serialize_datetime_with_timezone
109
- timezone, Time.zone = Time.zone, "Pacific Time (US & Canada)"
110
-
111
- toy = Toy.create(:name => 'Mickey', :updated_at => Time.utc(2006, 8, 1))
112
- unless current_adapter?(:IBM_DBAdapter)
113
- assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
114
- else
115
- assert_match %r{<updated-at type=\"timestamp\">2006-07-31 17:00:00 -0700</updated-at>}, toy.to_xml
116
- end
117
- ensure
118
- Time.zone = timezone
119
- end
120
-
121
- def test_should_serialize_datetime_with_timezone_reloaded
122
- timezone, Time.zone = Time.zone, "Pacific Time (US & Canada)"
123
-
124
- toy = Toy.create(:name => 'Minnie', :updated_at => Time.utc(2006, 8, 1)).reload
125
- unless current_adapter?(:IBM_DBAdapter)
126
- assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
127
- else
128
- assert_match %r{<updated-at type=\"timestamp\">2006-07-31 17:00:00 -0700</updated-at>}, toy.to_xml
129
- end
130
- ensure
131
- Time.zone = timezone
132
- end
133
- end
134
-
135
- class NilXmlSerializationTest < ActiveRecord::TestCase
136
- def setup
137
- @xml = Contact.new.to_xml(:root => 'xml_contact')
138
- end
139
-
140
- def test_should_serialize_string
141
- assert_match %r{<name nil="true"></name>}, @xml
142
- end
143
-
144
- def test_should_serialize_integer
145
- assert %r{<age (.*)></age>}.match(@xml)
146
- attributes = $1
147
- assert_match %r{nil="true"}, attributes
148
- assert_match %r{type="integer"}, attributes
149
- end
150
-
151
- def test_should_serialize_binary
152
- assert %r{<avatar (.*)></avatar>}.match(@xml)
153
- attributes = $1
154
- assert_match %r{type="binary"}, attributes
155
- assert_match %r{encoding="base64"}, attributes
156
- assert_match %r{nil="true"}, attributes
157
- end
158
-
159
- def test_should_serialize_datetime
160
- assert %r{<created-at (.*)></created-at>}.match(@xml)
161
- attributes = $1
162
- assert_match %r{nil="true"}, attributes
163
- assert_match %r{type="datetime"}, attributes
164
- end
165
-
166
- def test_should_serialize_boolean
167
- assert %r{<awesome (.*)></awesome>}.match(@xml)
168
- attributes = $1
169
- assert_match %r{type="boolean"}, attributes
170
- assert_match %r{nil="true"}, attributes
171
- end
172
-
173
- def test_should_serialize_yaml
174
- assert_match %r{<preferences nil=\"true\"></preferences>}, @xml
175
- end
176
- end
177
-
178
- class DatabaseConnectedXmlSerializationTest < ActiveRecord::TestCase
179
- fixtures :topics, :companies, :accounts, :authors, :posts, :projects
180
-
181
- def test_to_xml
182
- xml = REXML::Document.new(topics(:first).to_xml(:indent => 0))
183
- bonus_time_in_current_timezone = topics(:first).bonus_time.xmlschema
184
- written_on_in_current_timezone = topics(:first).written_on.xmlschema
185
- last_read_in_current_timezone = topics(:first).last_read.xmlschema
186
-
187
- assert_equal "topic", xml.root.name
188
- assert_equal "The First Topic" , xml.elements["//title"].text
189
- assert_equal "David" , xml.elements["//author-name"].text
190
- assert_match "Have a nice day", xml.elements["//content"].text
191
-
192
- assert_equal "1", xml.elements["//id"].text
193
- assert_equal "integer" , xml.elements["//id"].attributes['type']
194
-
195
- assert_equal "1", xml.elements["//replies-count"].text
196
- assert_equal "integer" , xml.elements["//replies-count"].attributes['type']
197
-
198
- assert_equal written_on_in_current_timezone, xml.elements["//written-on"].text
199
- assert_equal "datetime" , xml.elements["//written-on"].attributes['type']
200
-
201
- assert_equal "david@loudthinking.com", xml.elements["//author-email-address"].text
202
-
203
- assert_equal nil, xml.elements["//parent-id"].text
204
- assert_equal "integer", xml.elements["//parent-id"].attributes['type']
205
- assert_equal "true", xml.elements["//parent-id"].attributes['nil']
206
-
207
- if current_adapter?(:SybaseAdapter)
208
- assert_equal last_read_in_current_timezone, xml.elements["//last-read"].text
209
- assert_equal "datetime" , xml.elements["//last-read"].attributes['type']
210
- else
211
- # Oracle enhanced adapter allows to define Date attributes in model class (see topic.rb)
212
- assert_equal "2004-04-15", xml.elements["//last-read"].text
213
- assert_equal "date" , xml.elements["//last-read"].attributes['type']
214
- end
215
-
216
- # Oracle and DB2 don't have true boolean or time-only fields
217
- unless current_adapter?(:OracleAdapter, :DB2Adapter)
218
- assert_equal "false", xml.elements["//approved"].text
219
- assert_equal "boolean" , xml.elements["//approved"].attributes['type']
220
-
221
- assert_equal bonus_time_in_current_timezone, xml.elements["//bonus-time"].text
222
- assert_equal "datetime" , xml.elements["//bonus-time"].attributes['type']
223
- end
224
- end
225
-
226
- def test_except_option
227
- xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :replies_count])
228
- assert_equal "<topic>", xml.first(7)
229
- assert !xml.include?(%(<title>The First Topic</title>))
230
- assert xml.include?(%(<author-name>David</author-name>))
231
-
232
- xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :author_name, :replies_count])
233
- assert !xml.include?(%(<title>The First Topic</title>))
234
- assert !xml.include?(%(<author-name>David</author-name>))
235
- end
236
-
237
- # to_xml used to mess with the hash the user provided which
238
- # caused the builder to be reused. This meant the document kept
239
- # getting appended to.
240
-
241
- def test_modules
242
- projects = MyApplication::Business::Project.all
243
- xml = projects.to_xml
244
- root = projects.first.class.to_s.underscore.pluralize.tr('/','_').dasherize
245
- assert_match "<#{root} type=\"array\">", xml
246
- assert_match "</#{root}>", xml
247
- end
248
-
249
- def test_passing_hash_shouldnt_reuse_builder
250
- options = {:include=>:posts}
251
- david = authors(:david)
252
- first_xml_size = david.to_xml(options).size
253
- second_xml_size = david.to_xml(options).size
254
- assert_equal first_xml_size, second_xml_size
255
- end
256
-
257
- def test_include_uses_association_name
258
- xml = authors(:david).to_xml :include=>:hello_posts, :indent => 0
259
- assert_match %r{<hello-posts type="array">}, xml
260
- assert_match %r{<hello-post type="Post">}, xml
261
- assert_match %r{<hello-post type="StiPost">}, xml
262
- end
263
-
264
- def test_included_associations_should_skip_types
265
- xml = authors(:david).to_xml :include=>:hello_posts, :indent => 0, :skip_types => true
266
- assert_match %r{<hello-posts>}, xml
267
- assert_match %r{<hello-post>}, xml
268
- assert_match %r{<hello-post>}, xml
269
- end
270
-
271
- def test_including_has_many_association
272
- xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :include => :replies, :except => :replies_count)
273
- assert_equal "<topic>", xml.first(7)
274
- assert xml.include?(%(<replies type="array"><reply>))
275
- assert xml.include?(%(<title>The Second Topic of the day</title>))
276
- end
277
-
278
- def test_including_belongs_to_association
279
- xml = companies(:first_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
280
- assert !xml.include?("<firm>")
281
-
282
- xml = companies(:second_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
283
- assert xml.include?("<firm>")
284
- end
285
-
286
- def test_including_multiple_associations
287
- xml = companies(:first_firm).to_xml(:indent => 0, :skip_instruct => true, :include => [ :clients, :account ])
288
- assert_equal "<firm>", xml.first(6)
289
- assert xml.include?(%(<account>))
290
- assert xml.include?(%(<clients type="array"><client>))
291
- end
292
-
293
- def test_including_association_with_options
294
- xml = companies(:first_firm).to_xml(
295
- :indent => 0, :skip_instruct => true,
296
- :include => { :clients => { :only => :name } }
297
- )
298
-
299
- assert_equal "<firm>", xml.first(6)
300
- assert xml.include?(%(<client><name>Summit</name></client>))
301
- assert xml.include?(%(<clients type="array"><client>))
302
- end
303
-
304
- def test_methods_are_called_on_object
305
- xml = authors(:david).to_xml :methods => :label, :indent => 0
306
- assert_match %r{<label>.*</label>}, xml
307
- end
308
-
309
- def test_should_not_call_methods_on_associations_that_dont_respond
310
- xml = authors(:david).to_xml :include=>:hello_posts, :methods => :label, :indent => 2
311
- assert !authors(:david).hello_posts.first.respond_to?(:label)
312
- assert_match %r{^ <label>.*</label>}, xml
313
- assert_no_match %r{^ <label>}, xml
314
- end
315
-
316
- def test_procs_are_called_on_object
317
- proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') }
318
- xml = authors(:david).to_xml(:procs => [ proc ])
319
- assert_match %r{<nationality>Danish</nationality>}, xml
320
- end
321
-
322
- def test_dual_arity_procs_are_called_on_object
323
- proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
324
- xml = authors(:david).to_xml(:procs => [ proc ])
325
- assert_match %r{<name-reverse>divaD</name-reverse>}, xml
326
- end
327
-
328
- def test_top_level_procs_arent_applied_to_associations
329
- author_proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') }
330
- xml = authors(:david).to_xml(:procs => [ author_proc ], :include => :posts, :indent => 2)
331
-
332
- assert_match %r{^ <nationality>Danish</nationality>}, xml
333
- assert_no_match %r{^ {6}<nationality>Danish</nationality>}, xml
334
- end
335
-
336
- def test_procs_on_included_associations_are_called
337
- posts_proc = Proc.new { |options| options[:builder].tag!('copyright', 'DHH') }
338
- xml = authors(:david).to_xml(
339
- :indent => 2,
340
- :include => {
341
- :posts => { :procs => [ posts_proc ] }
342
- }
343
- )
344
-
345
- assert_no_match %r{^ <copyright>DHH</copyright>}, xml
346
- assert_match %r{^ {6}<copyright>DHH</copyright>}, xml
347
- end
348
-
349
- def test_should_include_empty_has_many_as_empty_array
350
- authors(:david).posts.delete_all
351
- xml = authors(:david).to_xml :include=>:posts, :indent => 2
352
-
353
- assert_equal [], Hash.from_xml(xml)['author']['posts']
354
- assert_match %r{^ <posts type="array"/>}, xml
355
- end
356
-
357
- def test_should_has_many_array_elements_should_include_type_when_different_from_guessed_value
358
- xml = authors(:david).to_xml :include=>:posts_with_comments, :indent => 2
359
-
360
- assert Hash.from_xml(xml)
361
- assert_match %r{^ <posts-with-comments type="array">}, xml
362
- assert_match %r{^ <posts-with-comment type="Post">}, xml
363
- assert_match %r{^ <posts-with-comment type="StiPost">}, xml
364
-
365
- types = Hash.from_xml(xml)['author']['posts_with_comments'].collect {|t| t['type'] }
366
- assert types.include?('SpecialPost')
367
- assert types.include?('Post')
368
- assert types.include?('StiPost')
369
- end
370
-
371
- def test_should_produce_xml_for_methods_returning_array
372
- xml = authors(:david).to_xml(:methods => :social)
373
- array = Hash.from_xml(xml)['author']['social']
374
- assert_equal 2, array.size
375
- assert array.include? 'twitter'
376
- assert array.include? 'github'
377
- end
378
-
379
- def test_should_support_aliased_attributes
380
- xml = Author.select("name as firstname").to_xml
381
- array = Hash.from_xml(xml)['authors']
382
- assert_equal array.size, array.select { |author| author.has_key? 'firstname' }.size
383
- end
384
-
385
- def test_array_to_xml_including_has_many_association
386
- xml = [ topics(:first), topics(:second) ].to_xml(:indent => 0, :skip_instruct => true, :include => :replies)
387
- assert xml.include?(%(<replies type="array"><reply>))
388
- end
389
-
390
- def test_array_to_xml_including_methods
391
- xml = [ topics(:first), topics(:second) ].to_xml(:indent => 0, :skip_instruct => true, :methods => [ :topic_id ])
392
- assert xml.include?(%(<topic-id type="integer">#{topics(:first).topic_id}</topic-id>)), xml
393
- assert xml.include?(%(<topic-id type="integer">#{topics(:second).topic_id}</topic-id>)), xml
394
- end
395
-
396
- def test_array_to_xml_including_has_one_association
397
- xml = [ companies(:first_firm), companies(:rails_core) ].to_xml(:indent => 0, :skip_instruct => true, :include => :account)
398
- assert xml.include?(companies(:first_firm).account.to_xml(:indent => 0, :skip_instruct => true))
399
- assert xml.include?(companies(:rails_core).account.to_xml(:indent => 0, :skip_instruct => true))
400
- end
401
-
402
- def test_array_to_xml_including_belongs_to_association
403
- xml = [ companies(:first_client), companies(:second_client), companies(:another_client) ].to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
404
- assert xml.include?(companies(:first_client).to_xml(:indent => 0, :skip_instruct => true))
405
- assert xml.include?(companies(:second_client).firm.to_xml(:indent => 0, :skip_instruct => true))
406
- assert xml.include?(companies(:another_client).firm.to_xml(:indent => 0, :skip_instruct => true))
407
- end
408
- end
1
+ require "cases/helper"
2
+ require "rexml/document"
3
+ require 'models/contact'
4
+ require 'models/post'
5
+ require 'models/author'
6
+ require 'models/comment'
7
+ require 'models/company_in_module'
8
+ require 'models/toy'
9
+ require 'models/topic'
10
+ require 'models/reply'
11
+ require 'models/company'
12
+
13
+ class XmlSerializationTest < ActiveRecord::TestCase
14
+ def test_should_serialize_default_root
15
+ @xml = Contact.new.to_xml
16
+ assert_match %r{^<contact>}, @xml
17
+ assert_match %r{</contact>$}, @xml
18
+ end
19
+
20
+ def test_should_serialize_default_root_with_namespace
21
+ @xml = Contact.new.to_xml :namespace=>"http://xml.rubyonrails.org/contact"
22
+ assert_match %r{^<contact xmlns="http://xml.rubyonrails.org/contact">}, @xml
23
+ assert_match %r{</contact>$}, @xml
24
+ end
25
+
26
+ def test_should_serialize_custom_root
27
+ @xml = Contact.new.to_xml :root => 'xml_contact'
28
+ assert_match %r{^<xml-contact>}, @xml
29
+ assert_match %r{</xml-contact>$}, @xml
30
+ end
31
+
32
+ def test_should_allow_undasherized_tags
33
+ @xml = Contact.new.to_xml :root => 'xml_contact', :dasherize => false
34
+ assert_match %r{^<xml_contact>}, @xml
35
+ assert_match %r{</xml_contact>$}, @xml
36
+ assert_match %r{<created_at}, @xml
37
+ end
38
+
39
+ def test_should_allow_camelized_tags
40
+ @xml = Contact.new.to_xml :root => 'xml_contact', :camelize => true
41
+ assert_match %r{^<XmlContact>}, @xml
42
+ assert_match %r{</XmlContact>$}, @xml
43
+ assert_match %r{<CreatedAt}, @xml
44
+ end
45
+
46
+ def test_should_allow_skipped_types
47
+ @xml = Contact.new(:age => 25).to_xml :skip_types => true
48
+ assert %r{<age>25</age>}.match(@xml)
49
+ end
50
+
51
+ def test_should_include_yielded_additions
52
+ @xml = Contact.new.to_xml do |xml|
53
+ xml.creator "David"
54
+ end
55
+ assert_match %r{<creator>David</creator>}, @xml
56
+ end
57
+
58
+ def test_to_xml_with_block
59
+ value = "Rockin' the block"
60
+ xml = Contact.new.to_xml(:skip_instruct => true) do |_xml|
61
+ _xml.tag! "arbitrary-element", value
62
+ end
63
+ assert_equal "<contact>", xml.first(9)
64
+ assert xml.include?(%(<arbitrary-element>#{value}</arbitrary-element>))
65
+ end
66
+
67
+ def test_should_skip_instruct_for_included_records
68
+ @contact = Contact.new
69
+ @contact.alternative = Contact.new(:name => 'Copa Cabana')
70
+ @xml = @contact.to_xml(:include => [ :alternative ])
71
+ assert_equal @xml.index('<?xml '), 0
72
+ assert_nil @xml.index('<?xml ', 1)
73
+ end
74
+ end
75
+
76
+ class DefaultXmlSerializationTest < ActiveRecord::TestCase
77
+ def setup
78
+ @contact = Contact.new(
79
+ :name => 'aaron stack',
80
+ :age => 25,
81
+ :avatar => 'binarydata',
82
+ :created_at => Time.utc(2006, 8, 1),
83
+ :awesome => false,
84
+ :preferences => { :gem => 'ruby' }
85
+ )
86
+ end
87
+
88
+ def test_should_serialize_string
89
+ assert_match %r{<name>aaron stack</name>}, @contact.to_xml
90
+ end
91
+
92
+ def test_should_serialize_integer
93
+ assert_match %r{<age type="integer">25</age>}, @contact.to_xml
94
+ end
95
+
96
+ def test_should_serialize_binary
97
+ xml = @contact.to_xml
98
+ assert_match %r{YmluYXJ5ZGF0YQ==\n</avatar>}, xml
99
+ assert_match %r{<avatar(.*)(type="binary")}, xml
100
+ assert_match %r{<avatar(.*)(encoding="base64")}, xml
101
+ end
102
+
103
+ def test_should_serialize_datetime
104
+ assert_match %r{<created-at type=\"dateTime\">2006-08-01T00:00:00Z</created-at>}, @contact.to_xml
105
+ end
106
+
107
+ def test_should_serialize_boolean
108
+ assert_match %r{<awesome type=\"boolean\">false</awesome>}, @contact.to_xml
109
+ end
110
+
111
+ def test_should_serialize_hash
112
+ assert_match %r{<preferences>\s*<gem>ruby</gem>\s*</preferences>}m, @contact.to_xml
113
+ end
114
+
115
+ def test_uses_serializable_hash_with_only_option
116
+ def @contact.serializable_hash(options=nil)
117
+ super(only: %w(name))
118
+ end
119
+
120
+ xml = @contact.to_xml
121
+ assert_match %r{<name>aaron stack</name>}, xml
122
+ assert_no_match %r{age}, xml
123
+ assert_no_match %r{awesome}, xml
124
+ end
125
+
126
+ def test_uses_serializable_hash_with_except_option
127
+ def @contact.serializable_hash(options=nil)
128
+ super(except: %w(age))
129
+ end
130
+
131
+ xml = @contact.to_xml
132
+ assert_match %r{<name>aaron stack</name>}, xml
133
+ assert_match %r{<awesome type=\"boolean\">false</awesome>}, xml
134
+ assert_no_match %r{age}, xml
135
+ end
136
+
137
+ def test_does_not_include_inheritance_column_from_sti
138
+ @contact = ContactSti.new(@contact.attributes)
139
+ assert_equal 'ContactSti', @contact.type
140
+
141
+ xml = @contact.to_xml
142
+ assert_match %r{<name>aaron stack</name>}, xml
143
+ assert_no_match %r{<type}, xml
144
+ assert_no_match %r{ContactSti}, xml
145
+ end
146
+
147
+ def test_serializable_hash_with_default_except_option_and_excluding_inheritance_column_from_sti
148
+ @contact = ContactSti.new(@contact.attributes)
149
+ assert_equal 'ContactSti', @contact.type
150
+
151
+ def @contact.serializable_hash(options={})
152
+ super({ except: %w(age) }.merge!(options))
153
+ end
154
+
155
+ xml = @contact.to_xml
156
+ assert_match %r{<name>aaron stack</name>}, xml
157
+ assert_no_match %r{age}, xml
158
+ assert_no_match %r{<type}, xml
159
+ assert_no_match %r{ContactSti}, xml
160
+ end
161
+ end
162
+
163
+ class DefaultXmlSerializationTimezoneTest < ActiveRecord::TestCase
164
+ def test_should_serialize_datetime_with_timezone
165
+ with_timezone_config zone: "Pacific Time (US & Canada)" do
166
+ toy = Toy.create(:name => 'Mickey', :updated_at => Time.utc(2006, 8, 1))
167
+ unless current_adapter?(:IBM_DBAdapter)
168
+ assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
169
+ else
170
+ #assert_match %r{<updated-at type=\"timestamp\">2006-07-31 17:00:00 -0700</updated-at>}, toy.to_xml
171
+ assert_match %r{<updated-at type=\"dateTime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
172
+ end
173
+ end
174
+ end
175
+
176
+ def test_should_serialize_datetime_with_timezone_reloaded
177
+ with_timezone_config zone: "Pacific Time (US & Canada)" do
178
+ toy = Toy.create(:name => 'Minnie', :updated_at => Time.utc(2006, 8, 1)).reload
179
+ unless current_adapter?(:IBM_DBAdapter)
180
+ assert_match %r{<updated-at type=\"datetime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
181
+ else
182
+ #assert_match %r{<updated-at type=\"timestamp\">2006-07-31 17:00:00 -0700</updated-at>}, toy.to_xml
183
+ assert_match %r{<updated-at type=\"dateTime\">2006-07-31T17:00:00-07:00</updated-at>}, toy.to_xml
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ class NilXmlSerializationTest < ActiveRecord::TestCase
190
+ def setup
191
+ @xml = Contact.new.to_xml(:root => 'xml_contact')
192
+ end
193
+
194
+ def test_should_serialize_string
195
+ assert_match %r{<name nil="true"/>}, @xml
196
+ end
197
+
198
+ def test_should_serialize_integer
199
+ assert %r{<age (.*)/>}.match(@xml)
200
+ attributes = $1
201
+ assert_match %r{nil="true"}, attributes
202
+ assert_match %r{type="integer"}, attributes
203
+ end
204
+
205
+ def test_should_serialize_binary
206
+ assert %r{<avatar (.*)/>}.match(@xml)
207
+ attributes = $1
208
+ assert_match %r{type="binary"}, attributes
209
+ assert_match %r{encoding="base64"}, attributes
210
+ assert_match %r{nil="true"}, attributes
211
+ end
212
+
213
+ def test_should_serialize_datetime
214
+ assert %r{<created-at (.*)/>}.match(@xml)
215
+ attributes = $1
216
+ assert_match %r{nil="true"}, attributes
217
+ assert_match %r{type="dateTime"}, attributes
218
+ end
219
+
220
+ def test_should_serialize_boolean
221
+ assert %r{<awesome (.*)/>}.match(@xml)
222
+ attributes = $1
223
+ assert_match %r{type="boolean"}, attributes
224
+ assert_match %r{nil="true"}, attributes
225
+ end
226
+
227
+ def test_should_serialize_yaml
228
+ assert_match %r{<preferences nil=\"true\"/>}, @xml
229
+ end
230
+ end
231
+
232
+ class DatabaseConnectedXmlSerializationTest < ActiveRecord::TestCase
233
+ fixtures :topics, :companies, :accounts, :authors, :posts, :projects, :author_addresses
234
+
235
+ def test_to_xml
236
+ xml = REXML::Document.new(topics(:first).to_xml(:indent => 0))
237
+ bonus_time_in_current_timezone = topics(:first).bonus_time.xmlschema
238
+ written_on_in_current_timezone = topics(:first).written_on.xmlschema
239
+
240
+ assert_equal "topic", xml.root.name
241
+ assert_equal "The First Topic" , xml.elements["//title"].text
242
+ assert_equal "David" , xml.elements["//author-name"].text
243
+ assert_match "Have a nice day", xml.elements["//content"].text
244
+
245
+ assert_equal "1", xml.elements["//id"].text
246
+ assert_equal "integer" , xml.elements["//id"].attributes['type']
247
+
248
+ assert_equal "1", xml.elements["//replies-count"].text
249
+ assert_equal "integer" , xml.elements["//replies-count"].attributes['type']
250
+
251
+ assert_equal written_on_in_current_timezone, xml.elements["//written-on"].text
252
+ assert_equal "dateTime" , xml.elements["//written-on"].attributes['type']
253
+
254
+ assert_equal "david@loudthinking.com", xml.elements["//author-email-address"].text
255
+
256
+ assert_equal nil, xml.elements["//parent-id"].text
257
+ assert_equal "integer", xml.elements["//parent-id"].attributes['type']
258
+ assert_equal "true", xml.elements["//parent-id"].attributes['nil']
259
+
260
+ # Oracle enhanced adapter allows to define Date attributes in model class (see topic.rb)
261
+ assert_equal "2004-04-15", xml.elements["//last-read"].text
262
+ assert_equal "date" , xml.elements["//last-read"].attributes['type']
263
+
264
+ # Oracle and DB2 don't have true boolean or time-only fields
265
+ unless current_adapter?(:OracleAdapter, :DB2Adapter)
266
+ assert_equal "false", xml.elements["//approved"].text
267
+ assert_equal "boolean" , xml.elements["//approved"].attributes['type']
268
+
269
+ assert_equal bonus_time_in_current_timezone, xml.elements["//bonus-time"].text
270
+ assert_equal "dateTime" , xml.elements["//bonus-time"].attributes['type']
271
+ end
272
+ end
273
+
274
+ def test_except_option
275
+ xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :replies_count])
276
+ assert_equal "<topic>", xml.first(7)
277
+ assert !xml.include?(%(<title>The First Topic</title>))
278
+ assert xml.include?(%(<author-name>David</author-name>))
279
+
280
+ xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :except => [:title, :author_name, :replies_count])
281
+ assert !xml.include?(%(<title>The First Topic</title>))
282
+ assert !xml.include?(%(<author-name>David</author-name>))
283
+ end
284
+
285
+ # to_xml used to mess with the hash the user provided which
286
+ # caused the builder to be reused. This meant the document kept
287
+ # getting appended to.
288
+
289
+ def test_modules
290
+ projects = MyApplication::Business::Project.all
291
+ xml = projects.to_xml
292
+ root = projects.first.class.to_s.underscore.pluralize.tr('/','_').dasherize
293
+ assert_match "<#{root} type=\"array\">", xml
294
+ assert_match "</#{root}>", xml
295
+ end
296
+
297
+ def test_passing_hash_shouldnt_reuse_builder
298
+ options = {:include=>:posts}
299
+ david = authors(:david)
300
+ first_xml_size = david.to_xml(options).size
301
+ second_xml_size = david.to_xml(options).size
302
+ assert_equal first_xml_size, second_xml_size
303
+ end
304
+
305
+ def test_include_uses_association_name
306
+ xml = authors(:david).to_xml :include=>:hello_posts, :indent => 0
307
+ assert_match %r{<hello-posts type="array">}, xml
308
+ assert_match %r{<hello-post type="Post">}, xml
309
+ assert_match %r{<hello-post type="StiPost">}, xml
310
+ end
311
+
312
+ def test_included_associations_should_skip_types
313
+ xml = authors(:david).to_xml :include=>:hello_posts, :indent => 0, :skip_types => true
314
+ assert_match %r{<hello-posts>}, xml
315
+ assert_match %r{<hello-post>}, xml
316
+ assert_match %r{<hello-post>}, xml
317
+ end
318
+
319
+ def test_including_has_many_association
320
+ xml = topics(:first).to_xml(:indent => 0, :skip_instruct => true, :include => :replies, :except => :replies_count)
321
+ assert_equal "<topic>", xml.first(7)
322
+ assert xml.include?(%(<replies type="array"><reply>))
323
+ assert xml.include?(%(<title>The Second Topic of the day</title>))
324
+ end
325
+
326
+ def test_including_belongs_to_association
327
+ xml = companies(:first_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
328
+ assert !xml.include?("<firm>")
329
+
330
+ xml = companies(:second_client).to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
331
+ assert xml.include?("<firm>")
332
+ end
333
+
334
+ def test_including_multiple_associations
335
+ xml = companies(:first_firm).to_xml(:indent => 0, :skip_instruct => true, :include => [ :clients, :account ])
336
+ assert_equal "<firm>", xml.first(6)
337
+ assert xml.include?(%(<account>))
338
+ assert xml.include?(%(<clients type="array"><client>))
339
+ end
340
+
341
+ def test_including_association_with_options
342
+ xml = companies(:first_firm).to_xml(
343
+ :indent => 0, :skip_instruct => true,
344
+ :include => { :clients => { :only => :name } }
345
+ )
346
+
347
+ assert_equal "<firm>", xml.first(6)
348
+ assert xml.include?(%(<client><name>Summit</name></client>))
349
+ assert xml.include?(%(<clients type="array"><client>))
350
+ end
351
+
352
+ def test_methods_are_called_on_object
353
+ xml = authors(:david).to_xml :methods => :label, :indent => 0
354
+ assert_match %r{<label>.*</label>}, xml
355
+ end
356
+
357
+ def test_should_not_call_methods_on_associations_that_dont_respond
358
+ xml = authors(:david).to_xml :include=>:hello_posts, :methods => :label, :indent => 2
359
+ assert !authors(:david).hello_posts.first.respond_to?(:label)
360
+ assert_match %r{^ <label>.*</label>}, xml
361
+ assert_no_match %r{^ <label>}, xml
362
+ end
363
+
364
+ def test_procs_are_called_on_object
365
+ proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') }
366
+ xml = authors(:david).to_xml(:procs => [ proc ])
367
+ assert_match %r{<nationality>Danish</nationality>}, xml
368
+ end
369
+
370
+ def test_dual_arity_procs_are_called_on_object
371
+ proc = Proc.new { |options, record| options[:builder].tag!('name-reverse', record.name.reverse) }
372
+ xml = authors(:david).to_xml(:procs => [ proc ])
373
+ assert_match %r{<name-reverse>divaD</name-reverse>}, xml
374
+ end
375
+
376
+ def test_top_level_procs_arent_applied_to_associations
377
+ author_proc = Proc.new { |options| options[:builder].tag!('nationality', 'Danish') }
378
+ xml = authors(:david).to_xml(:procs => [ author_proc ], :include => :posts, :indent => 2)
379
+
380
+ assert_match %r{^ <nationality>Danish</nationality>}, xml
381
+ assert_no_match %r{^ {6}<nationality>Danish</nationality>}, xml
382
+ end
383
+
384
+ def test_procs_on_included_associations_are_called
385
+ posts_proc = Proc.new { |options| options[:builder].tag!('copyright', 'DHH') }
386
+ xml = authors(:david).to_xml(
387
+ :indent => 2,
388
+ :include => {
389
+ :posts => { :procs => [ posts_proc ] }
390
+ }
391
+ )
392
+
393
+ assert_no_match %r{^ <copyright>DHH</copyright>}, xml
394
+ assert_match %r{^ {6}<copyright>DHH</copyright>}, xml
395
+ end
396
+
397
+ def test_should_include_empty_has_many_as_empty_array
398
+ authors(:david).posts.delete_all
399
+ xml = authors(:david).to_xml :include=>:posts, :indent => 2
400
+
401
+ assert_equal [], Hash.from_xml(xml)['author']['posts']
402
+ assert_match %r{^ <posts type="array"/>}, xml
403
+ end
404
+
405
+ def test_should_has_many_array_elements_should_include_type_when_different_from_guessed_value
406
+ xml = authors(:david).to_xml :include=>:posts_with_comments, :indent => 2
407
+
408
+ assert Hash.from_xml(xml)
409
+ assert_match %r{^ <posts-with-comments type="array">}, xml
410
+ assert_match %r{^ <posts-with-comment type="Post">}, xml
411
+ assert_match %r{^ <posts-with-comment type="StiPost">}, xml
412
+
413
+ types = Hash.from_xml(xml)['author']['posts_with_comments'].collect {|t| t['type'] }
414
+ assert types.include?('SpecialPost')
415
+ assert types.include?('Post')
416
+ assert types.include?('StiPost')
417
+ end
418
+
419
+ def test_should_produce_xml_for_methods_returning_array
420
+ xml = authors(:david).to_xml(:methods => :social)
421
+ array = Hash.from_xml(xml)['author']['social']
422
+ assert_equal 2, array.size
423
+ assert array.include? 'twitter'
424
+ assert array.include? 'github'
425
+ end
426
+
427
+ def test_should_support_aliased_attributes
428
+ xml = Author.select("name as firstname").to_xml
429
+ Author.all.each do |author|
430
+ assert xml.include?(%(<firstname>#{author.name}</firstname>)), xml
431
+ end
432
+ end
433
+
434
+ def test_array_to_xml_including_has_many_association
435
+ xml = [ topics(:first), topics(:second) ].to_xml(:indent => 0, :skip_instruct => true, :include => :replies)
436
+ assert xml.include?(%(<replies type="array"><reply>))
437
+ end
438
+
439
+ def test_array_to_xml_including_methods
440
+ xml = [ topics(:first), topics(:second) ].to_xml(:indent => 0, :skip_instruct => true, :methods => [ :topic_id ])
441
+ assert xml.include?(%(<topic-id type="integer">#{topics(:first).topic_id}</topic-id>)), xml
442
+ assert xml.include?(%(<topic-id type="integer">#{topics(:second).topic_id}</topic-id>)), xml
443
+ end
444
+
445
+ def test_array_to_xml_including_has_one_association
446
+ xml = [ companies(:first_firm), companies(:rails_core) ].to_xml(:indent => 0, :skip_instruct => true, :include => :account)
447
+ assert xml.include?(companies(:first_firm).account.to_xml(:indent => 0, :skip_instruct => true))
448
+ assert xml.include?(companies(:rails_core).account.to_xml(:indent => 0, :skip_instruct => true))
449
+ end
450
+
451
+ def test_array_to_xml_including_belongs_to_association
452
+ xml = [ companies(:first_client), companies(:second_client), companies(:another_client) ].to_xml(:indent => 0, :skip_instruct => true, :include => :firm)
453
+ assert xml.include?(companies(:first_client).to_xml(:indent => 0, :skip_instruct => true))
454
+ assert xml.include?(companies(:second_client).firm.to_xml(:indent => 0, :skip_instruct => true))
455
+ assert xml.include?(companies(:another_client).firm.to_xml(:indent => 0, :skip_instruct => true))
456
+ end
457
+ end