eactionpack 2.1.2

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 (338) hide show
  1. data/CHANGELOG +7 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +469 -0
  4. data/RUNNING_UNIT_TESTS +24 -0
  5. data/Rakefile +146 -0
  6. data/install.rb +30 -0
  7. data/lib/action_controller.rb +79 -0
  8. data/lib/action_controller/assertions.rb +69 -0
  9. data/lib/action_controller/assertions/dom_assertions.rb +39 -0
  10. data/lib/action_controller/assertions/model_assertions.rb +20 -0
  11. data/lib/action_controller/assertions/response_assertions.rb +172 -0
  12. data/lib/action_controller/assertions/routing_assertions.rb +146 -0
  13. data/lib/action_controller/assertions/selector_assertions.rb +491 -0
  14. data/lib/action_controller/assertions/tag_assertions.rb +130 -0
  15. data/lib/action_controller/base.rb +1288 -0
  16. data/lib/action_controller/benchmarking.rb +94 -0
  17. data/lib/action_controller/caching.rb +72 -0
  18. data/lib/action_controller/caching/actions.rb +144 -0
  19. data/lib/action_controller/caching/fragments.rb +138 -0
  20. data/lib/action_controller/caching/pages.rb +154 -0
  21. data/lib/action_controller/caching/sql_cache.rb +18 -0
  22. data/lib/action_controller/caching/sweeping.rb +97 -0
  23. data/lib/action_controller/cgi_ext.rb +16 -0
  24. data/lib/action_controller/cgi_ext/cookie.rb +110 -0
  25. data/lib/action_controller/cgi_ext/query_extension.rb +22 -0
  26. data/lib/action_controller/cgi_ext/session.rb +73 -0
  27. data/lib/action_controller/cgi_ext/stdinput.rb +24 -0
  28. data/lib/action_controller/cgi_process.rb +223 -0
  29. data/lib/action_controller/components.rb +166 -0
  30. data/lib/action_controller/cookies.rb +96 -0
  31. data/lib/action_controller/dispatcher.rb +162 -0
  32. data/lib/action_controller/filters.rb +642 -0
  33. data/lib/action_controller/flash.rb +172 -0
  34. data/lib/action_controller/headers.rb +31 -0
  35. data/lib/action_controller/helpers.rb +221 -0
  36. data/lib/action_controller/http_authentication.rb +124 -0
  37. data/lib/action_controller/integration.rb +634 -0
  38. data/lib/action_controller/layout.rb +309 -0
  39. data/lib/action_controller/mime_responds.rb +173 -0
  40. data/lib/action_controller/mime_type.rb +186 -0
  41. data/lib/action_controller/mime_types.rb +20 -0
  42. data/lib/action_controller/polymorphic_routes.rb +191 -0
  43. data/lib/action_controller/record_identifier.rb +102 -0
  44. data/lib/action_controller/request.rb +764 -0
  45. data/lib/action_controller/request_forgery_protection.rb +140 -0
  46. data/lib/action_controller/request_profiler.rb +169 -0
  47. data/lib/action_controller/rescue.rb +258 -0
  48. data/lib/action_controller/resources.rb +572 -0
  49. data/lib/action_controller/response.rb +76 -0
  50. data/lib/action_controller/routing.rb +387 -0
  51. data/lib/action_controller/routing/builder.rb +203 -0
  52. data/lib/action_controller/routing/optimisations.rb +120 -0
  53. data/lib/action_controller/routing/recognition_optimisation.rb +162 -0
  54. data/lib/action_controller/routing/route.rb +240 -0
  55. data/lib/action_controller/routing/route_set.rb +436 -0
  56. data/lib/action_controller/routing/routing_ext.rb +46 -0
  57. data/lib/action_controller/routing/segments.rb +283 -0
  58. data/lib/action_controller/session/active_record_store.rb +340 -0
  59. data/lib/action_controller/session/cookie_store.rb +166 -0
  60. data/lib/action_controller/session/drb_server.rb +32 -0
  61. data/lib/action_controller/session/drb_store.rb +35 -0
  62. data/lib/action_controller/session/mem_cache_store.rb +98 -0
  63. data/lib/action_controller/session_management.rb +158 -0
  64. data/lib/action_controller/status_codes.rb +88 -0
  65. data/lib/action_controller/streaming.rb +155 -0
  66. data/lib/action_controller/templates/rescues/_request_and_response.erb +24 -0
  67. data/lib/action_controller/templates/rescues/_trace.erb +26 -0
  68. data/lib/action_controller/templates/rescues/diagnostics.erb +11 -0
  69. data/lib/action_controller/templates/rescues/layout.erb +29 -0
  70. data/lib/action_controller/templates/rescues/missing_template.erb +2 -0
  71. data/lib/action_controller/templates/rescues/routing_error.erb +10 -0
  72. data/lib/action_controller/templates/rescues/template_error.erb +21 -0
  73. data/lib/action_controller/templates/rescues/unknown_action.erb +2 -0
  74. data/lib/action_controller/test_case.rb +83 -0
  75. data/lib/action_controller/test_process.rb +526 -0
  76. data/lib/action_controller/url_rewriter.rb +142 -0
  77. data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
  78. data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
  79. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +173 -0
  80. data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
  81. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
  82. data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
  83. data/lib/action_controller/verification.rb +130 -0
  84. data/lib/action_pack.rb +24 -0
  85. data/lib/action_pack/version.rb +9 -0
  86. data/lib/action_view.rb +44 -0
  87. data/lib/action_view/base.rb +335 -0
  88. data/lib/action_view/helpers/active_record_helper.rb +276 -0
  89. data/lib/action_view/helpers/asset_tag_helper.rb +599 -0
  90. data/lib/action_view/helpers/atom_feed_helper.rb +143 -0
  91. data/lib/action_view/helpers/benchmark_helper.rb +33 -0
  92. data/lib/action_view/helpers/cache_helper.rb +40 -0
  93. data/lib/action_view/helpers/capture_helper.rb +161 -0
  94. data/lib/action_view/helpers/date_helper.rb +711 -0
  95. data/lib/action_view/helpers/debug_helper.rb +31 -0
  96. data/lib/action_view/helpers/form_helper.rb +767 -0
  97. data/lib/action_view/helpers/form_options_helper.rb +458 -0
  98. data/lib/action_view/helpers/form_tag_helper.rb +458 -0
  99. data/lib/action_view/helpers/javascript_helper.rb +148 -0
  100. data/lib/action_view/helpers/number_helper.rb +186 -0
  101. data/lib/action_view/helpers/record_identification_helper.rb +20 -0
  102. data/lib/action_view/helpers/record_tag_helper.rb +59 -0
  103. data/lib/action_view/helpers/sanitize_helper.rb +229 -0
  104. data/lib/action_view/helpers/tag_helper.rb +134 -0
  105. data/lib/action_view/helpers/text_helper.rb +507 -0
  106. data/lib/action_view/helpers/url_helper.rb +573 -0
  107. data/lib/action_view/inline_template.rb +20 -0
  108. data/lib/action_view/partial_template.rb +70 -0
  109. data/lib/action_view/partials.rb +158 -0
  110. data/lib/action_view/template.rb +125 -0
  111. data/lib/action_view/template_error.rb +110 -0
  112. data/lib/action_view/template_finder.rb +176 -0
  113. data/lib/action_view/template_handler.rb +34 -0
  114. data/lib/action_view/template_handlers/builder.rb +27 -0
  115. data/lib/action_view/template_handlers/compilable.rb +128 -0
  116. data/lib/action_view/template_handlers/erb.rb +56 -0
  117. data/lib/action_view/test_case.rb +58 -0
  118. data/lib/actionpack.rb +1 -0
  119. data/test/abstract_unit.rb +36 -0
  120. data/test/active_record_unit.rb +105 -0
  121. data/test/activerecord/active_record_store_test.rb +141 -0
  122. data/test/activerecord/render_partial_with_record_identification_test.rb +191 -0
  123. data/test/adv_attr_test.rb +20 -0
  124. data/test/controller/action_pack_assertions_test.rb +543 -0
  125. data/test/controller/addresses_render_test.rb +43 -0
  126. data/test/controller/assert_select_test.rb +331 -0
  127. data/test/controller/base_test.rb +219 -0
  128. data/test/controller/benchmark_test.rb +32 -0
  129. data/test/controller/caching_test.rb +581 -0
  130. data/test/controller/capture_test.rb +89 -0
  131. data/test/controller/cgi_test.rb +116 -0
  132. data/test/controller/components_test.rb +140 -0
  133. data/test/controller/content_type_test.rb +139 -0
  134. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  135. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  136. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  137. data/test/controller/cookie_test.rb +146 -0
  138. data/test/controller/custom_handler_test.rb +45 -0
  139. data/test/controller/deprecation/deprecated_base_methods_test.rb +37 -0
  140. data/test/controller/dispatcher_test.rb +105 -0
  141. data/test/controller/fake_controllers.rb +33 -0
  142. data/test/controller/fake_models.rb +11 -0
  143. data/test/controller/filter_params_test.rb +49 -0
  144. data/test/controller/filters_test.rb +881 -0
  145. data/test/controller/flash_test.rb +146 -0
  146. data/test/controller/header_test.rb +14 -0
  147. data/test/controller/helper_test.rb +210 -0
  148. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  149. data/test/controller/html-scanner/document_test.rb +148 -0
  150. data/test/controller/html-scanner/node_test.rb +89 -0
  151. data/test/controller/html-scanner/sanitizer_test.rb +269 -0
  152. data/test/controller/html-scanner/tag_node_test.rb +238 -0
  153. data/test/controller/html-scanner/text_node_test.rb +50 -0
  154. data/test/controller/html-scanner/tokenizer_test.rb +131 -0
  155. data/test/controller/http_authentication_test.rb +54 -0
  156. data/test/controller/integration_test.rb +252 -0
  157. data/test/controller/integration_upload_test.rb +43 -0
  158. data/test/controller/layout_test.rb +255 -0
  159. data/test/controller/mime_responds_test.rb +514 -0
  160. data/test/controller/mime_type_test.rb +84 -0
  161. data/test/controller/new_render_test.rb +843 -0
  162. data/test/controller/polymorphic_routes_test.rb +174 -0
  163. data/test/controller/record_identifier_test.rb +139 -0
  164. data/test/controller/redirect_test.rb +289 -0
  165. data/test/controller/render_test.rb +484 -0
  166. data/test/controller/request_forgery_protection_test.rb +305 -0
  167. data/test/controller/request_test.rb +928 -0
  168. data/test/controller/rescue_test.rb +517 -0
  169. data/test/controller/resources_test.rb +873 -0
  170. data/test/controller/routing_test.rb +2464 -0
  171. data/test/controller/selector_test.rb +628 -0
  172. data/test/controller/send_file_test.rb +138 -0
  173. data/test/controller/session/cookie_store_test.rb +258 -0
  174. data/test/controller/session/mem_cache_store_test.rb +181 -0
  175. data/test/controller/session_fixation_test.rb +89 -0
  176. data/test/controller/session_management_test.rb +178 -0
  177. data/test/controller/test_test.rb +695 -0
  178. data/test/controller/url_rewriter_test.rb +310 -0
  179. data/test/controller/verification_test.rb +270 -0
  180. data/test/controller/view_paths_test.rb +140 -0
  181. data/test/controller/webservice_test.rb +229 -0
  182. data/test/fixtures/addresses/list.erb +1 -0
  183. data/test/fixtures/bad_customers/_bad_customer.html.erb +1 -0
  184. data/test/fixtures/companies.yml +24 -0
  185. data/test/fixtures/company.rb +10 -0
  186. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
  187. data/test/fixtures/content_type/render_default_for_js.js.erb +1 -0
  188. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
  189. data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
  190. data/test/fixtures/customers/_customer.html.erb +1 -0
  191. data/test/fixtures/db_definitions/sqlite.sql +49 -0
  192. data/test/fixtures/developer.rb +9 -0
  193. data/test/fixtures/developers.yml +21 -0
  194. data/test/fixtures/developers_projects.yml +13 -0
  195. data/test/fixtures/fun/games/hello_world.erb +1 -0
  196. data/test/fixtures/functional_caching/_partial.erb +3 -0
  197. data/test/fixtures/functional_caching/fragment_cached.html.erb +2 -0
  198. data/test/fixtures/functional_caching/html_fragment_cached_with_partial.html.erb +1 -0
  199. data/test/fixtures/functional_caching/js_fragment_cached_with_partial.js.rjs +1 -0
  200. data/test/fixtures/good_customers/_good_customer.html.erb +1 -0
  201. data/test/fixtures/helpers/abc_helper.rb +5 -0
  202. data/test/fixtures/helpers/fun/games_helper.rb +3 -0
  203. data/test/fixtures/helpers/fun/pdf_helper.rb +3 -0
  204. data/test/fixtures/layout_tests/alt/hello.rhtml +1 -0
  205. data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
  206. data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
  207. data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
  208. data/test/fixtures/layout_tests/layouts/multiple_extensions.html.erb +1 -0
  209. data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
  210. data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
  211. data/test/fixtures/layouts/block_with_layout.erb +3 -0
  212. data/test/fixtures/layouts/builder.builder +3 -0
  213. data/test/fixtures/layouts/partial_with_layout.erb +3 -0
  214. data/test/fixtures/layouts/standard.erb +1 -0
  215. data/test/fixtures/layouts/talk_from_action.erb +2 -0
  216. data/test/fixtures/layouts/yield.erb +2 -0
  217. data/test/fixtures/mascot.rb +3 -0
  218. data/test/fixtures/mascots.yml +4 -0
  219. data/test/fixtures/mascots/_mascot.html.erb +1 -0
  220. data/test/fixtures/multipart/binary_file +0 -0
  221. data/test/fixtures/multipart/boundary_problem_file +10 -0
  222. data/test/fixtures/multipart/bracketed_param +5 -0
  223. data/test/fixtures/multipart/large_text_file +10 -0
  224. data/test/fixtures/multipart/mixed_files +0 -0
  225. data/test/fixtures/multipart/mona_lisa.jpg +0 -0
  226. data/test/fixtures/multipart/single_parameter +5 -0
  227. data/test/fixtures/multipart/text_file +10 -0
  228. data/test/fixtures/override/test/hello_world.erb +1 -0
  229. data/test/fixtures/override2/layouts/test/sub.erb +1 -0
  230. data/test/fixtures/post_test/layouts/post.html.erb +1 -0
  231. data/test/fixtures/post_test/layouts/super_post.iphone.erb +1 -0
  232. data/test/fixtures/post_test/post/index.html.erb +1 -0
  233. data/test/fixtures/post_test/post/index.iphone.erb +1 -0
  234. data/test/fixtures/post_test/super_post/index.html.erb +1 -0
  235. data/test/fixtures/post_test/super_post/index.iphone.erb +1 -0
  236. data/test/fixtures/project.rb +3 -0
  237. data/test/fixtures/projects.yml +7 -0
  238. data/test/fixtures/public/404.html +1 -0
  239. data/test/fixtures/public/500.html +1 -0
  240. data/test/fixtures/public/images/rails.png +0 -0
  241. data/test/fixtures/public/javascripts/application.js +1 -0
  242. data/test/fixtures/public/javascripts/bank.js +1 -0
  243. data/test/fixtures/public/javascripts/robber.js +1 -0
  244. data/test/fixtures/public/javascripts/version.1.0.js +1 -0
  245. data/test/fixtures/public/stylesheets/bank.css +1 -0
  246. data/test/fixtures/public/stylesheets/robber.css +1 -0
  247. data/test/fixtures/public/stylesheets/version.1.0.css +1 -0
  248. data/test/fixtures/replies.yml +15 -0
  249. data/test/fixtures/reply.rb +7 -0
  250. data/test/fixtures/respond_to/all_types_with_layout.html.erb +1 -0
  251. data/test/fixtures/respond_to/custom_constant_handling_without_block.mobile.erb +1 -0
  252. data/test/fixtures/respond_to/iphone_with_html_response_type.html.erb +1 -0
  253. data/test/fixtures/respond_to/iphone_with_html_response_type.iphone.erb +1 -0
  254. data/test/fixtures/respond_to/layouts/missing.html.erb +1 -0
  255. data/test/fixtures/respond_to/layouts/standard.html.erb +1 -0
  256. data/test/fixtures/respond_to/layouts/standard.iphone.erb +1 -0
  257. data/test/fixtures/respond_to/using_defaults.html.erb +1 -0
  258. data/test/fixtures/respond_to/using_defaults.js.rjs +1 -0
  259. data/test/fixtures/respond_to/using_defaults.xml.builder +1 -0
  260. data/test/fixtures/respond_to/using_defaults_with_type_list.html.erb +1 -0
  261. data/test/fixtures/respond_to/using_defaults_with_type_list.js.rjs +1 -0
  262. data/test/fixtures/respond_to/using_defaults_with_type_list.xml.builder +1 -0
  263. data/test/fixtures/scope/test/modgreet.erb +1 -0
  264. data/test/fixtures/shared.html.erb +1 -0
  265. data/test/fixtures/symlink_parent/symlinked_layout.erb +5 -0
  266. data/test/fixtures/test/_customer.erb +1 -0
  267. data/test/fixtures/test/_customer_counter.erb +1 -0
  268. data/test/fixtures/test/_customer_greeting.erb +1 -0
  269. data/test/fixtures/test/_form.erb +1 -0
  270. data/test/fixtures/test/_hash_greeting.erb +1 -0
  271. data/test/fixtures/test/_hash_object.erb +2 -0
  272. data/test/fixtures/test/_hello.builder +1 -0
  273. data/test/fixtures/test/_labelling_form.erb +1 -0
  274. data/test/fixtures/test/_layout_for_partial.html.erb +3 -0
  275. data/test/fixtures/test/_partial.erb +1 -0
  276. data/test/fixtures/test/_partial.html.erb +1 -0
  277. data/test/fixtures/test/_partial.js.erb +1 -0
  278. data/test/fixtures/test/_partial_for_use_in_layout.html.erb +1 -0
  279. data/test/fixtures/test/_partial_only.erb +1 -0
  280. data/test/fixtures/test/_person.erb +2 -0
  281. data/test/fixtures/test/_raise.html.erb +1 -0
  282. data/test/fixtures/test/action_talk_to_layout.erb +2 -0
  283. data/test/fixtures/test/block_content_for.erb +2 -0
  284. data/test/fixtures/test/calling_partial_with_layout.html.erb +1 -0
  285. data/test/fixtures/test/capturing.erb +4 -0
  286. data/test/fixtures/test/content_for.erb +2 -0
  287. data/test/fixtures/test/content_for_concatenated.erb +3 -0
  288. data/test/fixtures/test/content_for_with_parameter.erb +2 -0
  289. data/test/fixtures/test/delete_with_js.rjs +2 -0
  290. data/test/fixtures/test/dot.directory/render_file_with_ivar.erb +1 -0
  291. data/test/fixtures/test/enum_rjs_test.rjs +6 -0
  292. data/test/fixtures/test/erb_content_for.erb +2 -0
  293. data/test/fixtures/test/formatted_html_erb.html.erb +1 -0
  294. data/test/fixtures/test/formatted_xml_erb.builder +1 -0
  295. data/test/fixtures/test/formatted_xml_erb.html.erb +1 -0
  296. data/test/fixtures/test/formatted_xml_erb.xml.erb +1 -0
  297. data/test/fixtures/test/greeting.erb +1 -0
  298. data/test/fixtures/test/greeting.js.rjs +1 -0
  299. data/test/fixtures/test/hello.builder +4 -0
  300. data/test/fixtures/test/hello_world.erb +1 -0
  301. data/test/fixtures/test/hello_world_container.builder +3 -0
  302. data/test/fixtures/test/hello_world_from_rxml.builder +4 -0
  303. data/test/fixtures/test/hello_world_with_layout_false.erb +1 -0
  304. data/test/fixtures/test/hello_xml_world.builder +11 -0
  305. data/test/fixtures/test/list.erb +1 -0
  306. data/test/fixtures/test/non_erb_block_content_for.builder +4 -0
  307. data/test/fixtures/test/potential_conflicts.erb +4 -0
  308. data/test/fixtures/test/render_file_from_template.html.erb +1 -0
  309. data/test/fixtures/test/render_file_with_ivar.erb +1 -0
  310. data/test/fixtures/test/render_file_with_locals.erb +1 -0
  311. data/test/fixtures/test/render_to_string_test.erb +1 -0
  312. data/test/fixtures/test/update_element_with_capture.erb +9 -0
  313. data/test/fixtures/test/using_layout_around_block.html.erb +1 -0
  314. data/test/fixtures/topic.rb +3 -0
  315. data/test/fixtures/topics.yml +22 -0
  316. data/test/fixtures/topics/_topic.html.erb +1 -0
  317. data/test/template/active_record_helper_test.rb +268 -0
  318. data/test/template/asset_tag_helper_test.rb +514 -0
  319. data/test/template/atom_feed_helper_test.rb +179 -0
  320. data/test/template/benchmark_helper_test.rb +60 -0
  321. data/test/template/date_helper_test.rb +1791 -0
  322. data/test/template/deprecated_erb_variable_test.rb +9 -0
  323. data/test/template/erb_util_test.rb +24 -0
  324. data/test/template/form_helper_test.rb +885 -0
  325. data/test/template/form_options_helper_test.rb +1333 -0
  326. data/test/template/form_tag_helper_test.rb +272 -0
  327. data/test/template/javascript_helper_test.rb +73 -0
  328. data/test/template/number_helper_test.rb +97 -0
  329. data/test/template/record_tag_helper_test.rb +54 -0
  330. data/test/template/sanitize_helper_test.rb +48 -0
  331. data/test/template/tag_helper_test.rb +77 -0
  332. data/test/template/template_finder_test.rb +73 -0
  333. data/test/template/template_object_test.rb +95 -0
  334. data/test/template/test_test.rb +56 -0
  335. data/test/template/text_helper_test.rb +367 -0
  336. data/test/template/url_helper_test.rb +544 -0
  337. data/test/testing_sandbox.rb +15 -0
  338. metadata +469 -0
@@ -0,0 +1,526 @@
1
+ require 'action_controller/assertions'
2
+ require 'action_controller/test_case'
3
+
4
+ module ActionController #:nodoc:
5
+ class Base
6
+ # Process a test request called with a TestRequest object.
7
+ def self.process_test(request)
8
+ new.process_test(request)
9
+ end
10
+
11
+ def process_test(request) #:nodoc:
12
+ process(request, TestResponse.new)
13
+ end
14
+
15
+ def process_with_test(*args)
16
+ returning process_without_test(*args) do
17
+ add_variables_to_assigns
18
+ end
19
+ end
20
+
21
+ alias_method_chain :process, :test
22
+ end
23
+
24
+ class TestRequest < AbstractRequest #:nodoc:
25
+ attr_accessor :cookies, :session_options
26
+ attr_accessor :query_parameters, :request_parameters, :path, :session, :env
27
+ attr_accessor :host, :user_agent
28
+
29
+ def initialize(query_parameters = nil, request_parameters = nil, session = nil)
30
+ @query_parameters = query_parameters || {}
31
+ @request_parameters = request_parameters || {}
32
+ @session = session || TestSession.new
33
+
34
+ initialize_containers
35
+ initialize_default_values
36
+
37
+ super()
38
+ end
39
+
40
+ def reset_session
41
+ @session = TestSession.new
42
+ end
43
+
44
+ # Wraps raw_post in a StringIO.
45
+ def body
46
+ StringIO.new(raw_post)
47
+ end
48
+
49
+ # Either the RAW_POST_DATA environment variable or the URL-encoded request
50
+ # parameters.
51
+ def raw_post
52
+ env['RAW_POST_DATA'] ||= returning(url_encoded_request_parameters) { |b| b.force_encoding(Encoding::BINARY) if b.respond_to?(:force_encoding) }
53
+ end
54
+
55
+ def port=(number)
56
+ @env["SERVER_PORT"] = number.to_i
57
+ @port_as_int = nil
58
+ end
59
+
60
+ def action=(action_name)
61
+ @query_parameters.update({ "action" => action_name })
62
+ @parameters = nil
63
+ end
64
+
65
+ # Used to check AbstractRequest's request_uri functionality.
66
+ # Disables the use of @path and @request_uri so superclass can handle those.
67
+ def set_REQUEST_URI(value)
68
+ @env["REQUEST_URI"] = value
69
+ @request_uri = nil
70
+ @path = nil
71
+ end
72
+
73
+ def request_uri=(uri)
74
+ @request_uri = uri
75
+ @path = uri.split("?").first
76
+ end
77
+
78
+ def accept=(mime_types)
79
+ @env["HTTP_ACCEPT"] = Array(mime_types).collect { |mime_types| mime_types.to_s }.join(",")
80
+ end
81
+
82
+ def remote_addr=(addr)
83
+ @env['REMOTE_ADDR'] = addr
84
+ end
85
+
86
+ def remote_addr
87
+ @env['REMOTE_ADDR']
88
+ end
89
+
90
+ def request_uri
91
+ @request_uri || super
92
+ end
93
+
94
+ def path
95
+ @path || super
96
+ end
97
+
98
+ def assign_parameters(controller_path, action, parameters)
99
+ parameters = parameters.symbolize_keys.merge(:controller => controller_path, :action => action)
100
+ extra_keys = ActionController::Routing::Routes.extra_keys(parameters)
101
+ non_path_parameters = get? ? query_parameters : request_parameters
102
+ parameters.each do |key, value|
103
+ if value.is_a? Fixnum
104
+ value = value.to_s
105
+ elsif value.is_a? Array
106
+ value = ActionController::Routing::PathSegment::Result.new(value)
107
+ end
108
+
109
+ if extra_keys.include?(key.to_sym)
110
+ non_path_parameters[key] = value
111
+ else
112
+ path_parameters[key.to_s] = value
113
+ end
114
+ end
115
+ @parameters = nil # reset TestRequest#parameters to use the new path_parameters
116
+ end
117
+
118
+ def recycle!
119
+ self.request_parameters = {}
120
+ self.query_parameters = {}
121
+ self.path_parameters = {}
122
+ @request_method, @accepts, @content_type = nil, nil, nil
123
+ end
124
+
125
+ def referer
126
+ @env["HTTP_REFERER"]
127
+ end
128
+
129
+ private
130
+ def initialize_containers
131
+ @env, @cookies = {}, {}
132
+ end
133
+
134
+ def initialize_default_values
135
+ @host = "test.host"
136
+ @request_uri = "/"
137
+ @user_agent = "Rails Testing"
138
+ self.remote_addr = "0.0.0.0"
139
+ @env["SERVER_PORT"] = 80
140
+ @env['REQUEST_METHOD'] = "GET"
141
+ end
142
+
143
+ def url_encoded_request_parameters
144
+ params = self.request_parameters.dup
145
+
146
+ %w(controller action only_path).each do |k|
147
+ params.delete(k)
148
+ params.delete(k.to_sym)
149
+ end
150
+
151
+ params.to_query
152
+ end
153
+ end
154
+
155
+ # A refactoring of TestResponse to allow the same behavior to be applied
156
+ # to the "real" CgiResponse class in integration tests.
157
+ module TestResponseBehavior #:nodoc:
158
+ # The response code of the request
159
+ def response_code
160
+ headers['Status'][0,3].to_i rescue 0
161
+ end
162
+
163
+ # Returns a String to ensure compatibility with Net::HTTPResponse
164
+ def code
165
+ headers['Status'].to_s.split(' ')[0]
166
+ end
167
+
168
+ def message
169
+ headers['Status'].to_s.split(' ',2)[1]
170
+ end
171
+
172
+ # Was the response successful?
173
+ def success?
174
+ (200..299).include?(response_code)
175
+ end
176
+
177
+ # Was the URL not found?
178
+ def missing?
179
+ response_code == 404
180
+ end
181
+
182
+ # Were we redirected?
183
+ def redirect?
184
+ (300..399).include?(response_code)
185
+ end
186
+
187
+ # Was there a server-side error?
188
+ def error?
189
+ (500..599).include?(response_code)
190
+ end
191
+
192
+ alias_method :server_error?, :error?
193
+
194
+ # Returns the redirection location or nil
195
+ def redirect_url
196
+ headers['Location']
197
+ end
198
+
199
+ # Does the redirect location match this regexp pattern?
200
+ def redirect_url_match?( pattern )
201
+ return false if redirect_url.nil?
202
+ p = Regexp.new(pattern) if pattern.class == String
203
+ p = pattern if pattern.class == Regexp
204
+ return false if p.nil?
205
+ p.match(redirect_url) != nil
206
+ end
207
+
208
+ # Returns the template path of the file which was used to
209
+ # render this response (or nil)
210
+ def rendered_file(with_controller=false)
211
+ unless template.first_render.nil?
212
+ unless with_controller
213
+ template.first_render
214
+ else
215
+ template.first_render.split('/').last || template.first_render
216
+ end
217
+ end
218
+ end
219
+
220
+ # Was this template rendered by a file?
221
+ def rendered_with_file?
222
+ !rendered_file.nil?
223
+ end
224
+
225
+ # A shortcut to the flash. Returns an empyt hash if no session flash exists.
226
+ def flash
227
+ session['flash'] || {}
228
+ end
229
+
230
+ # Do we have a flash?
231
+ def has_flash?
232
+ !session['flash'].empty?
233
+ end
234
+
235
+ # Do we have a flash that has contents?
236
+ def has_flash_with_contents?
237
+ !flash.empty?
238
+ end
239
+
240
+ # Does the specified flash object exist?
241
+ def has_flash_object?(name=nil)
242
+ !flash[name].nil?
243
+ end
244
+
245
+ # Does the specified object exist in the session?
246
+ def has_session_object?(name=nil)
247
+ !session[name].nil?
248
+ end
249
+
250
+ # A shortcut to the template.assigns
251
+ def template_objects
252
+ template.assigns || {}
253
+ end
254
+
255
+ # Does the specified template object exist?
256
+ def has_template_object?(name=nil)
257
+ !template_objects[name].nil?
258
+ end
259
+
260
+ # Returns the response cookies, converted to a Hash of (name => CGI::Cookie) pairs
261
+ #
262
+ # assert_equal ['AuthorOfNewPage'], r.cookies['author'].value
263
+ def cookies
264
+ headers['cookie'].inject({}) { |hash, cookie| hash[cookie.name] = cookie; hash }
265
+ end
266
+
267
+ # Returns binary content (downloadable file), converted to a String
268
+ def binary_content
269
+ raise "Response body is not a Proc: #{body.inspect}" unless body.kind_of?(Proc)
270
+ require 'stringio'
271
+
272
+ sio = StringIO.new
273
+ body.call(self, sio)
274
+
275
+ sio.rewind
276
+ sio.read
277
+ end
278
+ end
279
+
280
+ class TestResponse < AbstractResponse #:nodoc:
281
+ include TestResponseBehavior
282
+ end
283
+
284
+ class TestSession #:nodoc:
285
+ attr_accessor :session_id
286
+
287
+ def initialize(attributes = nil)
288
+ @session_id = ''
289
+ @attributes = attributes.nil? ? nil : attributes.stringify_keys
290
+ @saved_attributes = nil
291
+ end
292
+
293
+ def data
294
+ @attributes ||= @saved_attributes || {}
295
+ end
296
+
297
+ def [](key)
298
+ data[key.to_s]
299
+ end
300
+
301
+ def []=(key, value)
302
+ data[key.to_s] = value
303
+ end
304
+
305
+ def update
306
+ @saved_attributes = @attributes
307
+ end
308
+
309
+ def delete
310
+ @attributes = nil
311
+ end
312
+
313
+ def close
314
+ update
315
+ delete
316
+ end
317
+ end
318
+
319
+ # Essentially generates a modified Tempfile object similar to the object
320
+ # you'd get from the standard library CGI module in a multipart
321
+ # request. This means you can use an ActionController::TestUploadedFile
322
+ # object in the params of a test request in order to simulate
323
+ # a file upload.
324
+ #
325
+ # Usage example, within a functional test:
326
+ # post :change_avatar, :avatar => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/spongebob.png', 'image/png')
327
+ #
328
+ # Pass a true third parameter to ensure the uploaded file is opened in binary mode (only required for Windows):
329
+ # post :change_avatar, :avatar => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/spongebob.png', 'image/png', :binary)
330
+ require 'tempfile'
331
+ class TestUploadedFile
332
+ # The filename, *not* including the path, of the "uploaded" file
333
+ attr_reader :original_filename
334
+
335
+ # The content type of the "uploaded" file
336
+ attr_accessor :content_type
337
+
338
+ def initialize(path, content_type = Mime::TEXT, binary = false)
339
+ raise "#{path} file does not exist" unless File.exist?(path)
340
+ @content_type = content_type
341
+ @original_filename = path.sub(/^.*#{File::SEPARATOR}([^#{File::SEPARATOR}]+)$/) { $1 }
342
+ @tempfile = Tempfile.new(@original_filename)
343
+ @tempfile.set_encoding(Encoding::BINARY) if @tempfile.respond_to?(:set_encoding)
344
+ @tempfile.binmode if binary
345
+ FileUtils.copy_file(path, @tempfile.path)
346
+ end
347
+
348
+ def path #:nodoc:
349
+ @tempfile.path
350
+ end
351
+
352
+ alias local_path path
353
+
354
+ def method_missing(method_name, *args, &block) #:nodoc:
355
+ @tempfile.send!(method_name, *args, &block)
356
+ end
357
+ end
358
+
359
+ module TestProcess
360
+ def self.included(base)
361
+ # execute the request simulating a specific HTTP method and set/volley the response
362
+ %w( get post put delete head ).each do |method|
363
+ base.class_eval <<-EOV, __FILE__, __LINE__
364
+ def #{method}(action, parameters = nil, session = nil, flash = nil)
365
+ @request.env['REQUEST_METHOD'] = "#{method.upcase}" if defined?(@request)
366
+ process(action, parameters, session, flash)
367
+ end
368
+ EOV
369
+ end
370
+ end
371
+
372
+ # execute the request and set/volley the response
373
+ def process(action, parameters = nil, session = nil, flash = nil)
374
+ # Sanity check for required instance variables so we can give an
375
+ # understandable error message.
376
+ %w(@controller @request @response).each do |iv_name|
377
+ if !(instance_variable_names.include?(iv_name) || instance_variable_names.include?(iv_name.to_sym)) || instance_variable_get(iv_name).nil?
378
+ raise "#{iv_name} is nil: make sure you set it in your test's setup method."
379
+ end
380
+ end
381
+
382
+ @request.recycle!
383
+
384
+ @html_document = nil
385
+ @request.env['REQUEST_METHOD'] ||= "GET"
386
+ @request.action = action.to_s
387
+
388
+ parameters ||= {}
389
+ @request.assign_parameters(@controller.class.controller_path, action.to_s, parameters)
390
+
391
+ @request.session = ActionController::TestSession.new(session) unless session.nil?
392
+ @request.session["flash"] = ActionController::Flash::FlashHash.new.update(flash) if flash
393
+ build_request_uri(action, parameters)
394
+ @controller.process(@request, @response)
395
+ end
396
+
397
+ def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
398
+ @request.env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
399
+ @request.env['HTTP_ACCEPT'] = 'text/javascript, text/html, application/xml, text/xml, */*'
400
+ returning send!(request_method, action, parameters, session, flash) do
401
+ @request.env.delete 'HTTP_X_REQUESTED_WITH'
402
+ @request.env.delete 'HTTP_ACCEPT'
403
+ end
404
+ end
405
+ alias xhr :xml_http_request
406
+
407
+ def follow_redirect
408
+ redirected_controller = @response.redirected_to[:controller]
409
+ if redirected_controller && redirected_controller != @controller.controller_name
410
+ raise "Can't follow redirects outside of current controller (from #{@controller.controller_name} to #{redirected_controller})"
411
+ end
412
+
413
+ get(@response.redirected_to.delete(:action), @response.redirected_to.stringify_keys)
414
+ end
415
+
416
+ deprecate :follow_redirect => "If you wish to follow redirects, you should use integration tests"
417
+
418
+ def assigns(key = nil)
419
+ if key.nil?
420
+ @response.template.assigns
421
+ else
422
+ @response.template.assigns[key.to_s]
423
+ end
424
+ end
425
+
426
+ def session
427
+ @response.session
428
+ end
429
+
430
+ def flash
431
+ @response.flash
432
+ end
433
+
434
+ def cookies
435
+ @response.cookies
436
+ end
437
+
438
+ def redirect_to_url
439
+ @response.redirect_url
440
+ end
441
+
442
+ def build_request_uri(action, parameters)
443
+ unless @request.env['REQUEST_URI']
444
+ options = @controller.send!(:rewrite_options, parameters)
445
+ options.update(:only_path => true, :action => action)
446
+
447
+ url = ActionController::UrlRewriter.new(@request, parameters)
448
+ @request.set_REQUEST_URI(url.rewrite(options))
449
+ end
450
+ end
451
+
452
+ def html_document
453
+ xml = @response.content_type =~ /xml$/
454
+ @html_document ||= HTML::Document.new(@response.body, false, xml)
455
+ end
456
+
457
+ def find_tag(conditions)
458
+ html_document.find(conditions)
459
+ end
460
+
461
+ def find_all_tag(conditions)
462
+ html_document.find_all(conditions)
463
+ end
464
+
465
+ def method_missing(selector, *args)
466
+ return @controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
467
+ return super
468
+ end
469
+
470
+ # Shortcut for <tt>ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + path, type)</tt>:
471
+ #
472
+ # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png')
473
+ #
474
+ # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter.
475
+ # This will not affect other platforms:
476
+ #
477
+ # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png', :binary)
478
+ def fixture_file_upload(path, mime_type = nil, binary = false)
479
+ ActionController::TestUploadedFile.new(
480
+ Test::Unit::TestCase.respond_to?(:fixture_path) ? Test::Unit::TestCase.fixture_path + path : path,
481
+ mime_type,
482
+ binary
483
+ )
484
+ end
485
+
486
+ # A helper to make it easier to test different route configurations.
487
+ # This method temporarily replaces ActionController::Routing::Routes
488
+ # with a new RouteSet instance.
489
+ #
490
+ # The new instance is yielded to the passed block. Typically the block
491
+ # will create some routes using <tt>map.draw { map.connect ... }</tt>:
492
+ #
493
+ # with_routing do |set|
494
+ # set.draw do |map|
495
+ # map.connect ':controller/:action/:id'
496
+ # assert_equal(
497
+ # ['/content/10/show', {}],
498
+ # map.generate(:controller => 'content', :id => 10, :action => 'show')
499
+ # end
500
+ # end
501
+ # end
502
+ #
503
+ def with_routing
504
+ real_routes = ActionController::Routing::Routes
505
+ ActionController::Routing.module_eval { remove_const :Routes }
506
+
507
+ temporary_routes = ActionController::Routing::RouteSet.new
508
+ ActionController::Routing.module_eval { const_set :Routes, temporary_routes }
509
+
510
+ yield temporary_routes
511
+ ensure
512
+ if ActionController::Routing.const_defined? :Routes
513
+ ActionController::Routing.module_eval { remove_const :Routes }
514
+ end
515
+ ActionController::Routing.const_set(:Routes, real_routes) if real_routes
516
+ end
517
+ end
518
+ end
519
+
520
+ module Test
521
+ module Unit
522
+ class TestCase #:nodoc:
523
+ include ActionController::TestProcess
524
+ end
525
+ end
526
+ end