actionpack_csi 2.3.5.p6

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 (429) hide show
  1. data/CHANGELOG +5184 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +409 -0
  4. data/RUNNING_UNIT_TESTS +24 -0
  5. data/Rakefile +160 -0
  6. data/install.rb +30 -0
  7. data/lib/action_controller/assertions/dom_assertions.rb +55 -0
  8. data/lib/action_controller/assertions/model_assertions.rb +21 -0
  9. data/lib/action_controller/assertions/response_assertions.rb +160 -0
  10. data/lib/action_controller/assertions/routing_assertions.rb +146 -0
  11. data/lib/action_controller/assertions/selector_assertions.rb +638 -0
  12. data/lib/action_controller/assertions/tag_assertions.rb +127 -0
  13. data/lib/action_controller/base.rb +1423 -0
  14. data/lib/action_controller/benchmarking.rb +107 -0
  15. data/lib/action_controller/caching/actions.rb +177 -0
  16. data/lib/action_controller/caching/fragments.rb +120 -0
  17. data/lib/action_controller/caching/pages.rb +152 -0
  18. data/lib/action_controller/caching/sweeper.rb +45 -0
  19. data/lib/action_controller/caching/sweeping.rb +55 -0
  20. data/lib/action_controller/caching.rb +71 -0
  21. data/lib/action_controller/cgi_ext/cookie.rb +112 -0
  22. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  23. data/lib/action_controller/cgi_ext/stdinput.rb +24 -0
  24. data/lib/action_controller/cgi_ext.rb +15 -0
  25. data/lib/action_controller/cgi_process.rb +77 -0
  26. data/lib/action_controller/cookies.rb +95 -0
  27. data/lib/action_controller/dispatcher.rb +133 -0
  28. data/lib/action_controller/failsafe.rb +86 -0
  29. data/lib/action_controller/filters.rb +680 -0
  30. data/lib/action_controller/flash.rb +171 -0
  31. data/lib/action_controller/headers.rb +33 -0
  32. data/lib/action_controller/helpers.rb +225 -0
  33. data/lib/action_controller/http_authentication.rb +309 -0
  34. data/lib/action_controller/integration.rb +692 -0
  35. data/lib/action_controller/layout.rb +286 -0
  36. data/lib/action_controller/middleware_stack.rb +119 -0
  37. data/lib/action_controller/middlewares.rb +14 -0
  38. data/lib/action_controller/mime_responds.rb +193 -0
  39. data/lib/action_controller/mime_type.rb +212 -0
  40. data/lib/action_controller/mime_types.rb +21 -0
  41. data/lib/action_controller/params_parser.rb +77 -0
  42. data/lib/action_controller/performance_test.rb +15 -0
  43. data/lib/action_controller/polymorphic_routes.rb +189 -0
  44. data/lib/action_controller/rack_lint_patch.rb +36 -0
  45. data/lib/action_controller/record_identifier.rb +104 -0
  46. data/lib/action_controller/reloader.rb +54 -0
  47. data/lib/action_controller/request.rb +493 -0
  48. data/lib/action_controller/request_forgery_protection.rb +113 -0
  49. data/lib/action_controller/rescue.rb +183 -0
  50. data/lib/action_controller/resources.rb +682 -0
  51. data/lib/action_controller/response.rb +239 -0
  52. data/lib/action_controller/routing/builder.rb +197 -0
  53. data/lib/action_controller/routing/optimisations.rb +130 -0
  54. data/lib/action_controller/routing/recognition_optimisation.rb +167 -0
  55. data/lib/action_controller/routing/route.rb +265 -0
  56. data/lib/action_controller/routing/route_set.rb +502 -0
  57. data/lib/action_controller/routing/routing_ext.rb +49 -0
  58. data/lib/action_controller/routing/segments.rb +343 -0
  59. data/lib/action_controller/routing.rb +388 -0
  60. data/lib/action_controller/session/abstract_store.rb +181 -0
  61. data/lib/action_controller/session/cookie_store.rb +221 -0
  62. data/lib/action_controller/session/mem_cache_store.rb +51 -0
  63. data/lib/action_controller/session_management.rb +54 -0
  64. data/lib/action_controller/status_codes.rb +88 -0
  65. data/lib/action_controller/streaming.rb +181 -0
  66. data/lib/action_controller/string_coercion.rb +29 -0
  67. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  68. data/lib/action_controller/templates/rescues/_trace.erb +26 -0
  69. data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
  70. data/lib/action_controller/templates/rescues/layout.erb +29 -0
  71. data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
  72. data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
  73. data/lib/action_controller/templates/rescues/template_error.erb +21 -0
  74. data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
  75. data/lib/action_controller/test_case.rb +209 -0
  76. data/lib/action_controller/test_process.rb +580 -0
  77. data/lib/action_controller/translation.rb +13 -0
  78. data/lib/action_controller/uploaded_file.rb +44 -0
  79. data/lib/action_controller/url_rewriter.rb +216 -0
  80. data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
  81. data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
  82. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  83. data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
  84. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
  85. data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
  86. data/lib/action_controller/vendor/html-scanner.rb +16 -0
  87. data/lib/action_controller/verification.rb +130 -0
  88. data/lib/action_controller.rb +113 -0
  89. data/lib/action_pack/version.rb +9 -0
  90. data/lib/action_pack.rb +24 -0
  91. data/lib/action_view/base.rb +362 -0
  92. data/lib/action_view/erb/util.rb +44 -0
  93. data/lib/action_view/helpers/active_record_helper.rb +305 -0
  94. data/lib/action_view/helpers/asset_tag_helper.rb +694 -0
  95. data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
  96. data/lib/action_view/helpers/benchmark_helper.rb +54 -0
  97. data/lib/action_view/helpers/cache_helper.rb +39 -0
  98. data/lib/action_view/helpers/capture_helper.rb +136 -0
  99. data/lib/action_view/helpers/date_helper.rb +988 -0
  100. data/lib/action_view/helpers/debug_helper.rb +38 -0
  101. data/lib/action_view/helpers/form_helper.rb +1074 -0
  102. data/lib/action_view/helpers/form_options_helper.rb +600 -0
  103. data/lib/action_view/helpers/form_tag_helper.rb +487 -0
  104. data/lib/action_view/helpers/javascript_helper.rb +208 -0
  105. data/lib/action_view/helpers/number_helper.rb +308 -0
  106. data/lib/action_view/helpers/prototype_helper.rb +1305 -0
  107. data/lib/action_view/helpers/raw_output_helper.rb +9 -0
  108. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  109. data/lib/action_view/helpers/record_tag_helper.rb +58 -0
  110. data/lib/action_view/helpers/sanitize_helper.rb +259 -0
  111. data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
  112. data/lib/action_view/helpers/tag_helper.rb +150 -0
  113. data/lib/action_view/helpers/text_helper.rb +587 -0
  114. data/lib/action_view/helpers/translation_helper.rb +39 -0
  115. data/lib/action_view/helpers/url_helper.rb +639 -0
  116. data/lib/action_view/helpers.rb +59 -0
  117. data/lib/action_view/inline_template.rb +19 -0
  118. data/lib/action_view/locale/en.yml +117 -0
  119. data/lib/action_view/partials.rb +240 -0
  120. data/lib/action_view/paths.rb +69 -0
  121. data/lib/action_view/reloadable_template.rb +117 -0
  122. data/lib/action_view/renderable.rb +95 -0
  123. data/lib/action_view/renderable_partial.rb +47 -0
  124. data/lib/action_view/safe_buffer.rb +28 -0
  125. data/lib/action_view/template.rb +252 -0
  126. data/lib/action_view/template_error.rb +99 -0
  127. data/lib/action_view/template_handler.rb +34 -0
  128. data/lib/action_view/template_handlers/builder.rb +17 -0
  129. data/lib/action_view/template_handlers/erb.rb +22 -0
  130. data/lib/action_view/template_handlers/rjs.rb +13 -0
  131. data/lib/action_view/template_handlers.rb +48 -0
  132. data/lib/action_view/test_case.rb +162 -0
  133. data/lib/action_view.rb +58 -0
  134. data/lib/actionpack.rb +2 -0
  135. data/test/abstract_unit.rb +61 -0
  136. data/test/active_record_unit.rb +104 -0
  137. data/test/activerecord/active_record_store_test.rb +174 -0
  138. data/test/activerecord/render_partial_with_record_identification_test.rb +188 -0
  139. data/test/adv_attr_test.rb +20 -0
  140. data/test/controller/action_pack_assertions_test.rb +543 -0
  141. data/test/controller/addresses_render_test.rb +37 -0
  142. data/test/controller/assert_select_test.rb +734 -0
  143. data/test/controller/base_test.rb +217 -0
  144. data/test/controller/benchmark_test.rb +32 -0
  145. data/test/controller/caching_test.rb +729 -0
  146. data/test/controller/capture_test.rb +66 -0
  147. data/test/controller/content_type_test.rb +168 -0
  148. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  149. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  150. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  151. data/test/controller/cookie_test.rb +134 -0
  152. data/test/controller/deprecation/deprecated_base_methods_test.rb +32 -0
  153. data/test/controller/dispatcher_test.rb +144 -0
  154. data/test/controller/dom_assertions_test.rb +53 -0
  155. data/test/controller/failsafe_test.rb +60 -0
  156. data/test/controller/fake_controllers.rb +33 -0
  157. data/test/controller/fake_models.rb +19 -0
  158. data/test/controller/filter_params_test.rb +52 -0
  159. data/test/controller/filters_test.rb +885 -0
  160. data/test/controller/flash_test.rb +147 -0
  161. data/test/controller/header_test.rb +14 -0
  162. data/test/controller/helper_test.rb +224 -0
  163. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  164. data/test/controller/html-scanner/document_test.rb +148 -0
  165. data/test/controller/html-scanner/node_test.rb +89 -0
  166. data/test/controller/html-scanner/sanitizer_test.rb +274 -0
  167. data/test/controller/html-scanner/tag_node_test.rb +238 -0
  168. data/test/controller/html-scanner/text_node_test.rb +50 -0
  169. data/test/controller/html-scanner/tokenizer_test.rb +131 -0
  170. data/test/controller/http_basic_authentication_test.rb +113 -0
  171. data/test/controller/http_digest_authentication_test.rb +254 -0
  172. data/test/controller/integration_test.rb +483 -0
  173. data/test/controller/layout_test.rb +215 -0
  174. data/test/controller/logging_test.rb +46 -0
  175. data/test/controller/middleware_stack_test.rb +90 -0
  176. data/test/controller/mime_responds_test.rb +536 -0
  177. data/test/controller/mime_type_test.rb +93 -0
  178. data/test/controller/polymorphic_routes_test.rb +297 -0
  179. data/test/controller/rack_test.rb +311 -0
  180. data/test/controller/record_identifier_test.rb +139 -0
  181. data/test/controller/redirect_test.rb +285 -0
  182. data/test/controller/reloader_test.rb +124 -0
  183. data/test/controller/render_test.rb +1762 -0
  184. data/test/controller/request/json_params_parsing_test.rb +65 -0
  185. data/test/controller/request/multipart_params_parsing_test.rb +162 -0
  186. data/test/controller/request/query_string_parsing_test.rb +120 -0
  187. data/test/controller/request/test_request_test.rb +35 -0
  188. data/test/controller/request/url_encoded_params_parsing_test.rb +146 -0
  189. data/test/controller/request/xml_params_parsing_test.rb +103 -0
  190. data/test/controller/request_forgery_protection_test.rb +265 -0
  191. data/test/controller/request_test.rb +395 -0
  192. data/test/controller/rescue_test.rb +536 -0
  193. data/test/controller/resources_test.rb +1393 -0
  194. data/test/controller/routing_test.rb +2591 -0
  195. data/test/controller/selector_test.rb +628 -0
  196. data/test/controller/send_file_test.rb +171 -0
  197. data/test/controller/session/cookie_store_test.rb +216 -0
  198. data/test/controller/session/mem_cache_store_test.rb +127 -0
  199. data/test/controller/session/test_session_test.rb +58 -0
  200. data/test/controller/test_test.rb +700 -0
  201. data/test/controller/translation_test.rb +26 -0
  202. data/test/controller/url_rewriter_test.rb +385 -0
  203. data/test/controller/verification_test.rb +270 -0
  204. data/test/controller/view_paths_test.rb +141 -0
  205. data/test/controller/webservice_test.rb +273 -0
  206. data/test/fixtures/_top_level_partial.html.erb +1 -0
  207. data/test/fixtures/_top_level_partial_only.erb +1 -0
  208. data/test/fixtures/addresses/list.erb +1 -0
  209. data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
  210. data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
  211. data/test/fixtures/companies.yml +24 -0
  212. data/test/fixtures/company.rb +10 -0
  213. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
  214. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
  215. data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
  216. data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
  217. data/test/fixtures/customers/_customer.html.erb +1 -0
  218. data/test/fixtures/db_definitions/sqlite.sql +49 -0
  219. data/test/fixtures/developer.rb +9 -0
  220. data/test/fixtures/developers/_developer.erb +1 -0
  221. data/test/fixtures/developers.yml +21 -0
  222. data/test/fixtures/developers_projects.yml +13 -0
  223. data/test/fixtures/failsafe/500.html +1 -0
  224. data/test/fixtures/fun/games/_game.erb +1 -0
  225. data/test/fixtures/fun/games/hello_world.erb +1 -0
  226. data/test/fixtures/fun/serious/games/_game.erb +1 -0
  227. data/test/fixtures/functional_caching/_partial.erb +3 -0
  228. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
  229. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
  230. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
  231. data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
  232. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
  233. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
  234. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
  235. data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
  236. data/test/fixtures/helpers/abc_helper.rb +5 -0
  237. data/test/fixtures/helpers/fun/games_helper.rb +3 -0
  238. data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
  239. data/test/fixtures/layout_tests/abs_path_layout.rhtml +1 -0
  240. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  241. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  242. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
  243. data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
  244. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
  245. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  246. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
  247. data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
  248. data/test/fixtures/layouts/_column.html.erb +2 -0
  249. data/test/fixtures/layouts/block_with_layout.erb +3 -0
  250. data/test/fixtures/layouts/builder.builder +3 -0
  251. data/test/fixtures/layouts/default_html.html.erb +1 -0
  252. data/test/fixtures/layouts/partial_with_layout.erb +3 -0
  253. data/test/fixtures/layouts/standard.erb +1 -0
  254. data/test/fixtures/layouts/talk_from_action.erb +2 -0
  255. data/test/fixtures/layouts/xhr.html.erb +2 -0
  256. data/test/fixtures/layouts/yield.erb +2 -0
  257. data/test/fixtures/mascot.rb +3 -0
  258. data/test/fixtures/mascots/_mascot.html.erb +1 -0
  259. data/test/fixtures/mascots.yml +4 -0
  260. data/test/fixtures/multipart/binary_file +0 -0
  261. data/test/fixtures/multipart/boundary_problem_file +10 -0
  262. data/test/fixtures/multipart/bracketed_param +5 -0
  263. data/test/fixtures/multipart/empty +10 -0
  264. data/test/fixtures/multipart/hello.txt +1 -0
  265. data/test/fixtures/multipart/large_text_file +10 -0
  266. data/test/fixtures/multipart/mixed_files +0 -0
  267. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  268. data/test/fixtures/multipart/none +9 -0
  269. data/test/fixtures/multipart/single_parameter +5 -0
  270. data/test/fixtures/multipart/text_file +10 -0
  271. data/test/fixtures/override/test/hello_world.erb +1 -0
  272. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  273. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  274. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  275. data/test/fixtures/post_test/post/index.html.erb +1 -0
  276. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  277. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  278. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  279. data/test/fixtures/project.rb +3 -0
  280. data/test/fixtures/projects/_project.erb +1 -0
  281. data/test/fixtures/projects.yml +7 -0
  282. data/test/fixtures/public/404.html +1 -0
  283. data/test/fixtures/public/500.da.html +1 -0
  284. data/test/fixtures/public/500.html +1 -0
  285. data/test/fixtures/public/absolute/test.css +23 -0
  286. data/test/fixtures/public/absolute/test.js +63 -0
  287. data/test/fixtures/public/images/rails.png +0 -0
  288. data/test/fixtures/public/javascripts/application.js +1 -0
  289. data/test/fixtures/public/javascripts/bank.js +1 -0
  290. data/test/fixtures/public/javascripts/controls.js +1 -0
  291. data/test/fixtures/public/javascripts/dragdrop.js +1 -0
  292. data/test/fixtures/public/javascripts/effects.js +1 -0
  293. data/test/fixtures/public/javascripts/prototype.js +1 -0
  294. data/test/fixtures/public/javascripts/robber.js +1 -0
  295. data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
  296. data/test/fixtures/public/javascripts/version.1.0.js +1 -0
  297. data/test/fixtures/public/stylesheets/bank.css +1 -0
  298. data/test/fixtures/public/stylesheets/robber.css +1 -0
  299. data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
  300. data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
  301. data/test/fixtures/quiz/questions/_question.html.erb +1 -0
  302. data/test/fixtures/replies/_reply.erb +1 -0
  303. data/test/fixtures/replies.yml +15 -0
  304. data/test/fixtures/reply.rb +7 -0
  305. data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
  306. data/test/fixtures/respond_to/all_types_with_layout.js.rjs +1 -0
  307. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  308. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  309. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  310. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  311. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  312. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  313. data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
  314. data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
  315. data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
  316. data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
  317. data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
  318. data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
  319. data/test/fixtures/scope/test/modgreet.erb +1 -0
  320. data/test/fixtures/shared.html.erb +1 -0
  321. data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
  322. data/test/fixtures/test/_counter.html.erb +1 -0
  323. data/test/fixtures/test/_customer.erb +1 -0
  324. data/test/fixtures/test/_customer_counter.erb +1 -0
  325. data/test/fixtures/test/_customer_greeting.erb +1 -0
  326. data/test/fixtures/test/_customer_with_var.erb +1 -0
  327. data/test/fixtures/test/_form.erb +1 -0
  328. data/test/fixtures/test/_from_helper.erb +1 -0
  329. data/test/fixtures/test/_hash_greeting.erb +1 -0
  330. data/test/fixtures/test/_hash_object.erb +2 -0
  331. data/test/fixtures/test/_hello.builder +1 -0
  332. data/test/fixtures/test/_labelling_form.erb +1 -0
  333. data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
  334. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  335. data/test/fixtures/test/_local_inspector.html.erb +1 -0
  336. data/test/fixtures/test/_one.html.erb +1 -0
  337. data/test/fixtures/test/_partial.erb +1 -0
  338. data/test/fixtures/test/_partial.html.erb +1 -0
  339. data/test/fixtures/test/_partial.js.erb +1 -0
  340. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  341. data/test/fixtures/test/_partial_only.erb +1 -0
  342. data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
  343. data/test/fixtures/test/_person.erb +2 -0
  344. data/test/fixtures/test/_raise.html.erb +1 -0
  345. data/test/fixtures/test/_two.html.erb +1 -0
  346. data/test/fixtures/test/action_talk_to_layout.erb +2 -0
  347. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  348. data/test/fixtures/test/capturing.erb +4 -0
  349. data/test/fixtures/test/content_for.erb +2 -0
  350. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  351. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  352. data/test/fixtures/test/delete_with_js.rjs +2 -0
  353. data/test/fixtures/test/dont_pick_me +1 -0
  354. data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
  355. data/test/fixtures/test/enum_rjs_test.rjs +6 -0
  356. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  357. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  358. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  359. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  360. data/test/fixtures/test/greeting.erb +1 -0
  361. data/test/fixtures/test/greeting.js.rjs +1 -0
  362. data/test/fixtures/test/hello.builder +4 -0
  363. data/test/fixtures/test/hello_world.da.html.erb +1 -0
  364. data/test/fixtures/test/hello_world.erb +1 -0
  365. data/test/fixtures/test/hello_world.erb~ +1 -0
  366. data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
  367. data/test/fixtures/test/hello_world_container.builder +3 -0
  368. data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
  369. data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
  370. data/test/fixtures/test/hello_xml_world.builder +11 -0
  371. data/test/fixtures/test/hyphen-ated.erb +1 -0
  372. data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
  373. data/test/fixtures/test/list.erb +1 -0
  374. data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
  375. data/test/fixtures/test/malformed/malformed.erb~ +1 -0
  376. data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
  377. data/test/fixtures/test/nested_layout.erb +3 -0
  378. data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
  379. data/test/fixtures/test/potential_conflicts.erb +4 -0
  380. data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
  381. data/test/fixtures/test/render_file_from_template.html.erb +1 -0
  382. data/test/fixtures/test/render_file_with_ivar.erb +1 -0
  383. data/test/fixtures/test/render_file_with_locals.erb +1 -0
  384. data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
  385. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
  386. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
  387. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
  388. data/test/fixtures/test/render_to_string_test.erb +1 -0
  389. data/test/fixtures/test/sub_template_raise.html.erb +1 -0
  390. data/test/fixtures/test/template.erb +1 -0
  391. data/test/fixtures/test/update_element_with_capture.erb +9 -0
  392. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  393. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
  394. data/test/fixtures/test/utf8.html.erb +2 -0
  395. data/test/fixtures/topic.rb +3 -0
  396. data/test/fixtures/topics/_topic.html.erb +1 -0
  397. data/test/fixtures/topics.yml +22 -0
  398. data/test/template/active_record_helper_i18n_test.rb +44 -0
  399. data/test/template/active_record_helper_test.rb +302 -0
  400. data/test/template/asset_tag_helper_test.rb +771 -0
  401. data/test/template/atom_feed_helper_test.rb +315 -0
  402. data/test/template/benchmark_helper_test.rb +86 -0
  403. data/test/template/compiled_templates_test.rb +204 -0
  404. data/test/template/date_helper_i18n_test.rb +121 -0
  405. data/test/template/date_helper_test.rb +2485 -0
  406. data/test/template/erb_util_test.rb +24 -0
  407. data/test/template/form_helper_test.rb +1393 -0
  408. data/test/template/form_options_helper_i18n_test.rb +27 -0
  409. data/test/template/form_options_helper_test.rb +807 -0
  410. data/test/template/form_tag_helper_test.rb +344 -0
  411. data/test/template/javascript_helper_test.rb +106 -0
  412. data/test/template/number_helper_i18n_test.rb +69 -0
  413. data/test/template/number_helper_test.rb +132 -0
  414. data/test/template/prototype_helper_test.rb +639 -0
  415. data/test/template/raw_output_helper_test.rb +21 -0
  416. data/test/template/record_tag_helper_test.rb +58 -0
  417. data/test/template/render_test.rb +290 -0
  418. data/test/template/sanitize_helper_test.rb +57 -0
  419. data/test/template/scriptaculous_helper_test.rb +90 -0
  420. data/test/template/tag_helper_test.rb +98 -0
  421. data/test/template/template_test.rb +32 -0
  422. data/test/template/test_test.rb +54 -0
  423. data/test/template/text_helper_test.rb +543 -0
  424. data/test/template/translation_helper_test.rb +32 -0
  425. data/test/template/url_helper_test.rb +622 -0
  426. data/test/testing_sandbox.rb +15 -0
  427. data/test/view/safe_buffer_test.rb +36 -0
  428. data/test/view/test_case_test.rb +176 -0
  429. metadata +531 -0
@@ -0,0 +1,167 @@
1
+ module ActionController
2
+ module Routing
3
+ # BEFORE: 0.191446860631307 ms/url
4
+ # AFTER: 0.029847304022858 ms/url
5
+ # Speed up: 6.4 times
6
+ #
7
+ # Route recognition is slow due to one-by-one iterating over
8
+ # a whole routeset (each map.resources generates at least 14 routes)
9
+ # and matching weird regexps on each step.
10
+ #
11
+ # We optimize this by skipping all URI segments that 100% sure can't
12
+ # be matched, moving deeper in a tree of routes (where node == segment)
13
+ # until first possible match is accured. In such case, we start walking
14
+ # a flat list of routes, matching them with accurate matcher.
15
+ # So, first step: search a segment tree for the first relevant index.
16
+ # Second step: iterate routes starting with that index.
17
+ #
18
+ # How tree is walked? We can do a recursive tests, but it's smarter:
19
+ # We just create a tree of if-s and elsif-s matching segments.
20
+ #
21
+ # We have segments of 3 flavors:
22
+ # 1) nil (no segment, route finished)
23
+ # 2) const-dot-dynamic (like "/posts.:xml", "/preview.:size.jpg")
24
+ # 3) const (like "/posts", "/comments")
25
+ # 4) dynamic ("/:id", "file.:size.:extension")
26
+ #
27
+ # We split incoming string into segments and iterate over them.
28
+ # When segment is nil, we drop immediately, on a current node index.
29
+ # When segment is equal to some const, we step into branch.
30
+ # If none constants matched, we step into 'dynamic' branch (it's a last).
31
+ # If we can't match anything, we drop to last index on a level.
32
+ #
33
+ # Note: we maintain the original routes order, so we finish building
34
+ # steps on a first dynamic segment.
35
+ #
36
+ #
37
+ # Example. Given the routes:
38
+ # 0 /posts/
39
+ # 1 /posts/:id
40
+ # 2 /posts/:id/comments
41
+ # 3 /posts/blah
42
+ # 4 /users/
43
+ # 5 /users/:id
44
+ # 6 /users/:id/profile
45
+ #
46
+ # request_uri = /users/123
47
+ #
48
+ # There will be only 4 iterations:
49
+ # 1) segm test for /posts prefix, skip all /posts/* routes
50
+ # 2) segm test for /users/
51
+ # 3) segm test for /users/:id
52
+ # (jump to list index = 5)
53
+ # 4) full test for /users/:id => here we are!
54
+ class RouteSet
55
+ def recognize_path(path, environment={})
56
+ result = recognize_optimized(path, environment) and return result
57
+
58
+ # Route was not recognized. Try to find out why (maybe wrong verb).
59
+ allows = HTTP_METHODS.select { |verb| routes.find { |r| r.recognize(path, environment.merge(:method => verb)) } }
60
+
61
+ if environment[:method] && !HTTP_METHODS.include?(environment[:method])
62
+ raise NotImplemented.new(*allows)
63
+ elsif !allows.empty?
64
+ raise MethodNotAllowed.new(*allows)
65
+ else
66
+ raise RoutingError, "No route matches #{path.inspect} with #{environment.inspect}"
67
+ end
68
+ end
69
+
70
+ def segment_tree(routes)
71
+ tree = [0]
72
+
73
+ i = -1
74
+ routes.each do |route|
75
+ i += 1
76
+ # not fast, but runs only once
77
+ segments = to_plain_segments(route.segments.inject("") { |str,s| str << s.to_s })
78
+
79
+ node = tree
80
+ segments.each do |seg|
81
+ seg = :dynamic if seg && seg[0] == ?:
82
+ node << [seg, [i]] if node.empty? || node[node.size - 1][0] != seg
83
+ node = node[node.size - 1][1]
84
+ end
85
+ end
86
+ tree
87
+ end
88
+
89
+ def generate_code(list, padding=' ', level = 0)
90
+ # a digit
91
+ return padding + "#{list[0]}\n" if list.size == 1 && !(Array === list[0])
92
+
93
+ body = padding + "(seg = segments[#{level}]; \n"
94
+
95
+ i = 0
96
+ was_nil = false
97
+ list.each do |item|
98
+ if Array === item
99
+ i += 1
100
+ start = (i == 1)
101
+ tag, sub = item
102
+ if tag == :dynamic
103
+ body += padding + "#{start ? 'if' : 'elsif'} true\n"
104
+ body += generate_code(sub, padding + " ", level + 1)
105
+ break
106
+ elsif tag == nil && !was_nil
107
+ was_nil = true
108
+ body += padding + "#{start ? 'if' : 'elsif'} seg.nil?\n"
109
+ body += generate_code(sub, padding + " ", level + 1)
110
+ else
111
+ body += padding + "#{start ? 'if' : 'elsif'} seg == '#{tag}'\n"
112
+ body += generate_code(sub, padding + " ", level + 1)
113
+ end
114
+ end
115
+ end
116
+ body += padding + "else\n"
117
+ body += padding + " #{list[0]}\n"
118
+ body += padding + "end)\n"
119
+ body
120
+ end
121
+
122
+ # this must be really fast
123
+ def to_plain_segments(str)
124
+ str = str.dup
125
+ str.sub!(/^\/+/,'')
126
+ str.sub!(/\/+$/,'')
127
+ segments = str.split(/\.[^\/]+\/+|\/+|\.[^\/]+\Z/) # cut off ".format" also
128
+ segments << nil
129
+ segments
130
+ end
131
+
132
+ private
133
+ def write_recognize_optimized!
134
+ tree = segment_tree(routes)
135
+ body = generate_code(tree)
136
+
137
+ remove_recognize_optimized!
138
+
139
+ instance_eval %{
140
+ def recognize_optimized(path, env)
141
+ segments = to_plain_segments(path)
142
+ index = #{body}
143
+ return nil unless index
144
+ while index < routes.size
145
+ result = routes[index].recognize(path, env) and return result
146
+ index += 1
147
+ end
148
+ nil
149
+ end
150
+ }, '(recognize_optimized)', 1
151
+ end
152
+
153
+ def clear_recognize_optimized!
154
+ remove_recognize_optimized!
155
+ write_recognize_optimized!
156
+ end
157
+
158
+ def remove_recognize_optimized!
159
+ if respond_to?(:recognize_optimized)
160
+ class << self
161
+ remove_method :recognize_optimized
162
+ end
163
+ end
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,265 @@
1
+ module ActionController
2
+ module Routing
3
+ class Route #:nodoc:
4
+ attr_accessor :segments, :requirements, :conditions, :optimise
5
+
6
+ def initialize(segments = [], requirements = {}, conditions = {})
7
+ @segments = segments
8
+ @requirements = requirements
9
+ @conditions = conditions
10
+
11
+ if !significant_keys.include?(:action) && !requirements[:action]
12
+ @requirements[:action] = "index"
13
+ @significant_keys << :action
14
+ end
15
+
16
+ # Routes cannot use the current string interpolation method
17
+ # if there are user-supplied <tt>:requirements</tt> as the interpolation
18
+ # code won't raise RoutingErrors when generating
19
+ has_requirements = @segments.detect { |segment| segment.respond_to?(:regexp) && segment.regexp }
20
+ if has_requirements || @requirements.keys.to_set != Routing::ALLOWED_REQUIREMENTS_FOR_OPTIMISATION
21
+ @optimise = false
22
+ else
23
+ @optimise = true
24
+ end
25
+ end
26
+
27
+ # Indicates whether the routes should be optimised with the string interpolation
28
+ # version of the named routes methods.
29
+ def optimise?
30
+ @optimise && ActionController::Base::optimise_named_routes
31
+ end
32
+
33
+ def segment_keys
34
+ segments.collect do |segment|
35
+ segment.key if segment.respond_to? :key
36
+ end.compact
37
+ end
38
+
39
+ def required_segment_keys
40
+ required_segments = segments.select {|seg| (!seg.optional? && !seg.is_a?(DividerSegment)) || seg.is_a?(PathSegment) }
41
+ required_segments.collect { |seg| seg.key if seg.respond_to?(:key)}.compact
42
+ end
43
+
44
+ # Build a query string from the keys of the given hash. If +only_keys+
45
+ # is given (as an array), only the keys indicated will be used to build
46
+ # the query string. The query string will correctly build array parameter
47
+ # values.
48
+ def build_query_string(hash, only_keys = nil)
49
+ elements = []
50
+
51
+ (only_keys || hash.keys).each do |key|
52
+ if value = hash[key]
53
+ elements << value.to_query(key)
54
+ end
55
+ end
56
+
57
+ elements.empty? ? '' : "?#{elements.sort * '&'}"
58
+ end
59
+
60
+ # A route's parameter shell contains parameter values that are not in the
61
+ # route's path, but should be placed in the recognized hash.
62
+ #
63
+ # For example, +{:controller => 'pages', :action => 'show'} is the shell for the route:
64
+ #
65
+ # map.connect '/page/:id', :controller => 'pages', :action => 'show', :id => /\d+/
66
+ #
67
+ def parameter_shell
68
+ @parameter_shell ||= returning({}) do |shell|
69
+ requirements.each do |key, requirement|
70
+ shell[key] = requirement unless requirement.is_a? Regexp
71
+ end
72
+ end
73
+ end
74
+
75
+ # Return an array containing all the keys that are used in this route. This
76
+ # includes keys that appear inside the path, and keys that have requirements
77
+ # placed upon them.
78
+ def significant_keys
79
+ @significant_keys ||= returning([]) do |sk|
80
+ segments.each { |segment| sk << segment.key if segment.respond_to? :key }
81
+ sk.concat requirements.keys
82
+ sk.uniq!
83
+ end
84
+ end
85
+
86
+ # Return a hash of key/value pairs representing the keys in the route that
87
+ # have defaults, or which are specified by non-regexp requirements.
88
+ def defaults
89
+ @defaults ||= returning({}) do |hash|
90
+ segments.each do |segment|
91
+ next unless segment.respond_to? :default
92
+ hash[segment.key] = segment.default unless segment.default.nil?
93
+ end
94
+ requirements.each do |key,req|
95
+ next if Regexp === req || req.nil?
96
+ hash[key] = req
97
+ end
98
+ end
99
+ end
100
+
101
+ def matches_controller_and_action?(controller, action)
102
+ prepare_matching!
103
+ (@controller_requirement.nil? || @controller_requirement === controller) &&
104
+ (@action_requirement.nil? || @action_requirement === action)
105
+ end
106
+
107
+ def to_s
108
+ @to_s ||= begin
109
+ segs = segments.inject("") { |str,s| str << s.to_s }
110
+ "%-6s %-40s %s" % [(conditions[:method] || :any).to_s.upcase, segs, requirements.inspect]
111
+ end
112
+ end
113
+
114
+ # TODO: Route should be prepared and frozen on initialize
115
+ def freeze
116
+ unless frozen?
117
+ write_generation!
118
+ write_recognition!
119
+ prepare_matching!
120
+
121
+ parameter_shell
122
+ significant_keys
123
+ defaults
124
+ to_s
125
+ end
126
+
127
+ super
128
+ end
129
+
130
+ def generate(options, hash, expire_on = {})
131
+ path, hash = generate_raw(options, hash, expire_on)
132
+ append_query_string(path, hash, extra_keys(options))
133
+ end
134
+
135
+ def generate_extras(options, hash, expire_on = {})
136
+ path, hash = generate_raw(options, hash, expire_on)
137
+ [path, extra_keys(options)]
138
+ end
139
+
140
+ private
141
+ def requirement_for(key)
142
+ return requirements[key] if requirements.key? key
143
+ segments.each do |segment|
144
+ return segment.regexp if segment.respond_to?(:key) && segment.key == key
145
+ end
146
+ nil
147
+ end
148
+
149
+ # Write and compile a +generate+ method for this Route.
150
+ def write_generation!
151
+ # Build the main body of the generation
152
+ body = "expired = false\n#{generation_extraction}\n#{generation_structure}"
153
+
154
+ # If we have conditions that must be tested first, nest the body inside an if
155
+ body = "if #{generation_requirements}\n#{body}\nend" if generation_requirements
156
+ args = "options, hash, expire_on = {}"
157
+
158
+ # Nest the body inside of a def block, and then compile it.
159
+ raw_method = method_decl = "def generate_raw(#{args})\npath = begin\n#{body}\nend\n[path, hash]\nend"
160
+ instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})"
161
+
162
+ # expire_on.keys == recall.keys; in other words, the keys in the expire_on hash
163
+ # are the same as the keys that were recalled from the previous request. Thus,
164
+ # we can use the expire_on.keys to determine which keys ought to be used to build
165
+ # the query string. (Never use keys from the recalled request when building the
166
+ # query string.)
167
+
168
+ raw_method
169
+ end
170
+
171
+ # Build several lines of code that extract values from the options hash. If any
172
+ # of the values are missing or rejected then a return will be executed.
173
+ def generation_extraction
174
+ segments.collect do |segment|
175
+ segment.extraction_code
176
+ end.compact * "\n"
177
+ end
178
+
179
+ # Produce a condition expression that will check the requirements of this route
180
+ # upon generation.
181
+ def generation_requirements
182
+ requirement_conditions = requirements.collect do |key, req|
183
+ if req.is_a? Regexp
184
+ value_regexp = Regexp.new "\\A#{req.to_s}\\Z"
185
+ "hash[:#{key}] && #{value_regexp.inspect} =~ options[:#{key}]"
186
+ else
187
+ "hash[:#{key}] == #{req.inspect}"
188
+ end
189
+ end
190
+ requirement_conditions * ' && ' unless requirement_conditions.empty?
191
+ end
192
+
193
+ def generation_structure
194
+ segments.last.string_structure segments[0..-2]
195
+ end
196
+
197
+ # Write and compile a +recognize+ method for this Route.
198
+ def write_recognition!
199
+ # Create an if structure to extract the params from a match if it occurs.
200
+ body = "params = parameter_shell.dup\n#{recognition_extraction * "\n"}\nparams"
201
+ body = "if #{recognition_conditions.join(" && ")}\n#{body}\nend"
202
+
203
+ # Build the method declaration and compile it
204
+ method_decl = "def recognize(path, env = {})\n#{body}\nend"
205
+ instance_eval method_decl, "generated code (#{__FILE__}:#{__LINE__})"
206
+ method_decl
207
+ end
208
+
209
+ # Plugins may override this method to add other conditions, like checks on
210
+ # host, subdomain, and so forth. Note that changes here only affect route
211
+ # recognition, not generation.
212
+ def recognition_conditions
213
+ result = ["(match = #{Regexp.new(recognition_pattern).inspect}.match(path))"]
214
+ result << "[conditions[:method]].flatten.include?(env[:method])" if conditions[:method]
215
+ result
216
+ end
217
+
218
+ # Build the regular expression pattern that will match this route.
219
+ def recognition_pattern(wrap = true)
220
+ pattern = ''
221
+ segments.reverse_each do |segment|
222
+ pattern = segment.build_pattern pattern
223
+ end
224
+ wrap ? ("\\A" + pattern + "\\Z") : pattern
225
+ end
226
+
227
+ # Write the code to extract the parameters from a matched route.
228
+ def recognition_extraction
229
+ next_capture = 1
230
+ extraction = segments.collect do |segment|
231
+ x = segment.match_extraction(next_capture)
232
+ next_capture += segment.number_of_captures
233
+ x
234
+ end
235
+ extraction.compact
236
+ end
237
+
238
+ # Generate the query string with any extra keys in the hash and append
239
+ # it to the given path, returning the new path.
240
+ def append_query_string(path, hash, query_keys = nil)
241
+ return nil unless path
242
+ query_keys ||= extra_keys(hash)
243
+ "#{path}#{build_query_string(hash, query_keys)}"
244
+ end
245
+
246
+ # Determine which keys in the given hash are "extra". Extra keys are
247
+ # those that were not used to generate a particular route. The extra
248
+ # keys also do not include those recalled from the prior request, nor
249
+ # do they include any keys that were implied in the route (like a
250
+ # <tt>:controller</tt> that is required, but not explicitly used in the
251
+ # text of the route.)
252
+ def extra_keys(hash, recall = {})
253
+ (hash || {}).keys.map { |k| k.to_sym } - (recall || {}).keys - significant_keys
254
+ end
255
+
256
+ def prepare_matching!
257
+ unless defined? @matching_prepared
258
+ @controller_requirement = requirement_for(:controller)
259
+ @action_requirement = requirement_for(:action)
260
+ @matching_prepared = true
261
+ end
262
+ end
263
+ end
264
+ end
265
+ end