actionpack 1.13.6 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (317) hide show
  1. data/CHANGELOG +1400 -20
  2. data/MIT-LICENSE +1 -1
  3. data/README +5 -5
  4. data/RUNNING_UNIT_TESTS +4 -5
  5. data/Rakefile +5 -6
  6. data/install.rb +2 -2
  7. data/lib/action_controller.rb +11 -15
  8. data/lib/action_controller/assertions.rb +12 -25
  9. data/lib/action_controller/assertions/dom_assertions.rb +18 -4
  10. data/lib/action_controller/assertions/model_assertions.rb +8 -1
  11. data/lib/action_controller/assertions/response_assertions.rb +35 -12
  12. data/lib/action_controller/assertions/routing_assertions.rb +56 -12
  13. data/lib/action_controller/assertions/selector_assertions.rb +105 -38
  14. data/lib/action_controller/assertions/tag_assertions.rb +28 -15
  15. data/lib/action_controller/base.rb +318 -250
  16. data/lib/action_controller/benchmarking.rb +33 -29
  17. data/lib/action_controller/caching.rb +130 -64
  18. data/lib/action_controller/cgi_ext.rb +16 -0
  19. data/lib/action_controller/cgi_ext/{cookie_performance_fix.rb → cookie.rb} +25 -40
  20. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  21. data/lib/action_controller/cgi_ext/session.rb +73 -0
  22. data/lib/action_controller/cgi_ext/stdinput.rb +23 -0
  23. data/lib/action_controller/cgi_process.rb +34 -57
  24. data/lib/action_controller/components.rb +19 -36
  25. data/lib/action_controller/cookies.rb +10 -9
  26. data/lib/action_controller/dispatcher.rb +195 -0
  27. data/lib/action_controller/filters.rb +35 -34
  28. data/lib/action_controller/flash.rb +30 -35
  29. data/lib/action_controller/helpers.rb +121 -47
  30. data/lib/action_controller/http_authentication.rb +126 -0
  31. data/lib/action_controller/integration.rb +105 -101
  32. data/lib/action_controller/layout.rb +59 -47
  33. data/lib/action_controller/mime_responds.rb +57 -68
  34. data/lib/action_controller/mime_type.rb +43 -80
  35. data/lib/action_controller/mime_types.rb +20 -0
  36. data/lib/action_controller/polymorphic_routes.rb +88 -0
  37. data/lib/action_controller/record_identifier.rb +91 -0
  38. data/lib/action_controller/request.rb +553 -88
  39. data/lib/action_controller/request_forgery_protection.rb +126 -0
  40. data/lib/action_controller/request_profiler.rb +138 -0
  41. data/lib/action_controller/rescue.rb +185 -69
  42. data/lib/action_controller/resources.rb +211 -172
  43. data/lib/action_controller/response.rb +49 -8
  44. data/lib/action_controller/routing.rb +359 -236
  45. data/lib/action_controller/routing_optimisation.rb +119 -0
  46. data/lib/action_controller/session/active_record_store.rb +3 -2
  47. data/lib/action_controller/session/cookie_store.rb +161 -0
  48. data/lib/action_controller/session/mem_cache_store.rb +9 -16
  49. data/lib/action_controller/session_management.rb +17 -8
  50. data/lib/action_controller/streaming.rb +6 -3
  51. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  52. data/lib/action_controller/templates/rescues/{_trace.rhtml → _trace.erb} +0 -0
  53. data/lib/action_controller/templates/rescues/{diagnostics.rhtml → diagnostics.erb} +2 -2
  54. data/lib/action_controller/templates/rescues/{layout.rhtml → layout.erb} +0 -0
  55. data/lib/action_controller/templates/rescues/{missing_template.rhtml → missing_template.erb} +0 -0
  56. data/lib/action_controller/templates/rescues/{routing_error.rhtml → routing_error.erb} +0 -0
  57. data/lib/action_controller/templates/rescues/{template_error.rhtml → template_error.erb} +2 -2
  58. data/lib/action_controller/templates/rescues/{unknown_action.rhtml → unknown_action.erb} +0 -0
  59. data/lib/action_controller/test_case.rb +53 -0
  60. data/lib/action_controller/test_process.rb +59 -46
  61. data/lib/action_controller/url_rewriter.rb +48 -24
  62. data/lib/action_controller/vendor/html-scanner/html/document.rb +7 -4
  63. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  64. data/lib/action_controller/vendor/html-scanner/html/selector.rb +11 -6
  65. data/lib/action_controller/verification.rb +27 -21
  66. data/lib/action_pack.rb +1 -1
  67. data/lib/action_pack/version.rb +4 -4
  68. data/lib/action_view.rb +2 -3
  69. data/lib/action_view/base.rb +218 -63
  70. data/lib/action_view/compiled_templates.rb +1 -2
  71. data/lib/action_view/helpers/active_record_helper.rb +35 -17
  72. data/lib/action_view/helpers/asset_tag_helper.rb +395 -87
  73. data/lib/action_view/helpers/atom_feed_helper.rb +111 -0
  74. data/lib/action_view/helpers/benchmark_helper.rb +12 -5
  75. data/lib/action_view/helpers/cache_helper.rb +29 -0
  76. data/lib/action_view/helpers/capture_helper.rb +97 -63
  77. data/lib/action_view/helpers/date_helper.rb +295 -35
  78. data/lib/action_view/helpers/debug_helper.rb +6 -2
  79. data/lib/action_view/helpers/form_helper.rb +354 -111
  80. data/lib/action_view/helpers/form_options_helper.rb +171 -109
  81. data/lib/action_view/helpers/form_tag_helper.rb +332 -76
  82. data/lib/action_view/helpers/javascript_helper.rb +35 -11
  83. data/lib/action_view/helpers/javascripts/controls.js +484 -354
  84. data/lib/action_view/helpers/javascripts/dragdrop.js +88 -58
  85. data/lib/action_view/helpers/javascripts/effects.js +396 -364
  86. data/lib/action_view/helpers/javascripts/prototype.js +2817 -1107
  87. data/lib/action_view/helpers/number_helper.rb +84 -60
  88. data/lib/action_view/helpers/prototype_helper.rb +419 -43
  89. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  90. data/lib/action_view/helpers/record_tag_helper.rb +59 -0
  91. data/lib/action_view/helpers/sanitize_helper.rb +223 -0
  92. data/lib/action_view/helpers/scriptaculous_helper.rb +63 -4
  93. data/lib/action_view/helpers/tag_helper.rb +69 -39
  94. data/lib/action_view/helpers/text_helper.rb +221 -148
  95. data/lib/action_view/helpers/url_helper.rb +283 -165
  96. data/lib/action_view/partials.rb +134 -62
  97. data/lib/action_view/template_error.rb +4 -12
  98. data/lib/actionpack.rb +1 -0
  99. data/test/abstract_unit.rb +21 -1
  100. data/test/action_view_test.rb +26 -0
  101. data/test/active_record_unit.rb +12 -20
  102. data/test/activerecord/active_record_store_test.rb +2 -2
  103. data/test/activerecord/render_partial_with_record_identification_test.rb +74 -0
  104. data/test/controller/action_pack_assertions_test.rb +21 -152
  105. data/test/controller/addresses_render_test.rb +2 -7
  106. data/test/controller/assert_select_test.rb +120 -14
  107. data/test/controller/base_test.rb +11 -13
  108. data/test/controller/caching_test.rb +125 -5
  109. data/test/controller/capture_test.rb +23 -16
  110. data/test/controller/cgi_test.rb +66 -391
  111. data/test/controller/components_test.rb +31 -42
  112. data/test/controller/content_type_test.rb +1 -1
  113. data/test/controller/cookie_test.rb +42 -14
  114. data/test/controller/deprecation/deprecated_base_methods_test.rb +1 -42
  115. data/test/controller/dispatcher_test.rb +123 -0
  116. data/test/controller/fake_models.rb +5 -0
  117. data/test/controller/filters_test.rb +44 -7
  118. data/test/controller/flash_test.rb +46 -2
  119. data/test/controller/fragment_store_setting_test.rb +10 -8
  120. data/test/controller/helper_test.rb +19 -2
  121. data/test/controller/html-scanner/document_test.rb +124 -0
  122. data/test/controller/html-scanner/node_test.rb +69 -0
  123. data/test/controller/html-scanner/sanitizer_test.rb +250 -0
  124. data/test/controller/html-scanner/tag_node_test.rb +239 -0
  125. data/test/controller/html-scanner/text_node_test.rb +51 -0
  126. data/test/controller/html-scanner/tokenizer_test.rb +125 -0
  127. data/test/controller/http_authentication_test.rb +54 -0
  128. data/test/controller/integration_test.rb +12 -26
  129. data/test/controller/layout_test.rb +64 -12
  130. data/test/controller/mime_responds_test.rb +193 -38
  131. data/test/controller/mime_type_test.rb +30 -8
  132. data/test/controller/new_render_test.rb +104 -22
  133. data/test/controller/polymorphic_routes_test.rb +98 -0
  134. data/test/controller/record_identifier_test.rb +103 -0
  135. data/test/controller/redirect_test.rb +120 -18
  136. data/test/controller/render_test.rb +195 -45
  137. data/test/controller/request_forgery_protection_test.rb +217 -0
  138. data/test/controller/request_test.rb +545 -27
  139. data/test/controller/rescue_test.rb +501 -0
  140. data/test/controller/resources_test.rb +258 -132
  141. data/test/controller/routing_test.rb +502 -106
  142. data/test/controller/selector_test.rb +5 -5
  143. data/test/controller/send_file_test.rb +17 -7
  144. data/test/controller/session/cookie_store_test.rb +246 -0
  145. data/test/controller/session/mem_cache_store_test.rb +182 -0
  146. data/test/controller/session_fixation_test.rb +8 -11
  147. data/test/controller/session_management_test.rb +7 -7
  148. data/test/controller/test_test.rb +150 -38
  149. data/test/controller/url_rewriter_test.rb +87 -12
  150. data/test/controller/verification_test.rb +11 -0
  151. data/test/controller/view_paths_test.rb +137 -0
  152. data/test/controller/webservice_test.rb +11 -75
  153. data/test/fixtures/addresses/{list.rhtml → list.erb} +0 -0
  154. data/test/fixtures/db_definitions/sqlite.sql +2 -1
  155. data/test/fixtures/developer.rb +2 -0
  156. data/test/fixtures/fun/games/{hello_world.rhtml → hello_world.erb} +0 -0
  157. data/test/fixtures/helpers/fun/pdf_helper.rb +1 -1
  158. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  159. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  160. data/test/fixtures/layouts/{builder.rxml → builder.builder} +0 -0
  161. data/test/fixtures/layouts/{standard.rhtml → standard.erb} +0 -0
  162. data/test/fixtures/layouts/{talk_from_action.rhtml → talk_from_action.erb} +0 -0
  163. data/test/fixtures/layouts/{yield.rhtml → yield.erb} +0 -0
  164. data/test/fixtures/multipart/binary_file +0 -0
  165. data/test/fixtures/multipart/bracketed_param +5 -0
  166. data/test/fixtures/override/test/hello_world.erb +1 -0
  167. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  168. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  169. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  170. data/test/fixtures/post_test/post/index.html.erb +1 -0
  171. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  172. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  173. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  174. data/test/fixtures/public/404.html +1 -0
  175. data/test/fixtures/public/500.html +1 -0
  176. data/test/fixtures/public/javascripts/application.js +0 -1
  177. data/test/fixtures/public/javascripts/bank.js +1 -0
  178. data/test/fixtures/public/javascripts/robber.js +1 -0
  179. data/test/fixtures/public/stylesheets/bank.css +1 -0
  180. data/test/fixtures/public/stylesheets/robber.css +1 -0
  181. data/test/fixtures/replies.yml +2 -0
  182. data/test/fixtures/reply.rb +2 -1
  183. data/test/fixtures/respond_to/{all_types_with_layout.rhtml → all_types_with_layout.html.erb} +0 -0
  184. data/test/fixtures/respond_to/{all_types_with_layout.rjs → all_types_with_layout.js.rjs} +0 -0
  185. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  186. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  187. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  188. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  189. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  190. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  191. data/test/fixtures/respond_to/{using_defaults.rhtml → using_defaults.html.erb} +0 -0
  192. data/test/fixtures/respond_to/{using_defaults.rjs → using_defaults.js.rjs} +0 -0
  193. data/test/fixtures/respond_to/{using_defaults.rxml → using_defaults.xml.builder} +0 -0
  194. data/test/fixtures/respond_to/{using_defaults_with_type_list.rhtml → using_defaults_with_type_list.html.erb} +0 -0
  195. data/test/fixtures/respond_to/{using_defaults_with_type_list.rjs → using_defaults_with_type_list.js.rjs} +0 -0
  196. data/test/fixtures/respond_to/{using_defaults_with_type_list.rxml → using_defaults_with_type_list.xml.builder} +0 -0
  197. data/test/fixtures/scope/test/{modgreet.rhtml → modgreet.erb} +0 -0
  198. data/test/fixtures/test/{_customer.rhtml → _customer.erb} +0 -0
  199. data/test/fixtures/test/{_customer_greeting.rhtml → _customer_greeting.erb} +0 -0
  200. data/test/fixtures/test/_hash_greeting.erb +1 -0
  201. data/test/fixtures/test/_hash_object.erb +2 -0
  202. data/test/fixtures/test/{_hello.rxml → _hello.builder} +0 -0
  203. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  204. data/test/fixtures/test/_partial.erb +1 -0
  205. data/test/fixtures/test/_partial.html.erb +1 -0
  206. data/test/fixtures/test/_partial.js.erb +1 -0
  207. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  208. data/test/fixtures/test/{_partial_only.rhtml → _partial_only.erb} +0 -0
  209. data/test/fixtures/test/{_person.rhtml → _person.erb} +0 -0
  210. data/test/fixtures/test/{action_talk_to_layout.rhtml → action_talk_to_layout.erb} +0 -0
  211. data/test/fixtures/test/{block_content_for.rhtml → block_content_for.erb} +0 -0
  212. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  213. data/test/fixtures/test/{capturing.rhtml → capturing.erb} +0 -0
  214. data/test/fixtures/test/{content_for.rhtml → content_for.erb} +0 -0
  215. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  216. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  217. data/test/fixtures/test/dot.directory/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  218. data/test/fixtures/test/{erb_content_for.rhtml → erb_content_for.erb} +0 -0
  219. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  220. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  221. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  222. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  223. data/test/fixtures/test/{greeting.rhtml → greeting.erb} +0 -0
  224. data/test/fixtures/test/{hello.rxml → hello.builder} +0 -0
  225. data/test/fixtures/test/{hello_world.rxml → hello_world.builder} +0 -0
  226. data/test/fixtures/test/{hello_world.rhtml → hello_world.erb} +0 -0
  227. data/test/fixtures/test/{hello_world_container.rxml → hello_world_container.builder} +0 -0
  228. data/test/fixtures/test/{hello_world_with_layout_false.rhtml → hello_world_with_layout_false.erb} +0 -0
  229. data/test/fixtures/test/{hello_xml_world.rxml → hello_xml_world.builder} +0 -0
  230. data/test/fixtures/test/list.erb +1 -0
  231. data/test/fixtures/test/{non_erb_block_content_for.rxml → non_erb_block_content_for.builder} +0 -0
  232. data/test/fixtures/test/{potential_conflicts.rhtml → potential_conflicts.erb} +0 -0
  233. data/test/fixtures/test/{render_file_with_ivar.rhtml → render_file_with_ivar.erb} +0 -0
  234. data/test/fixtures/test/{render_file_with_locals.rhtml → render_file_with_locals.erb} +0 -0
  235. data/test/fixtures/test/{render_to_string_test.rhtml → render_to_string_test.erb} +0 -0
  236. data/test/fixtures/test/{update_element_with_capture.rhtml → update_element_with_capture.erb} +0 -0
  237. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  238. data/test/fixtures/topic.rb +1 -1
  239. data/test/template/active_record_helper_test.rb +67 -20
  240. data/test/template/asset_tag_helper_test.rb +222 -54
  241. data/test/template/atom_feed_helper_test.rb +101 -0
  242. data/test/template/benchmark_helper_test.rb +2 -2
  243. data/test/template/compiled_templates_test.rb +76 -32
  244. data/test/template/date_helper_test.rb +125 -9
  245. data/test/template/form_helper_test.rb +326 -33
  246. data/test/template/form_options_helper_test.rb +822 -15
  247. data/test/template/form_tag_helper_test.rb +96 -30
  248. data/test/template/javascript_helper_test.rb +61 -13
  249. data/test/template/number_helper_test.rb +12 -11
  250. data/test/template/prototype_helper_test.rb +185 -24
  251. data/test/template/sanitize_helper_test.rb +49 -0
  252. data/test/template/scriptaculous_helper_test.rb +9 -3
  253. data/test/template/tag_helper_test.rb +13 -2
  254. data/test/template/text_helper_test.rb +38 -52
  255. data/test/template/url_helper_test.rb +216 -46
  256. metadata +144 -116
  257. data/examples/.htaccess +0 -24
  258. data/examples/address_book/index.rhtml +0 -33
  259. data/examples/address_book/layout.rhtml +0 -8
  260. data/examples/address_book_controller.cgi +0 -9
  261. data/examples/address_book_controller.fcgi +0 -6
  262. data/examples/address_book_controller.rb +0 -52
  263. data/examples/address_book_controller.rbx +0 -4
  264. data/examples/benchmark.rb +0 -52
  265. data/examples/benchmark_with_ar.fcgi +0 -89
  266. data/examples/blog_controller.cgi +0 -53
  267. data/examples/debate/index.rhtml +0 -14
  268. data/examples/debate/new_topic.rhtml +0 -22
  269. data/examples/debate/topic.rhtml +0 -32
  270. data/examples/debate_controller.cgi +0 -57
  271. data/lib/action_controller/assertions/deprecated_assertions.rb +0 -228
  272. data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -36
  273. data/lib/action_controller/cgi_ext/cgi_methods.rb +0 -211
  274. data/lib/action_controller/cgi_ext/pstore_performance_fix.rb +0 -30
  275. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +0 -95
  276. data/lib/action_controller/cgi_ext/session_performance_fix.rb +0 -30
  277. data/lib/action_controller/deprecated_dependencies.rb +0 -65
  278. data/lib/action_controller/deprecated_redirects.rb +0 -17
  279. data/lib/action_controller/deprecated_request_methods.rb +0 -34
  280. data/lib/action_controller/macros/auto_complete.rb +0 -53
  281. data/lib/action_controller/macros/in_place_editing.rb +0 -33
  282. data/lib/action_controller/pagination.rb +0 -408
  283. data/lib/action_controller/scaffolding.rb +0 -189
  284. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -44
  285. data/lib/action_controller/templates/scaffolds/edit.rhtml +0 -7
  286. data/lib/action_controller/templates/scaffolds/layout.rhtml +0 -69
  287. data/lib/action_controller/templates/scaffolds/list.rhtml +0 -27
  288. data/lib/action_controller/templates/scaffolds/new.rhtml +0 -6
  289. data/lib/action_controller/templates/scaffolds/show.rhtml +0 -9
  290. data/lib/action_controller/vendor/xml_node.rb +0 -97
  291. data/lib/action_view/helpers/deprecated_helper.rb +0 -37
  292. data/lib/action_view/helpers/java_script_macros_helper.rb +0 -233
  293. data/lib/action_view/helpers/pagination_helper.rb +0 -86
  294. data/test/activerecord/active_record_assertions_test.rb +0 -92
  295. data/test/activerecord/pagination_test.rb +0 -165
  296. data/test/controller/deprecated_instance_variables_test.rb +0 -48
  297. data/test/controller/raw_post_test.rb +0 -68
  298. data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +0 -1
  299. data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +0 -1
  300. data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +0 -1
  301. data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +0 -1
  302. data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +0 -1
  303. data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +0 -1
  304. data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +0 -1
  305. data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +0 -1
  306. data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +0 -1
  307. data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +0 -1
  308. data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +0 -1
  309. data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +0 -1
  310. data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +0 -1
  311. data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +0 -1
  312. data/test/fixtures/respond_to/layouts/standard.rhtml +0 -1
  313. data/test/fixtures/test/_hash_object.rhtml +0 -1
  314. data/test/fixtures/test/list.rhtml +0 -1
  315. data/test/template/deprecated_helper_test.rb +0 -36
  316. data/test/template/deprecated_instance_variables_test.rb +0 -43
  317. data/test/template/java_script_macros_helper_test.rb +0 -109
@@ -1,4 +1,34 @@
1
- require File.dirname(__FILE__) + '/../abstract_unit'
1
+ require "#{File.dirname(__FILE__)}/../abstract_unit"
2
+
3
+ silence_warnings do
4
+ Post = Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
5
+ Post.class_eval do
6
+ alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
7
+ alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
8
+ alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
9
+
10
+ def new_record=(boolean)
11
+ @new_record = boolean
12
+ end
13
+
14
+ def new_record?
15
+ @new_record
16
+ end
17
+ end
18
+
19
+ class Comment
20
+ attr_reader :id
21
+ attr_reader :post_id
22
+ def save; @id = 1; @post_id = 1 end
23
+ def new_record?; @id.nil? end
24
+ def name
25
+ @id.nil? ? 'new comment' : "comment ##{@id}"
26
+ end
27
+ end
28
+ end
29
+
30
+ class Comment::Nested < Comment; end
31
+
2
32
 
3
33
  class FormHelperTest < Test::Unit::TestCase
4
34
  include ActionView::Helpers::FormHelper
@@ -6,22 +36,24 @@ class FormHelperTest < Test::Unit::TestCase
6
36
  include ActionView::Helpers::UrlHelper
7
37
  include ActionView::Helpers::TagHelper
8
38
  include ActionView::Helpers::TextHelper
9
-
10
- silence_warnings do
11
- Post = Struct.new("Post", :title, :author_name, :body, :secret, :written_on, :cost)
12
- Post.class_eval do
13
- alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
14
- alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
15
- alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
16
- end
17
- end
39
+ include ActionView::Helpers::ActiveRecordHelper
40
+ include ActionView::Helpers::RecordIdentificationHelper
41
+ include ActionController::PolymorphicRoutes
18
42
 
19
43
  def setup
20
44
  @post = Post.new
21
- def @post.errors() Class.new{ def on(field) field == "author_name" end }.new end
22
-
45
+ @comment = Comment.new
46
+ def @post.errors()
47
+ Class.new{
48
+ def on(field); "can't be empty" if field == "author_name"; end
49
+ def empty?() false end
50
+ def count() 1 end
51
+ def full_messages() [ "Author name can't be empty" ] end
52
+ }.new
53
+ end
23
54
  def @post.id; 123; end
24
55
  def @post.id_before_type_cast; 123; end
56
+ def @post.to_param; '123'; end
25
57
 
26
58
  @post.title = "Hello World"
27
59
  @post.author_name = ""
@@ -31,7 +63,7 @@ class FormHelperTest < Test::Unit::TestCase
31
63
 
32
64
  @controller = Class.new do
33
65
  attr_reader :url_for_options
34
- def url_for(options, *parameters_for_method_reference)
66
+ def url_for(options)
35
67
  @url_for_options = options
36
68
  "http://www.example.com"
37
69
  end
@@ -39,6 +71,19 @@ class FormHelperTest < Test::Unit::TestCase
39
71
  @controller = @controller.new
40
72
  end
41
73
 
74
+ def test_label
75
+ assert_dom_equal('<label for="post_title">Title</label>', label("post", "title"))
76
+ assert_dom_equal('<label for="post_title">The title goes here</label>', label("post", "title", "The title goes here"))
77
+ assert_dom_equal(
78
+ '<label class="title_label" for="post_title">Title</label>',
79
+ label("post", "title", nil, :class => 'title_label')
80
+ )
81
+ end
82
+
83
+ def test_label_with_symbols
84
+ assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
85
+ end
86
+
42
87
  def test_text_field
43
88
  assert_dom_equal(
44
89
  '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
@@ -70,6 +115,12 @@ class FormHelperTest < Test::Unit::TestCase
70
115
  assert_dom_equal expected, text_field("post", "title", :maxlength => 35)
71
116
  end
72
117
 
118
+ def test_text_field_removing_size
119
+ expected = '<input id="post_title" maxlength="35" name="post[title]" type="text" value="Hello World" />'
120
+ assert_dom_equal expected, text_field("post", "title", "maxlength" => 35, "size" => nil)
121
+ assert_dom_equal expected, text_field("post", "title", :maxlength => 35, :size => nil)
122
+ end
123
+
73
124
  def test_text_field_doesnt_change_param_values
74
125
  object_name = 'post[]'
75
126
  expected = '<input id="post_123_title" name="post[123][title]" size="30" type="text" value="Hello World" />'
@@ -77,6 +128,22 @@ class FormHelperTest < Test::Unit::TestCase
77
128
  assert_equal object_name, "post[]"
78
129
  end
79
130
 
131
+ def test_hidden_field
132
+ assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
133
+ hidden_field("post", "title")
134
+ end
135
+
136
+ def test_hidden_field_with_escapes
137
+ @post.title = "<b>Hello World</b>"
138
+ assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
139
+ hidden_field("post", "title")
140
+ end
141
+
142
+ def test_text_field_with_options
143
+ assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
144
+ hidden_field("post", "title", :value => "Something Else")
145
+ end
146
+
80
147
  def test_check_box
81
148
  assert_dom_equal(
82
149
  '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
@@ -106,6 +173,13 @@ class FormHelperTest < Test::Unit::TestCase
106
173
  )
107
174
  end
108
175
 
176
+ def test_checkbox_disabled_still_submits_checked_value
177
+ assert_dom_equal(
178
+ '<input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="1" />',
179
+ check_box("post", "secret", { :disabled => :true })
180
+ )
181
+ end
182
+
109
183
  def test_radio_button
110
184
  assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
111
185
  radio_button("post", "title", "Hello World")
@@ -120,7 +194,7 @@ class FormHelperTest < Test::Unit::TestCase
120
194
  radio_button("post", "secret", "1")
121
195
  )
122
196
  end
123
-
197
+
124
198
  def test_radio_button_respects_passed_in_id
125
199
  assert_dom_equal('<input checked="checked" id="foo" name="post[secret]" type="radio" value="1" />',
126
200
  radio_button("post", "secret", "1", :id=>"foo")
@@ -141,27 +215,20 @@ class FormHelperTest < Test::Unit::TestCase
141
215
  text_area("post", "body")
142
216
  )
143
217
  end
144
-
218
+
145
219
  def test_text_area_with_alternate_value
146
220
  assert_dom_equal(
147
221
  '<textarea cols="40" id="post_body" name="post[body]" rows="20">Testing alternate values.</textarea>',
148
222
  text_area("post", "body", :value => 'Testing alternate values.')
149
223
  )
150
224
  end
151
-
225
+
152
226
  def test_text_area_with_size_option
153
227
  assert_dom_equal(
154
228
  '<textarea cols="183" id="post_body" name="post[body]" rows="820">Back to the hill and over it again!</textarea>',
155
229
  text_area("post", "body", :size => "183x820")
156
230
  )
157
231
  end
158
-
159
- def test_date_selects
160
- assert_dom_equal(
161
- '<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
162
- text_area("post", "body")
163
- )
164
- end
165
232
 
166
233
  def test_explicit_name
167
234
  assert_dom_equal(
@@ -205,6 +272,10 @@ class FormHelperTest < Test::Unit::TestCase
205
272
 
206
273
  def test_auto_index
207
274
  pid = @post.id
275
+ assert_dom_equal(
276
+ "<label for=\"post_#{pid}_title\">Title</label>",
277
+ label("post[]", "title")
278
+ )
208
279
  assert_dom_equal(
209
280
  "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
210
281
  )
@@ -229,17 +300,21 @@ class FormHelperTest < Test::Unit::TestCase
229
300
  _erbout = ''
230
301
 
231
302
  form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
303
+ _erbout.concat f.label(:title)
232
304
  _erbout.concat f.text_field(:title)
233
305
  _erbout.concat f.text_area(:body)
234
306
  _erbout.concat f.check_box(:secret)
307
+ _erbout.concat f.submit('Create post')
235
308
  end
236
309
 
237
310
  expected =
238
311
  "<form action='http://www.example.com' id='create-post' method='post'>" +
312
+ "<label for='post_title'>Title</label>" +
239
313
  "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
240
314
  "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
241
315
  "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
242
316
  "<input name='post[secret]' type='hidden' value='0' />" +
317
+ "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
243
318
  "</form>"
244
319
 
245
320
  assert_dom_equal expected, _erbout
@@ -285,11 +360,12 @@ class FormHelperTest < Test::Unit::TestCase
285
360
 
286
361
  assert_dom_equal expected, _erbout
287
362
  end
288
-
363
+
289
364
  def test_form_for_with_index
290
365
  _erbout = ''
291
366
 
292
367
  form_for("post[]", @post) do |f|
368
+ _erbout.concat f.label(:title)
293
369
  _erbout.concat f.text_field(:title)
294
370
  _erbout.concat f.text_area(:body)
295
371
  _erbout.concat f.check_box(:secret)
@@ -297,11 +373,29 @@ class FormHelperTest < Test::Unit::TestCase
297
373
 
298
374
  expected =
299
375
  "<form action='http://www.example.com' method='post'>" +
300
- "<input name='post[123][title]' size='30' type='text' id='post_title' value='Hello World' />" +
301
- "<textarea name='post[123][body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
302
- "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
376
+ "<label for=\"post_123_title\">Title</label>" +
377
+ "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
378
+ "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
379
+ "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
303
380
  "<input name='post[123][secret]' type='hidden' value='0' />" +
304
381
  "</form>"
382
+
383
+ assert_dom_equal expected, _erbout
384
+ end
385
+
386
+ def test_nested_fields_for
387
+ _erbout = ''
388
+ form_for(:post, @post) do |f|
389
+ f.fields_for(:comment, @post) do |c|
390
+ _erbout.concat c.text_field(:title)
391
+ end
392
+ end
393
+
394
+ expected = "<form action='http://www.example.com' method='post'>" +
395
+ "<input name='post[comment][title]' size='30' type='text' id='post_comment_title' value='Hello World' />" +
396
+ "</form>"
397
+
398
+ assert_dom_equal expected, _erbout
305
399
  end
306
400
 
307
401
  def test_fields_for
@@ -339,10 +433,39 @@ class FormHelperTest < Test::Unit::TestCase
339
433
  assert_dom_equal expected, _erbout
340
434
  end
341
435
 
436
+ def test_fields_for_with_only_object
437
+ _erbout = ''
438
+ fields_for(@post) do |f|
439
+ _erbout.concat f.text_field(:title)
440
+ _erbout.concat f.text_area(:body)
441
+ _erbout.concat f.check_box(:secret)
442
+ end
443
+
444
+ expected =
445
+ "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
446
+ "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
447
+ "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
448
+ "<input name='post[secret]' type='hidden' value='0' />"
449
+
450
+ assert_dom_equal expected, _erbout
451
+ end
452
+
453
+ def test_fields_for_object_with_bracketed_name
454
+ _erbout = ''
455
+ fields_for("author[post]", @post) do |f|
456
+ _erbout.concat f.label(:title)
457
+ _erbout.concat f.text_field(:title)
458
+ end
459
+
460
+ assert_dom_equal "<label for=\"author_post_title\">Title</label>" +
461
+ "<input name='author[post][title]' size='30' type='text' id='author_post_title' value='Hello World' />",
462
+ _erbout
463
+ end
464
+
342
465
  def test_form_builder_does_not_have_form_for_method
343
466
  assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
344
467
  end
345
-
468
+
346
469
  def test_form_for_and_fields_for
347
470
  _erbout = ''
348
471
 
@@ -365,7 +488,29 @@ class FormHelperTest < Test::Unit::TestCase
365
488
 
366
489
  assert_dom_equal expected, _erbout
367
490
  end
368
-
491
+
492
+ def test_form_for_and_fields_for_with_object
493
+ _erbout = ''
494
+
495
+ form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
496
+ _erbout.concat post_form.text_field(:title)
497
+ _erbout.concat post_form.text_area(:body)
498
+
499
+ post_form.fields_for(@comment) do |comment_fields|
500
+ _erbout.concat comment_fields.text_field(:name)
501
+ end
502
+ end
503
+
504
+ expected =
505
+ "<form action='http://www.example.com' id='create-post' method='post'>" +
506
+ "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
507
+ "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
508
+ "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" +
509
+ "</form>"
510
+
511
+ assert_dom_equal expected, _erbout
512
+ end
513
+
369
514
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
370
515
  (field_helpers - %w(hidden_field)).each do |selector|
371
516
  src = <<-END_SRC
@@ -376,7 +521,7 @@ class FormHelperTest < Test::Unit::TestCase
376
521
  class_eval src, __FILE__, __LINE__
377
522
  end
378
523
  end
379
-
524
+
380
525
  def test_form_for_with_labelled_builder
381
526
  _erbout = ''
382
527
 
@@ -421,6 +566,42 @@ class FormHelperTest < Test::Unit::TestCase
421
566
  ActionView::Base.default_form_builder = old_default_form_builder
422
567
  end
423
568
 
569
+ def test_default_form_builder_with_active_record_helpers
570
+
571
+ _erbout = ''
572
+ form_for(:post, @post) do |f|
573
+ _erbout.concat f.error_message_on('author_name')
574
+ _erbout.concat f.error_messages
575
+ end
576
+
577
+ expected = %(<form action='http://www.example.com' method='post'>) +
578
+ %(<div class='formError'>can't be empty</div>) +
579
+ %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
580
+ %(</form>)
581
+
582
+ assert_dom_equal expected, _erbout
583
+
584
+ end
585
+
586
+ def test_default_form_builder_no_instance_variable
587
+ post = @post
588
+ @post = nil
589
+
590
+ _erbout = ''
591
+ form_for(:post, post) do |f|
592
+ _erbout.concat f.error_message_on('author_name')
593
+ _erbout.concat f.error_messages
594
+ end
595
+
596
+ expected = %(<form action='http://www.example.com' method='post'>) +
597
+ %(<div class='formError'>can't be empty</div>) +
598
+ %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
599
+ %(</form>)
600
+
601
+ assert_dom_equal expected, _erbout
602
+
603
+ end
604
+
424
605
  # Perhaps this test should be moved to prototype helper tests.
425
606
  def test_remote_form_for_with_labelled_builder
426
607
  self.extend ActionView::Helpers::PrototypeHelper
@@ -460,7 +641,7 @@ class FormHelperTest < Test::Unit::TestCase
460
641
 
461
642
  assert_dom_equal expected, _erbout
462
643
  end
463
-
644
+
464
645
  def test_form_for_with_html_options_adds_options_to_form_tag
465
646
  _erbout = ''
466
647
 
@@ -469,13 +650,13 @@ class FormHelperTest < Test::Unit::TestCase
469
650
 
470
651
  assert_dom_equal expected, _erbout
471
652
  end
472
-
653
+
473
654
  def test_form_for_with_string_url_option
474
655
  _erbout = ''
475
656
 
476
657
  form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end
477
658
 
478
- assert_equal 'http://www.otherdomain.com', @controller.url_for_options
659
+ assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', _erbout
479
660
  end
480
661
 
481
662
  def test_form_for_with_hash_url_option
@@ -486,7 +667,85 @@ class FormHelperTest < Test::Unit::TestCase
486
667
  assert_equal 'controller', @controller.url_for_options[:controller]
487
668
  assert_equal 'action', @controller.url_for_options[:action]
488
669
  end
670
+
671
+ def test_form_for_with_record_url_option
672
+ _erbout = ''
673
+
674
+ form_for(:post, @post, :url => @post) do |f| end
675
+
676
+ expected = "<form action=\"/posts/123\" method=\"post\"></form>"
677
+ assert_equal expected, _erbout
678
+ end
679
+
680
+ def test_form_for_with_existing_object
681
+ _erbout = ''
682
+
683
+ form_for(@post) do |f| end
684
+
685
+ expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
686
+ assert_equal expected, _erbout
687
+ end
688
+
689
+ def test_form_for_with_new_object
690
+ _erbout = ''
691
+
692
+ post = Post.new
693
+ post.new_record = true
694
+ def post.id() nil end
695
+
696
+ form_for(post) do |f| end
697
+
698
+ expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
699
+ assert_equal expected, _erbout
700
+ end
701
+
702
+ def test_form_for_with_existing_object_in_list
703
+ @post.new_record = false
704
+ @comment.save
705
+ _erbout = ''
706
+ form_for([@post, @comment]) {}
707
+
708
+ expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
709
+ assert_dom_equal expected, _erbout
710
+ end
711
+
712
+ def test_form_for_with_new_object_in_list
713
+ @post.new_record = false
714
+ _erbout = ''
715
+ form_for([@post, @comment]) {}
716
+
717
+ expected = %(<form action="#{comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
718
+ assert_dom_equal expected, _erbout
719
+ end
720
+
721
+ def test_form_for_with_existing_object_and_namespace_in_list
722
+ @post.new_record = false
723
+ @comment.save
724
+ _erbout = ''
725
+ form_for([:admin, @post, @comment]) {}
726
+
727
+ expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
728
+ assert_dom_equal expected, _erbout
729
+ end
730
+
731
+ def test_form_for_with_new_object_and_namespace_in_list
732
+ @post.new_record = false
733
+ _erbout = ''
734
+ form_for([:admin, @post, @comment]) {}
489
735
 
736
+ expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
737
+ assert_dom_equal expected, _erbout
738
+ end
739
+
740
+ def test_form_for_with_existing_object_and_custom_url
741
+ _erbout = ''
742
+
743
+ form_for(@post, :url => "/super_posts") do |f| end
744
+
745
+ expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
746
+ assert_equal expected, _erbout
747
+ end
748
+
490
749
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
491
750
  self.extend ActionView::Helpers::PrototypeHelper
492
751
  _erbout = ''
@@ -496,4 +755,38 @@ class FormHelperTest < Test::Unit::TestCase
496
755
 
497
756
  assert_dom_equal expected, _erbout
498
757
  end
758
+
759
+
760
+ protected
761
+ def comments_path(post)
762
+ "/posts/#{post.id}/comments"
763
+ end
764
+ alias_method :post_comments_path, :comments_path
765
+
766
+ def comment_path(post, comment)
767
+ "/posts/#{post.id}/comments/#{comment.id}"
768
+ end
769
+ alias_method :post_comment_path, :comment_path
770
+
771
+ def admin_comments_path(post)
772
+ "/admin/posts/#{post.id}/comments"
773
+ end
774
+ alias_method :admin_post_comments_path, :admin_comments_path
775
+
776
+ def admin_comment_path(post, comment)
777
+ "/admin/posts/#{post.id}/comments/#{comment.id}"
778
+ end
779
+ alias_method :admin_post_comment_path, :admin_comment_path
780
+
781
+ def posts_path
782
+ "/posts"
783
+ end
784
+
785
+ def post_path(post)
786
+ "/posts/#{post.id}"
787
+ end
788
+
789
+ def protect_against_forgery?
790
+ false
791
+ end
499
792
  end