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,13 +1,13 @@
1
1
  module ActionView
2
- # There's also a convenience method for rendering sub templates within the current controller that depends on a single object
3
- # (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being
4
- # prefixed with an underscore -- as to separate them from regular templates that could be rendered on their own.
2
+ # There's also a convenience method for rendering sub templates within the current controller that depends on a single object
3
+ # (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being
4
+ # prefixed with an underscore -- as to separate them from regular templates that could be rendered on their own.
5
5
  #
6
6
  # In a template for Advertiser#account:
7
7
  #
8
8
  # <%= render :partial => "account" %>
9
9
  #
10
- # This would render "advertiser/_account.rhtml" and pass the instance variable @account in as a local variable +account+ to
10
+ # This would render "advertiser/_account.erb" and pass the instance variable @account in as a local variable +account+ to
11
11
  # the template for display.
12
12
  #
13
13
  # In another template for Advertiser#buy, we could have:
@@ -18,8 +18,8 @@ module ActionView
18
18
  # <%= render :partial => "ad", :locals => { :ad => ad } %>
19
19
  # <% end %>
20
20
  #
21
- # This would first render "advertiser/_account.rhtml" with @buyer passed in as the local variable +account+, then render
22
- # "advertiser/_ad.rhtml" and pass the local variable +ad+ to the template for display.
21
+ # This would first render "advertiser/_account.erb" with @buyer passed in as the local variable +account+, then render
22
+ # "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display.
23
23
  #
24
24
  # == Rendering a collection of partials
25
25
  #
@@ -30,62 +30,131 @@ module ActionView
30
30
  #
31
31
  # <%= render :partial => "ad", :collection => @advertisements %>
32
32
  #
33
- # This will render "advertiser/_ad.rhtml" and pass the local variable +ad+ to the template for display. An iteration counter
34
- # will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
33
+ # This will render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. An iteration counter
34
+ # will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
35
35
  # example above, the template would be fed +ad_counter+.
36
36
  #
37
37
  # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also just keep domain objects,
38
38
  # like Active Records, in there.
39
- #
39
+ #
40
40
  # == Rendering shared partials
41
41
  #
42
42
  # Two controllers can share a set of partials and render them like this:
43
43
  #
44
44
  # <%= render :partial => "advertisement/ad", :locals => { :ad => @advertisement } %>
45
45
  #
46
- # This will render the partial "advertisement/_ad.rhtml" regardless of which controller this is being called from.
46
+ # This will render the partial "advertisement/_ad.erb" regardless of which controller this is being called from.
47
+ #
48
+ # == Rendering partials with layouts
49
+ #
50
+ # Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally
51
+ # for the entire action, but they work in a similar fashion. Imagine a list with two types of users:
52
+ #
53
+ # <%# app/views/users/index.html.erb &>
54
+ # Here's the administrator:
55
+ # <%= render :partial => "user", :layout => "administrator", :locals => { :user => administrator } %>
56
+ #
57
+ # Here's the editor:
58
+ # <%= render :partial => "user", :layout => "editor", :locals => { :user => editor } %>
59
+ #
60
+ # <%# app/views/users/_user.html.erb &>
61
+ # Name: <%= user.name %>
62
+ #
63
+ # <%# app/views/users/_administrator.html.erb &>
64
+ # <div id="administrator">
65
+ # Budget: $<%= user.budget %>
66
+ # <%= yield %>
67
+ # </div>
68
+ #
69
+ # <%# app/views/users/_editor.html.erb &>
70
+ # <div id="editor">
71
+ # Deadline: $<%= user.deadline %>
72
+ # <%= yield %>
73
+ # </div>
74
+ #
75
+ # ...this will return:
76
+ #
77
+ # Here's the administrator:
78
+ # <div id="administrator">
79
+ # Budget: $<%= user.budget %>
80
+ # Name: <%= user.name %>
81
+ # </div>
82
+ #
83
+ # Here's the editor:
84
+ # <div id="editor">
85
+ # Deadline: $<%= user.deadline %>
86
+ # Name: <%= user.name %>
87
+ # </div>
88
+ #
89
+ # You can also apply a layout to a block within any template:
90
+ #
91
+ # <%# app/views/users/_chief.html.erb &>
92
+ # <% render(:layout => "administrator", :locals => { :user => chief }) do %>
93
+ # Title: <%= chief.title %>
94
+ # <% end %>
95
+ #
96
+ # ...this will return:
97
+ #
98
+ # <div id="administrator">
99
+ # Budget: $<%= user.budget %>
100
+ # Title: <%= chief.name %>
101
+ # </div>
102
+ #
103
+ # As you can see, the :locals hash is shared between both the partial and its layout.
47
104
  module Partials
48
- # Deprecated, use render :partial
49
- def render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc:
50
- path, partial_name = partial_pieces(partial_path)
51
- object = extracting_object(partial_name, local_assigns, deprecated_local_assigns)
52
- local_assigns = extract_local_assigns(local_assigns, deprecated_local_assigns)
53
- local_assigns = local_assigns ? local_assigns.clone : {}
54
- add_counter_to_local_assigns!(partial_name, local_assigns)
55
- add_object_to_local_assigns!(partial_name, local_assigns, object)
105
+ private
106
+ def render_partial(partial_path, object_assigns = nil, local_assigns = nil) #:nodoc:
107
+ case partial_path
108
+ when String, Symbol, NilClass
109
+ path, partial_name = partial_pieces(partial_path)
110
+ object = extracting_object(partial_name, object_assigns)
111
+ local_assigns = local_assigns ? local_assigns.clone : {}
112
+ add_counter_to_local_assigns!(partial_name, local_assigns)
113
+ add_object_to_local_assigns!(partial_name, local_assigns, object)
56
114
 
57
- if logger
58
- ActionController::Base.benchmark("Rendered #{path}/_#{partial_name}", Logger::DEBUG, false) do
59
- render("#{path}/_#{partial_name}", local_assigns)
115
+ if logger && logger.debug?
116
+ ActionController::Base.benchmark("Rendered #{path}/_#{partial_name}", Logger::DEBUG, false) do
117
+ render("#{path}/_#{partial_name}", local_assigns)
118
+ end
119
+ else
120
+ render("#{path}/_#{partial_name}", local_assigns)
121
+ end
122
+ when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::Associations::HasManyThroughAssociation
123
+ if partial_path.any?
124
+ path = ActionController::RecordIdentifier.partial_path(partial_path.first)
125
+ collection = partial_path
126
+ render_partial_collection(path, collection, nil, object_assigns.value)
127
+ else
128
+ ""
129
+ end
130
+ else
131
+ render_partial(
132
+ ActionController::RecordIdentifier.partial_path(partial_path),
133
+ object_assigns, local_assigns)
60
134
  end
61
- else
62
- render("#{path}/_#{partial_name}", local_assigns)
63
135
  end
64
- end
65
136
 
66
- # Deprecated, use render :partial, :collection
67
- def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil) #:nodoc:
68
- collection_of_partials = Array.new
69
- counter_name = partial_counter_name(partial_name)
70
- local_assigns = local_assigns ? local_assigns.clone : {}
71
- collection.each_with_index do |element, counter|
72
- local_assigns[counter_name] = counter
73
- collection_of_partials.push(render_partial(partial_name, element, local_assigns))
74
- end
137
+ def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil) #:nodoc:
138
+ collection_of_partials = Array.new
139
+ counter_name = partial_counter_name(partial_name)
140
+ local_assigns = local_assigns ? local_assigns.clone : {}
141
+ collection.each_with_index do |element, counter|
142
+ local_assigns[counter_name] = counter
143
+ collection_of_partials.push(render_partial(partial_name, element, local_assigns))
144
+ end
75
145
 
76
- return " " if collection_of_partials.empty?
146
+ return " " if collection_of_partials.empty?
77
147
 
78
- if partial_spacer_template
79
- spacer_path, spacer_name = partial_pieces(partial_spacer_template)
80
- collection_of_partials.join(render("#{spacer_path}/_#{spacer_name}"))
81
- else
82
- collection_of_partials.join
148
+ if partial_spacer_template
149
+ spacer_path, spacer_name = partial_pieces(partial_spacer_template)
150
+ collection_of_partials.join(render("#{spacer_path}/_#{spacer_name}"))
151
+ else
152
+ collection_of_partials.join
153
+ end
83
154
  end
84
- end
85
-
86
- alias_method :render_collection_of_partials, :render_partial_collection
87
-
88
- private
155
+
156
+ alias_method :render_collection_of_partials, :render_partial_collection
157
+
89
158
  def partial_pieces(partial_path)
90
159
  if partial_path.include?('/')
91
160
  return File.dirname(partial_path), File.basename(partial_path)
@@ -95,34 +164,37 @@ module ActionView
95
164
  end
96
165
 
97
166
  def partial_counter_name(partial_name)
98
- "#{partial_name.split('/').last}_counter".intern
167
+ "#{partial_variable_name(partial_name)}_counter".intern
99
168
  end
100
-
101
- def extracting_object(partial_name, local_assigns, deprecated_local_assigns)
102
- if local_assigns.is_a?(Hash) || local_assigns.nil?
103
- controller.instance_variable_get("@#{partial_name}")
169
+
170
+ def partial_variable_name(partial_name)
171
+ partial_name.split('/').last.split('.').first.intern
172
+ end
173
+
174
+ def extracting_object(partial_name, object_assigns)
175
+ variable_name = partial_variable_name(partial_name)
176
+ if object_assigns.nil?
177
+ controller.instance_variable_get("@#{variable_name}")
104
178
  else
105
- # deprecated form where object could be passed in as second parameter
106
- local_assigns
179
+ object_assigns
107
180
  end
108
181
  end
109
-
110
- def extract_local_assigns(local_assigns, deprecated_local_assigns)
111
- local_assigns.is_a?(Hash) ? local_assigns : deprecated_local_assigns
112
- end
113
-
182
+
114
183
  def add_counter_to_local_assigns!(partial_name, local_assigns)
115
184
  counter_name = partial_counter_name(partial_name)
116
185
  local_assigns[counter_name] = 1 unless local_assigns.has_key?(counter_name)
117
186
  end
118
187
 
119
188
  def add_object_to_local_assigns!(partial_name, local_assigns, object)
120
- local_assigns[partial_name.intern] ||=
121
- if object.is_a?(ActionView::Base::ObjectWrapper)
122
- object.value
123
- else
124
- object
125
- end || controller.instance_variable_get("@#{partial_name}")
189
+ variable_name = partial_variable_name(partial_name)
190
+
191
+ local_assigns[:object] ||=
192
+ local_assigns[variable_name] ||=
193
+ if object.is_a?(ActionView::Base::ObjectWrapper)
194
+ object.value
195
+ else
196
+ object
197
+ end || controller.instance_variable_get("@#{variable_name}")
126
198
  end
127
199
  end
128
200
  end
@@ -10,8 +10,6 @@ module ActionView
10
10
  @base_path, @assigns, @source, @original_exception =
11
11
  base_path, assigns.dup, source, original_exception
12
12
  @file_path = file_path
13
-
14
- remove_deprecated_assigns!
15
13
  end
16
14
 
17
15
  def message
@@ -82,16 +80,10 @@ module ActionView
82
80
  end
83
81
 
84
82
  private
85
- def remove_deprecated_assigns!
86
- ActionController::Base::DEPRECATED_INSTANCE_VARIABLES.each do |ivar|
87
- @assigns.delete(ivar)
88
- end
89
- end
90
-
91
83
  def strip_base_path(path)
92
- File.expand_path(path).
93
- gsub(/^#{Regexp.escape File.expand_path(RAILS_ROOT)}/, '').
94
- gsub(@base_path, "")
84
+ stripped_path = File.expand_path(path).gsub(@base_path, "")
85
+ stripped_path.gsub!(/^#{Regexp.escape File.expand_path(RAILS_ROOT)}/, '') if defined?(RAILS_ROOT)
86
+ stripped_path
95
87
  end
96
88
 
97
89
  def source_location
@@ -106,5 +98,5 @@ end
106
98
 
107
99
  if defined?(Exception::TraceSubstitutions)
108
100
  Exception::TraceSubstitutions << [/:in\s+`_run_(html|xml).*'\s*$/, '']
109
- Exception::TraceSubstitutions << [%r{^\s*#{Regexp.escape RAILS_ROOT}}, '#{RAILS_ROOT}'] if defined?(RAILS_ROOT)
101
+ Exception::TraceSubstitutions << [%r{^\s*#{Regexp.escape RAILS_ROOT}/}, ''] if defined?(RAILS_ROOT)
110
102
  end
@@ -0,0 +1 @@
1
+ require 'action_pack'
@@ -3,14 +3,34 @@ $:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib/active_support')
3
3
  $:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
4
4
 
5
5
  require 'yaml'
6
+ require 'stringio'
6
7
  require 'test/unit'
7
8
  require 'action_controller'
8
- require 'breakpoint'
9
+ require 'action_controller/cgi_ext'
9
10
  require 'action_controller/test_process'
10
11
 
12
+ begin
13
+ require 'ruby-debug'
14
+ rescue LoadError
15
+ # Debugging disabled. `gem install ruby-debug` to enable.
16
+ end
17
+
11
18
  # Show backtraces for deprecated behavior for quicker cleanup.
12
19
  ActiveSupport::Deprecation.debug = true
13
20
 
14
21
  ActionController::Base.logger = nil
15
22
  ActionController::Base.ignore_missing_templates = false
16
23
  ActionController::Routing::Routes.reload rescue nil
24
+
25
+
26
+ # Wrap tests that use Mocha and skip if unavailable.
27
+ def uses_mocha(test_name)
28
+ unless Object.const_defined?(:Mocha)
29
+ require 'mocha'
30
+ require 'stubba'
31
+ end
32
+ yield
33
+ rescue LoadError => load_error
34
+ raise unless load_error.message =~ /mocha/i
35
+ $stderr.puts "Skipping #{test_name} tests. `gem install mocha` and try again."
36
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/abstract_unit'
2
+ require 'test/unit'
3
+
4
+ class ActionViewTests < Test::Unit::TestCase
5
+ def test_find_template_extension_from_first_render
6
+ base = ActionView::Base.new
7
+
8
+ assert_nil base.send(:find_template_extension_from_first_render)
9
+
10
+ {
11
+ nil => nil,
12
+ '' => nil,
13
+ 'foo' => nil,
14
+ '/foo' => nil,
15
+ 'foo.rb' => 'rb',
16
+ 'foo.bar.rb' => 'bar.rb',
17
+ 'baz/foo.rb' => 'rb',
18
+ 'baz/foo.bar.rb' => 'bar.rb',
19
+ 'baz/foo.o/foo.rb' => 'rb',
20
+ 'baz/foo.o/foo.bar.rb' => 'bar.rb',
21
+ }.each do |input,expectation|
22
+ base.instance_variable_set('@first_render', input)
23
+ assert_equal expectation, base.send(:find_template_extension_from_first_render)
24
+ end
25
+ end
26
+ end
@@ -51,22 +51,23 @@ class ActiveRecordTestConnector
51
51
 
52
52
  def setup_connection
53
53
  if Object.const_defined?(:ActiveRecord)
54
+ defaults = { :database => ':memory:' }
54
55
  begin
55
- connection_options = {:adapter => 'sqlite3', :dbfile => ':memory:'}
56
- ActiveRecord::Base.establish_connection(connection_options)
57
- ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => connection_options }
56
+ options = defaults.merge :adapter => 'sqlite3', :timeout => 500
57
+ ActiveRecord::Base.establish_connection(options)
58
+ ActiveRecord::Base.configurations = { 'sqlite3_ar_integration' => options }
58
59
  ActiveRecord::Base.connection
59
60
  rescue Exception # errors from establishing a connection
60
- $stderr.puts 'SQLite 3 unavailable; falling to SQLite 2.'
61
- connection_options = {:adapter => 'sqlite', :dbfile => ':memory:'}
62
- ActiveRecord::Base.establish_connection(connection_options)
63
- ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => connection_options }
61
+ $stderr.puts 'SQLite 3 unavailable; trying SQLite 2.'
62
+ options = defaults.merge :adapter => 'sqlite'
63
+ ActiveRecord::Base.establish_connection(options)
64
+ ActiveRecord::Base.configurations = { 'sqlite2_ar_integration' => options }
64
65
  ActiveRecord::Base.connection
65
66
  end
66
67
 
67
68
  Object.send(:const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')) unless Object.const_defined?(:QUOTED_TYPE)
68
69
  else
69
- raise "Couldn't locate ActiveRecord."
70
+ raise "Can't setup connection since ActiveRecord isn't loaded."
70
71
  end
71
72
  end
72
73
 
@@ -83,7 +84,7 @@ class ActiveRecordTestConnector
83
84
  end
84
85
  end
85
86
 
86
- # Test case for inheiritance
87
+ # Test case for inheritance
87
88
  class ActiveRecordTestCase < Test::Unit::TestCase
88
89
  # Set our fixture path
89
90
  if ActiveRecordTestConnector.able_to_connect
@@ -95,22 +96,13 @@ class ActiveRecordTestCase < Test::Unit::TestCase
95
96
  super if ActiveRecordTestConnector.connected
96
97
  end
97
98
 
98
- def setup
99
- abort_tests unless ActiveRecordTestConnector.connected
99
+ def run(*args)
100
+ super if ActiveRecordTestConnector.connected
100
101
  end
101
102
 
102
103
  # Default so Test::Unit::TestCase doesn't complain
103
104
  def test_truth
104
105
  end
105
-
106
- private
107
- # If things go wrong, we don't want to run our test cases. We'll just define them to test nothing.
108
- def abort_tests
109
- $stderr.puts 'No Active Record connection, aborting tests.'
110
- self.class.public_instance_methods.grep(/^test./).each do |method|
111
- self.class.class_eval { define_method(method.to_sym){} }
112
- end
113
- end
114
106
  end
115
107
 
116
108
  ActiveRecordTestConnector.setup
@@ -53,7 +53,7 @@ class ActiveRecordStoreTest < ActiveRecordTestCase
53
53
  @new_session['foo'] = 'bar'
54
54
  end
55
55
 
56
- # this test only applies for eager sesssion saving
56
+ # this test only applies for eager session saving
57
57
  # def test_another_instance
58
58
  # @another = CGI::Session.new(@cgi, 'session_id' => @new_session.session_id, 'database_manager' => CGI::Session::ActiveRecordStore)
59
59
  # assert_equal @new_session.session_id, @another.session_id
@@ -128,7 +128,7 @@ end
128
128
 
129
129
  class SqlBypassActiveRecordStoreTest < ActiveRecordStoreTest
130
130
  def session_class
131
- unless @session_class
131
+ unless defined? @session_class
132
132
  @session_class = CGI::Session::ActiveRecordStore::SqlBypass
133
133
  @session_class.connection = CGI::Session::ActiveRecordStore::Session.connection
134
134
  end
@@ -0,0 +1,74 @@
1
+ require File.dirname(__FILE__) + '/../active_record_unit'
2
+
3
+ class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase
4
+ fixtures :developers, :projects, :developers_projects, :topics, :replies
5
+
6
+ class RenderPartialWithRecordIdentificationController < ActionController::Base
7
+ def render_with_has_many_and_belongs_to_association
8
+ @developer = Developer.find(1)
9
+ render :partial => @developer.projects
10
+ end
11
+
12
+ def render_with_has_many_association
13
+ @topic = Topic.find(1)
14
+ render :partial => @topic.replies
15
+ end
16
+
17
+ def render_with_has_many_through_association
18
+ @developer = Developer.find(:first)
19
+ render :partial => @developer.topics
20
+ end
21
+
22
+ def render_with_belongs_to_association
23
+ @reply = Reply.find(1)
24
+ render :partial => @reply.topic
25
+ end
26
+
27
+ def render_with_record
28
+ @developer = Developer.find(:first)
29
+ render :partial => @developer
30
+ end
31
+
32
+ def render_with_record_collection
33
+ @developers = Developer.find(:all)
34
+ render :partial => @developers
35
+ end
36
+ end
37
+
38
+ def setup
39
+ @controller = RenderPartialWithRecordIdentificationController.new
40
+ @request = ActionController::TestRequest.new
41
+ @response = ActionController::TestResponse.new
42
+ super
43
+ end
44
+
45
+ def test_rendering_partial_with_has_many_and_belongs_to_association
46
+ get :render_with_has_many_and_belongs_to_association
47
+ assert_template 'projects/_project'
48
+ end
49
+
50
+ def test_rendering_partial_with_has_many_association
51
+ get :render_with_has_many_association
52
+ assert_template 'replies/_reply'
53
+ end
54
+
55
+ def test_rendering_partial_with_has_many_association
56
+ get :render_with_has_many_through_association
57
+ assert_template 'topics/_topic'
58
+ end
59
+
60
+ def test_rendering_partial_with_belongs_to_association
61
+ get :render_with_belongs_to_association
62
+ assert_template 'topics/_topic'
63
+ end
64
+
65
+ def test_render_with_record
66
+ get :render_with_record
67
+ assert_template 'developers/_developer'
68
+ end
69
+
70
+ def test_render_with_record_collection
71
+ get :render_with_record_collection
72
+ assert_template 'developers/_developer'
73
+ end
74
+ end