thorero 0.9.4.4 → 0.9.4.5

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 (298) hide show
  1. data/LICENSE +1 -1
  2. data/README +21 -0
  3. data/Rakefile +275 -108
  4. data/TODO +0 -0
  5. data/bin/merb +12 -0
  6. data/bin/merb-specs +5 -0
  7. data/docs/bootloading.dox +58 -0
  8. data/docs/documentation_standards +40 -0
  9. data/docs/merb-core-call-stack-diagram.mmap +0 -0
  10. data/docs/merb-core-call-stack-diagram.pdf +0 -0
  11. data/docs/merb-core-call-stack-diagram.png +0 -0
  12. data/docs/new_render_api +51 -0
  13. data/lib/merb-core.rb +603 -0
  14. data/lib/merb-core/autoload.rb +32 -0
  15. data/lib/merb-core/bootloader.rb +708 -0
  16. data/lib/merb-core/config.rb +303 -0
  17. data/lib/merb-core/constants.rb +43 -0
  18. data/lib/merb-core/controller/abstract_controller.rb +578 -0
  19. data/lib/merb-core/controller/exceptions.rb +302 -0
  20. data/lib/merb-core/controller/merb_controller.rb +256 -0
  21. data/lib/merb-core/controller/mime.rb +106 -0
  22. data/lib/merb-core/controller/mixins/authentication.rb +87 -0
  23. data/lib/merb-core/controller/mixins/controller.rb +290 -0
  24. data/lib/merb-core/controller/mixins/render.rb +481 -0
  25. data/lib/merb-core/controller/mixins/responder.rb +472 -0
  26. data/lib/merb-core/controller/template.rb +254 -0
  27. data/lib/merb-core/core_ext.rb +8 -0
  28. data/lib/merb-core/core_ext/kernel.rb +319 -0
  29. data/lib/merb-core/dispatch/cookies.rb +91 -0
  30. data/lib/merb-core/dispatch/dispatcher.rb +278 -0
  31. data/lib/merb-core/dispatch/exceptions.html.erb +303 -0
  32. data/lib/merb-core/dispatch/request.rb +603 -0
  33. data/lib/merb-core/dispatch/router.rb +179 -0
  34. data/lib/merb-core/dispatch/router/behavior.rb +867 -0
  35. data/lib/merb-core/dispatch/router/cached_proc.rb +52 -0
  36. data/lib/merb-core/dispatch/router/route.rb +321 -0
  37. data/lib/merb-core/dispatch/session.rb +78 -0
  38. data/lib/merb-core/dispatch/session/cookie.rb +168 -0
  39. data/lib/merb-core/dispatch/session/memcached.rb +184 -0
  40. data/lib/merb-core/dispatch/session/memory.rb +241 -0
  41. data/lib/merb-core/dispatch/worker.rb +28 -0
  42. data/lib/merb-core/gem_ext/erubis.rb +77 -0
  43. data/lib/{extlib → merb-core}/logger.rb +2 -2
  44. data/lib/merb-core/plugins.rb +59 -0
  45. data/lib/merb-core/rack.rb +21 -0
  46. data/lib/merb-core/rack/adapter.rb +44 -0
  47. data/lib/merb-core/rack/adapter/ebb.rb +25 -0
  48. data/lib/merb-core/rack/adapter/evented_mongrel.rb +26 -0
  49. data/lib/merb-core/rack/adapter/fcgi.rb +17 -0
  50. data/lib/merb-core/rack/adapter/irb.rb +118 -0
  51. data/lib/merb-core/rack/adapter/mongrel.rb +26 -0
  52. data/lib/merb-core/rack/adapter/runner.rb +28 -0
  53. data/lib/merb-core/rack/adapter/swiftiplied_mongrel.rb +26 -0
  54. data/lib/merb-core/rack/adapter/thin.rb +39 -0
  55. data/lib/merb-core/rack/adapter/thin_turbo.rb +24 -0
  56. data/lib/merb-core/rack/adapter/webrick.rb +36 -0
  57. data/lib/merb-core/rack/application.rb +18 -0
  58. data/lib/merb-core/rack/handler/mongrel.rb +97 -0
  59. data/lib/merb-core/rack/middleware.rb +26 -0
  60. data/lib/merb-core/rack/middleware/path_prefix.rb +31 -0
  61. data/lib/merb-core/rack/middleware/profiler.rb +19 -0
  62. data/lib/merb-core/rack/middleware/static.rb +45 -0
  63. data/lib/merb-core/server.rb +252 -0
  64. data/lib/merb-core/tasks/audit.rake +68 -0
  65. data/lib/merb-core/tasks/merb.rb +1 -0
  66. data/lib/merb-core/tasks/merb_rake_helper.rb +12 -0
  67. data/lib/merb-core/test.rb +11 -0
  68. data/lib/merb-core/test/helpers.rb +9 -0
  69. data/lib/merb-core/test/helpers/controller_helper.rb +8 -0
  70. data/lib/merb-core/test/helpers/multipart_request_helper.rb +175 -0
  71. data/lib/merb-core/test/helpers/request_helper.rb +344 -0
  72. data/lib/merb-core/test/helpers/route_helper.rb +33 -0
  73. data/lib/merb-core/test/helpers/view_helper.rb +121 -0
  74. data/lib/merb-core/test/matchers.rb +9 -0
  75. data/lib/merb-core/test/matchers/controller_matchers.rb +319 -0
  76. data/lib/merb-core/test/matchers/route_matchers.rb +136 -0
  77. data/lib/merb-core/test/matchers/view_matchers.rb +335 -0
  78. data/lib/merb-core/test/run_specs.rb +47 -0
  79. data/lib/merb-core/test/tasks/spectasks.rb +68 -0
  80. data/lib/merb-core/test/test_ext/hpricot.rb +32 -0
  81. data/lib/merb-core/test/test_ext/object.rb +14 -0
  82. data/lib/merb-core/test/test_ext/string.rb +14 -0
  83. data/lib/merb-core/vendor/facets.rb +2 -0
  84. data/lib/merb-core/vendor/facets/dictionary.rb +433 -0
  85. data/lib/merb-core/vendor/facets/inflect.rb +345 -0
  86. data/lib/merb-core/version.rb +11 -0
  87. data/spec/private/config/adapter_spec.rb +32 -0
  88. data/spec/private/config/config_spec.rb +202 -0
  89. data/spec/private/config/environment_spec.rb +13 -0
  90. data/spec/private/config/spec_helper.rb +1 -0
  91. data/spec/private/core_ext/kernel_spec.rb +169 -0
  92. data/spec/private/dispatch/bootloader_spec.rb +24 -0
  93. data/spec/private/dispatch/cookies_spec.rb +107 -0
  94. data/spec/private/dispatch/dispatch_spec.rb +35 -0
  95. data/spec/private/dispatch/fixture/app/controllers/application.rb +4 -0
  96. data/spec/private/dispatch/fixture/app/controllers/exceptions.rb +27 -0
  97. data/spec/private/dispatch/fixture/app/controllers/foo.rb +21 -0
  98. data/spec/private/dispatch/fixture/app/helpers/global_helpers.rb +8 -0
  99. data/spec/private/dispatch/fixture/app/views/exeptions/client_error.html.erb +37 -0
  100. data/spec/private/dispatch/fixture/app/views/exeptions/internal_server_error.html.erb +216 -0
  101. data/spec/private/dispatch/fixture/app/views/exeptions/not_acceptable.html.erb +38 -0
  102. data/spec/private/dispatch/fixture/app/views/exeptions/not_found.html.erb +40 -0
  103. data/spec/private/dispatch/fixture/app/views/foo/bar.html.erb +0 -0
  104. data/spec/private/dispatch/fixture/app/views/layout/application.html.erb +11 -0
  105. data/spec/private/dispatch/fixture/config/black_hole.rb +12 -0
  106. data/spec/private/dispatch/fixture/config/environments/development.rb +6 -0
  107. data/spec/private/dispatch/fixture/config/environments/production.rb +5 -0
  108. data/spec/private/dispatch/fixture/config/environments/test.rb +6 -0
  109. data/spec/private/dispatch/fixture/config/init.rb +45 -0
  110. data/spec/private/dispatch/fixture/config/rack.rb +11 -0
  111. data/spec/private/dispatch/fixture/config/router.rb +35 -0
  112. data/spec/private/dispatch/fixture/log/merb_test.log +1874 -0
  113. data/spec/private/dispatch/fixture/public/images/merb.jpg +0 -0
  114. data/spec/private/dispatch/fixture/public/merb.fcgi +4 -0
  115. data/spec/private/dispatch/fixture/public/stylesheets/master.css +119 -0
  116. data/spec/private/dispatch/route_params_spec.rb +24 -0
  117. data/spec/private/dispatch/session_mixin_spec.rb +47 -0
  118. data/spec/private/dispatch/spec_helper.rb +1 -0
  119. data/spec/private/plugins/plugin_spec.rb +166 -0
  120. data/spec/private/rack/application_spec.rb +49 -0
  121. data/spec/private/router/behavior_spec.rb +60 -0
  122. data/spec/private/router/fixture/log/merb_test.log +139 -0
  123. data/spec/private/router/route_spec.rb +414 -0
  124. data/spec/private/router/router_spec.rb +175 -0
  125. data/spec/private/vendor/facets/plural_spec.rb +564 -0
  126. data/spec/private/vendor/facets/singular_spec.rb +489 -0
  127. data/spec/public/DEFINITIONS +11 -0
  128. data/spec/public/abstract_controller/controllers/alt_views/layout/application.erb +1 -0
  129. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_string_controller_layout.erb +1 -0
  130. data/spec/public/abstract_controller/controllers/alt_views/layout/merb/test/fixtures/abstract/render_template_controller_layout.erb +1 -0
  131. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/index.erb +1 -0
  132. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/display_object_with_multiple_roots/show.erb +1 -0
  133. data/spec/public/abstract_controller/controllers/alt_views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
  134. data/spec/public/abstract_controller/controllers/alt_views/partial/basic_partial_with_multiple_roots/_partial.erb +1 -0
  135. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_and_custom_location/index.erb +1 -0
  136. data/spec/public/abstract_controller/controllers/alt_views/render_template_multiple_roots_inherited/index.erb +1 -0
  137. data/spec/public/abstract_controller/controllers/cousins.rb +41 -0
  138. data/spec/public/abstract_controller/controllers/display.rb +54 -0
  139. data/spec/public/abstract_controller/controllers/filters.rb +193 -0
  140. data/spec/public/abstract_controller/controllers/helpers.rb +41 -0
  141. data/spec/public/abstract_controller/controllers/partial.rb +121 -0
  142. data/spec/public/abstract_controller/controllers/render.rb +113 -0
  143. data/spec/public/abstract_controller/controllers/views/helpers/capture/index.erb +1 -0
  144. data/spec/public/abstract_controller/controllers/views/helpers/capture_eq/index.erb +1 -0
  145. data/spec/public/abstract_controller/controllers/views/helpers/capture_with_args/index.erb +1 -0
  146. data/spec/public/abstract_controller/controllers/views/helpers/concat/index.erb +1 -0
  147. data/spec/public/abstract_controller/controllers/views/layout/alt.erb +1 -0
  148. data/spec/public/abstract_controller/controllers/views/layout/custom.erb +1 -0
  149. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object/index.erb +1 -0
  150. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/display_object_with_action/new.erb +1 -0
  151. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template/index.erb +1 -0
  152. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_app_layout/index.erb +0 -0
  153. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_custom_layout/index.erb +1 -0
  154. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/index.erb +1 -0
  155. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_template_multiple_roots/show.erb +1 -0
  156. data/spec/public/abstract_controller/controllers/views/merb/test/fixtures/abstract/render_two_throw_contents/index.erb +1 -0
  157. data/spec/public/abstract_controller/controllers/views/partial/another_directory/_partial.erb +1 -0
  158. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/_partial.erb +1 -0
  159. data/spec/public/abstract_controller/controllers/views/partial/basic_partial/index.erb +1 -0
  160. data/spec/public/abstract_controller/controllers/views/partial/basic_partial_with_multiple_roots/index.erb +1 -0
  161. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_first.erb +1 -0
  162. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/_second.erb +1 -0
  163. data/spec/public/abstract_controller/controllers/views/partial/nested_partial/index.erb +1 -0
  164. data/spec/public/abstract_controller/controllers/views/partial/partial_in_another_directory/index.erb +1 -0
  165. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/_collection.erb +1 -0
  166. data/spec/public/abstract_controller/controllers/views/partial/partial_with_both/index.erb +1 -0
  167. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/_collection.erb +1 -0
  168. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections/index.erb +1 -0
  169. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/_collection.erb +1 -0
  170. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_as/index.erb +1 -0
  171. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/_collection.erb +1 -0
  172. data/spec/public/abstract_controller/controllers/views/partial/partial_with_collections_and_counter/index.erb +1 -0
  173. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/_variables.erb +1 -0
  174. data/spec/public/abstract_controller/controllers/views/partial/partial_with_locals/index.erb +1 -0
  175. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/_both.erb +1 -0
  176. data/spec/public/abstract_controller/controllers/views/partial/partial_with_with_and_locals/index.erb +1 -0
  177. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/_partial.erb +1 -0
  178. data/spec/public/abstract_controller/controllers/views/partial/with_absolute_partial/index.erb +1 -0
  179. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/_with_partial.erb +1 -0
  180. data/spec/public/abstract_controller/controllers/views/partial/with_as_partial/index.erb +1 -0
  181. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/_with_partial.erb +1 -0
  182. data/spec/public/abstract_controller/controllers/views/partial/with_nil_partial/index.erb +1 -0
  183. data/spec/public/abstract_controller/controllers/views/partial/with_partial/_with_partial.erb +1 -0
  184. data/spec/public/abstract_controller/controllers/views/partial/with_partial/index.erb +1 -0
  185. data/spec/public/abstract_controller/controllers/views/test_display/foo.html.erb +1 -0
  186. data/spec/public/abstract_controller/controllers/views/test_render/foo.html.erb +0 -0
  187. data/spec/public/abstract_controller/controllers/views/wonderful/index.erb +1 -0
  188. data/spec/public/abstract_controller/display_spec.rb +33 -0
  189. data/spec/public/abstract_controller/filter_spec.rb +106 -0
  190. data/spec/public/abstract_controller/helper_spec.rb +21 -0
  191. data/spec/public/abstract_controller/partial_spec.rb +61 -0
  192. data/spec/public/abstract_controller/render_spec.rb +90 -0
  193. data/spec/public/abstract_controller/spec_helper.rb +31 -0
  194. data/spec/public/boot_loader/boot_loader_spec.rb +33 -0
  195. data/spec/public/boot_loader/spec_helper.rb +1 -0
  196. data/spec/public/controller/authentication_spec.rb +103 -0
  197. data/spec/public/controller/base_spec.rb +36 -0
  198. data/spec/public/controller/controllers/authentication.rb +45 -0
  199. data/spec/public/controller/controllers/base.rb +36 -0
  200. data/spec/public/controller/controllers/display.rb +118 -0
  201. data/spec/public/controller/controllers/redirect.rb +30 -0
  202. data/spec/public/controller/controllers/responder.rb +93 -0
  203. data/spec/public/controller/controllers/url.rb +7 -0
  204. data/spec/public/controller/controllers/views/layout/custom.html.erb +1 -0
  205. data/spec/public/controller/controllers/views/layout/custom_arg.html.erb +1 -0
  206. data/spec/public/controller/controllers/views/layout/custom_arg.json.erb +1 -0
  207. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.html.erb +1 -0
  208. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_and_local_provides/index.xml.erb +1 -0
  209. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.html.erb +1 -0
  210. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/class_provides/index.xml.erb +1 -0
  211. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/index.html.erb +1 -0
  212. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template/no_layout.html.erb +1 -0
  213. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/display_with_template_argument/index.html.erb +1 -0
  214. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/html_default/index.html.erb +1 -0
  215. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/layout/custom.html.erb +1 -0
  216. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.html.erb +1 -0
  217. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/local_provides/index.xml.erb +1 -0
  218. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.html.erb +1 -0
  219. data/spec/public/controller/controllers/views/merb/test/fixtures/controllers/multi_provides/index.js.erb +1 -0
  220. data/spec/public/controller/display_spec.rb +84 -0
  221. data/spec/public/controller/redirect_spec.rb +27 -0
  222. data/spec/public/controller/responder_spec.rb +163 -0
  223. data/spec/public/controller/spec_helper.rb +11 -0
  224. data/spec/public/controller/url_spec.rb +180 -0
  225. data/spec/public/core/merb_core_spec.rb +45 -0
  226. data/spec/public/core_ext/class_spec.rb +91 -0
  227. data/spec/public/core_ext/fixtures/core_ext_dependency.rb +2 -0
  228. data/spec/public/core_ext/kernel_spec.rb +9 -0
  229. data/spec/public/core_ext/spec_helper.rb +1 -0
  230. data/spec/public/directory_structure/directory/app/controllers/application.rb +3 -0
  231. data/spec/public/directory_structure/directory/app/controllers/base.rb +13 -0
  232. data/spec/public/directory_structure/directory/app/controllers/custom.rb +19 -0
  233. data/spec/public/directory_structure/directory/app/views/base/template.html.erb +1 -0
  234. data/spec/public/directory_structure/directory/app/views/wonderful/template.erb +1 -0
  235. data/spec/public/directory_structure/directory/config/router.rb +3 -0
  236. data/spec/public/directory_structure/directory/log/merb_test.log +562 -0
  237. data/spec/public/directory_structure/directory_spec.rb +44 -0
  238. data/spec/public/logger/logger_spec.rb +181 -0
  239. data/spec/public/logger/spec_helper.rb +1 -0
  240. data/spec/public/reloading/directory/app/controllers/application.rb +3 -0
  241. data/spec/public/reloading/directory/app/controllers/reload.rb +6 -0
  242. data/spec/public/reloading/directory/config/init.rb +2 -0
  243. data/spec/public/reloading/directory/log/merb_test.log +138 -0
  244. data/spec/public/reloading/reload_spec.rb +103 -0
  245. data/spec/public/request/multipart_spec.rb +41 -0
  246. data/spec/public/request/request_spec.rb +228 -0
  247. data/spec/public/router/default_spec.rb +21 -0
  248. data/spec/public/router/deferred_spec.rb +22 -0
  249. data/spec/public/router/fixation_spec.rb +27 -0
  250. data/spec/public/router/fixture/log/merb_test.log +1556 -0
  251. data/spec/public/router/namespace_spec.rb +113 -0
  252. data/spec/public/router/nested_matches_spec.rb +97 -0
  253. data/spec/public/router/nested_resources_spec.rb +41 -0
  254. data/spec/public/router/resource_spec.rb +37 -0
  255. data/spec/public/router/resources_spec.rb +82 -0
  256. data/spec/public/router/spec_helper.rb +90 -0
  257. data/spec/public/router/special_spec.rb +61 -0
  258. data/spec/public/router/string_spec.rb +61 -0
  259. data/spec/public/template/template_spec.rb +104 -0
  260. data/spec/public/template/templates/error.html.erb +2 -0
  261. data/spec/public/template/templates/template.html.erb +1 -0
  262. data/spec/public/template/templates/template.html.myt +1 -0
  263. data/spec/public/test/controller_matchers_spec.rb +402 -0
  264. data/spec/public/test/controllers/controller_assertion_mock.rb +7 -0
  265. data/spec/public/test/controllers/dispatch_controller.rb +11 -0
  266. data/spec/public/test/controllers/spec_helper_controller.rb +38 -0
  267. data/spec/public/test/multipart_request_helper_spec.rb +159 -0
  268. data/spec/public/test/multipart_upload_text_file.txt +1 -0
  269. data/spec/public/test/request_helper_spec.rb +221 -0
  270. data/spec/public/test/route_helper_spec.rb +71 -0
  271. data/spec/public/test/route_matchers_spec.rb +162 -0
  272. data/spec/public/test/view_helper_spec.rb +96 -0
  273. data/spec/public/test/view_matchers_spec.rb +183 -0
  274. data/spec/spec_helper.rb +68 -0
  275. metadata +493 -41
  276. data/README.txt +0 -3
  277. data/lib/extlib.rb +0 -32
  278. data/lib/extlib/assertions.rb +0 -8
  279. data/lib/extlib/blank.rb +0 -42
  280. data/lib/extlib/class.rb +0 -175
  281. data/lib/extlib/hash.rb +0 -410
  282. data/lib/extlib/hook.rb +0 -366
  283. data/lib/extlib/inflection.rb +0 -141
  284. data/lib/extlib/lazy_array.rb +0 -106
  285. data/lib/extlib/mash.rb +0 -143
  286. data/lib/extlib/module.rb +0 -37
  287. data/lib/extlib/object.rb +0 -165
  288. data/lib/extlib/object_space.rb +0 -13
  289. data/lib/extlib/pathname.rb +0 -5
  290. data/lib/extlib/pooling.rb +0 -233
  291. data/lib/extlib/rubygems.rb +0 -38
  292. data/lib/extlib/simple_set.rb +0 -39
  293. data/lib/extlib/string.rb +0 -132
  294. data/lib/extlib/struct.rb +0 -8
  295. data/lib/extlib/tasks/release.rb +0 -9
  296. data/lib/extlib/time.rb +0 -12
  297. data/lib/extlib/version.rb +0 -3
  298. data/lib/extlib/virtual_file.rb +0 -10
@@ -0,0 +1,302 @@
1
+ module Merb
2
+ # ControllerExceptions are a way of simplifying controller code by placing
3
+ # exceptional logic back into the MVC pattern.
4
+ #
5
+ # When a ControllerException is raised within your application merb will
6
+ # attempt to re-route the request to your Exceptions controller to render
7
+ # the error in a friendly mannor.
8
+ #
9
+ # For example you might have an action in your app that raises NotFound
10
+ # if a some resource was not available
11
+ #
12
+
13
+ # def show
14
+ # product = Product.find(params[:id])
15
+ # raise NotFound if product.nil?
16
+ # [...]
17
+ # end
18
+ #
19
+ # This would halt execution of your action and re-route it over to your
20
+ # Exceptions controller which might look something like
21
+ #
22
+ # class Exceptions < Application
23
+
24
+ # def not_found
25
+ # render :layout => :none
26
+ # end
27
+ # end
28
+ #
29
+ # As usual the not_found action will look for a template in
30
+ # app/views/exceptions/not_found.html.erb
31
+ #
32
+ # Note: All standard ControllerExceptions have an HTTP status code associated
33
+ # with them which is sent to the browser when the action it is rendered.
34
+ #
35
+ # Note: If you do not specifiy how to handle raised ControllerExceptions
36
+ # or an unhandlable exception occurs within your customised exception action
37
+ # then they will be rendered using the built-in error template
38
+ # in development mode this "built in" template will show stack-traces for
39
+ # any of the ServerError family of exceptions (you can force the stack-trace
40
+ # to display in production mode using the :exception_details config option in
41
+ # merb.yml)
42
+ #
43
+ #
44
+ # ==== Internal Exceptions
45
+ #
46
+ # Any other rogue errors (not ControllerExceptions) that occur during the
47
+ # execution of you app will be converted into the ControllerException
48
+ # InternalServerError, and like all ControllerExceptions can be caught
49
+ # on your Exceptions controller.
50
+ #
51
+ # InternalServerErrors return status 500, a common use for cusomizing this
52
+ # action might be to send emails to the development team, warning that their
53
+ # application have exploded. Mock example:
54
+ #
55
+
56
+ # def internal_server_error
57
+ # MySpecialMailer.deliver(
58
+ # "team@cowboys.com",
59
+ # "Exception occured at #{Time.now}",
60
+ # params[:exception])
61
+ # render 'Something is wrong, but the team are on it!'
62
+ # end
63
+ #
64
+ # Note: The special param[:exception] is available in all Exception actions
65
+ # and contains the ControllerException that was raised (this is handy if
66
+ # you want to display the associated message or display more detailed info)
67
+ #
68
+ #
69
+ # ==== Extending ControllerExceptions
70
+ #
71
+ # To extend the use of the ControllerExceptions one may extend any of the
72
+ # HTTPError classes.
73
+ #
74
+ # As an example we can create an exception called AdminAccessRequired.
75
+ #
76
+ # class AdminAccessRequired < Merb::ControllerExceptions::Unauthorized; end
77
+ #
78
+ # Add the required action to our Exceptions controller
79
+ #
80
+ # class Exceptions < Application
81
+
82
+ # def admin_access_required
83
+ # render
84
+ # end
85
+ # end
86
+ #
87
+ # In app/views/exceptions/admin_access_required.rhtml
88
+ #
89
+ # <h1>You're not an administrator!</h1>
90
+ # <p>You tried to access <%= @tried_to_access %> but that URL is
91
+ # restricted to administrators.</p>
92
+ #
93
+ module ControllerExceptions
94
+
95
+ # Mapping of status code names to their numeric value.
96
+ STATUS_CODES = {}
97
+
98
+ class Base < StandardError #:doc:
99
+
100
+ # ==== Returns
101
+ # String:: The snake cased name of the error without the namespace.
102
+ def name; self.class.name; end
103
+
104
+ # === Returns
105
+ # Integer:: The status-code of the error.
106
+ def status; self.class.status; end
107
+ alias :to_i :status
108
+
109
+ class << self
110
+
111
+ # ==== Returns
112
+ # String:: The snake cased name of the class without the namespace.
113
+ def name
114
+ self.to_s.split('::').last.snake_case
115
+ end
116
+
117
+ # Get the actual status-code for an Exception class.
118
+ #
119
+ # As usual, this can come from a constant upwards in
120
+ # the inheritance chain.
121
+ #
122
+ # ==== Returns
123
+ # Fixnum:: The status code of this exception.
124
+ def status
125
+ const_get(:STATUS) rescue 0
126
+ end
127
+ alias :to_i :status
128
+
129
+ # Set the actual status-code for an Exception class.
130
+ #
131
+ # If possible, set the STATUS constant, and update
132
+ # any previously registered (inherited) status-code.
133
+ #
134
+ # ==== Parameters
135
+ # num<~to_i>:: The status code
136
+ def status=(num)
137
+ unless self.status?
138
+ register_status_code(self, num)
139
+ self.const_set(:STATUS, num.to_i)
140
+ end
141
+ end
142
+
143
+ # See if a status-code has been defined (on self explicitly).
144
+ #
145
+ # ==== Returns
146
+ # Boolean:: Whether the a status code has been set
147
+ def status?
148
+ self.const_defined?(:STATUS)
149
+ end
150
+
151
+ # Registers any subclasses with status codes for easy lookup by
152
+ # set_status in Merb::Controller.
153
+ #
154
+ # Inheritance ensures this method gets inherited by any subclasses, so
155
+ # it goes all the way down the chain of inheritance.
156
+ #
157
+ # ==== Parameters
158
+ #
159
+ # subclass<Merb::ControllerExceptions::Base>::
160
+ # The Exception class that is inheriting from Merb::ControllerExceptions::Base
161
+ def inherited(subclass)
162
+ # don't set the constant yet - any class methods will be called after self.inherited
163
+ # unless self.status = ... is set explicitly, the status code will be inherited
164
+ register_status_code(subclass, self.status) if self.status?
165
+ end
166
+
167
+ private
168
+
169
+ # Register the status-code for an Exception class.
170
+ #
171
+ # ==== Parameters
172
+ # num<~to_i>:: The status code
173
+ def register_status_code(klass, code)
174
+ STATUS_CODES[klass.name.to_sym] = code.to_i
175
+ end
176
+
177
+ end
178
+ end
179
+
180
+ class Informational < Merb::ControllerExceptions::Base; end
181
+
182
+ class Continue < Merb::ControllerExceptions::Informational; self.status = 100; end
183
+
184
+ class SwitchingProtocols < Merb::ControllerExceptions::Informational; self.status = 101; end
185
+
186
+ class Successful < Merb::ControllerExceptions::Base; end
187
+
188
+ class OK < Merb::ControllerExceptions::Successful; self.status = 200; end
189
+
190
+ class Created < Merb::ControllerExceptions::Successful; self.status = 201; end
191
+
192
+ class Accepted < Merb::ControllerExceptions::Successful; self.status = 202; end
193
+
194
+ class NonAuthoritativeInformation < Merb::ControllerExceptions::Successful; self.status = 203; end
195
+
196
+ class NoContent < Merb::ControllerExceptions::Successful; self.status = 204; end
197
+
198
+ class ResetContent < Merb::ControllerExceptions::Successful; self.status = 205; end
199
+
200
+ class PartialContent < Merb::ControllerExceptions::Successful; self.status = 206; end
201
+
202
+ class Redirection < Merb::ControllerExceptions::Base; end
203
+
204
+ class MultipleChoices < Merb::ControllerExceptions::Redirection; self.status = 300; end
205
+
206
+ class MovedPermanently < Merb::ControllerExceptions::Redirection; self.status = 301; end
207
+
208
+ class MovedTemporarily < Merb::ControllerExceptions::Redirection; self.status = 302; end
209
+
210
+ class SeeOther < Merb::ControllerExceptions::Redirection; self.status = 303; end
211
+
212
+ class NotModified < Merb::ControllerExceptions::Redirection; self.status = 304; end
213
+
214
+ class UseProxy < Merb::ControllerExceptions::Redirection; self.status = 305; end
215
+
216
+ class TemporaryRedirect < Merb::ControllerExceptions::Redirection; self.status = 307; end
217
+
218
+ class ClientError < Merb::ControllerExceptions::Base; end
219
+
220
+ class BadRequest < Merb::ControllerExceptions::ClientError; self.status = 400; end
221
+
222
+ class MultiPartParseError < Merb::ControllerExceptions::BadRequest; end
223
+
224
+ class Unauthorized < Merb::ControllerExceptions::ClientError; self.status = 401; end
225
+
226
+ class PaymentRequired < Merb::ControllerExceptions::ClientError; self.status = 402; end
227
+
228
+ class Forbidden < Merb::ControllerExceptions::ClientError; self.status = 403; end
229
+
230
+ class NotFound < Merb::ControllerExceptions::ClientError; self.status = 404; end
231
+
232
+ class ActionNotFound < Merb::ControllerExceptions::NotFound; end
233
+
234
+ class TemplateNotFound < Merb::ControllerExceptions::NotFound; end
235
+
236
+ class LayoutNotFound < Merb::ControllerExceptions::NotFound; end
237
+
238
+ class MethodNotAllowed < Merb::ControllerExceptions::ClientError; self.status = 405; end
239
+
240
+ class NotAcceptable < Merb::ControllerExceptions::ClientError; self.status = 406; end
241
+
242
+ class ProxyAuthenticationRequired < Merb::ControllerExceptions::ClientError; self.status = 407; end
243
+
244
+ class RequestTimeout < Merb::ControllerExceptions::ClientError; self.status = 408; end
245
+
246
+ class Conflict < Merb::ControllerExceptions::ClientError; self.status = 409; end
247
+
248
+ class Gone < Merb::ControllerExceptions::ClientError; self.status = 410; end
249
+
250
+ class LengthRequired < Merb::ControllerExceptions::ClientError; self.status = 411; end
251
+
252
+ class PreconditionFailed < Merb::ControllerExceptions::ClientError; self.status = 412; end
253
+
254
+ class RequestEntityTooLarge < Merb::ControllerExceptions::ClientError; self.status = 413; end
255
+
256
+ class RequestURITooLarge < Merb::ControllerExceptions::ClientError; self.status = 414; end
257
+
258
+ class UnsupportedMediaType < Merb::ControllerExceptions::ClientError; self.status = 415; end
259
+
260
+ class RequestRangeNotSatisfiable < Merb::ControllerExceptions::ClientError; self.status = 416; end
261
+
262
+ class ExpectationFailed < Merb::ControllerExceptions::ClientError; self.status = 417; end
263
+
264
+ class ServerError < Merb::ControllerExceptions::Base; end
265
+
266
+ class NotImplemented < Merb::ControllerExceptions::ServerError; self.status = 501; end
267
+
268
+ class BadGateway < Merb::ControllerExceptions::ServerError; self.status = 502; end
269
+
270
+ class ServiceUnavailable < Merb::ControllerExceptions::ServerError; self.status = 503; end
271
+
272
+ class GatewayTimeout < Merb::ControllerExceptions::ServerError; self.status = 504; end
273
+
274
+ class HTTPVersionNotSupported < Merb::ControllerExceptions::ServerError; self.status = 505; end
275
+
276
+ class InternalServerError < Merb::ControllerExceptions::ServerError #:doc:
277
+ self.status = 500;
278
+ # DEFAULT_TEMPLATE = ::Merb::Dispatcher::DEFAULT_ERROR_TEMPLATE
279
+ def initialize(exception = nil)
280
+ @exception = exception
281
+ @coderay = CodeRay rescue nil
282
+ end
283
+
284
+ def backtrace
285
+ @exception ? @exception.backtrace : backtrace
286
+ end
287
+
288
+ def message
289
+ @exception ? @exception.message : message
290
+ end
291
+ end
292
+ end
293
+
294
+ # Required to show exceptions in the log file
295
+ #
296
+ # e<Exception>:: The exception that a message is being generated for
297
+ def self.exception(e)
298
+ "#{ e.message } - (#{ e.class })\n" <<
299
+ "#{(e.backtrace or []).join("\n")}"
300
+ end
301
+
302
+ end
@@ -0,0 +1,256 @@
1
+ class Merb::Controller < Merb::AbstractController
2
+
3
+ class_inheritable_accessor :_hidden_actions, :_shown_actions
4
+ self._hidden_actions ||= []
5
+ self._shown_actions ||= []
6
+
7
+ cattr_accessor :_subclasses, :_session_id_key, :_session_secret_key, :_session_expiry, :_session_cookie_domain
8
+ self._subclasses = Set.new
9
+
10
+ def self.subclasses_list() _subclasses end
11
+
12
+ self._session_secret_key = nil
13
+ self._session_id_key = Merb::Config[:session_id_key] || '_session_id'
14
+ self._session_expiry = Merb::Config[:session_expiry] || Merb::Const::WEEK * 2
15
+ self._session_cookie_domain = Merb::Config[:session_cookie_domain]
16
+
17
+ include Merb::ResponderMixin
18
+ include Merb::ControllerMixin
19
+ include Merb::AuthenticationMixin
20
+
21
+ attr_accessor :route
22
+
23
+ class << self
24
+
25
+ # ==== Parameters
26
+ # klass<Merb::Controller>::
27
+ # The Merb::Controller inheriting from the base class.
28
+ def inherited(klass)
29
+ _subclasses << klass.to_s
30
+ super
31
+ klass._template_root = Merb.dir_for(:view) unless self._template_root
32
+ end
33
+
34
+ # Hide each of the given methods from being callable as actions.
35
+ #
36
+ # ==== Parameters
37
+ # *names<~to-s>:: Actions that should be added to the list.
38
+ #
39
+ # ==== Returns
40
+ # Array[String]::
41
+ # An array of actions that should not be possible to dispatch to.
42
+ #
43
+ #---
44
+ # @public
45
+ def hide_action(*names)
46
+ self._hidden_actions = self._hidden_actions | names.map { |n| n.to_s }
47
+ end
48
+
49
+ # Makes each of the given methods being callable as actions. You can use
50
+ # this to make methods included from modules callable as actions.
51
+ #
52
+ # ==== Parameters
53
+ # *names<~to-s>:: Actions that should be added to the list.
54
+ #
55
+ # ==== Returns
56
+ # Array[String]::
57
+ # An array of actions that should be dispatched to even if they would not
58
+ # otherwise be.
59
+ #
60
+ # ==== Example
61
+ # module Foo
62
+ # def self.included(base)
63
+ # base.show_action(:foo)
64
+ # end
65
+ #
66
+ # def foo
67
+ # # some actiony stuff
68
+ # end
69
+ #
70
+ # def foo_helper
71
+ # # this should not be an action
72
+ # end
73
+ # end
74
+ #
75
+ #---
76
+ # @public
77
+ def show_action(*names)
78
+ self._shown_actions = self._shown_actions | names.map {|n| n.to_s}
79
+ end
80
+
81
+ # The list of actions that are callable, after taking defaults,
82
+ # _hidden_actions and _shown_actions into consideration. It is calculated
83
+ # once, the first time an action is dispatched for this controller.
84
+ #
85
+ # ==== Returns
86
+ # SimpleSet[String]:: A set of actions that should be callable.
87
+ def callable_actions
88
+ @callable_actions ||= Extlib::SimpleSet.new(_callable_methods)
89
+ end
90
+
91
+ # This is a stub method so plugins can implement param filtering if they want.
92
+ #
93
+ # ==== Parameters
94
+ # params<Hash{Symbol => String}>:: A list of params
95
+ #
96
+ # ==== Returns
97
+ # Hash{Symbol => String}:: A new list of params, filtered as desired
98
+ #---
99
+ # @semipublic
100
+ def _filter_params(params)
101
+ params
102
+ end
103
+
104
+ private
105
+
106
+ # All methods that are callable as actions.
107
+ #
108
+ # ==== Returns
109
+ # Array:: A list of method names that are also actions
110
+ def _callable_methods
111
+ callables = []
112
+ klass = self
113
+ begin
114
+ callables << (klass.public_instance_methods(false) + klass._shown_actions) - klass._hidden_actions
115
+ klass = klass.superclass
116
+ end until klass == Merb::AbstractController || klass == Object
117
+ callables.flatten.reject{|action| action =~ /^_.*/}
118
+ end
119
+
120
+ end # class << self
121
+
122
+ # The location to look for a template for a particular controller, context,
123
+ # and mime-type. This is overridden from AbstractController, which defines a
124
+ # version of this that does not involve mime-types.
125
+ #
126
+ # ==== Parameters
127
+ # context<~to_s>:: The name of the action or template basename that will be rendered.
128
+ # type<~to_s>::
129
+ # The mime-type of the template that will be rendered. Defaults to nil.
130
+ # controller<~to_s>::
131
+ # The name of the controller that will be rendered. Defaults to
132
+ # controller_name.
133
+ #
134
+ # ==== Notes
135
+ # By default, this renders ":controller/:action.:type". To change this,
136
+ # override it in your application class or in individual controllers.
137
+ #
138
+ #---
139
+ # @public
140
+ def _template_location(context, type = nil, controller = controller_name)
141
+ _conditionally_append_extension(controller ? "#{controller}/#{context}" : "#{context}", type)
142
+ end
143
+
144
+ # The location to look for a template and mime-type. This is overridden
145
+ # from AbstractController, which defines a version of this that does not
146
+ # involve mime-types.
147
+ #
148
+ # ==== Parameters
149
+ # template<String>::
150
+ # The absolute path to a template - without mime and template extension.
151
+ # The mime-type extension is optional - it will be appended from the
152
+ # current content type if it hasn't been added already.
153
+ # type<~to_s>::
154
+ # The mime-type of the template that will be rendered. Defaults to nil.
155
+ #
156
+ # @public
157
+ def _absolute_template_location(template, type)
158
+ _conditionally_append_extension(template, type)
159
+ end
160
+
161
+ # Build a new controller.
162
+ #
163
+ # Sets the variables that came in through the dispatch as available to
164
+ # the controller.
165
+ #
166
+ # This method uses the :session_id_cookie_only and :query_string_whitelist
167
+ # configuration options. See CONFIG for more details.
168
+ #
169
+ # ==== Parameters
170
+ # request<Merb::Request>:: The Merb::Request that came in from Mongrel.
171
+ # status<Integer>:: An integer code for the status. Defaults to 200.
172
+ # headers<Hash{header => value}>::
173
+ # A hash of headers to start the controller with. These headers can be
174
+ # overridden later by the #headers method.
175
+ #---
176
+ # @semipublic
177
+ def initialize(request, status=200, headers={'Content-Type' => 'text/html; charset=utf-8'})
178
+ super()
179
+ @request, @_status, @headers = request, status, headers
180
+ end
181
+
182
+ # Dispatch the action.
183
+ #
184
+ # ==== Parameters
185
+ # action<~to_s>:: An action to dispatch to. Defaults to :index.
186
+ #
187
+ # ==== Returns
188
+ # String:: The string sent to the logger for time spent.
189
+ #
190
+ # ==== Raises
191
+ # ActionNotFound:: The requested action was not found in class.
192
+ #---
193
+ # @semipublic
194
+ def _dispatch(action=:index)
195
+ start = Time.now
196
+ if self.class.callable_actions.include?(action.to_s)
197
+ super(action)
198
+ else
199
+ raise ActionNotFound, "Action '#{action}' was not found in #{self.class}"
200
+ end
201
+ @_benchmarks[:action_time] = Time.now - start
202
+ end
203
+
204
+ attr_reader :request, :headers
205
+
206
+ def status
207
+ @_status
208
+ end
209
+
210
+ # Set the response status code.
211
+ #
212
+ # ==== Parameters
213
+ # s<Fixnum, Symbol>:: A status-code or named http-status
214
+ def status=(s)
215
+ if s.is_a?(Symbol) && STATUS_CODES.key?(s)
216
+ @_status = STATUS_CODES[s]
217
+ elsif s.is_a?(Fixnum)
218
+ @_status = s
219
+ else
220
+ raise ArgumentError, "Status should be of type Fixnum or Symbol, was #{s.class}"
221
+ end
222
+ end
223
+
224
+ # ==== Returns
225
+ # Hash:: The parameters from the request object
226
+ def params() request.params end
227
+
228
+ # ==== Returns
229
+ # Merb::Cookies::
230
+ # A new Merb::Cookies instance representing the cookies that came in
231
+ # from the request object
232
+ #
233
+ # ==== Notes
234
+ # Headers are passed into the cookie object so that you can do:
235
+ # cookies[:foo] = "bar"
236
+ def cookies() @_cookies ||= _setup_cookies end
237
+
238
+ # ==== Returns
239
+ # Hash:: The session that was extracted from the request object.
240
+ def session() request.session end
241
+
242
+ # Hide any methods that may have been exposed as actions before.
243
+ hide_action(*_callable_methods)
244
+
245
+ private
246
+
247
+ # If not already added, add the proper mime extension to the template path.
248
+ def _conditionally_append_extension(template, type = nil)
249
+ type && !template.match(/\.#{type.to_s.escape_regexp}$/) ? "#{template}.#{type}" : template
250
+ end
251
+
252
+ # Create a default cookie jar, and pre-set a fixation cookie if fixation is enabled.
253
+ def _setup_cookies
254
+ ::Merb::Cookies.new(request.cookies, @headers)
255
+ end
256
+ end