actionpack-rack-upgrade 2.3.14

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 (441) hide show
  1. data/CHANGELOG +5250 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +409 -0
  4. data/RUNNING_UNIT_TESTS +24 -0
  5. data/Rakefile +158 -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 +169 -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 +1425 -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 +197 -0
  27. data/lib/action_controller/dispatcher.rb +133 -0
  28. data/lib/action_controller/failsafe.rb +87 -0
  29. data/lib/action_controller/filters.rb +680 -0
  30. data/lib/action_controller/flash.rb +213 -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 +708 -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 +495 -0
  48. data/lib/action_controller/request_forgery_protection.rb +116 -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 +237 -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 +503 -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 +276 -0
  61. data/lib/action_controller/session/cookie_store.rb +240 -0
  62. data/lib/action_controller/session/mem_cache_store.rb +60 -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 +229 -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/helpers/active_record_helper.rb +305 -0
  93. data/lib/action_view/helpers/asset_tag_helper.rb +695 -0
  94. data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
  95. data/lib/action_view/helpers/benchmark_helper.rb +54 -0
  96. data/lib/action_view/helpers/cache_helper.rb +39 -0
  97. data/lib/action_view/helpers/capture_helper.rb +136 -0
  98. data/lib/action_view/helpers/csrf_helper.rb +14 -0
  99. data/lib/action_view/helpers/date_helper.rb +989 -0
  100. data/lib/action_view/helpers/debug_helper.rb +38 -0
  101. data/lib/action_view/helpers/form_helper.rb +1118 -0
  102. data/lib/action_view/helpers/form_options_helper.rb +599 -0
  103. data/lib/action_view/helpers/form_tag_helper.rb +490 -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 +251 -0
  111. data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
  112. data/lib/action_view/helpers/tag_helper.rb +151 -0
  113. data/lib/action_view/helpers/text_helper.rb +597 -0
  114. data/lib/action_view/helpers/translation_helper.rb +67 -0
  115. data/lib/action_view/helpers/url_helper.rb +637 -0
  116. data/lib/action_view/helpers.rb +61 -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 +241 -0
  120. data/lib/action_view/paths.rb +77 -0
  121. data/lib/action_view/reloadable_template.rb +117 -0
  122. data/lib/action_view/renderable.rb +109 -0
  123. data/lib/action_view/renderable_partial.rb +53 -0
  124. data/lib/action_view/template.rb +252 -0
  125. data/lib/action_view/template_error.rb +99 -0
  126. data/lib/action_view/template_handler.rb +34 -0
  127. data/lib/action_view/template_handlers/builder.rb +17 -0
  128. data/lib/action_view/template_handlers/erb.rb +25 -0
  129. data/lib/action_view/template_handlers/rjs.rb +13 -0
  130. data/lib/action_view/template_handlers.rb +48 -0
  131. data/lib/action_view/test_case.rb +162 -0
  132. data/lib/action_view.rb +58 -0
  133. data/lib/actionpack.rb +2 -0
  134. data/test/abstract_unit.rb +78 -0
  135. data/test/active_record_unit.rb +104 -0
  136. data/test/activerecord/active_record_store_test.rb +221 -0
  137. data/test/activerecord/render_partial_with_record_identification_test.rb +188 -0
  138. data/test/adv_attr_test.rb +20 -0
  139. data/test/controller/action_pack_assertions_test.rb +545 -0
  140. data/test/controller/addresses_render_test.rb +37 -0
  141. data/test/controller/assert_select_test.rb +735 -0
  142. data/test/controller/base_test.rb +217 -0
  143. data/test/controller/benchmark_test.rb +32 -0
  144. data/test/controller/caching_test.rb +743 -0
  145. data/test/controller/capture_test.rb +66 -0
  146. data/test/controller/content_type_test.rb +178 -0
  147. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  148. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  149. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  150. data/test/controller/cookie_test.rb +208 -0
  151. data/test/controller/deprecation/deprecated_base_methods_test.rb +32 -0
  152. data/test/controller/dispatcher_test.rb +144 -0
  153. data/test/controller/dom_assertions_test.rb +53 -0
  154. data/test/controller/failsafe_test.rb +60 -0
  155. data/test/controller/fake_controllers.rb +33 -0
  156. data/test/controller/fake_models.rb +19 -0
  157. data/test/controller/filter_params_test.rb +52 -0
  158. data/test/controller/filters_test.rb +885 -0
  159. data/test/controller/flash_test.rb +174 -0
  160. data/test/controller/header_test.rb +14 -0
  161. data/test/controller/helper_test.rb +224 -0
  162. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  163. data/test/controller/html-scanner/document_test.rb +148 -0
  164. data/test/controller/html-scanner/node_test.rb +89 -0
  165. data/test/controller/html-scanner/sanitizer_test.rb +281 -0
  166. data/test/controller/html-scanner/tag_node_test.rb +238 -0
  167. data/test/controller/html-scanner/text_node_test.rb +50 -0
  168. data/test/controller/html-scanner/tokenizer_test.rb +131 -0
  169. data/test/controller/http_basic_authentication_test.rb +113 -0
  170. data/test/controller/http_digest_authentication_test.rb +254 -0
  171. data/test/controller/integration_test.rb +526 -0
  172. data/test/controller/layout_test.rb +215 -0
  173. data/test/controller/localized_templates_test.rb +24 -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/output_escaping_test.rb +19 -0
  179. data/test/controller/polymorphic_routes_test.rb +297 -0
  180. data/test/controller/rack_test.rb +308 -0
  181. data/test/controller/record_identifier_test.rb +139 -0
  182. data/test/controller/redirect_test.rb +285 -0
  183. data/test/controller/reloader_test.rb +125 -0
  184. data/test/controller/render_test.rb +1783 -0
  185. data/test/controller/request/json_params_parsing_test.rb +65 -0
  186. data/test/controller/request/multipart_params_parsing_test.rb +177 -0
  187. data/test/controller/request/query_string_parsing_test.rb +120 -0
  188. data/test/controller/request/test_request_test.rb +35 -0
  189. data/test/controller/request/url_encoded_params_parsing_test.rb +146 -0
  190. data/test/controller/request/xml_params_parsing_test.rb +103 -0
  191. data/test/controller/request_forgery_protection_test.rb +233 -0
  192. data/test/controller/request_test.rb +395 -0
  193. data/test/controller/rescue_test.rb +541 -0
  194. data/test/controller/resources_test.rb +1393 -0
  195. data/test/controller/routing_test.rb +2592 -0
  196. data/test/controller/selector_test.rb +628 -0
  197. data/test/controller/send_file_test.rb +171 -0
  198. data/test/controller/session/abstract_store_test.rb +64 -0
  199. data/test/controller/session/cookie_store_test.rb +354 -0
  200. data/test/controller/session/mem_cache_store_test.rb +187 -0
  201. data/test/controller/session/test_session_test.rb +58 -0
  202. data/test/controller/test_test.rb +700 -0
  203. data/test/controller/translation_test.rb +26 -0
  204. data/test/controller/url_rewriter_test.rb +395 -0
  205. data/test/controller/verification_test.rb +270 -0
  206. data/test/controller/view_paths_test.rb +141 -0
  207. data/test/controller/webservice_test.rb +260 -0
  208. data/test/fixtures/_top_level_partial.html.erb +1 -0
  209. data/test/fixtures/_top_level_partial_only.erb +1 -0
  210. data/test/fixtures/addresses/list.erb +1 -0
  211. data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
  212. data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
  213. data/test/fixtures/companies.yml +24 -0
  214. data/test/fixtures/company.rb +10 -0
  215. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
  216. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
  217. data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
  218. data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
  219. data/test/fixtures/customers/_customer.html.erb +1 -0
  220. data/test/fixtures/db_definitions/sqlite.sql +49 -0
  221. data/test/fixtures/developer.rb +9 -0
  222. data/test/fixtures/developers/_developer.erb +1 -0
  223. data/test/fixtures/developers.yml +21 -0
  224. data/test/fixtures/developers_projects.yml +13 -0
  225. data/test/fixtures/failsafe/500.html +1 -0
  226. data/test/fixtures/fun/games/_game.erb +1 -0
  227. data/test/fixtures/fun/games/hello_world.erb +1 -0
  228. data/test/fixtures/fun/serious/games/_game.erb +1 -0
  229. data/test/fixtures/functional_caching/_partial.erb +3 -0
  230. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
  231. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
  232. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
  233. data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
  234. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
  235. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
  236. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
  237. data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
  238. data/test/fixtures/helpers/abc_helper.rb +5 -0
  239. data/test/fixtures/helpers/fun/games_helper.rb +3 -0
  240. data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
  241. data/test/fixtures/layout_tests/abs_path_layout.rhtml +1 -0
  242. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  243. data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
  244. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
  245. data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
  246. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
  247. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  248. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
  249. data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
  250. data/test/fixtures/layouts/_column.html.erb +2 -0
  251. data/test/fixtures/layouts/block_with_layout.erb +3 -0
  252. data/test/fixtures/layouts/builder.builder +3 -0
  253. data/test/fixtures/layouts/default_html.html.erb +1 -0
  254. data/test/fixtures/layouts/partial_with_layout.erb +3 -0
  255. data/test/fixtures/layouts/standard.erb +1 -0
  256. data/test/fixtures/layouts/talk_from_action.erb +2 -0
  257. data/test/fixtures/layouts/xhr.html.erb +2 -0
  258. data/test/fixtures/layouts/yield.erb +2 -0
  259. data/test/fixtures/localized/hello_world.de.html +1 -0
  260. data/test/fixtures/localized/hello_world.en.html +1 -0
  261. data/test/fixtures/mascot.rb +3 -0
  262. data/test/fixtures/mascots/_mascot.html.erb +1 -0
  263. data/test/fixtures/mascots.yml +4 -0
  264. data/test/fixtures/multipart/binary_file +0 -0
  265. data/test/fixtures/multipart/boundary_problem_file +10 -0
  266. data/test/fixtures/multipart/bracketed_param +5 -0
  267. data/test/fixtures/multipart/empty +10 -0
  268. data/test/fixtures/multipart/hello.txt +1 -0
  269. data/test/fixtures/multipart/large_text_file +10 -0
  270. data/test/fixtures/multipart/mixed_files +0 -0
  271. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  272. data/test/fixtures/multipart/none +9 -0
  273. data/test/fixtures/multipart/single_parameter +5 -0
  274. data/test/fixtures/multipart/text_file +10 -0
  275. data/test/fixtures/override/test/hello_world.erb +1 -0
  276. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  277. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  278. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  279. data/test/fixtures/post_test/post/index.html.erb +1 -0
  280. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  281. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  282. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  283. data/test/fixtures/project.rb +3 -0
  284. data/test/fixtures/projects/_project.erb +1 -0
  285. data/test/fixtures/projects.yml +7 -0
  286. data/test/fixtures/public/404.html +1 -0
  287. data/test/fixtures/public/500.da.html +1 -0
  288. data/test/fixtures/public/500.html +1 -0
  289. data/test/fixtures/public/absolute/test.css +23 -0
  290. data/test/fixtures/public/absolute/test.js +63 -0
  291. data/test/fixtures/public/images/rails.png +0 -0
  292. data/test/fixtures/public/javascripts/application.js +1 -0
  293. data/test/fixtures/public/javascripts/bank.js +1 -0
  294. data/test/fixtures/public/javascripts/controls.js +1 -0
  295. data/test/fixtures/public/javascripts/dragdrop.js +1 -0
  296. data/test/fixtures/public/javascripts/effects.js +1 -0
  297. data/test/fixtures/public/javascripts/prototype.js +1 -0
  298. data/test/fixtures/public/javascripts/robber.js +1 -0
  299. data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
  300. data/test/fixtures/public/javascripts/version.1.0.js +1 -0
  301. data/test/fixtures/public/stylesheets/bank.css +1 -0
  302. data/test/fixtures/public/stylesheets/robber.css +1 -0
  303. data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
  304. data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
  305. data/test/fixtures/quiz/questions/_question.html.erb +1 -0
  306. data/test/fixtures/replies/_reply.erb +1 -0
  307. data/test/fixtures/replies.yml +15 -0
  308. data/test/fixtures/reply.rb +7 -0
  309. data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
  310. data/test/fixtures/respond_to/all_types_with_layout.js.rjs +1 -0
  311. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  312. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  313. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  314. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  315. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  316. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  317. data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
  318. data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
  319. data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
  320. data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
  321. data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
  322. data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
  323. data/test/fixtures/scope/test/modgreet.erb +1 -0
  324. data/test/fixtures/session_autoload_test/session_autoload_test/foo.rb +10 -0
  325. data/test/fixtures/shared.html.erb +1 -0
  326. data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
  327. data/test/fixtures/test/_counter.html.erb +1 -0
  328. data/test/fixtures/test/_customer.erb +1 -0
  329. data/test/fixtures/test/_customer_counter.erb +1 -0
  330. data/test/fixtures/test/_customer_counter_with_as.erb +1 -0
  331. data/test/fixtures/test/_customer_greeting.erb +1 -0
  332. data/test/fixtures/test/_customer_with_var.erb +1 -0
  333. data/test/fixtures/test/_form.erb +1 -0
  334. data/test/fixtures/test/_from_helper.erb +1 -0
  335. data/test/fixtures/test/_hash_greeting.erb +1 -0
  336. data/test/fixtures/test/_hash_object.erb +2 -0
  337. data/test/fixtures/test/_hello.builder +1 -0
  338. data/test/fixtures/test/_labelling_form.erb +1 -0
  339. data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
  340. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  341. data/test/fixtures/test/_local_inspector.html.erb +1 -0
  342. data/test/fixtures/test/_one.html.erb +1 -0
  343. data/test/fixtures/test/_partial.erb +1 -0
  344. data/test/fixtures/test/_partial.html.erb +1 -0
  345. data/test/fixtures/test/_partial.js.erb +1 -0
  346. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  347. data/test/fixtures/test/_partial_only.erb +1 -0
  348. data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
  349. data/test/fixtures/test/_person.erb +2 -0
  350. data/test/fixtures/test/_raise.html.erb +1 -0
  351. data/test/fixtures/test/_two.html.erb +1 -0
  352. data/test/fixtures/test/_utf8_partial.html.erb +1 -0
  353. data/test/fixtures/test/_utf8_partial_magic.html.erb +2 -0
  354. data/test/fixtures/test/action_talk_to_layout.erb +2 -0
  355. data/test/fixtures/test/array_translation.erb +1 -0
  356. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  357. data/test/fixtures/test/capturing.erb +4 -0
  358. data/test/fixtures/test/content_for.erb +2 -0
  359. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  360. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  361. data/test/fixtures/test/delete_with_js.rjs +2 -0
  362. data/test/fixtures/test/dont_pick_me +1 -0
  363. data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
  364. data/test/fixtures/test/enum_rjs_test.rjs +6 -0
  365. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  366. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  367. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  368. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  369. data/test/fixtures/test/greeting.erb +1 -0
  370. data/test/fixtures/test/greeting.js.rjs +1 -0
  371. data/test/fixtures/test/hello.builder +4 -0
  372. data/test/fixtures/test/hello_world.da.html.erb +1 -0
  373. data/test/fixtures/test/hello_world.erb +1 -0
  374. data/test/fixtures/test/hello_world.erb~ +1 -0
  375. data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
  376. data/test/fixtures/test/hello_world_container.builder +3 -0
  377. data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
  378. data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
  379. data/test/fixtures/test/hello_xml_world.builder +11 -0
  380. data/test/fixtures/test/hyphen-ated.erb +1 -0
  381. data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
  382. data/test/fixtures/test/list.erb +1 -0
  383. data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
  384. data/test/fixtures/test/malformed/malformed.erb~ +1 -0
  385. data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
  386. data/test/fixtures/test/nested_layout.erb +3 -0
  387. data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
  388. data/test/fixtures/test/potential_conflicts.erb +4 -0
  389. data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
  390. data/test/fixtures/test/render_file_from_template.html.erb +1 -0
  391. data/test/fixtures/test/render_file_with_ivar.erb +1 -0
  392. data/test/fixtures/test/render_file_with_locals.erb +1 -0
  393. data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
  394. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
  395. data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
  396. data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
  397. data/test/fixtures/test/render_to_string_test.erb +1 -0
  398. data/test/fixtures/test/scoped_array_translation.erb +1 -0
  399. data/test/fixtures/test/sub_template_raise.html.erb +1 -0
  400. data/test/fixtures/test/template.erb +1 -0
  401. data/test/fixtures/test/translation.erb +1 -0
  402. data/test/fixtures/test/update_element_with_capture.erb +9 -0
  403. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  404. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
  405. data/test/fixtures/test/utf8.html.erb +4 -0
  406. data/test/fixtures/test/utf8_magic.html.erb +5 -0
  407. data/test/fixtures/test/utf8_magic_with_bare_partial.html.erb +5 -0
  408. data/test/fixtures/topic.rb +3 -0
  409. data/test/fixtures/topics/_topic.html.erb +1 -0
  410. data/test/fixtures/topics.yml +22 -0
  411. data/test/template/active_record_helper_i18n_test.rb +51 -0
  412. data/test/template/active_record_helper_test.rb +302 -0
  413. data/test/template/asset_tag_helper_test.rb +770 -0
  414. data/test/template/atom_feed_helper_test.rb +315 -0
  415. data/test/template/benchmark_helper_test.rb +86 -0
  416. data/test/template/compiled_templates_test.rb +204 -0
  417. data/test/template/date_helper_i18n_test.rb +121 -0
  418. data/test/template/date_helper_test.rb +2603 -0
  419. data/test/template/erb_util_test.rb +36 -0
  420. data/test/template/form_helper_test.rb +1447 -0
  421. data/test/template/form_options_helper_i18n_test.rb +27 -0
  422. data/test/template/form_options_helper_test.rb +811 -0
  423. data/test/template/form_tag_helper_test.rb +356 -0
  424. data/test/template/javascript_helper_test.rb +106 -0
  425. data/test/template/number_helper_i18n_test.rb +69 -0
  426. data/test/template/number_helper_test.rb +132 -0
  427. data/test/template/prototype_helper_test.rb +639 -0
  428. data/test/template/raw_output_helper_test.rb +21 -0
  429. data/test/template/record_tag_helper_test.rb +58 -0
  430. data/test/template/render_test.rb +329 -0
  431. data/test/template/sanitize_helper_test.rb +57 -0
  432. data/test/template/scriptaculous_helper_test.rb +90 -0
  433. data/test/template/tag_helper_test.rb +98 -0
  434. data/test/template/template_test.rb +32 -0
  435. data/test/template/test_test.rb +54 -0
  436. data/test/template/text_helper_test.rb +597 -0
  437. data/test/template/translation_helper_test.rb +95 -0
  438. data/test/template/url_helper_test.rb +641 -0
  439. data/test/testing_sandbox.rb +15 -0
  440. data/test/view/test_case_test.rb +176 -0
  441. metadata +519 -0
@@ -0,0 +1,281 @@
1
+ require 'abstract_unit'
2
+
3
+ class SanitizerTest < ActionController::TestCase
4
+ def setup
5
+ @sanitizer = nil # used by assert_sanitizer
6
+ end
7
+
8
+ def test_strip_tags_with_quote
9
+ sanitizer = HTML::FullSanitizer.new
10
+ string = '<" <img src="trollface.gif" onload="alert(1)"> hi'
11
+
12
+ assert_equal ' hi', sanitizer.sanitize(string)
13
+ end
14
+
15
+ def test_strip_tags
16
+ sanitizer = HTML::FullSanitizer.new
17
+ assert_equal("<<<bad html", sanitizer.sanitize("<<<bad html"))
18
+ assert_equal("<<", sanitizer.sanitize("<<<bad html>"))
19
+ assert_equal("Dont touch me", sanitizer.sanitize("Dont touch me"))
20
+ assert_equal("This is a test.", sanitizer.sanitize("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>"))
21
+ assert_equal("Weirdos", sanitizer.sanitize("Wei<<a>a onclick='alert(document.cookie);'</a>/>rdos"))
22
+ assert_equal("This is a test.", sanitizer.sanitize("This is a test."))
23
+ assert_equal(
24
+ %{This is a test.\n\n\nIt no longer contains any HTML.\n}, sanitizer.sanitize(
25
+ %{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}))
26
+ assert_equal "This has a here.", sanitizer.sanitize("This has a <!-- comment --> here.")
27
+ assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.")
28
+ assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...")
29
+ assert_equal "non printable char is a tag", sanitizer.sanitize("<\x07a href='/hello'>non printable char is a tag</a>")
30
+ [nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) }
31
+ end
32
+
33
+ def test_strip_links
34
+ sanitizer = HTML::LinkSanitizer.new
35
+ assert_equal "Dont touch me", sanitizer.sanitize("Dont touch me")
36
+ assert_equal "on my mind\nall day long", sanitizer.sanitize("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>")
37
+ assert_equal "0wn3d", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'><a href='http://www.rubyonrails.com/' onlclick='steal()'>0wn3d</a></a>")
38
+ assert_equal "Magic", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic")
39
+ assert_equal "FrrFox", sanitizer.sanitize("<href onlclick='steal()'>FrrFox</a></href>")
40
+ assert_equal "My mind\nall <b>day</b> long", sanitizer.sanitize("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>")
41
+ assert_equal "all <b>day</b> long", sanitizer.sanitize("<<a>a href='hello'>all <b>day</b> long<</A>/a>")
42
+
43
+ assert_equal "<a<a", sanitizer.sanitize("<a<a")
44
+ end
45
+
46
+ def test_sanitize_form
47
+ assert_sanitized "<form action=\"/foo/bar\" method=\"post\"><input></form>", ''
48
+ end
49
+
50
+ def test_sanitize_plaintext
51
+ raw = "<plaintext><span>foo</span></plaintext>"
52
+ assert_sanitized raw, "<span>foo</span>"
53
+ end
54
+
55
+ def test_sanitize_script
56
+ assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f"
57
+ end
58
+
59
+ # fucked
60
+ def test_sanitize_js_handlers
61
+ raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
62
+ assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>}
63
+ end
64
+
65
+ def test_sanitize_javascript_href
66
+ raw = %{href="javascript:bang" <a href="javascript:bang" name="hello">foo</a>, <span href="javascript:bang">bar</span>}
67
+ assert_sanitized raw, %{href="javascript:bang" <a name="hello">foo</a>, <span>bar</span>}
68
+ end
69
+
70
+ def test_sanitize_image_src
71
+ raw = %{src="javascript:bang" <img src="javascript:bang" width="5">foo</img>, <span src="javascript:bang">bar</span>}
72
+ assert_sanitized raw, %{src="javascript:bang" <img width="5">foo</img>, <span>bar</span>}
73
+ end
74
+
75
+ HTML::WhiteListSanitizer.allowed_tags.each do |tag_name|
76
+ define_method "test_should_allow_#{tag_name}_tag" do
77
+ assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar baz</#{tag_name}> end)
78
+ end
79
+ end
80
+
81
+ def test_should_allow_anchors
82
+ assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>), %(<a href="foo"></a>)
83
+ end
84
+
85
+ # RFC 3986, sec 4.2
86
+ def test_allow_colons_in_path_component
87
+ assert_sanitized("<a href=\"./this:that\">foo</a>")
88
+ end
89
+
90
+ %w(src width height alt).each do |img_attr|
91
+ define_method "test_should_allow_image_#{img_attr}_attribute" do
92
+ assert_sanitized %(<img #{img_attr}="foo" onclick="bar" />), %(<img #{img_attr}="foo" />)
93
+ end
94
+ end
95
+
96
+ def test_should_handle_non_html
97
+ assert_sanitized 'abc'
98
+ end
99
+
100
+ def test_should_handle_blank_text
101
+ assert_sanitized nil
102
+ assert_sanitized ''
103
+ end
104
+
105
+ def test_should_allow_custom_tags
106
+ text = "<u>foo</u>"
107
+ sanitizer = HTML::WhiteListSanitizer.new
108
+ assert_equal(text, sanitizer.sanitize(text, :tags => %w(u)))
109
+ end
110
+
111
+ def test_should_allow_only_custom_tags
112
+ text = "<u>foo</u> with <i>bar</i>"
113
+ sanitizer = HTML::WhiteListSanitizer.new
114
+ assert_equal("<u>foo</u> with bar", sanitizer.sanitize(text, :tags => %w(u)))
115
+ end
116
+
117
+ def test_should_allow_custom_tags_with_attributes
118
+ text = %(<blockquote cite="http://example.com/">foo</blockquote>)
119
+ sanitizer = HTML::WhiteListSanitizer.new
120
+ assert_equal(text, sanitizer.sanitize(text))
121
+ end
122
+
123
+ def test_should_allow_custom_tags_with_custom_attributes
124
+ text = %(<blockquote foo="bar">Lorem ipsum</blockquote>)
125
+ sanitizer = HTML::WhiteListSanitizer.new
126
+ assert_equal(text, sanitizer.sanitize(text, :attributes => ['foo']))
127
+ end
128
+
129
+ [%w(img src), %w(a href)].each do |(tag, attr)|
130
+ define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do
131
+ assert_sanitized %(<#{tag} #{attr}="javascript:bang" title="1">boo</#{tag}>), %(<#{tag} title="1">boo</#{tag}>)
132
+ end
133
+ end
134
+
135
+ def test_should_flag_bad_protocols
136
+ sanitizer = HTML::WhiteListSanitizer.new
137
+ %w(about chrome data disk hcp help javascript livescript lynxcgi lynxexec ms-help ms-its mhtml mocha opera res resource shell vbscript view-source vnd.ms.radio wysiwyg).each do |proto|
138
+ assert sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://bad")
139
+ end
140
+ end
141
+
142
+ def test_should_accept_good_protocols
143
+ sanitizer = HTML::WhiteListSanitizer.new
144
+ HTML::WhiteListSanitizer.allowed_protocols.each do |proto|
145
+ assert !sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://good")
146
+ end
147
+ end
148
+
149
+ def test_should_reject_hex_codes_in_protocol
150
+ assert_sanitized %(<a href="&#37;6A&#37;61&#37;76&#37;61&#37;73&#37;63&#37;72&#37;69&#37;70&#37;74&#37;3A&#37;61&#37;6C&#37;65&#37;72&#37;74&#37;28&#37;22&#37;58&#37;53&#37;53&#37;22&#37;29">1</a>), "<a>1</a>"
151
+ assert @sanitizer.send(:contains_bad_protocols?, 'src', "%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29")
152
+ end
153
+
154
+ def test_should_block_script_tag
155
+ assert_sanitized %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), ""
156
+ end
157
+
158
+ [%(<IMG SRC="javascript:alert('XSS');">),
159
+ %(<IMG SRC=javascript:alert('XSS')>),
160
+ %(<IMG SRC=JaVaScRiPt:alert('XSS')>),
161
+ %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">),
162
+ %(<IMG SRC=javascript:alert(&quot;XSS&quot;)>),
163
+ %(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>),
164
+ %(<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>),
165
+ %(<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>),
166
+ %(<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>),
167
+ %(<IMG SRC="jav\tascript:alert('XSS');">),
168
+ %(<IMG SRC="jav&#x09;ascript:alert('XSS');">),
169
+ %(<IMG SRC="jav&#x0A;ascript:alert('XSS');">),
170
+ %(<IMG SRC="jav&#x0D;ascript:alert('XSS');">),
171
+ %(<IMG SRC=" &#14; javascript:alert('XSS');">),
172
+ %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i|
173
+ define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do
174
+ assert_sanitized img_hack, "<img>"
175
+ end
176
+ end
177
+
178
+ def test_should_sanitize_tag_broken_up_by_null
179
+ assert_sanitized %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>), "alert(\"XSS\")"
180
+ end
181
+
182
+ def test_should_sanitize_invalid_script_tag
183
+ assert_sanitized %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), ""
184
+ end
185
+
186
+ def test_should_sanitize_script_tag_with_multiple_open_brackets
187
+ assert_sanitized %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "&lt;"
188
+ assert_sanitized %(<iframe src=http://ha.ckers.org/scriptlet.html\n<a), %(&lt;a)
189
+ end
190
+
191
+ def test_should_sanitize_unclosed_script
192
+ assert_sanitized %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<b>"
193
+ end
194
+
195
+ def test_should_sanitize_half_open_scripts
196
+ assert_sanitized %(<IMG SRC="javascript:alert('XSS')"), "<img>"
197
+ end
198
+
199
+ def test_should_not_fall_for_ridiculous_hack
200
+ img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>)
201
+ assert_sanitized img_hack, "<img>"
202
+ end
203
+
204
+ # fucked
205
+ def test_should_sanitize_attributes
206
+ assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="'&gt;&lt;script&gt;alert()&lt;/script&gt;">blah</span>)
207
+ end
208
+
209
+ def test_should_sanitize_illegal_style_properties
210
+ raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;)
211
+ expected = %(display: block; width: 100%; height: 100%; background-color: black; background-image: ; background-x: center; background-y: center;)
212
+ assert_equal expected, sanitize_css(raw)
213
+ end
214
+
215
+ def test_should_sanitize_with_trailing_space
216
+ raw = "display:block; "
217
+ expected = "display: block;"
218
+ assert_equal expected, sanitize_css(raw)
219
+ end
220
+
221
+ def test_should_sanitize_xul_style_attributes
222
+ raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss'))
223
+ assert_equal '', sanitize_css(raw)
224
+ end
225
+
226
+ def test_should_sanitize_invalid_tag_names
227
+ assert_sanitized(%(a b c<script/XSS src="http://ha.ckers.org/xss.js"></script>d e f), "a b cd e f")
228
+ end
229
+
230
+ def test_should_sanitize_non_alpha_and_non_digit_characters_in_tags
231
+ assert_sanitized('<a onclick!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>foo</a>', "<a>foo</a>")
232
+ end
233
+
234
+ def test_should_sanitize_invalid_tag_names_in_single_tags
235
+ assert_sanitized('<img/src="http://ha.ckers.org/xss.js"/>', "<img />")
236
+ end
237
+
238
+ def test_should_sanitize_img_dynsrc_lowsrc
239
+ assert_sanitized(%(<img lowsrc="javascript:alert('XSS')" />), "<img />")
240
+ end
241
+
242
+ def test_should_sanitize_div_background_image_unicode_encoded
243
+ raw = %(background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029)
244
+ assert_equal '', sanitize_css(raw)
245
+ end
246
+
247
+ def test_should_sanitize_div_style_expression
248
+ raw = %(width: expression(alert('XSS'));)
249
+ assert_equal '', sanitize_css(raw)
250
+ end
251
+
252
+ def test_should_sanitize_img_vbscript
253
+ assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />'
254
+ end
255
+
256
+ def test_should_sanitize_cdata_section
257
+ assert_sanitized "<![CDATA[<span>section</span>]]>", "&lt;![CDATA[&lt;span>section&lt;/span>]]>"
258
+ end
259
+
260
+ def test_should_sanitize_unterminated_cdata_section
261
+ assert_sanitized "<![CDATA[<span>neverending...", "&lt;![CDATA[&lt;span>neverending...]]>"
262
+ end
263
+
264
+ def test_should_not_mangle_urls_with_ampersand
265
+ assert_sanitized %{<a href=\"http://www.domain.com?var1=1&amp;var2=2\">my link</a>}
266
+ end
267
+
268
+ protected
269
+ def assert_sanitized(input, expected = nil)
270
+ @sanitizer ||= HTML::WhiteListSanitizer.new
271
+ if input
272
+ assert_dom_equal expected || input, @sanitizer.sanitize(input)
273
+ else
274
+ assert_nil @sanitizer.sanitize(input)
275
+ end
276
+ end
277
+
278
+ def sanitize_css(input)
279
+ (@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input)
280
+ end
281
+ end
@@ -0,0 +1,238 @@
1
+ require 'abstract_unit'
2
+
3
+ class TagNodeTest < Test::Unit::TestCase
4
+ def test_open_without_attributes
5
+ node = tag("<tag>")
6
+ assert_equal "tag", node.name
7
+ assert_equal Hash.new, node.attributes
8
+ assert_nil node.closing
9
+ end
10
+
11
+ def test_open_with_attributes
12
+ node = tag("<TAG1 foo=hey_ho x:bar=\"blah blah\" BAZ='blah blah blah' >")
13
+ assert_equal "tag1", node.name
14
+ assert_equal "hey_ho", node["foo"]
15
+ assert_equal "blah blah", node["x:bar"]
16
+ assert_equal "blah blah blah", node["baz"]
17
+ end
18
+
19
+ def test_self_closing_without_attributes
20
+ node = tag("<tag/>")
21
+ assert_equal "tag", node.name
22
+ assert_equal Hash.new, node.attributes
23
+ assert_equal :self, node.closing
24
+ end
25
+
26
+ def test_self_closing_with_attributes
27
+ node = tag("<tag a=b/>")
28
+ assert_equal "tag", node.name
29
+ assert_equal( { "a" => "b" }, node.attributes )
30
+ assert_equal :self, node.closing
31
+ end
32
+
33
+ def test_closing_without_attributes
34
+ node = tag("</tag>")
35
+ assert_equal "tag", node.name
36
+ assert_nil node.attributes
37
+ assert_equal :close, node.closing
38
+ end
39
+
40
+ def test_bracket_op_when_no_attributes
41
+ node = tag("</tag>")
42
+ assert_nil node["foo"]
43
+ end
44
+
45
+ def test_bracket_op_when_attributes
46
+ node = tag("<tag a=b/>")
47
+ assert_equal "b", node["a"]
48
+ end
49
+
50
+ def test_attributes_with_escaped_quotes
51
+ node = tag("<tag a='b\\'c' b=\"bob \\\"float\\\"\">")
52
+ assert_equal "b\\'c", node["a"]
53
+ assert_equal "bob \\\"float\\\"", node["b"]
54
+ end
55
+
56
+ def test_to_s
57
+ node = tag("<a b=c d='f' g=\"h 'i'\" />")
58
+ assert_equal %(<a b='c' d='f' g='h \\'i\\'' />), node.to_s
59
+ end
60
+
61
+ def test_tag
62
+ assert tag("<tag>").tag?
63
+ end
64
+
65
+ def test_match_tag_as_string
66
+ assert tag("<tag>").match(:tag => "tag")
67
+ assert !tag("<tag>").match(:tag => "b")
68
+ end
69
+
70
+ def test_match_tag_as_regexp
71
+ assert tag("<tag>").match(:tag => /t.g/)
72
+ assert !tag("<tag>").match(:tag => /t[bqs]g/)
73
+ end
74
+
75
+ def test_match_attributes_as_string
76
+ t = tag("<tag a=something b=else />")
77
+ assert t.match(:attributes => {"a" => "something"})
78
+ assert t.match(:attributes => {"b" => "else"})
79
+ end
80
+
81
+ def test_match_attributes_as_regexp
82
+ t = tag("<tag a=something b=else />")
83
+ assert t.match(:attributes => {"a" => /^something$/})
84
+ assert t.match(:attributes => {"b" => /e.*e/})
85
+ assert t.match(:attributes => {"a" => /me..i/, "b" => /.ls.$/})
86
+ end
87
+
88
+ def test_match_attributes_as_number
89
+ t = tag("<tag a=15 b=3.1415 />")
90
+ assert t.match(:attributes => {"a" => 15})
91
+ assert t.match(:attributes => {"b" => 3.1415})
92
+ assert t.match(:attributes => {"a" => 15, "b" => 3.1415})
93
+ end
94
+
95
+ def test_match_attributes_exist
96
+ t = tag("<tag a=15 b=3.1415 />")
97
+ assert t.match(:attributes => {"a" => true})
98
+ assert t.match(:attributes => {"b" => true})
99
+ assert t.match(:attributes => {"a" => true, "b" => true})
100
+ end
101
+
102
+ def test_match_attributes_not_exist
103
+ t = tag("<tag a=15 b=3.1415 />")
104
+ assert t.match(:attributes => {"c" => false})
105
+ assert t.match(:attributes => {"c" => nil})
106
+ assert t.match(:attributes => {"a" => true, "c" => false})
107
+ end
108
+
109
+ def test_match_parent_success
110
+ t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
111
+ assert t.match(:parent => {:tag => "foo", :attributes => {"k" => /v.l/, "j" => false}})
112
+ end
113
+
114
+ def test_match_parent_fail
115
+ t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
116
+ assert !t.match(:parent => {:tag => /kafka/})
117
+ end
118
+
119
+ def test_match_child_success
120
+ t = tag("<tag x:k='something'>")
121
+ tag("<child v=john a=kelly>", t)
122
+ tag("<sib m=vaughn v=james>", t)
123
+ assert t.match(:child => { :tag => "sib", :attributes => {"v" => /j/}})
124
+ assert t.match(:child => { :attributes => {"a" => "kelly"}})
125
+ end
126
+
127
+ def test_match_child_fail
128
+ t = tag("<tag x:k='something'>")
129
+ tag("<child v=john a=kelly>", t)
130
+ tag("<sib m=vaughn v=james>", t)
131
+ assert !t.match(:child => { :tag => "sib", :attributes => {"v" => /r/}})
132
+ assert !t.match(:child => { :attributes => {"v" => false}})
133
+ end
134
+
135
+ def test_match_ancestor_success
136
+ t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
137
+ assert t.match(:ancestor => {:tag => "parent", :attributes => {"a" => /ll/}})
138
+ assert t.match(:ancestor => {:attributes => {"m" => "vaughn"}})
139
+ end
140
+
141
+ def test_match_ancestor_fail
142
+ t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
143
+ assert !t.match(:ancestor => {:tag => /^parent/, :attributes => {"v" => /m/}})
144
+ assert !t.match(:ancestor => {:attributes => {"v" => false}})
145
+ end
146
+
147
+ def test_match_descendant_success
148
+ tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
149
+ assert t.match(:descendant => {:tag => "child", :attributes => {"a" => /ll/}})
150
+ assert t.match(:descendant => {:attributes => {"m" => "vaughn"}})
151
+ end
152
+
153
+ def test_match_descendant_fail
154
+ tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
155
+ assert !t.match(:descendant => {:tag => /^child/, :attributes => {"v" => /m/}})
156
+ assert !t.match(:descendant => {:attributes => {"v" => false}})
157
+ end
158
+
159
+ def test_match_child_count
160
+ t = tag("<tag x:k='something'>")
161
+ tag("hello", t)
162
+ tag("<child v=john a=kelly>", t)
163
+ tag("<sib m=vaughn v=james>", t)
164
+ assert t.match(:children => { :count => 2 })
165
+ assert t.match(:children => { :count => 2..4 })
166
+ assert t.match(:children => { :less_than => 4 })
167
+ assert t.match(:children => { :greater_than => 1 })
168
+ assert !t.match(:children => { :count => 3 })
169
+ end
170
+
171
+ def test_conditions_as_strings
172
+ t = tag("<tag x:k='something'>")
173
+ assert t.match("tag" => "tag")
174
+ assert t.match("attributes" => { "x:k" => "something" })
175
+ assert !t.match("tag" => "gat")
176
+ assert !t.match("attributes" => { "x:j" => "something" })
177
+ end
178
+
179
+ def test_attributes_as_symbols
180
+ t = tag("<child v=john a=kelly>")
181
+ assert t.match(:attributes => { :v => /oh/ })
182
+ assert t.match(:attributes => { :a => /ll/ })
183
+ end
184
+
185
+ def test_match_sibling
186
+ t = tag("<tag x:k='something'>")
187
+ tag("hello", t)
188
+ tag("<span a=b>", t)
189
+ tag("world", t)
190
+ m = tag("<span k=r>", t)
191
+ tag("<span m=l>", t)
192
+
193
+ assert m.match(:sibling => {:tag => "span", :attributes => {:a => true}})
194
+ assert m.match(:sibling => {:tag => "span", :attributes => {:m => true}})
195
+ assert !m.match(:sibling => {:tag => "span", :attributes => {:k => true}})
196
+ end
197
+
198
+ def test_match_sibling_before
199
+ t = tag("<tag x:k='something'>")
200
+ tag("hello", t)
201
+ tag("<span a=b>", t)
202
+ tag("world", t)
203
+ m = tag("<span k=r>", t)
204
+ tag("<span m=l>", t)
205
+
206
+ assert m.match(:before => {:tag => "span", :attributes => {:m => true}})
207
+ assert !m.match(:before => {:tag => "span", :attributes => {:a => true}})
208
+ assert !m.match(:before => {:tag => "span", :attributes => {:k => true}})
209
+ end
210
+
211
+ def test_match_sibling_after
212
+ t = tag("<tag x:k='something'>")
213
+ tag("hello", t)
214
+ tag("<span a=b>", t)
215
+ tag("world", t)
216
+ m = tag("<span k=r>", t)
217
+ tag("<span m=l>", t)
218
+
219
+ assert m.match(:after => {:tag => "span", :attributes => {:a => true}})
220
+ assert !m.match(:after => {:tag => "span", :attributes => {:m => true}})
221
+ assert !m.match(:after => {:tag => "span", :attributes => {:k => true}})
222
+ end
223
+
224
+ def test_to_s
225
+ t = tag("<b x='foo'>")
226
+ tag("hello", t)
227
+ tag("<hr />", t)
228
+ assert_equal %(<b x="foo">hello<hr /></b>), t.to_s
229
+ end
230
+
231
+ private
232
+
233
+ def tag(content, parent=nil)
234
+ node = HTML::Node.parse(parent,0,0,content)
235
+ parent.children << node if parent
236
+ node
237
+ end
238
+ end
@@ -0,0 +1,50 @@
1
+ require 'abstract_unit'
2
+
3
+ class TextNodeTest < Test::Unit::TestCase
4
+ def setup
5
+ @node = HTML::Text.new(nil, 0, 0, "hello, howdy, aloha, annyeong")
6
+ end
7
+
8
+ def test_to_s
9
+ assert_equal "hello, howdy, aloha, annyeong", @node.to_s
10
+ end
11
+
12
+ def test_find_string
13
+ assert_equal @node, @node.find("hello, howdy, aloha, annyeong")
14
+ assert_equal false, @node.find("bogus")
15
+ end
16
+
17
+ def test_find_regexp
18
+ assert_equal @node, @node.find(/an+y/)
19
+ assert_nil @node.find(/b/)
20
+ end
21
+
22
+ def test_find_hash
23
+ assert_equal @node, @node.find(:content => /howdy/)
24
+ assert_nil @node.find(:content => /^howdy$/)
25
+ assert_equal false, @node.find(:content => "howdy")
26
+ end
27
+
28
+ def test_find_other
29
+ assert_nil @node.find(:hello)
30
+ end
31
+
32
+ def test_match_string
33
+ assert @node.match("hello, howdy, aloha, annyeong")
34
+ assert_equal false, @node.match("bogus")
35
+ end
36
+
37
+ def test_match_regexp
38
+ assert_not_nil @node, @node.match(/an+y/)
39
+ assert_nil @node.match(/b/)
40
+ end
41
+
42
+ def test_match_hash
43
+ assert_not_nil @node, @node.match(:content => "howdy")
44
+ assert_nil @node.match(:content => /^howdy$/)
45
+ end
46
+
47
+ def test_match_other
48
+ assert_nil @node.match(:hello)
49
+ end
50
+ end