merb-core 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (274) hide show
  1. data/CHANGELOG +136 -2
  2. data/CONTRIBUTORS +6 -0
  3. data/PUBLIC_CHANGELOG +38 -0
  4. data/Rakefile +38 -30
  5. data/lib/merb-core.rb +88 -23
  6. data/lib/merb-core/bootloader.rb +235 -51
  7. data/lib/merb-core/config.rb +121 -36
  8. data/lib/merb-core/controller/abstract_controller.rb +59 -36
  9. data/lib/merb-core/controller/exceptions.rb +2 -15
  10. data/lib/merb-core/controller/merb_controller.rb +44 -1
  11. data/lib/merb-core/controller/mime.rb +4 -0
  12. data/lib/merb-core/controller/mixins/controller.rb +38 -21
  13. data/lib/merb-core/controller/mixins/render.rb +44 -29
  14. data/lib/merb-core/controller/mixins/responder.rb +3 -31
  15. data/lib/merb-core/controller/template.rb +45 -21
  16. data/lib/merb-core/core_ext/kernel.rb +60 -32
  17. data/lib/merb-core/dispatch/default_exception/default_exception.rb +2 -2
  18. data/lib/merb-core/dispatch/default_exception/views/_css.html.erb +3 -1
  19. data/lib/merb-core/dispatch/default_exception/views/_javascript.html.erb +71 -67
  20. data/lib/merb-core/dispatch/default_exception/views/index.html.erb +7 -3
  21. data/lib/merb-core/dispatch/dispatcher.rb +3 -3
  22. data/lib/merb-core/dispatch/request.rb +56 -9
  23. data/lib/merb-core/dispatch/router.rb +159 -133
  24. data/lib/merb-core/dispatch/router/behavior.rb +462 -703
  25. data/lib/merb-core/dispatch/router/cached_proc.rb +3 -3
  26. data/lib/merb-core/dispatch/router/resources.rb +289 -0
  27. data/lib/merb-core/dispatch/router/route.rb +514 -294
  28. data/lib/merb-core/dispatch/session.rb +4 -2
  29. data/lib/merb-core/logger.rb +213 -202
  30. data/lib/merb-core/plugins.rb +9 -1
  31. data/lib/merb-core/rack.rb +3 -1
  32. data/lib/merb-core/rack/adapter.rb +7 -4
  33. data/lib/merb-core/rack/adapter/abstract.rb +188 -0
  34. data/lib/merb-core/rack/adapter/ebb.rb +12 -13
  35. data/lib/merb-core/rack/adapter/evented_mongrel.rb +2 -15
  36. data/lib/merb-core/rack/adapter/irb.rb +3 -2
  37. data/lib/merb-core/rack/adapter/mongrel.rb +22 -15
  38. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +4 -16
  39. data/lib/merb-core/rack/adapter/thin.rb +21 -22
  40. data/lib/merb-core/rack/adapter/thin_turbo.rb +4 -11
  41. data/lib/merb-core/rack/adapter/webrick.rb +54 -18
  42. data/lib/merb-core/rack/application.rb +4 -4
  43. data/lib/merb-core/rack/handler/mongrel.rb +12 -13
  44. data/lib/merb-core/rack/middleware/csrf.rb +1 -1
  45. data/lib/merb-core/rack/stream_wrapper.rb +41 -0
  46. data/lib/merb-core/server.rb +157 -90
  47. data/lib/merb-core/tasks/gem_management.rb +267 -0
  48. data/lib/merb-core/tasks/merb.rb +1 -0
  49. data/lib/merb-core/tasks/merb_rake_helper.rb +48 -34
  50. data/lib/merb-core/tasks/stats.rake +1 -1
  51. data/lib/merb-core/test.rb +9 -3
  52. data/lib/merb-core/test/helpers.rb +1 -0
  53. data/lib/merb-core/test/helpers/mock_request_helper.rb +393 -0
  54. data/lib/merb-core/test/helpers/multipart_request_helper.rb +3 -2
  55. data/lib/merb-core/test/helpers/request_helper.rb +40 -372
  56. data/lib/merb-core/test/helpers/route_helper.rb +16 -2
  57. data/lib/merb-core/test/matchers.rb +1 -0
  58. data/lib/merb-core/test/matchers/controller_matchers.rb +4 -247
  59. data/lib/merb-core/test/matchers/request_matchers.rb +140 -0
  60. data/lib/merb-core/test/matchers/view_matchers.rb +22 -4
  61. data/lib/merb-core/test/run_specs.rb +118 -26
  62. data/lib/merb-core/test/test_ext/rspec.rb +181 -0
  63. data/lib/merb-core/version.rb +1 -9
  64. metadata +10 -342
  65. data/docs/bootloading.dox +0 -58
  66. data/docs/documentation_standards +0 -40
  67. data/docs/merb-core-call-stack-diagram.mmap +0 -0
  68. data/docs/merb-core-call-stack-diagram.pdf +0 -0
  69. data/docs/merb-core-call-stack-diagram.png +0 -0
  70. data/docs/new_render_api +0 -51
  71. data/lib/merb-core/vendor/facets.rb +0 -2
  72. data/lib/merb-core/vendor/facets/dictionary.rb +0 -433
  73. data/lib/merb-core/vendor/facets/inflect.rb +0 -342
  74. data/spec/private/config/adapter_spec.rb +0 -32
  75. data/spec/private/config/config_spec.rb +0 -202
  76. data/spec/private/config/environment_spec.rb +0 -13
  77. data/spec/private/config/merb_spec.rb +0 -34
  78. data/spec/private/config/spec_helper.rb +0 -1
  79. data/spec/private/core_ext/kernel_spec.rb +0 -159
  80. data/spec/private/dispatch/bootloader_spec.rb +0 -24
  81. data/spec/private/dispatch/fixture/app/controllers/application.rb +0 -4
  82. data/spec/private/dispatch/fixture/app/controllers/exceptions.rb +0 -25
  83. data/spec/private/dispatch/fixture/app/controllers/foo.rb +0 -19
  84. data/spec/private/dispatch/fixture/app/helpers/global_helpers.rb +0 -8
  85. data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +0 -37
  86. data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +0 -216
  87. data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +0 -38
  88. data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +0 -40
  89. data/spec/private/dispatch/fixture/app/views/foo/bar.html.erb +0 -0
  90. data/spec/private/dispatch/fixture/app/views/layout/application.html.erb +0 -11
  91. data/spec/private/dispatch/fixture/config/black_hole.rb +0 -12
  92. data/spec/private/dispatch/fixture/config/environments/development.rb +0 -6
  93. data/spec/private/dispatch/fixture/config/environments/production.rb +0 -5
  94. data/spec/private/dispatch/fixture/config/environments/test.rb +0 -6
  95. data/spec/private/dispatch/fixture/config/init.rb +0 -45
  96. data/spec/private/dispatch/fixture/config/rack.rb +0 -11
  97. data/spec/private/dispatch/fixture/config/router.rb +0 -35
  98. data/spec/private/dispatch/fixture/log/merb_test.log +0 -8839
  99. data/spec/private/dispatch/fixture/public/images/merb.jpg +0 -0
  100. data/spec/private/dispatch/fixture/public/merb.fcgi +0 -4
  101. data/spec/private/dispatch/fixture/public/stylesheets/master.css +0 -119
  102. data/spec/private/dispatch/route_params_spec.rb +0 -23
  103. data/spec/private/dispatch/spec_helper.rb +0 -1
  104. data/spec/private/router/behavior_spec.rb +0 -60
  105. data/spec/private/router/fixture/log/merb_test.log +0 -35
  106. data/spec/private/router/route_spec.rb +0 -418
  107. data/spec/private/router/router_spec.rb +0 -183
  108. data/spec/private/vendor/facets/plural_spec.rb +0 -564
  109. data/spec/private/vendor/facets/singular_spec.rb +0 -489
  110. data/spec/public/DEFINITIONS +0 -11
  111. data/spec/public/abstract_controller/controllers/alt_views/layout/application.erb +0 -1
  112. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_string_controller_layout.erb +0 -1
  113. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_template_controller_layout.erb +0 -1
  114. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/index.erb +0 -1
  115. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/show.erb +0 -1
  116. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +0 -1
  117. data/spec/public/abstract_controller/controllers/alt_views/partial/basic_partial_with_multiple_roots/_partial.erb +0 -1
  118. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_and_custom_location/index.erb +0 -1
  119. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_inherited/index.erb +0 -1
  120. data/spec/public/abstract_controller/controllers/cousins.rb +0 -41
  121. data/spec/public/abstract_controller/controllers/display.rb +0 -60
  122. data/spec/public/abstract_controller/controllers/filters.rb +0 -260
  123. data/spec/public/abstract_controller/controllers/helpers.rb +0 -41
  124. data/spec/public/abstract_controller/controllers/partial.rb +0 -121
  125. data/spec/public/abstract_controller/controllers/render.rb +0 -113
  126. data/spec/public/abstract_controller/controllers/views/helpers/capture/index.erb +0 -1
  127. data/spec/public/abstract_controller/controllers/views/helpers/capture_eq/index.erb +0 -1
  128. data/spec/public/abstract_controller/controllers/views/helpers/capture_with_args/index.erb +0 -1
  129. data/spec/public/abstract_controller/controllers/views/helpers/concat/index.erb +0 -1
  130. data/spec/public/abstract_controller/controllers/views/layout/alt.erb +0 -1
  131. data/spec/public/abstract_controller/controllers/views/layout/custom.erb +0 -1
  132. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object/index.erb +0 -1
  133. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object_with_action/new.erb +0 -1
  134. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template/index.erb +0 -1
  135. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_app_layout/index.erb +0 -0
  136. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_custom_layout/index.erb +0 -1
  137. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +0 -1
  138. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/show.erb +0 -1
  139. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_two_throw_contents/index.erb +0 -1
  140. data/spec/public/abstract_controller/controllers/views/partial/another_directory/_partial.erb +0 -1
  141. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/_partial.erb +0 -1
  142. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/index.erb +0 -1
  143. data/spec/public/abstract_controller/controllers/views/partial/basic_partial_with_multiple_roots/index.erb +0 -1
  144. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_first.erb +0 -1
  145. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_second.erb +0 -1
  146. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/index.erb +0 -1
  147. data/spec/public/abstract_controller/controllers/views/partial/partial_in_another_directory/index.erb +0 -1
  148. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/_collection.erb +0 -1
  149. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/index.erb +0 -1
  150. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/_collection.erb +0 -1
  151. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/index.erb +0 -1
  152. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/_collection.erb +0 -1
  153. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/index.erb +0 -1
  154. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/_collection.erb +0 -1
  155. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/index.erb +0 -1
  156. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/_variables.erb +0 -1
  157. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/index.erb +0 -1
  158. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/_both.erb +0 -1
  159. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/index.erb +0 -1
  160. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/_partial.erb +0 -1
  161. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/index.erb +0 -1
  162. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/_with_partial.erb +0 -1
  163. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/index.erb +0 -1
  164. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/_with_partial.erb +0 -1
  165. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/index.erb +0 -1
  166. data/spec/public/abstract_controller/controllers/views/partial/with_partial/_with_partial.erb +0 -1
  167. data/spec/public/abstract_controller/controllers/views/partial/with_partial/index.erb +0 -1
  168. data/spec/public/abstract_controller/controllers/views/test_display/foo.html.erb +0 -1
  169. data/spec/public/abstract_controller/controllers/views/test_render/foo.html.erb +0 -0
  170. data/spec/public/abstract_controller/controllers/views/wonderful/index.erb +0 -1
  171. data/spec/public/abstract_controller/display_spec.rb +0 -37
  172. data/spec/public/abstract_controller/filter_spec.rb +0 -136
  173. data/spec/public/abstract_controller/helper_spec.rb +0 -21
  174. data/spec/public/abstract_controller/partial_spec.rb +0 -61
  175. data/spec/public/abstract_controller/render_spec.rb +0 -90
  176. data/spec/public/abstract_controller/spec_helper.rb +0 -31
  177. data/spec/public/boot_loader/boot_loader_spec.rb +0 -33
  178. data/spec/public/boot_loader/spec_helper.rb +0 -1
  179. data/spec/public/controller/authentication_spec.rb +0 -174
  180. data/spec/public/controller/base_spec.rb +0 -88
  181. data/spec/public/controller/conditional_get_spec.rb +0 -100
  182. data/spec/public/controller/config/init.rb +0 -6
  183. data/spec/public/controller/controllers/authentication.rb +0 -74
  184. data/spec/public/controller/controllers/base.rb +0 -65
  185. data/spec/public/controller/controllers/conditional_get.rb +0 -35
  186. data/spec/public/controller/controllers/cookies.rb +0 -36
  187. data/spec/public/controller/controllers/dispatcher.rb +0 -35
  188. data/spec/public/controller/controllers/display.rb +0 -118
  189. data/spec/public/controller/controllers/redirect.rb +0 -36
  190. data/spec/public/controller/controllers/responder.rb +0 -93
  191. data/spec/public/controller/controllers/url.rb +0 -7
  192. data/spec/public/controller/controllers/views/layout/custom.html.erb +0 -1
  193. data/spec/public/controller/controllers/views/layout/custom_arg.html.erb +0 -1
  194. data/spec/public/controller/controllers/views/layout/custom_arg.json.erb +0 -1
  195. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.html.erb +0 -1
  196. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.xml.erb +0 -1
  197. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +0 -1
  198. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.xml.erb +0 -1
  199. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/index.html.erb +0 -1
  200. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/no_layout.html.erb +0 -1
  201. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template_argument/index.html.erb +0 -1
  202. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/html_default/index.html.erb +0 -1
  203. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/layout/custom.html.erb +0 -1
  204. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.html.erb +0 -1
  205. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.xml.erb +0 -1
  206. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.html.erb +0 -1
  207. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.js.erb +0 -1
  208. data/spec/public/controller/cookies_spec.rb +0 -95
  209. data/spec/public/controller/dispatcher_spec.rb +0 -410
  210. data/spec/public/controller/display_spec.rb +0 -84
  211. data/spec/public/controller/redirect_spec.rb +0 -33
  212. data/spec/public/controller/responder_spec.rb +0 -169
  213. data/spec/public/controller/spec_helper.rb +0 -13
  214. data/spec/public/controller/url_spec.rb +0 -255
  215. data/spec/public/core/merb_core_spec.rb +0 -45
  216. data/spec/public/core_ext/fixtures/core_ext_dependency.rb +0 -2
  217. data/spec/public/core_ext/kernel_spec.rb +0 -88
  218. data/spec/public/core_ext/spec_helper.rb +0 -1
  219. data/spec/public/directory_structure/directory/app/controllers/application.rb +0 -3
  220. data/spec/public/directory_structure/directory/app/controllers/base.rb +0 -13
  221. data/spec/public/directory_structure/directory/app/controllers/custom.rb +0 -19
  222. data/spec/public/directory_structure/directory/app/views/base/template.html.erb +0 -1
  223. data/spec/public/directory_structure/directory/app/views/wonderful/template.erb +0 -1
  224. data/spec/public/directory_structure/directory/config/router.rb +0 -3
  225. data/spec/public/directory_structure/directory/log/merb_test.log +0 -4588
  226. data/spec/public/directory_structure/directory_spec.rb +0 -43
  227. data/spec/public/logger/logger_spec.rb +0 -181
  228. data/spec/public/logger/spec_helper.rb +0 -1
  229. data/spec/public/rack/conditinal_get_middleware_spec.rb +0 -127
  230. data/spec/public/rack/csrf_middleware_spec.rb +0 -70
  231. data/spec/public/rack/rack_middleware_spec.rb +0 -99
  232. data/spec/public/rack/shared_example_groups.rb +0 -35
  233. data/spec/public/reloading/directory/app/controllers/application.rb +0 -3
  234. data/spec/public/reloading/directory/app/controllers/reload.rb +0 -6
  235. data/spec/public/reloading/directory/config/init.rb +0 -2
  236. data/spec/public/reloading/directory/log/merb_test.log +0 -288231
  237. data/spec/public/reloading/reload_spec.rb +0 -103
  238. data/spec/public/request/multipart_spec.rb +0 -41
  239. data/spec/public/request/request_spec.rb +0 -250
  240. data/spec/public/router/default_spec.rb +0 -21
  241. data/spec/public/router/deferred_spec.rb +0 -22
  242. data/spec/public/router/fixation_spec.rb +0 -49
  243. data/spec/public/router/fixture/log/merb_test.log +0 -524
  244. data/spec/public/router/namespace_spec.rb +0 -113
  245. data/spec/public/router/nested_matches_spec.rb +0 -97
  246. data/spec/public/router/nested_resources_spec.rb +0 -41
  247. data/spec/public/router/resource_spec.rb +0 -37
  248. data/spec/public/router/resources_spec.rb +0 -82
  249. data/spec/public/router/spec_helper.rb +0 -90
  250. data/spec/public/router/special_spec.rb +0 -61
  251. data/spec/public/router/string_spec.rb +0 -61
  252. data/spec/public/session/controllers/sessions.rb +0 -56
  253. data/spec/public/session/cookie_session_spec.rb +0 -73
  254. data/spec/public/session/memcached_session_spec.rb +0 -31
  255. data/spec/public/session/memory_session_spec.rb +0 -28
  256. data/spec/public/session/multiple_sessions_spec.rb +0 -74
  257. data/spec/public/session/no_session_spec.rb +0 -12
  258. data/spec/public/session/session_spec.rb +0 -106
  259. data/spec/public/template/template_spec.rb +0 -104
  260. data/spec/public/template/templates/error.html.erb +0 -2
  261. data/spec/public/template/templates/template.html.erb +0 -1
  262. data/spec/public/template/templates/template.html.myt +0 -1
  263. data/spec/public/test/controller_matchers_spec.rb +0 -412
  264. data/spec/public/test/controllers/controller_assertion_mock.rb +0 -7
  265. data/spec/public/test/controllers/dispatch_controller.rb +0 -11
  266. data/spec/public/test/controllers/spec_helper_controller.rb +0 -39
  267. data/spec/public/test/multipart_request_helper_spec.rb +0 -159
  268. data/spec/public/test/multipart_upload_text_file.txt +0 -1
  269. data/spec/public/test/request_helper_spec.rb +0 -269
  270. data/spec/public/test/route_helper_spec.rb +0 -78
  271. data/spec/public/test/route_matchers_spec.rb +0 -166
  272. data/spec/public/test/view_helper_spec.rb +0 -96
  273. data/spec/public/test/view_matchers_spec.rb +0 -183
  274. data/spec/spec_helper.rb +0 -121
@@ -0,0 +1,267 @@
1
+ require 'rubygems'
2
+ require 'rubygems/dependency_installer'
3
+ require 'rubygems/uninstaller'
4
+ require 'rubygems/dependency'
5
+
6
+ module ColorfulMessages
7
+
8
+ # red
9
+ def error(*messages)
10
+ puts messages.map { |msg| "\033[1;31m#{msg}\033[0m" }
11
+ end
12
+
13
+ # yellow
14
+ def warning(*messages)
15
+ puts messages.map { |msg| "\033[1;33m#{msg}\033[0m" }
16
+ end
17
+
18
+ # green
19
+ def success(*messages)
20
+ puts messages.map { |msg| "\033[1;32m#{msg}\033[0m" }
21
+ end
22
+
23
+ alias_method :message, :success
24
+
25
+ end
26
+
27
+ module GemManagement
28
+
29
+ include ColorfulMessages
30
+
31
+ # Install a gem - looks remotely and local gem cache;
32
+ # won't process rdoc or ri options.
33
+ def install_gem(gem, options = {})
34
+ refresh = options.delete(:refresh) || []
35
+ from_cache = (options.key?(:cache) && options.delete(:cache))
36
+ if from_cache
37
+ install_gem_from_cache(gem, options)
38
+ else
39
+ version = options.delete(:version)
40
+ Gem.configuration.update_sources = false
41
+
42
+ update_source_index(options[:install_dir]) if options[:install_dir]
43
+
44
+ installer = Gem::DependencyInstaller.new(options.merge(:user_install => false))
45
+
46
+ # Exclude gems to refresh from index - force (re)install of new version
47
+ # def installer.source_index; @source_index; end
48
+ unless refresh.empty?
49
+ source_index = installer.instance_variable_get(:@source_index)
50
+ source_index.gems.each do |name, spec|
51
+ source_index.gems.delete(name) if refresh.include?(spec.name)
52
+ end
53
+ end
54
+
55
+ exception = nil
56
+ begin
57
+ installer.install gem, version
58
+ rescue Gem::InstallError => e
59
+ exception = e
60
+ rescue Gem::GemNotFoundException => e
61
+ if from_cache && gem_file = find_gem_in_cache(gem, version)
62
+ puts "Located #{gem} in gem cache..."
63
+ installer.install gem_file
64
+ else
65
+ exception = e
66
+ end
67
+ rescue => e
68
+ exception = e
69
+ end
70
+ if installer.installed_gems.empty? && exception
71
+ error "Failed to install gem '#{gem} (#{version})' (#{exception.message})"
72
+ end
73
+ installer.installed_gems.each do |spec|
74
+ success "Successfully installed #{spec.full_name}"
75
+ end
76
+ return !installer.installed_gems.empty?
77
+ end
78
+ end
79
+
80
+ # Install a gem - looks in the system's gem cache instead of remotely;
81
+ # won't process rdoc or ri options.
82
+ def install_gem_from_cache(gem, options = {})
83
+ version = options.delete(:version)
84
+ Gem.configuration.update_sources = false
85
+ installer = Gem::DependencyInstaller.new(options.merge(:user_install => false))
86
+ exception = nil
87
+ begin
88
+ if gem_file = find_gem_in_cache(gem, version)
89
+ puts "Located #{gem} in gem cache..."
90
+ installer.install gem_file
91
+ else
92
+ raise Gem::InstallError, "Unknown gem #{gem}"
93
+ end
94
+ rescue Gem::InstallError => e
95
+ exception = e
96
+ end
97
+ if installer.installed_gems.empty? && exception
98
+ error "Failed to install gem '#{gem}' (#{e.message})"
99
+ end
100
+ installer.installed_gems.each do |spec|
101
+ success "Successfully installed #{spec.full_name}"
102
+ end
103
+ end
104
+
105
+ # Install a gem from source - builds and packages it first then installs.
106
+ def install_gem_from_src(gem_src_dir, options = {})
107
+ if !File.directory?(gem_src_dir)
108
+ raise "Missing rubygem source path: #{gem_src_dir}"
109
+ end
110
+ if options[:install_dir] && !File.directory?(options[:install_dir])
111
+ raise "Missing rubygems path: #{options[:install_dir]}"
112
+ end
113
+
114
+ gem_name = File.basename(gem_src_dir)
115
+ gem_pkg_dir = File.expand_path(File.join(gem_src_dir, 'pkg'))
116
+
117
+ # We need to use local bin executables if available.
118
+ thor = "#{Gem.ruby} -S #{which('thor')}"
119
+ rake = "#{Gem.ruby} -S #{which('rake')}"
120
+
121
+ # Handle pure Thor installation instead of Rake
122
+ if File.exists?(File.join(gem_src_dir, 'Thorfile'))
123
+ # Remove any existing packages.
124
+ FileUtils.rm_rf(gem_pkg_dir) if File.directory?(gem_pkg_dir)
125
+ # Create the package.
126
+ FileUtils.cd(gem_src_dir) { system("#{thor} :package") }
127
+ # Install the package using rubygems.
128
+ if package = Dir[File.join(gem_pkg_dir, "#{gem_name}-*.gem")].last
129
+ FileUtils.cd(File.dirname(package)) do
130
+ install_gem(File.basename(package), options.dup)
131
+ return true
132
+ end
133
+ else
134
+ raise Gem::InstallError, "No package found for #{gem_name}"
135
+ end
136
+ # Handle elaborate installation through Rake
137
+ else
138
+ # Clean and regenerate any subgems for meta gems.
139
+ Dir[File.join(gem_src_dir, '*', 'Rakefile')].each do |rakefile|
140
+ FileUtils.cd(File.dirname(rakefile)) do
141
+ system("#{rake} clobber_package; #{rake} package")
142
+ end
143
+ end
144
+
145
+ # Handle the main gem install.
146
+ if File.exists?(File.join(gem_src_dir, 'Rakefile'))
147
+ subgems = []
148
+ # Remove any existing packages.
149
+ FileUtils.cd(gem_src_dir) { system("#{rake} clobber_package") }
150
+ # Create the main gem pkg dir if it doesn't exist.
151
+ FileUtils.mkdir_p(gem_pkg_dir) unless File.directory?(gem_pkg_dir)
152
+ # Copy any subgems to the main gem pkg dir.
153
+ Dir[File.join(gem_src_dir, '*', 'pkg', '*.gem')].each do |subgem_pkg|
154
+ if name = File.basename(subgem_pkg, '.gem')[/^(.*?)-([\d\.]+)$/, 1]
155
+ subgems << name
156
+ end
157
+ dest = File.join(gem_pkg_dir, File.basename(subgem_pkg))
158
+ FileUtils.copy_entry(subgem_pkg, dest, true, false, true)
159
+ end
160
+
161
+ # Finally generate the main package and install it; subgems
162
+ # (dependencies) are local to the main package.
163
+ FileUtils.cd(gem_src_dir) do
164
+ system("#{rake} package")
165
+ FileUtils.cd(gem_pkg_dir) do
166
+ if package = Dir[File.join(gem_pkg_dir, "#{gem_name}-*.gem")].last
167
+ # If the (meta) gem has it's own package, install it.
168
+ install_gem(File.basename(package), options.merge(:refresh => subgems))
169
+ else
170
+ # Otherwise install each package seperately.
171
+ Dir["*.gem"].each { |gem| install_gem(gem, options.dup) }
172
+ end
173
+ end
174
+ return true
175
+ end
176
+ end
177
+ end
178
+ raise Gem::InstallError, "No Rakefile found for #{gem_name}"
179
+ end
180
+
181
+ # Uninstall a gem.
182
+ def uninstall_gem(gem, options = {})
183
+ if options[:version] && !options[:version].is_a?(Gem::Requirement)
184
+ options[:version] = Gem::Requirement.new ["= #{options[:version]}"]
185
+ end
186
+ update_source_index(options[:install_dir]) if options[:install_dir]
187
+ Gem::Uninstaller.new(gem, options).uninstall
188
+ end
189
+
190
+ # Use the local bin/* executables if available.
191
+ def which(executable)
192
+ if File.executable?(exec = File.join(Dir.pwd, 'bin', executable))
193
+ exec
194
+ else
195
+ executable
196
+ end
197
+ end
198
+
199
+ # Create a modified executable wrapper in the specified bin directory.
200
+ def ensure_bin_wrapper_for(gem_dir, bin_dir, *gems)
201
+ if bin_dir && File.directory?(bin_dir)
202
+ gems.each do |gem|
203
+ if gemspec_path = Dir[File.join(gem_dir, 'specifications', "#{gem}-*.gemspec")].last
204
+ spec = Gem::Specification.load(gemspec_path)
205
+ spec.executables.each do |exec|
206
+ executable = File.join(bin_dir, exec)
207
+ message "Writing executable wrapper #{executable}"
208
+ File.open(executable, 'w', 0755) do |f|
209
+ f.write(executable_wrapper(spec, exec))
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ private
218
+
219
+ def executable_wrapper(spec, bin_file_name)
220
+ <<-TEXT
221
+ #!/usr/bin/env ruby
222
+ #
223
+ # This file was generated by Merb's GemManagement
224
+ #
225
+ # The application '#{spec.name}' is installed as part of a gem, and
226
+ # this file is here to facilitate running it.
227
+
228
+ begin
229
+ require 'minigems'
230
+ rescue LoadError
231
+ require 'rubygems'
232
+ end
233
+
234
+ if File.directory?(gems_dir = File.join(Dir.pwd, 'gems')) ||
235
+ File.directory?(gems_dir = File.join(File.dirname(__FILE__), '..', 'gems'))
236
+ $BUNDLE = true; Gem.clear_paths; Gem.path.unshift(gems_dir)
237
+ end
238
+
239
+ version = "#{Gem::Requirement.default}"
240
+
241
+ if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
242
+ version = $1
243
+ ARGV.shift
244
+ end
245
+
246
+ gem '#{spec.name}', version
247
+ load '#{bin_file_name}'
248
+ TEXT
249
+ end
250
+
251
+ def find_gem_in_cache(gem, version)
252
+ spec = if version
253
+ version = Gem::Requirement.new ["= #{version}"] unless version.is_a?(Gem::Requirement)
254
+ Gem.source_index.find_name(gem, version).first
255
+ else
256
+ Gem.source_index.find_name(gem).sort_by { |g| g.version }.last
257
+ end
258
+ if spec && File.exists?(gem_file = "#{spec.installation_path}/cache/#{spec.full_name}.gem")
259
+ gem_file
260
+ end
261
+ end
262
+
263
+ def update_source_index(dir)
264
+ Gem.source_index.load_gems_in(File.join(dir, 'specifications'))
265
+ end
266
+
267
+ end
@@ -1 +1,2 @@
1
+ require 'merb-core/tasks/merb_rake_helper'
1
2
  Dir[File.dirname(__FILE__) / '*.rake'].each { |ext| load ext }
@@ -1,37 +1,51 @@
1
- def sudo
2
- ENV['MERB_SUDO'] ||= "sudo"
3
- sudo = windows? ? "" : ENV['MERB_SUDO']
4
- end
1
+ require File.join(File.dirname(__FILE__), 'gem_management')
5
2
 
6
- def windows?
7
- (PLATFORM =~ /win32|cygwin/) rescue nil
8
- end
3
+ module Merb
4
+ module RakeHelper
5
+
6
+ extend GemManagement
7
+
8
+ def self.install(name, options = {})
9
+ defaults = { :cache => false }
10
+ defaults[:install_dir] = ENV['GEM_DIR'] if ENV['GEM_DIR']
11
+ opts = defaults.merge(options)
12
+ install_gem_from_src(Dir.pwd, opts)
13
+ ensure_wrapper(opts[:install_dir] || Gem.default_dir, name)
14
+ end
15
+
16
+ def self.install_package(pkg, options = {})
17
+ defaults = { :cache => false }
18
+ defaults[:install_dir] = ENV['GEM_DIR'] if ENV['GEM_DIR']
19
+ opts = defaults.merge(options)
20
+ install_gem(pkg, opts)
21
+ name = File.basename(pkg, '.gem')[/^(.*?)-([\d\.]+)$/, 1]
22
+ ensure_wrapper(opts[:install_dir] || Gem.default_dir, name)
23
+ end
24
+
25
+ def self.uninstall(name, options = {})
26
+ defaults = { :ignore => true, :executables => true }
27
+ defaults[:install_dir] = ENV['GEM_DIR'] if ENV['GEM_DIR']
28
+ uninstall_gem(name, defaults.merge(options))
29
+ end
30
+
31
+ def self.sudo
32
+ ENV['MERB_SUDO'] ||= "sudo"
33
+ sudo = windows? ? "" : ENV['MERB_SUDO']
34
+ end
9
35
 
10
- def install_home
11
- ENV['GEM_HOME'] ? "-i #{ENV['GEM_HOME']}" : ""
12
- end
13
-
14
- def install_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
15
- options << " -i #{ENV['GEM_DIR']}" if ENV['GEM_DIR']
16
- %{#{sudo} gem install #{install_home} --local pkg/#{gem_name}-#{gem_version}.gem #{options}}
17
- end
18
-
19
- def dev_install_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
20
- options << ' --development'
21
- install_command(gem_name, gem_version, options)
22
- end
23
-
24
- def jinstall_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
25
- options << " -i #{ENV['GEM_DIR']}" if ENV['GEM_DIR']
26
- %{#{sudo} jruby -S gem install #{install_home} --local pkg/#{gem_name}-#{gem_version}.gem #{options}}
27
- end
28
-
29
- def dev_jinstall_command(gem_name, gem_version, options = '--no-update-sources --no-rdoc --no-ri')
30
- options << ' --development'
31
- jinstall_command(gem_name, gem_version, options)
32
- end
33
-
34
- def uninstall_command(gem_name, options = '')
35
- options << " -i #{ENV['GEM_DIR']}" if ENV['GEM_DIR']
36
- %{#{sudo} gem uninstall #{gem_name} #{options}}
36
+ def self.windows?
37
+ (PLATFORM =~ /win32|cygwin/) rescue nil
38
+ end
39
+
40
+ protected
41
+
42
+ def self.ensure_wrapper(gemdir, name)
43
+ # See if there's a local bin dir - one directory up from ./gems
44
+ bindir = File.expand_path(File.join(gemdir, '..', 'bin'))
45
+ # Fall back to system wide bindir - usually needs sudo permissions
46
+ bindir = Gem.bindir unless File.directory?(bindir)
47
+ ensure_bin_wrapper_for(gemdir, bindir, name)
48
+ end
49
+
50
+ end
37
51
  end
@@ -39,7 +39,7 @@ task :stats do
39
39
  :models => 'app/models',
40
40
  :lib => 'lib',
41
41
  :spec => 'spec'
42
- }
42
+ }.reject {|name, dir| !File.exist?(dir) }
43
43
  EMPTY_STATS = { :lines => 0, :loc => 0, :classes => 0, :modules => 0, :methods => 0 }
44
44
 
45
45
  @all = {}
@@ -1,6 +1,9 @@
1
- require "hpricot"
1
+ begin
2
+ require "hpricot"
3
+ require 'merb-core/test/test_ext/hpricot'
4
+ rescue
5
+ end
2
6
 
3
- require 'merb-core/test/test_ext/hpricot'
4
7
  require 'merb-core/test/test_ext/object'
5
8
  require 'merb-core/test/test_ext/string'
6
9
 
@@ -8,4 +11,7 @@ module Merb; module Test; end; end
8
11
 
9
12
  require 'merb-core/test/helpers'
10
13
 
11
- require 'merb-core/test/matchers'
14
+ if Merb.test_framework.to_s == "rspec"
15
+ require 'merb-core/test/test_ext/rspec'
16
+ require 'merb-core/test/matchers'
17
+ end
@@ -2,6 +2,7 @@
2
2
  # testing helpers
3
3
  module Merb::Test::Helpers; end
4
4
 
5
+ require "merb-core/test/helpers/mock_request_helper"
5
6
  require "merb-core/test/helpers/request_helper"
6
7
  require "merb-core/test/helpers/multipart_request_helper"
7
8
  require "merb-core/test/helpers/controller_helper"
@@ -0,0 +1,393 @@
1
+ require 'tempfile'
2
+
3
+ module Merb
4
+ module Test
5
+ module RequestHelper
6
+ # FakeRequest sets up a default enviroment which can be overridden either
7
+ # by passing and env into initialize or using request['HTTP_VAR'] = 'foo'
8
+ class FakeRequest < Request
9
+
10
+ # ==== Parameters
11
+ # env<Hash>:: Environment options that override the defaults.
12
+ # req<StringIO>:: The request to set as input for Rack.
13
+ def initialize(env = {}, req = StringIO.new)
14
+ env.environmentize_keys!
15
+ env['rack.input'] = req
16
+ super(DEFAULT_ENV.merge(env))
17
+ end
18
+
19
+ private
20
+ DEFAULT_ENV = Mash.new({
21
+ 'SERVER_NAME' => 'localhost',
22
+ 'PATH_INFO' => '/',
23
+ 'HTTP_ACCEPT_ENCODING' => 'gzip,deflate',
24
+ 'HTTP_USER_AGENT' => 'Mozilla/5.0 (Macintosh; U; PPC Mac OS X Mach-O; en-US; rv:1.8.0.1) Gecko/20060214 Camino/1.0',
25
+ 'SCRIPT_NAME' => '/',
26
+ 'SERVER_PROTOCOL' => 'HTTP/1.1',
27
+ 'HTTP_CACHE_CONTROL' => 'max-age=0',
28
+ 'HTTP_ACCEPT_LANGUAGE' => 'en,ja;q=0.9,fr;q=0.9,de;q=0.8,es;q=0.7,it;q=0.7,nl;q=0.6,sv;q=0.5,nb;q=0.5,da;q=0.4,fi;q=0.3,pt;q=0.3,zh-Hans;q=0.2,zh-Hant;q=0.1,ko;q=0.1',
29
+ 'HTTP_HOST' => 'localhost',
30
+ 'REMOTE_ADDR' => '127.0.0.1',
31
+ 'SERVER_SOFTWARE' => 'Mongrel 1.1',
32
+ 'HTTP_KEEP_ALIVE' => '300',
33
+ 'HTTP_REFERER' => 'http://localhost/',
34
+ 'HTTP_ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
35
+ 'HTTP_VERSION' => 'HTTP/1.1',
36
+ 'REQUEST_URI' => '/',
37
+ 'SERVER_PORT' => '80',
38
+ 'GATEWAY_INTERFACE' => 'CGI/1.2',
39
+ 'HTTP_ACCEPT' => 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5',
40
+ 'HTTP_CONNECTION' => 'keep-alive',
41
+ 'REQUEST_METHOD' => 'GET'
42
+ }) unless defined?(DEFAULT_ENV)
43
+ end
44
+
45
+ # CookieJar keeps track of cookies in a simple Mash.
46
+ class CookieJar < Mash
47
+
48
+ # ==== Parameters
49
+ # request<Merb::Request, Merb::FakeRequest>:: The controller request.
50
+ def update_from_request(request)
51
+ request.cookies.each do |key, value|
52
+ if value.blank?
53
+ self.delete(key)
54
+ else
55
+ self[key] = Merb::Request.unescape(value)
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+
62
+ # ==== Parameters
63
+ # env<Hash>:: A hash of environment keys to be merged into the default list.
64
+ # opt<Hash>:: A hash of options (see below).
65
+ #
66
+ # ==== Options (opt)
67
+ # :post_body<String>:: The post body for the request.
68
+ # :req<String>::
69
+ # The request string. This will only be used if :post_body is left out.
70
+ #
71
+ # ==== Returns
72
+ # FakeRequest:: A Request object that is built based on the parameters.
73
+ #
74
+ # ==== Notes
75
+ # If you pass a post body, the content-type will be set to URL-encoded.
76
+ #
77
+ #---
78
+ # @public
79
+ def fake_request(env = {}, opt = {})
80
+ if opt[:post_body]
81
+ req = opt[:post_body]
82
+ env[:content_type] ||= "application/x-www-form-urlencoded"
83
+ else
84
+ req = opt[:req]
85
+ end
86
+ FakeRequest.new(env, StringIO.new(req || ''))
87
+ end
88
+
89
+ # Dispatches an action to the given class. This bypasses the router and is
90
+ # suitable for unit testing of controllers.
91
+ #
92
+ # ==== Parameters
93
+ # controller_klass<Controller>::
94
+ # The controller class object that the action should be dispatched to.
95
+ # action<Symbol>:: The action name, as a symbol.
96
+ # params<Hash>::
97
+ # An optional hash that will end up as params in the controller instance.
98
+ # env<Hash>::
99
+ # An optional hash that is passed to the fake request. Any request options
100
+ # should go here (see +fake_request+), including :req or :post_body
101
+ # for setting the request body itself.
102
+ # &blk::
103
+ # The controller is yielded to the block provided for actions *prior* to
104
+ # the action being dispatched.
105
+ #
106
+ # ==== Example
107
+ # dispatch_to(MyController, :create, :name => 'Homer' ) do |controller|
108
+ # controller.stub!(:current_user).and_return(@user)
109
+ # end
110
+ #
111
+ # ==== Notes
112
+ # Does not use routes.
113
+ #
114
+ #---
115
+ # @public
116
+ def dispatch_to(controller_klass, action, params = {}, env = {}, &blk)
117
+ params = merge_controller_and_action(controller_klass, action, params)
118
+ dispatch_request(build_request(params, env), controller_klass, action.to_s, &blk)
119
+ end
120
+
121
+ # Keep track of cookie values in CookieJar within the context of the
122
+ # block; you need to set this up for secific controllers.
123
+ #
124
+ # ==== Parameters
125
+ # *controller_classes:: Controller classes to operate on in the context of the block.
126
+ # &blk:: The context to operate on; optionally accepts the cookie jar as an argument.
127
+ def with_cookies(*controller_classes, &blk)
128
+ cookie_jar = CookieJar.new
129
+ before_cb = lambda { |c| c.cookies.update(cookie_jar) }
130
+ after_cb = lambda { |c| cookie_jar.update_from_request(c.request) }
131
+ controller_classes.each do |klass|
132
+ klass._before_dispatch_callbacks << before_cb
133
+ klass._after_dispatch_callbacks << after_cb
134
+ end
135
+ blk.arity == 1 ? blk.call(cookie_jar) : blk.call
136
+ controller_classes.each do |klass|
137
+ klass._before_dispatch_callbacks.delete before_cb
138
+ klass._after_dispatch_callbacks.delete after_cb
139
+ end
140
+ end
141
+
142
+ # Dispatches an action to the given class and using HTTP Basic Authentication
143
+ # This bypasses the router and is suitable for unit testing of controllers.
144
+ #
145
+ # ==== Parameters
146
+ # controller_klass<Controller>::
147
+ # The controller class object that the action should be dispatched to.
148
+ # action<Symbol>:: The action name, as a symbol.
149
+ # username<String>:: The username.
150
+ # password<String>:: The password.
151
+ # params<Hash>::
152
+ # An optional hash that will end up as params in the controller instance.
153
+ # env<Hash>::
154
+ # An optional hash that is passed to the fake request. Any request options
155
+ # should go here (see +fake_request+), including :req or :post_body
156
+ # for setting the request body itself.
157
+ # &blk::
158
+ # The controller is yielded to the block provided for actions *prior* to
159
+ # the action being dispatched.
160
+ #
161
+ # ==== Example
162
+ # dispatch_with_basic_authentication_to(MyController, :create, 'Fred', 'secret', :name => 'Homer' ) do |controller|
163
+ # controller.stub!(:current_user).and_return(@user)
164
+ # end
165
+ #
166
+ # ==== Notes
167
+ # Does not use routes.
168
+ #
169
+ #---
170
+ # @public
171
+ def dispatch_with_basic_authentication_to(controller_klass, action, username, password, params = {}, env = {}, &blk)
172
+ env["X_HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{username}:#{password}")}"
173
+
174
+ params = merge_controller_and_action(controller_klass, action, params)
175
+ dispatch_request(build_request(params, env), controller_klass, action.to_s, &blk)
176
+ end
177
+
178
+ def merge_controller_and_action(controller_klass, action, params)
179
+ params[:controller] = controller_klass.name.to_const_path
180
+ params[:action] = action.to_s
181
+
182
+ params
183
+ end
184
+
185
+ # Prepares and returns a request suitable for dispatching with
186
+ # dispatch_request. If you don't need to modify the request
187
+ # object before dispatching (e.g. to add cookies), you probably
188
+ # want to use dispatch_to instead.
189
+ #
190
+ # ==== Parameters
191
+ # params<Hash>::
192
+ # An optional hash that will end up as params in the controller instance.
193
+ # env<Hash>::
194
+ # An optional hash that is passed to the fake request. Any request options
195
+ # should go here (see +fake_request+), including :req or :post_body
196
+ # for setting the request body itself.
197
+ #
198
+ # ==== Example
199
+ # req = build_request(:id => 1)
200
+ # req.cookies['app_cookie'] = "testing"
201
+ # dispatch_request(req, MyController, :edit)
202
+ #
203
+ # ==== Notes
204
+ # Does not use routes.
205
+ #
206
+ #---
207
+ # @public
208
+ def build_request(params = {}, env = {})
209
+ params = Merb::Request.params_to_query_string(params)
210
+
211
+ query_string = env[:query_string] || env['QUERY_STRING']
212
+ env[:query_string] = query_string ? "#{query_string}&#{params}" : params
213
+
214
+ post_body = env[:post_body] || env['POST_BODY']
215
+ fake_request(env, { :post_body => post_body, :req => env[:req] })
216
+ end
217
+
218
+ # An HTTP GET request that operates through the router.
219
+ #
220
+ # ==== Parameters
221
+ # path<String>:: The path that should go to the router as the request uri.
222
+ # params<Hash>::
223
+ # An optional hash that will end up as params in the controller instance.
224
+ # env<Hash>::
225
+ # An optional hash that is passed to the fake request. Any request options
226
+ # should go here (see +fake_request+).
227
+ # &blk::
228
+ # The controller is yielded to the block provided for actions *prior* to
229
+ # the action being dispatched.
230
+ #---
231
+ # @public
232
+ def get(path, params = {}, env = {}, &block)
233
+ env[:request_method] = "GET"
234
+ mock_request(path, params, env, &block)
235
+ end
236
+
237
+ # An HTTP POST request that operates through the router.
238
+ #
239
+ # ==== Parameters
240
+ # path<String>:: The path that should go to the router as the request uri.
241
+ # params<Hash>::
242
+ # An optional hash that will end up as params in the controller instance.
243
+ # env<Hash>::
244
+ # An optional hash that is passed to the fake request. Any request options
245
+ # should go here (see fake_request).
246
+ # &blk::
247
+ # The controller is yielded to the block provided for actions *prior* to
248
+ # the action being dispatched.
249
+ #---
250
+ # @public
251
+ def post(path, params = {}, env = {}, &block)
252
+ env[:request_method] = "POST"
253
+ mock_request(path, params, env, &block)
254
+ end
255
+
256
+ # An HTTP PUT request that operates through the router.
257
+ #
258
+ # ==== Parameters
259
+ # path<String>:: The path that should go to the router as the request uri.
260
+ # params<Hash>::
261
+ # An optional hash that will end up as params in the controller instance.
262
+ # env<Hash>::
263
+ # An optional hash that is passed to the fake request. Any request options
264
+ # should go here (see fake_request).
265
+ # &blk::
266
+ # The controller is yielded to the block provided for actions *prior* to
267
+ # the action being dispatched.
268
+ #---
269
+ # @public
270
+ def put(path, params = {}, env = {}, &block)
271
+ env[:request_method] = "PUT"
272
+ mock_request(path, params, env, &block)
273
+ end
274
+
275
+ # An HTTP DELETE request that operates through the router
276
+ #
277
+ # ==== Parameters
278
+ # path<String>:: The path that should go to the router as the request uri.
279
+ # params<Hash>::
280
+ # An optional hash that will end up as params in the controller instance.
281
+ # env<Hash>::
282
+ # An optional hash that is passed to the fake request. Any request options
283
+ # should go here (see fake_request).
284
+ # &blk::
285
+ # The controller is yielded to the block provided for actions *prior* to
286
+ # the action being dispatched.
287
+ #---
288
+ # @public
289
+ def delete(path, params = {}, env = {}, &block)
290
+ env[:request_method] = "DELETE"
291
+ mock_request(path, params, env, &block)
292
+ end
293
+
294
+ # A generic request that checks the router for the controller and action.
295
+ # This request goes through the Merb::Router and finishes at the controller.
296
+ #
297
+ # ==== Parameters
298
+ # path<String>:: The path that should go to the router as the request uri.
299
+ # params<Hash>::
300
+ # An optional hash that will end up as params in the controller instance.
301
+ # env<Hash>::
302
+ # An optional hash that is passed to the fake request. Any request options
303
+ # should go here (see +fake_request+).
304
+ # &blk::
305
+ # The controller is yielded to the block provided for actions *prior* to
306
+ # the action being dispatched.
307
+ #
308
+ # ==== Example
309
+ # request(path, { :name => 'Homer' }, { :request_method => "PUT" }) do |controller|
310
+ # controller.stub!(:current_user).and_return(@user)
311
+ # end
312
+ #
313
+ # ==== Notes
314
+ # Uses Routes.
315
+ #
316
+ #---
317
+ # @semi-public
318
+ def mock_request(path, params = {}, env= {}, &block)
319
+ env[:request_method] ||= "GET"
320
+ env[:request_uri], env[:query_string] = path.split('?')
321
+
322
+ multipart = env.delete(:test_with_multipart)
323
+
324
+ request = build_request(params, env)
325
+
326
+ opts = check_request_for_route(request) # Check that the request will be routed correctly
327
+ controller_name = (opts[:namespace] ? opts.delete(:namespace) + '/' : '') + opts.delete(:controller)
328
+ klass = Object.full_const_get(controller_name.snake_case.to_const_string)
329
+
330
+ action = opts.delete(:action).to_s
331
+ params.merge!(opts)
332
+
333
+ multipart.nil? ? dispatch_to(klass, action, params, env, &block) : dispatch_multipart_to(klass, action, params, env, &block)
334
+ end
335
+
336
+
337
+ # The workhorse for the dispatch*to helpers.
338
+ #
339
+ # ==== Parameters
340
+ # request<Merb::Test::RequestHelper::FakeRequest, Merb::Request>::
341
+ # A request object that has been setup for testing.
342
+ # controller_klass<Merb::Controller>::
343
+ # The class object off the controller to dispatch the action to.
344
+ # action<Symbol>:: The action to dispatch the request to.
345
+ # &blk::
346
+ # The controller is yielded to the block provided for actions *prior* to
347
+ # the action being dispatched.
348
+ #
349
+ # ==== Returns
350
+ # An instance of +controller_klass+ based on the parameters.
351
+ #
352
+ # ==== Notes
353
+ # Does not use routes.
354
+ #
355
+ #---
356
+ # @public
357
+ def dispatch_request(request, controller_klass, action, &blk)
358
+ controller = controller_klass.new(request)
359
+ yield controller if block_given?
360
+ controller._dispatch(action)
361
+
362
+ Merb.logger.info controller._benchmarks.inspect
363
+ Merb.logger.flush
364
+
365
+ controller
366
+ end
367
+
368
+ # Checks to see that a request is routable.
369
+ #
370
+ # ==== Parameters
371
+ # request<Merb::Test::RequestHelper::FakeRequest, Merb::Request>::
372
+ # The request object to inspect.
373
+ #
374
+ # ==== Raises
375
+ # Merb::ControllerExceptions::BadRequest::
376
+ # No matching route was found.
377
+ #
378
+ # ==== Returns
379
+ # Hash:: The parameters built based on the matching route.
380
+ #
381
+ #---
382
+ # @semi-public
383
+ def check_request_for_route(request)
384
+ match = ::Merb::Router.match(request)
385
+ if match[0].nil? && match[1].empty?
386
+ raise ::Merb::ControllerExceptions::BadRequest, "No routes match the request. Request uri: #{request.uri}"
387
+ else
388
+ match[1]
389
+ end
390
+ end # check_request_for_route
391
+ end # RequestHelper
392
+ end # Test
393
+ end # Merb