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,52 @@
1
+ module Merb
2
+
3
+ class Router
4
+ # Cache procs for future reference in eval statement
5
+ class CachedProc
6
+ @@index = 0
7
+ @@list = []
8
+
9
+ attr_accessor :cache, :index
10
+
11
+ # ==== Parameters
12
+ # cache<Proc>:: The block of code to cache.
13
+ def initialize(cache)
14
+ @cache, @index = cache, CachedProc.register(self)
15
+ end
16
+
17
+ # ==== Returns
18
+ # String:: The CachedProc object in a format embeddable within a string.
19
+ def to_s
20
+ "CachedProc[#{@index}].cache"
21
+ end
22
+
23
+ class << self
24
+
25
+ # ==== Parameters
26
+ # cached_code<CachedProc>:: The cached code to register.
27
+ #
28
+ # ==== Returns
29
+ # Fixnum:: The index of the newly registered CachedProc.
30
+ def register(cached_code)
31
+ CachedProc[@@index] = cached_code
32
+ @@index += 1
33
+ @@index - 1
34
+ end
35
+
36
+ # Sets the cached code for a specific index.
37
+ #
38
+ # ==== Parameters
39
+ # index<Fixnum>:: The index of the cached code to set.
40
+ # code<CachedProc>:: The cached code to set.
41
+ def []=(index, code) @@list[index] = code end
42
+
43
+ # ==== Parameters
44
+ # index<Fixnum>:: The index of the cached code to retrieve.
45
+ #
46
+ # ==== Returns
47
+ # CachedProc:: The cached code at index.
48
+ def [](index) @@list[index] end
49
+ end
50
+ end # CachedProc
51
+ end
52
+ end
@@ -0,0 +1,321 @@
1
+ require 'merb-core/controller/mixins/responder'
2
+ module Merb
3
+
4
+ class Router
5
+ # Route instances incapsulate information about particular route
6
+ # definition. Route definition ties
7
+ # number of conditions (URL match, HTTP request method) with
8
+ # resulting hash of route parameters:
9
+ # controller, action, format and named parameters
10
+ # from the URL.
11
+ #
12
+ # The following routes definition:
13
+ #
14
+ # Merb::Router.prepare do |r|
15
+ # r.match("api/:action/:token.:format").to(:controller => "dev").fixatable
16
+ # end
17
+ #
18
+ # maps URL matching pattern to controller named "dev"
19
+ # and specifies fixation for that route. Path and request method are
20
+ # route conditions, controller name, action name, format and
21
+ # value of segment we decided to call :token are route parameters.
22
+ #
23
+ # ==== How route definitions are used.
24
+ #
25
+ # When routes are compiled, each route produces
26
+ # a string with eval-able if/elsif condition statement.
27
+ # This statement together with others constructs body
28
+ # of Merb::Router.match method.
29
+ # Condition statements are Ruby code in form of string.
30
+ #
31
+ # ==== Segments.
32
+ #
33
+ # Route definitions use conventional syntax for named parameters.
34
+ # This splits route path into segments. Static (not changing) segments
35
+ # represented internally as strings, named parameters are stored
36
+ # as symbols and called symbol segments. Symbol segments
37
+ # map to groups in regular expression in resulting condition statement.
38
+ #
39
+ # ==== Route conditions.
40
+ #
41
+ # Because route conditions include path matching,
42
+ # regular expression is created from string that uses
43
+ # :segment format to fetch groups and assign them to
44
+ # named parameters. This regular expression is used
45
+ # to produce compiled statement mentioned above.
46
+ #
47
+ # Route conditions may also include
48
+ # user agent. Symbol segments
49
+ #
50
+ # Here is example of Route conditions:
51
+ # {
52
+ # :path => /^\/continents\/?(\.([^\/.,;?]+))?$/,
53
+ # :method => /^get$/
54
+ # }
55
+ #
56
+ #
57
+ # ==== Route parameters.
58
+ #
59
+ # Route parameters is a Hash with controller name,
60
+ # action name and parameters key/value pairs.
61
+ # It is then merged with request.params hash.
62
+ #
63
+ # Example of route parameters:
64
+ #
65
+ # {
66
+ # :action => "\"index\"",
67
+ # :format => "path2",
68
+ # :controller => "\"continents\""
69
+ # }
70
+ #
71
+ # Router takes first matching route and uses it's parameters
72
+ # to dispatch request to certain controller and action.
73
+ #
74
+ # ==== Behavior
75
+ #
76
+ # Each route has utility collaborator called behavior
77
+ # that incapsulates additional information about route
78
+ # (like namespace or if route is deferred) and also
79
+ # provides utility methods.
80
+ #
81
+ # ==== Route registration.
82
+ #
83
+ # When route is added to set of routes, it is called route
84
+ # registration. Registred route knows it's index in routes set.
85
+ #
86
+ # ==== Fixation
87
+ # Fixatable routes allow setting of session key from GET params
88
+ # found in incoming request. This is very useful to allow certain
89
+ # URLs to be used by rich media applications and other kinds
90
+ # of clients that have no other way of passing session identifier.
91
+ #
92
+ # ==== Conditional block.
93
+ # Conditional block is anonymous function that is evaluated
94
+ # when deferred routes are processed. Unless route is deferred,
95
+ # it has no condition block.
96
+ class Route
97
+ attr_reader :conditions, :conditional_block
98
+ attr_reader :params, :behavior, :segments, :index, :symbol
99
+
100
+ # ==== Parameters
101
+ # conditions<Hash>:: Conditions for the route.
102
+ # params<Hash>:: Parameters for the route.
103
+ # behavior<Merb::Router::Behavior>::
104
+ # The associated behavior. Defaults to nil.
105
+ # &conditional_block::
106
+ # A block with the conditions to be met for the route to take effect.
107
+ def initialize(conditions, params, behavior = nil, &conditional_block)
108
+ @conditions, @params, @behavior = conditions, params, behavior
109
+ @conditional_block = conditional_block
110
+ @fixation=false
111
+ if @behavior && (path = @behavior.merged_original_conditions[:path])
112
+ @segments = segments_from_path(path)
113
+ end
114
+ end
115
+
116
+ # ==== Returns
117
+ # Boolean:: True if fixation is allowed.
118
+ def allow_fixation?
119
+ @fixation
120
+ end
121
+
122
+ # ==== Parameters
123
+ # enabled<Boolean>:: True enables fixation on the route.
124
+ def fixatable(enable=true)
125
+ @fixation = enable
126
+ self
127
+ end
128
+
129
+ # Concatenates all route segments and returns result.
130
+ # Symbol segments have colon preserved.
131
+ #
132
+ # ==== Returns
133
+ # String:: The route as a string, e.g. "admin/:controller/:id".
134
+ def to_s
135
+ (segments || []).inject('') do |str,seg|
136
+ str << (seg.is_a?(Symbol) ? ":#{seg}" : seg)
137
+ end
138
+ end
139
+
140
+ # Registers the route in the Router.routes array.
141
+ # After registration route has index.
142
+ def register
143
+ @index = Router.routes.size
144
+ Router.routes << self
145
+ self
146
+ end
147
+
148
+ # ==== Returns
149
+ # Array:: All the symbols in the segments array.
150
+ def symbol_segments
151
+ (segments || []).select{ |s| s.is_a?(Symbol) }
152
+ end
153
+
154
+ # Turn a path into string and symbol segments so it can be reconstructed,
155
+ # as in the case of a named route.
156
+ #
157
+ # ==== Parameters
158
+ # path<String>:: The path to split into segments.
159
+ #
160
+ # ==== Returns
161
+ # Array:: The Symbol and String segments for the path.
162
+ def segments_from_path(path)
163
+ # Remove leading ^ and trailing $ from each segment (left-overs from regexp joining)
164
+ strip = proc { |str| str.gsub(/^\^/, '').gsub(/\$$/, '') }
165
+ segments = []
166
+ while match = (path.match(SEGMENT_REGEXP))
167
+ segments << strip[match.pre_match] unless match.pre_match.empty?
168
+ segments << match[2].intern
169
+ path = strip[match.post_match]
170
+ end
171
+ segments << strip[path] unless path.empty?
172
+ segments
173
+ end
174
+
175
+ # Names this route in Router. Name must be a Symbol.
176
+ #
177
+ # ==== Parameters
178
+ # symbol<Symbol>:: The name of the route.
179
+ #
180
+ # ==== Raises
181
+ # ArgumentError:: symbol is not a Symbol.
182
+ def name(symbol = nil)
183
+ raise ArgumentError unless (@symbol = symbol).is_a?(Symbol)
184
+ Router.named_routes[@symbol] = self
185
+ end
186
+
187
+ # ==== Returns
188
+ # Boolean::
189
+ # True if this route is a regexp, i.e. its behavior or one of the
190
+ # behavior's ancestors is a regexp.
191
+ def regexp?
192
+ @regexp ||= behavior.regexp? || behavior.ancestors.any? { |a| a.regexp? }
193
+ end
194
+
195
+ # Generates URL using route segments and given parameters.
196
+ # If parameter value responds to :to_param, it is called.
197
+ #
198
+ # ==== Parameters
199
+ # params<Hash>:: Optional parameters for the route.
200
+ # fallback<Hash>:: Optional parameters for the fallback route.
201
+ #
202
+ # ==== Returns
203
+ # String::
204
+ # The URL corresponding to the params, using the stored route segments
205
+ # for reconstruction of the URL.
206
+ def generate(params = {}, fallback = {})
207
+ raise "Cannot generate regexp Routes" if regexp?
208
+ query_params = params.dup if params.is_a? Hash
209
+ url = @segments.map do |segment|
210
+ value =
211
+ if segment.is_a? Symbol
212
+ if params.is_a? Hash
213
+ if segment.to_s =~ /_id/ && params[:id].respond_to?(segment)
214
+ params[segment] = params[:id].send(segment)
215
+ end
216
+ query_params.delete segment
217
+ params[segment] || fallback[segment]
218
+ else
219
+ if segment == :id && params.respond_to?(:to_param)
220
+ params.to_param
221
+ elsif segment == :id && params.is_a?(Fixnum)
222
+ params
223
+ elsif params.respond_to?(segment)
224
+ params.send(segment)
225
+ else
226
+ fallback[segment]
227
+ end
228
+ end
229
+ elsif segment.respond_to? :to_s
230
+ segment
231
+ else
232
+ raise "Segment type '#{segment.class}' can't be converted to a string"
233
+ end
234
+ (value.respond_to?(:to_param) ? value.to_param : value).to_s.unescape_regexp
235
+ end.join
236
+ if query_params && format = query_params.delete(:format)
237
+ format = fallback[:format] if format == :current
238
+ url += ".#{format}"
239
+ end
240
+ if query_params && !query_params.empty?
241
+ url += "?" + Merb::Request.params_to_query_string(query_params)
242
+ end
243
+ url
244
+ end
245
+
246
+ # Generates and returns if statement used to
247
+ # construct final condition statement of the route.
248
+ #
249
+ # ==== Params
250
+ # params_as_string<String>::
251
+ # The params hash as a string, e.g. ":foo => 'bar'".
252
+ #
253
+ # ==== Returns
254
+ # Array:: All the conditions as eval'able strings.
255
+ def if_conditions(params_as_string)
256
+ cond = []
257
+ condition_string = proc do |key, value, regexp_string|
258
+ max = Behavior.count_parens_up_to(value.source, value.source.size)
259
+ captures = max == 0 ? "" : (1..max).to_a.map{ |n| "#{key}#{n}" }.join(", ") + " = " +
260
+ (1..max).to_a.map{ |n| "$#{n}"}.join(", ")
261
+ " (#{value.inspect} =~ #{regexp_string}) #{" && (" + captures + ")" unless captures.empty?}"
262
+ end
263
+ @conditions.each_pair do |key, value|
264
+
265
+ # Note: =~ is slightly faster than .match
266
+ cond << case key
267
+ when :path then condition_string[key, value, "cached_path"]
268
+ when :method then condition_string[key, value, "cached_method"]
269
+ else condition_string[key, value, "request.#{key}.to_s"]
270
+ end
271
+ end
272
+ if @conditional_block
273
+ str = " # #{@conditional_block.inspect.scan(/@([^>]+)/).flatten.first}\n"
274
+ str << " (block_result = #{CachedProc.new(@conditional_block)}.call(request, params.merge({#{params_as_string}})))" if @conditional_block
275
+ cond << str
276
+ end
277
+ cond
278
+ end
279
+
280
+ # Compiles the route to a form used by Merb::Router. This form sometimes
281
+ # referred as condition statement of the route.
282
+ #
283
+ # ==== Parameters
284
+ # first<Boolean>::
285
+ # True if this is the first route in set of routes. Defaults to false.
286
+ #
287
+ # ==== Returns
288
+ # String:: The code corresponding to the route in a form suited for eval.
289
+ def compile(first = false)
290
+ code = ""
291
+ default_params = { :action => "index" }
292
+ get_value = proc do |key|
293
+ if default_params.has_key?(key) && params[key][0] != ?"
294
+ "#{params[key]} || \"#{default_params[key]}\""
295
+ else
296
+ "#{params[key]}"
297
+ end
298
+ end
299
+ params_as_string = params.keys.map { |k| "#{k.inspect} => #{get_value[k]}" }.join(', ')
300
+ code << " els" unless first
301
+ code << "if # #{@behavior.merged_original_conditions.inspect} \n"
302
+ code << if_conditions(params_as_string).join(" && ") << "\n"
303
+ code << " # then\n"
304
+ if @conditional_block
305
+ code << " [#{@index.inspect}, block_result]\n"
306
+ else
307
+ code << " [#{@index.inspect}, {#{params_as_string}}]\n"
308
+ end
309
+ end
310
+
311
+ # Prints a trace of the behavior for this route.
312
+ def behavior_trace
313
+ if @behavior
314
+ puts @behavior.send(:ancestors).reverse.map{|a| a.inspect}.join("\n"); puts @behavior.inspect; puts
315
+ else
316
+ puts "No behavior to trace #{self}"
317
+ end
318
+ end
319
+ end # Route
320
+ end
321
+ end
@@ -0,0 +1,78 @@
1
+ module Merb
2
+
3
+ module SessionMixin
4
+ # Sets the session id cookie, along with the correct
5
+ # expiry and domain -- used for new or reset sessions
6
+ def set_session_id_cookie(key)
7
+ options = {}
8
+ options[:value] = key
9
+ options[:expires] = Time.now + _session_expiry if _session_expiry > 0
10
+ options[:domain] = _session_cookie_domain if _session_cookie_domain
11
+ cookies[_session_id_key] = options
12
+ end
13
+
14
+ @_finalize_session_exception_callbacks = []
15
+ @_persist_exception_callbacks = []
16
+
17
+ # ==== Returns
18
+ # String:: A random 32 character string for use as a unique session ID.
19
+ def rand_uuid
20
+ values = [
21
+ rand(0x0010000),
22
+ rand(0x0010000),
23
+ rand(0x0010000),
24
+ rand(0x0010000),
25
+ rand(0x0010000),
26
+ rand(0x1000000),
27
+ rand(0x1000000),
28
+ ]
29
+ "%04x%04x%04x%04x%04x%06x%06x" % values
30
+ end
31
+
32
+ # Marks this session as needing a new cookie.
33
+ def needs_new_cookie!
34
+ @_new_cookie = true
35
+ end
36
+
37
+ # Adds a callback to the list of callbacks run when
38
+ # exception is raised on session finalization, so
39
+ # you can recover.
40
+ #
41
+ # See session mixins documentation for details on
42
+ # session finalization.
43
+ #
44
+ # ==== Params
45
+ # &block::
46
+ # A block to be added to the callbacks that will be executed
47
+ # if there's exception on session finalization.
48
+ def finalize_session_exception_callbacks(&block)
49
+ if block_given?
50
+ @_finalize_session_exception_callbacks << block
51
+ else
52
+ @_finalize_session_exception_callbacks
53
+ end
54
+ end
55
+
56
+ # Adds a callback to the list of callbacks run when
57
+ # exception is raised on session persisting, so
58
+ # you can recover.
59
+ #
60
+ # See session mixins documentation for details on
61
+ # session persisting.
62
+ #
63
+ # ==== Params
64
+ # &block::
65
+ # A block to be added to the callbacks that will be executed
66
+ # if there's exception on session persisting.
67
+ def persist_exception_callbacks(&block)
68
+ if block_given?
69
+ @_persist_exception_callbacks << block
70
+ else
71
+ @_persist_exception_callbacks
72
+ end
73
+ end
74
+
75
+ module_function :rand_uuid, :needs_new_cookie!, :finalize_session_exception_callbacks, :persist_exception_callbacks
76
+ end
77
+
78
+ end