middleman 2.0.16.1 → 3.0.0.alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (259) hide show
  1. data/.gitignore +2 -1
  2. data/CHANGELOG +16 -8
  3. data/features/builder.feature +2 -5
  4. data/features/cache_buster.feature +1 -1
  5. data/features/clean_build.feature +0 -1
  6. data/features/coffee-script.feature +3 -3
  7. data/features/custom_layout_engines.feature +10 -0
  8. data/features/directory_index.feature +0 -1
  9. data/features/dynamic_pages.feature +0 -1
  10. data/features/fonts.feature +0 -1
  11. data/features/{padrino_helpers.feature → former_padrino_helpers.feature} +1 -1
  12. data/features/sprockets.feature +34 -5
  13. data/features/sprockets_gems.feature +7 -4
  14. data/features/step_definitions/asset_host_steps.rb +7 -6
  15. data/features/step_definitions/builder_steps.rb +4 -0
  16. data/features/step_definitions/middleman_steps.rb +22 -16
  17. data/features/step_definitions/page_layout_steps.rb +10 -8
  18. data/fixtures/custom-layout-app/config.rb +1 -0
  19. data/fixtures/custom-layout-app/source/index.html.erb +1 -0
  20. data/fixtures/custom-layout-app/source/layout.haml +6 -0
  21. data/fixtures/sprockets-app/config.rb +2 -1
  22. data/fixtures/sprockets-app/source/library/css/bootstrap_include.css.scss +1 -0
  23. data/fixtures/sprockets-app/source/library/css/plain.css +3 -0
  24. data/fixtures/sprockets-app/source/library/css/sprockets_base1.css.scss +1 -0
  25. data/fixtures/sprockets-app/source/library/css/sprockets_base2.css.scss +1 -0
  26. data/fixtures/sprockets-app/source/library/css/sprockets_sub.css.scss +1 -0
  27. data/fixtures/sprockets-app/source/{jquery_include.js → library/js/jquery_include.js} +0 -0
  28. data/fixtures/sprockets-app/source/library/js/plain.js +3 -0
  29. data/fixtures/sprockets-app/source/library/{javascripts → js}/sprockets_base.js +0 -0
  30. data/fixtures/sprockets-app/source/library/{javascripts → js}/sprockets_sub.js +0 -0
  31. data/fixtures/test-app/config.rb +5 -4
  32. data/fixtures/test-app/source/{padrino_test.html.haml → former_padrino_test.html.haml} +0 -0
  33. data/fixtures/test-app/source/stylesheets/sprockets_base1.css.scss +1 -0
  34. data/fixtures/test-app/source/stylesheets/sprockets_base2.css.scss +1 -0
  35. data/fixtures/test-app/source/stylesheets/sprockets_sub.css.scss +1 -0
  36. data/lib/middleman.rb +27 -25
  37. data/lib/middleman/base.rb +408 -166
  38. data/lib/middleman/builder.rb +78 -162
  39. data/lib/middleman/cli.rb +61 -32
  40. data/lib/middleman/core_extensions/assets.rb +4 -44
  41. data/lib/middleman/core_extensions/builder.rb +12 -16
  42. data/lib/middleman/core_extensions/compass.rb +28 -57
  43. data/lib/middleman/core_extensions/data.rb +65 -49
  44. data/lib/middleman/core_extensions/default_helpers.rb +33 -18
  45. data/lib/middleman/core_extensions/features.rb +48 -26
  46. data/lib/middleman/core_extensions/file_watcher.rb +66 -0
  47. data/lib/middleman/core_extensions/front_matter.rb +91 -86
  48. data/lib/middleman/core_extensions/rendering.rb +9 -8
  49. data/lib/middleman/core_extensions/routing.rb +19 -53
  50. data/lib/middleman/core_extensions/sitemap.rb +229 -0
  51. data/lib/middleman/core_extensions/sprockets.rb +53 -37
  52. data/lib/middleman/features/asset_host.rb +20 -10
  53. data/lib/middleman/features/automatic_image_sizes.rb +12 -9
  54. data/lib/middleman/features/cache_buster.rb +38 -25
  55. data/lib/middleman/features/directory_indexes.rb +31 -28
  56. data/lib/middleman/features/minify_css.rb +3 -2
  57. data/lib/middleman/features/minify_css/cssmin.rb +55 -0
  58. data/lib/middleman/features/minify_javascript.rb +12 -5
  59. data/lib/middleman/features/relative_assets.rb +28 -25
  60. data/lib/middleman/features/sitemap_tree.rb +34 -0
  61. data/lib/middleman/guard.rb +57 -23
  62. data/lib/middleman/renderers/erb.rb +29 -0
  63. data/lib/middleman/renderers/liquid.rb +3 -12
  64. data/lib/middleman/renderers/markdown.rb +16 -15
  65. data/lib/middleman/renderers/sass.rb +34 -38
  66. data/lib/middleman/vendor/hooks-0.2.0/CHANGES.textile +9 -0
  67. data/lib/middleman/vendor/hooks-0.2.0/Gemfile +3 -0
  68. data/lib/middleman/vendor/hooks-0.2.0/README.rdoc +107 -0
  69. data/lib/middleman/vendor/hooks-0.2.0/Rakefile +12 -0
  70. data/lib/middleman/vendor/hooks-0.2.0/hooks.gemspec +22 -0
  71. data/lib/middleman/vendor/hooks-0.2.0/lib/hooks.rb +109 -0
  72. data/lib/middleman/vendor/hooks-0.2.0/lib/hooks/inheritable_attribute.rb +33 -0
  73. data/lib/middleman/vendor/hooks-0.2.0/test/hooks_test.rb +141 -0
  74. data/lib/middleman/vendor/hooks-0.2.0/test/inheritable_attribute_test.rb +55 -0
  75. data/lib/middleman/vendor/hooks-0.2.0/test/test_helper.rb +10 -0
  76. data/lib/middleman/vendor/padrino-core-0.10.5/.document +5 -0
  77. data/lib/middleman/vendor/padrino-core-0.10.5/.gitignore +22 -0
  78. data/lib/middleman/vendor/padrino-core-0.10.5/.yardopts +1 -0
  79. data/lib/middleman/vendor/padrino-core-0.10.5/LICENSE.txt +20 -0
  80. data/lib/middleman/vendor/padrino-core-0.10.5/README.rdoc +294 -0
  81. data/lib/middleman/vendor/padrino-core-0.10.5/Rakefile +5 -0
  82. data/lib/middleman/vendor/padrino-core-0.10.5/bin/padrino +9 -0
  83. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core.rb +167 -0
  84. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application.rb +270 -0
  85. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/rendering.rb +292 -0
  86. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/routing.rb +934 -0
  87. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/application/showexceptions.rb +20 -0
  88. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/caller.rb +53 -0
  89. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/adapter.rb +24 -0
  90. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/base.rb +151 -0
  91. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/console.rb +20 -0
  92. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake.rb +24 -0
  93. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake_tasks.rb +59 -0
  94. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/command.rb +38 -0
  95. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/404.png +0 -0
  96. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/images/500.png +0 -0
  97. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/loader.rb +210 -0
  98. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/cs.yml +34 -0
  99. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/da.yml +34 -0
  100. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/de.yml +34 -0
  101. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/en.yml +34 -0
  102. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/es.yml +34 -0
  103. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/fr.yml +34 -0
  104. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/hu.yml +34 -0
  105. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/it.yml +40 -0
  106. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ja.yml +34 -0
  107. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/lv.yml +34 -0
  108. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/nl.yml +34 -0
  109. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/no.yml +35 -0
  110. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pl.yml +34 -0
  111. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pt_br.yml +40 -0
  112. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ru.yml +35 -0
  113. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/tr.yml +34 -0
  114. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/uk.yml +34 -0
  115. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_cn.yml +34 -0
  116. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_tw.yml +34 -0
  117. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/logger.rb +345 -0
  118. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/mounter.rb +224 -0
  119. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/reloader.rb +254 -0
  120. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/router.rb +98 -0
  121. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/server.rb +79 -0
  122. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite.rb +199 -0
  123. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/tasks.rb +21 -0
  124. data/lib/middleman/vendor/padrino-core-0.10.5/lib/padrino-core/version.rb +20 -0
  125. data/lib/middleman/vendor/padrino-core-0.10.5/padrino-core.gemspec +38 -0
  126. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/.components +6 -0
  127. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/.gitignore +7 -0
  128. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/complex.rb +32 -0
  129. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/apps/simple.rb +33 -0
  130. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/a.rb +9 -0
  131. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/b.rb +4 -0
  132. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/c.rb +1 -0
  133. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/e.rb +13 -0
  134. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/f.rb +2 -0
  135. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/g.rb +2 -0
  136. data/lib/middleman/vendor/padrino-core-0.10.5/test/fixtures/dependencies/d.rb +4 -0
  137. data/lib/middleman/vendor/padrino-core-0.10.5/test/helper.rb +81 -0
  138. data/lib/middleman/vendor/padrino-core-0.10.5/test/mini_shoulda.rb +45 -0
  139. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_application.rb +108 -0
  140. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_core.rb +79 -0
  141. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_dependencies.rb +44 -0
  142. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_filters.rb +278 -0
  143. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_locale.rb +21 -0
  144. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_logger.rb +100 -0
  145. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_mounter.rb +177 -0
  146. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_reloader_complex.rb +75 -0
  147. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_reloader_simple.rb +98 -0
  148. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_rendering.rb +461 -0
  149. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_restful_routing.rb +33 -0
  150. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_router.rb +146 -0
  151. data/lib/middleman/vendor/padrino-core-0.10.5/test/test_routing.rb +1673 -0
  152. data/lib/middleman/vendor/padrino-helpers-0.10.5/.document +5 -0
  153. data/lib/middleman/vendor/padrino-helpers-0.10.5/.gitignore +21 -0
  154. data/lib/middleman/vendor/padrino-helpers-0.10.5/.yardopts +1 -0
  155. data/lib/middleman/vendor/padrino-helpers-0.10.5/LICENSE.txt +20 -0
  156. data/lib/middleman/vendor/padrino-helpers-0.10.5/README.rdoc +239 -0
  157. data/lib/middleman/vendor/padrino-helpers-0.10.5/Rakefile +5 -0
  158. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers.rb +58 -0
  159. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/asset_tag_helpers.rb +420 -0
  160. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/abstract_form_builder.rb +220 -0
  161. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/standard_form_builder.rb +43 -0
  162. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_helpers.rb +602 -0
  163. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/format_helpers.rb +381 -0
  164. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/cs.yml +103 -0
  165. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/da.yml +91 -0
  166. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/de.yml +81 -0
  167. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/en.yml +103 -0
  168. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/es.yml +103 -0
  169. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/fr.yml +80 -0
  170. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/hu.yml +103 -0
  171. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/it.yml +89 -0
  172. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ja.yml +103 -0
  173. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/lv.yml +103 -0
  174. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/nl.yml +82 -0
  175. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/no.yml +91 -0
  176. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pl.yml +95 -0
  177. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pt_br.yml +103 -0
  178. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ru.yml +103 -0
  179. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/tr.yml +103 -0
  180. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/uk.yml +103 -0
  181. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_cn.yml +104 -0
  182. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_tw.yml +103 -0
  183. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/number_helpers.rb +288 -0
  184. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers.rb +175 -0
  185. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/abstract_handler.rb +98 -0
  186. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/erb_handler.rb +79 -0
  187. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/haml_handler.rb +63 -0
  188. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/slim_handler.rb +81 -0
  189. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/render_helpers.rb +60 -0
  190. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/tag_helpers.rb +103 -0
  191. data/lib/middleman/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/translation_helpers.rb +38 -0
  192. data/lib/middleman/vendor/padrino-helpers-0.10.5/padrino-helpers.gemspec +27 -0
  193. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/app.rb +73 -0
  194. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.erb +14 -0
  195. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.haml +12 -0
  196. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.slim +13 -0
  197. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.erb +14 -0
  198. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.haml +12 -0
  199. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.slim +12 -0
  200. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.erb +11 -0
  201. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.haml +9 -0
  202. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.slim +9 -0
  203. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.erb +5 -0
  204. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.haml +5 -0
  205. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.slim +5 -0
  206. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.erb +20 -0
  207. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.haml +15 -0
  208. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.slim +15 -0
  209. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.erb +56 -0
  210. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.haml +47 -0
  211. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.slim +47 -0
  212. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.erb +56 -0
  213. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.haml +45 -0
  214. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.slim +45 -0
  215. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.erb +5 -0
  216. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.haml +4 -0
  217. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.slim +4 -0
  218. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.erb +3 -0
  219. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.haml +3 -0
  220. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.slim +3 -0
  221. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.erb +3 -0
  222. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.haml +3 -0
  223. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.slim +3 -0
  224. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_erb.erb +1 -0
  225. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_haml.haml +1 -0
  226. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_slim.slim +1 -0
  227. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.erb +1 -0
  228. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.haml +1 -0
  229. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.slim +1 -0
  230. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/app.rb +50 -0
  231. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engine.haml +5 -0
  232. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_erb.erb +1 -0
  233. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_haml.haml +1 -0
  234. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_slim.slim +1 -0
  235. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/erb/test.erb +1 -0
  236. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/explicit_engine.haml +5 -0
  237. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/haml/test.haml +1 -0
  238. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/_user.haml +7 -0
  239. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/haml_template.haml +1 -0
  240. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/some_template.haml +2 -0
  241. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/helper.rb +66 -0
  242. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_asset_tag_helpers.rb +320 -0
  243. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_builder.rb +996 -0
  244. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_form_helpers.rb +645 -0
  245. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_format_helpers.rb +227 -0
  246. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_locale.rb +20 -0
  247. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_number_helpers.rb +136 -0
  248. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_output_helpers.rb +153 -0
  249. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_render_helpers.rb +76 -0
  250. data/lib/middleman/vendor/padrino-helpers-0.10.5/test/test_tag_helpers.rb +105 -0
  251. data/lib/middleman/version.rb +1 -1
  252. data/middleman-x86-mingw32.gemspec +16 -33
  253. data/middleman.gemspec +16 -31
  254. metadata +590 -349
  255. data/features/sinatra.feature +0 -6
  256. data/lib/middleman/core_extensions/rack_map.rb +0 -35
  257. data/lib/middleman/renderers/coffee_script.rb +0 -8
  258. data/lib/middleman/renderers/haml.rb +0 -31
  259. data/lib/middleman/renderers/slim.rb +0 -8
@@ -0,0 +1,33 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ describe "Routing" do
4
+ should 'perform restul routing' do
5
+ mock_app do
6
+ controller :parent => :parents do
7
+ get :index do
8
+ "#{url_for(:index, params[:parent_id])} get"
9
+ end
10
+
11
+ put :index, :with => :asset_id do
12
+ "#{url_for(:index, params[:parent_id], :asset_id => params[:asset_id])} put"
13
+ end
14
+
15
+ post :index, :with => :asset_id do
16
+ "#{url_for(:index, :parent_id => params[:parent_id], :asset_id => params[:asset_id])} post"
17
+ end
18
+
19
+ delete :index, :with => :asset_id do
20
+ "#{url_for(:index, params[:parent_id], :asset_id => params[:asset_id])} delete"
21
+ end
22
+ end
23
+ end
24
+ get "/parents/1"
25
+ assert_equal "/parents/1 get", body
26
+ put "/parents/1/hi"
27
+ assert_equal "/parents/1/hi put", body
28
+ post "/parents/1/hi"
29
+ assert_equal "/parents/1/hi post", body
30
+ delete "/parents/1/hi"
31
+ assert_equal "/parents/1/hi delete", body
32
+ end
33
+ end
@@ -0,0 +1,146 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+ require File.expand_path(File.dirname(__FILE__) + '/fixtures/apps/simple')
3
+
4
+ describe "Router" do
5
+
6
+ def setup
7
+ Padrino.clear!
8
+ end
9
+
10
+ should "dispatch paths correctly" do
11
+ app = lambda { |env|
12
+ [200, {
13
+ 'X-ScriptName' => env['SCRIPT_NAME'],
14
+ 'X-PathInfo' => env['PATH_INFO'],
15
+ 'Content-Type' => 'text/plain'
16
+ }, [""]]
17
+ }
18
+ map = Padrino::Router.new(
19
+ { :path => '/bar', :to => app },
20
+ { :path => '/foo', :to => app },
21
+ { :path => '/foo/bar', :to => app }
22
+ )
23
+
24
+ res = Rack::MockRequest.new(map).get("/")
25
+ assert res.not_found?
26
+
27
+ res = Rack::MockRequest.new(map).get("/qux")
28
+ assert res.not_found?
29
+
30
+ res = Rack::MockRequest.new(map).get("/foo")
31
+ assert res.ok?
32
+ assert_equal "/foo", res["X-ScriptName"]
33
+ assert_equal "/", res["X-PathInfo"]
34
+
35
+ res = Rack::MockRequest.new(map).get("/foo/")
36
+ assert res.ok?
37
+ assert_equal "/foo", res["X-ScriptName"]
38
+ assert_equal "/", res["X-PathInfo"]
39
+
40
+ res = Rack::MockRequest.new(map).get("/foo/bar")
41
+ assert res.ok?
42
+ assert_equal "/foo/bar", res["X-ScriptName"]
43
+ assert_equal "/", res["X-PathInfo"]
44
+
45
+ res = Rack::MockRequest.new(map).get("/foo/bar/")
46
+ assert res.ok?
47
+ assert_equal "/foo/bar", res["X-ScriptName"]
48
+ assert_equal "/", res["X-PathInfo"]
49
+
50
+ res = Rack::MockRequest.new(map).get("/foo///bar//quux")
51
+ assert_equal 200, res.status
52
+ assert res.ok?
53
+ assert_equal "/foo/bar", res["X-ScriptName"]
54
+ assert_equal "//quux", res["X-PathInfo"]
55
+
56
+ res = Rack::MockRequest.new(map).get("/foo/quux", "SCRIPT_NAME" => "/bleh")
57
+ assert res.ok?
58
+ assert_equal "/bleh/foo", res["X-ScriptName"]
59
+ assert_equal "/quux", res["X-PathInfo"]
60
+
61
+ res = Rack::MockRequest.new(map).get("/bar", 'HTTP_HOST' => 'foo.org')
62
+ assert res.ok?
63
+ assert_equal "/bar", res["X-ScriptName"]
64
+ assert_equal "/", res["X-PathInfo"]
65
+
66
+ res = Rack::MockRequest.new(map).get("/bar/", 'HTTP_HOST' => 'foo.org')
67
+ assert res.ok?
68
+ assert_equal "/bar", res["X-ScriptName"]
69
+ assert_equal "/", res["X-PathInfo"]
70
+ end
71
+
72
+ should "dispatches hosts correctly" do
73
+ map = Padrino::Router.new(
74
+ { :host => "foo.org", :to => lambda { |env|
75
+ [200,
76
+ { "Content-Type" => "text/plain",
77
+ "X-Position" => "foo.org",
78
+ "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
79
+ }, [""]]}},
80
+ { :host => "subdomain.foo.org", :to => lambda { |env|
81
+ [200,
82
+ { "Content-Type" => "text/plain",
83
+ "X-Position" => "subdomain.foo.org",
84
+ "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
85
+ }, [""]]}},
86
+ { :host => /.*\.bar.org/, :to => lambda { |env|
87
+ [200,
88
+ { "Content-Type" => "text/plain",
89
+ "X-Position" => "bar.org",
90
+ "X-Host" => env["HTTP_HOST"] || env["SERVER_NAME"],
91
+ }, [""]]}}
92
+ )
93
+
94
+ res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "bar.org")
95
+ assert res.not_found?
96
+
97
+ res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "at.bar.org")
98
+ assert res.ok?
99
+ assert_equal "bar.org", res["X-Position"]
100
+
101
+ res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "foo.org")
102
+ assert res.ok?
103
+ assert_equal "foo.org", res["X-Position"]
104
+
105
+ res = Rack::MockRequest.new(map).get("/", "HTTP_HOST" => "subdomain.foo.org", "SERVER_NAME" => "foo.org")
106
+ assert res.ok?
107
+ assert_equal "subdomain.foo.org", res["X-Position"]
108
+ end
109
+
110
+ should "works with padrino core applications" do
111
+ Padrino.mount("simple_demo").host("padrino.org")
112
+ assert_equal ["simple_demo"], Padrino.mounted_apps.map(&:name)
113
+ assert_equal ["padrino.org"], Padrino.mounted_apps.map(&:app_host)
114
+
115
+ res = Rack::MockRequest.new(Padrino.application).get("/")
116
+ assert res.not_found?
117
+
118
+ res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "bar.org")
119
+ assert res.not_found?
120
+
121
+ res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "padrino.org")
122
+ assert res.ok?
123
+ end
124
+
125
+ should "works with padrino applications" do
126
+ Padrino.mount("simple_demo").to("/foo").host(/.*\.padrino.org/)
127
+
128
+ res = Rack::MockRequest.new(Padrino.application).get("/")
129
+ assert res.not_found?
130
+
131
+ res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "bar.org")
132
+ assert res.not_found?
133
+
134
+ res = Rack::MockRequest.new(Padrino.application).get("/", "HTTP_HOST" => "padrino.org")
135
+ assert res.not_found?
136
+
137
+ res = Rack::MockRequest.new(Padrino.application).get("/none", "HTTP_HOST" => "foo.padrino.org")
138
+ assert res.not_found?
139
+
140
+ res = Rack::MockRequest.new(Padrino.application).get("/foo", "HTTP_HOST" => "bar.padrino.org")
141
+ assert res.ok?
142
+
143
+ res = Rack::MockRequest.new(Padrino.application).get("/foo/", "HTTP_HOST" => "bar.padrino.org")
144
+ assert res.ok?
145
+ end
146
+ end
@@ -0,0 +1,1673 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/helper')
2
+
3
+ class FooError < RuntimeError; end
4
+
5
+
6
+ describe "Routing" do
7
+ setup do
8
+ Padrino::Application.send(:register, Padrino::Rendering)
9
+ Padrino::Rendering::DEFAULT_RENDERING_OPTIONS[:strict_format] = false
10
+ end
11
+
12
+ should "serve static files with simple cache control" do
13
+ mock_app do
14
+ set :static_cache_control, :public
15
+ set :public_folder, File.dirname(__FILE__)
16
+ end
17
+ get "/#{File.basename(__FILE__)}"
18
+ assert headers.has_key?('Cache-Control')
19
+ assert_equal headers['Cache-Control'], 'public'
20
+ end # static simple
21
+
22
+ should "serve static files with cache control and max_age" do
23
+ mock_app do
24
+ set :static_cache_control, [:public, :must_revalidate, {:max_age => 300}]
25
+ set :public_folder, File.dirname(__FILE__)
26
+ end
27
+ get "/#{File.basename(__FILE__)}"
28
+ assert headers.has_key?('Cache-Control')
29
+ assert_equal headers['Cache-Control'], 'public, must-revalidate, max-age=300'
30
+ end # static max_age
31
+
32
+ should 'ignore trailing delimiters for basic route' do
33
+ mock_app do
34
+ get("/foo"){ "okey" }
35
+ get(:test) { "tester" }
36
+ end
37
+ get "/foo"
38
+ assert_equal "okey", body
39
+ get "/foo/"
40
+ assert_equal "okey", body
41
+ get "/test"
42
+ assert_equal "tester", body
43
+ get "/test/"
44
+ assert_equal "tester", body
45
+ end
46
+
47
+ should 'fail with unrecognized route exception when not found' do
48
+ mock_app do
49
+ get(:index){ "okey" }
50
+ end
51
+ get @app.url_for(:index)
52
+ assert_equal "okey", body
53
+ assert_raises(Padrino::Routing::UnrecognizedException) {
54
+ get @app.url_for(:fake)
55
+ }
56
+ end
57
+
58
+ should 'accept regexp routes' do
59
+ mock_app do
60
+ get(%r{/fob|/baz}) { "regexp" }
61
+ get("/foo") { "str" }
62
+ get %r{/([0-9]+)/} do |num|
63
+ "Your lucky number: #{num} #{params[:captures].first}"
64
+ end
65
+ get /\/page\/([0-9]+)|\// do |num|
66
+ "My lucky number: #{num} #{params[:captures].first}"
67
+ end
68
+ end
69
+ get "/foo"
70
+ assert_equal "str", body
71
+ get "/fob"
72
+ assert_equal "regexp", body
73
+ get "/baz"
74
+ assert_equal "regexp", body
75
+ get "/1234/"
76
+ assert_equal "Your lucky number: 1234 1234", body
77
+ get "/page/99"
78
+ assert_equal "My lucky number: 99 99", body
79
+ end
80
+
81
+ should "parse routes with question marks" do
82
+ mock_app do
83
+ get("/foo/?"){ "okey" }
84
+ post('/unauthenticated/?') { "no access" }
85
+ end
86
+ get "/foo"
87
+ assert_equal "okey", body
88
+ get "/foo/"
89
+ assert_equal "okey", body
90
+ post "/unauthenticated"
91
+ assert_equal "no access", body
92
+ post "/unauthenticated/"
93
+ assert_equal "no access", body
94
+ end
95
+
96
+ should 'match correctly similar paths' do
97
+ mock_app do
98
+ get("/my/:foo_id"){ params[:foo_id] }
99
+ get("/my/:bar_id/bar"){ params[:bar_id] }
100
+ end
101
+ get "/my/1"
102
+ assert_equal "1", body
103
+ get "/my/2/bar"
104
+ assert_equal "2", body
105
+ end
106
+
107
+ should "match user agents" do
108
+ app = mock_app do
109
+ get("/main", :agent => /IE/){ "hello IE" }
110
+ get("/main"){ "hello" }
111
+ end
112
+ get "/main"
113
+ assert_equal "hello", body
114
+ get "/main", {}, {'HTTP_USER_AGENT' => 'This is IE'}
115
+ assert_equal "hello IE", body
116
+ end
117
+
118
+ should "use regex for parts of a route" do
119
+ app = mock_app do
120
+ get("/main/:id", :id => /\d+/){ "hello #{params[:id]}" }
121
+ end
122
+ get "/main/123"
123
+ assert_equal "hello 123", body
124
+ get "/main/asd"
125
+ assert_equal 404, status
126
+ end
127
+
128
+ should "not generate overlapping head urls" do
129
+ app = mock_app do
130
+ get("/main"){ "hello" }
131
+ post("/main"){ "hello" }
132
+ end
133
+ assert_equal 3, app.routes.size, "should generate GET, HEAD and PUT"
134
+ assert_equal ["GET"], app.routes[0].conditions[:request_method]
135
+ assert_equal ["HEAD"], app.routes[1].conditions[:request_method]
136
+ assert_equal ["POST"], app.routes[2].conditions[:request_method]
137
+ end
138
+
139
+ should 'generate basic urls' do
140
+ mock_app do
141
+ get(:foo){ "/foo" }
142
+ get(:foo, :with => :id){ |id| "/foo/#{id}" }
143
+ get([:foo, :id]){ |id| "/foo/#{id}" }
144
+ get(:hash, :with => :id){ url(:hash, :id => 1) }
145
+ get([:hash, :id]){ url(:hash, :id => 1) }
146
+ get(:array, :with => :id){ url(:array, 23) }
147
+ get([:array, :id]){ url(:array, 23) }
148
+ get(:hash_with_extra, :with => :id){ url(:hash_with_extra, :id => 1, :query => 'string') }
149
+ get([:hash_with_extra, :id]){ url(:hash_with_extra, :id => 1, :query => 'string') }
150
+ get(:array_with_extra, :with => :id){ url(:array_with_extra, 23, :query => 'string') }
151
+ get([:array_with_extra, :id]){ url(:array_with_extra, 23, :query => 'string') }
152
+ get("/old-bar/:id"){ params[:id] }
153
+ post(:mix, :map => "/mix-bar/:id"){ params[:id] }
154
+ get(:mix, :map => "/mix-bar/:id"){ params[:id] }
155
+ end
156
+ get "/foo"
157
+ assert_equal "/foo", body
158
+ get "/foo/123"
159
+ assert_equal "/foo/123", body
160
+ get "/hash/2"
161
+ assert_equal "/hash/1", body
162
+ get "/array/23"
163
+ assert_equal "/array/23", body
164
+ get "/hash_with_extra/1"
165
+ assert_equal "/hash_with_extra/1?query=string", body
166
+ get "/array_with_extra/23"
167
+ assert_equal "/array_with_extra/23?query=string", body
168
+ get "/old-bar/3"
169
+ assert_equal "3", body
170
+ post "/mix-bar/4"
171
+ assert_equal "4", body
172
+ get "/mix-bar/4"
173
+ assert_equal "4", body
174
+ end
175
+
176
+ should 'generate url with format' do
177
+ mock_app do
178
+ get(:a, :provides => :any){ url(:a, :format => :json) }
179
+ get(:b, :provides => :js){ url(:b, :format => :js) }
180
+ get(:c, :provides => [:js, :json]){ url(:c, :format => :json) }
181
+ get(:d, :provides => [:html, :js]){ url(:d, :format => :js, :foo => :bar) }
182
+ end
183
+ get "/a.js"
184
+ assert_equal "/a.json", body
185
+ get "/b.js"
186
+ assert_equal "/b.js", body
187
+ get "/b.ru"
188
+ assert_equal 405, status
189
+ get "/c.js"
190
+ assert_equal "/c.json", body
191
+ get "/c.json"
192
+ assert_equal "/c.json", body
193
+ get "/c.ru"
194
+ assert_equal 405, status
195
+ get "/d"
196
+ assert_equal "/d.js?foo=bar", body
197
+ get "/d.js"
198
+ assert_equal "/d.js?foo=bar", body
199
+ get "/e.xml"
200
+ assert_equal 404, status
201
+ end
202
+
203
+ should 'use padrino url method' do
204
+ mock_app do
205
+ end
206
+
207
+ assert_equal @app.method(:url).owner, Padrino::Routing::ClassMethods
208
+ end
209
+
210
+ should 'work correctly with sinatra redirects' do
211
+ mock_app do
212
+ get(:index) { redirect url(:index) }
213
+ get(:google) { redirect "http://google.com" }
214
+ get("/foo") { redirect "/bar" }
215
+ get("/bar") { "Bar" }
216
+ end
217
+
218
+ get "/"
219
+ assert_equal "http://example.org/", headers['Location']
220
+ get "/google"
221
+ assert_equal "http://google.com", headers['Location']
222
+ get "/foo"
223
+ assert_equal "http://example.org/bar", headers['Location']
224
+ end
225
+
226
+ should "return 406 on Accept-Headers it does not provide" do
227
+ mock_app do
228
+ get(:a, :provides => [:html, :js]){ content_type }
229
+ end
230
+
231
+ get "/a", {}, {"HTTP_ACCEPT" => "application/yaml"}
232
+ assert_equal 406, status
233
+ end
234
+
235
+ should "return 406 on file extensions it does not provide and flag is set" do
236
+ mock_app do
237
+ enable :treat_format_as_accept
238
+ get(:a, :provides => [:html, :js]){ content_type }
239
+ end
240
+
241
+ get "/a.xml", {}, {}
242
+ assert_equal 406, status
243
+ end
244
+
245
+ should "return 404 on file extensions it does not provide and flag is not set" do
246
+ mock_app do
247
+ get(:a, :provides => [:html, :js]){ content_type }
248
+ end
249
+
250
+ get "/a.xml", {}, {}
251
+ assert_equal 405, status
252
+ end
253
+
254
+ should "not set content_type to :html if Accept */* and html not in provides" do
255
+ mock_app do
256
+ get("/foo", :provides => [:json, :xml]) { content_type.to_s }
257
+ end
258
+
259
+ get '/foo', {}, { 'HTTP_ACCEPT' => '*/*;q=0.5' }
260
+ assert_equal 'json', body
261
+ end
262
+
263
+ should "set content_type to :json if Accept contains */*" do
264
+ mock_app do
265
+ get("/foo", :provides => [:json]) { content_type.to_s }
266
+ end
267
+
268
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' }
269
+ assert_equal 'json', body
270
+ end
271
+
272
+ should "set content_type to :json if render => :json" do
273
+ mock_app do
274
+ get("/foo"){ render :foo => :bar }
275
+ end
276
+
277
+ get '/foo'
278
+ assert_equal 'application/json;charset=utf-8', content_type
279
+ end
280
+
281
+ should 'set and get content_type' do
282
+ mock_app do
283
+ get("/foo"){ content_type(:json); content_type.to_s }
284
+ end
285
+ get "/foo"
286
+ assert_equal 'application/json;charset=utf-8', content_type
287
+ assert_equal 'json', body
288
+ end
289
+
290
+ should "send the appropriate number of params" do
291
+ mock_app do
292
+ get('/id/:user_id', :provides => [:json]) { |user_id, format| user_id}
293
+ end
294
+ get '/id/5.json'
295
+ assert_equal '5', body
296
+ end
297
+
298
+ should "allow .'s in param values" do
299
+ mock_app do
300
+ get('/id/:email', :provides => [:json]) { |email, format| [email, format] * '/' }
301
+ end
302
+ get '/id/foo@bar.com.json'
303
+ assert_equal 'foo@bar.com/json', body
304
+ end
305
+
306
+ should "set correct content_type for Accept not equal to */* even if */* also provided" do
307
+ mock_app do
308
+ get("/foo", :provides => [:html, :js, :xml]) { content_type.to_s }
309
+ end
310
+
311
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' }
312
+ assert_equal 'js', body
313
+ end
314
+
315
+ should "return the first content type in provides if accept header is empty" do
316
+ mock_app do
317
+ get(:a, :provides => [:js]){ content_type.to_s }
318
+ end
319
+
320
+ get "/a", {}, {}
321
+ assert_equal "js", body
322
+ end
323
+
324
+ should "not default to HTML if HTML is not provided and no type is given" do
325
+ mock_app do
326
+ get(:a, :provides => [:js]){ content_type }
327
+ end
328
+
329
+ get "/a", {}, {}
330
+ assert_equal "application/javascript;charset=utf-8", content_type
331
+ end
332
+
333
+ should "not match routes if url_format and http_accept is provided but not included" do
334
+ mock_app do
335
+ get(:a, :provides => [:js, :html]){ content_type }
336
+ end
337
+
338
+ get "/a.xml", {}, {"HTTP_ACCEPT" => "text/html"}
339
+ assert_equal 405, status
340
+ end
341
+
342
+ should "generate routes for format simple" do
343
+ mock_app do
344
+ get(:foo, :provides => [:html, :rss]) { render :haml, "Test" }
345
+ end
346
+ get "/foo"
347
+ assert_equal "Test\n", body
348
+ get "/foo.rss"
349
+ assert_equal "Test\n", body
350
+ end
351
+
352
+ should "should inject the controller name into the request" do
353
+ mock_app do
354
+ controller :posts do
355
+ get(:index) { request.controller }
356
+ controller :mini do
357
+ get(:index) { request.controller }
358
+ end
359
+ end
360
+ end
361
+ get "/posts"
362
+ assert_equal "posts", body
363
+ get "/mini"
364
+ assert_equal "mini", body
365
+ end
366
+
367
+ should "support not_found" do
368
+ mock_app do
369
+ not_found do
370
+ response.status = 404
371
+ 'whatever'
372
+ end
373
+
374
+ get :index, :map => "/" do
375
+ 'index'
376
+ end
377
+ end
378
+ get '/something'
379
+ assert_equal 'whatever', body
380
+ assert_equal 404, status
381
+ get '/'
382
+ assert_equal 'index', body
383
+ assert_equal 200, status
384
+ end
385
+
386
+ should "should inject the route into the request" do
387
+ mock_app do
388
+ controller :posts do
389
+ get(:index) { request.route_obj.named.to_s }
390
+ end
391
+ end
392
+ get "/posts"
393
+ assert_equal "posts_index", body
394
+ end
395
+
396
+ should "preserve the format if you set it manually" do
397
+ mock_app do
398
+ before do
399
+ params[:format] = "json"
400
+ end
401
+
402
+ get "test", :provides => [:html, :json] do
403
+ content_type.inspect
404
+ end
405
+ end
406
+ get "/test"
407
+ assert_equal ":json", body
408
+ get "/test.html"
409
+ assert_equal ":json", body
410
+ get "/test.php"
411
+ assert_equal ":json", body
412
+ end
413
+
414
+ should "correctly accept '.' in the route" do
415
+ mock_app do
416
+ get "test.php", :provides => [:html, :json] do
417
+ content_type.inspect
418
+ end
419
+ end
420
+ get "/test.php"
421
+ assert_equal ":html", body
422
+ get "/test.php.json"
423
+ assert_equal ":json", body
424
+ end
425
+
426
+ should "correctly accept priority of format" do
427
+ mock_app do
428
+ get "test.php", :provides => [:html, :json, :xml] do
429
+ content_type.inspect
430
+ end
431
+ end
432
+
433
+ get "/test.php"
434
+ assert_equal ":html", body
435
+ get "/test.php", {}, { 'HTTP_ACCEPT' => 'application/xml' }
436
+ assert_equal ":xml", body
437
+ get "/test.php?format=json", { 'HTTP_ACCEPT' => 'application/xml' }
438
+ assert_equal ":json", body
439
+ get "/test.php.json?format=html", { 'HTTP_ACCEPT' => 'application/xml' }
440
+ assert_equal ":json", body
441
+ end
442
+
443
+ should "generate routes for format with controller" do
444
+ mock_app do
445
+ controller :posts do
446
+ get(:index, :provides => [:html, :rss, :atom, :js]) { render :haml, "Index.#{content_type}" }
447
+ get(:show, :with => :id, :provides => [:html, :rss, :atom]) { render :haml, "Show.#{content_type}" }
448
+ end
449
+ end
450
+ get "/posts"
451
+ assert_equal "Index.html\n", body
452
+ get "/posts.rss"
453
+ assert_equal "Index.rss\n", body
454
+ get "/posts.atom"
455
+ assert_equal "Index.atom\n", body
456
+ get "/posts.js"
457
+ assert_equal "Index.js\n", body
458
+ get "/posts/show/5"
459
+ assert_equal "Show.html\n", body
460
+ get "/posts/show/5.rss"
461
+ assert_equal "Show.rss\n", body
462
+ get "/posts/show/10.atom"
463
+ assert_equal "Show.atom\n", body
464
+ end
465
+
466
+ should 'map routes' do
467
+ mock_app do
468
+ get(:bar){ "bar" }
469
+ end
470
+ get "/bar"
471
+ assert_equal "bar", body
472
+ assert_equal "/bar", @app.url(:bar)
473
+ end
474
+
475
+ should 'remove index from path' do
476
+ mock_app do
477
+ get(:index){ "index" }
478
+ get("/accounts/index"){ "accounts" }
479
+ end
480
+ get "/"
481
+ assert_equal "index", body
482
+ assert_equal "/", @app.url(:index)
483
+ get "/accounts/index"
484
+ assert_equal "accounts", body
485
+ end
486
+
487
+ should 'remove index from path with params' do
488
+ mock_app do
489
+ get(:index, :with => :name){ "index with #{params[:name]}" }
490
+ end
491
+ get "/bobby"
492
+ assert_equal "index with bobby", body
493
+ assert_equal "/john", @app.url(:index, :name => "john")
494
+ end
495
+
496
+ should 'parse named params' do
497
+ mock_app do
498
+ get(:print, :with => :id){ "Im #{params[:id]}" }
499
+ end
500
+ get "/print/9"
501
+ assert_equal "Im 9", body
502
+ assert_equal "/print/9", @app.url(:print, :id => 9)
503
+ end
504
+
505
+ should '405 on wrong request_method' do
506
+ mock_app do
507
+ post('/bar'){ "bar" }
508
+ end
509
+ get "/bar"
510
+ assert_equal 405, status
511
+ end
512
+
513
+ should 'respond to' do
514
+ mock_app do
515
+ get(:a, :provides => :js){ "js" }
516
+ get(:b, :provides => :any){ "any" }
517
+ get(:c, :provides => [:js, :json]){ "js,json" }
518
+ get(:d, :provides => [:html, :js]){ "html,js"}
519
+ end
520
+ get "/a"
521
+ assert_equal 200, status
522
+ assert_equal "js", body
523
+ get "/a.js"
524
+ assert_equal "js", body
525
+ get "/b"
526
+ assert_equal "any", body
527
+ # TODO randomly fails in minitest :(
528
+ # assert_raises(RuntimeError) { get "/b.foo" }
529
+ get "/c"
530
+ assert_equal 200, status
531
+ assert_equal "js,json", body
532
+ get "/c.js"
533
+ assert_equal "js,json", body
534
+ get "/c.json"
535
+ assert_equal "js,json", body
536
+ get "/d"
537
+ assert_equal "html,js", body
538
+ get "/d.js"
539
+ assert_equal "html,js", body
540
+ end
541
+
542
+ should 'respond_to and set content_type' do
543
+ Rack::Mime::MIME_TYPES['.foo'] = 'application/foo'
544
+ mock_app do
545
+ get :a, :provides => :any do
546
+ case content_type
547
+ when :js then "js"
548
+ when :json then "json"
549
+ when :foo then "foo"
550
+ when :html then "html"
551
+ end
552
+ end
553
+ end
554
+ get "/a.js"
555
+ assert_equal "js", body
556
+ assert_equal 'application/javascript;charset=utf-8', response["Content-Type"]
557
+ get "/a.json"
558
+ assert_equal "json", body
559
+ assert_equal 'application/json;charset=utf-8', response["Content-Type"]
560
+ get "/a.foo"
561
+ assert_equal "foo", body
562
+ assert_equal 'application/foo;charset=utf-8', response["Content-Type"]
563
+ get "/a"
564
+ assert_equal "html", body
565
+ assert_equal 'text/html;charset=utf-8', response["Content-Type"]
566
+ end
567
+
568
+ should 'use controllers' do
569
+ mock_app do
570
+ controller "/admin" do
571
+ get("/"){ "index" }
572
+ get("/show/:id"){ "show #{params[:id]}" }
573
+ end
574
+ end
575
+ get "/admin"
576
+ assert_equal "index", body
577
+ get "/admin/show/1"
578
+ assert_equal "show 1", body
579
+ end
580
+
581
+ should 'use named controllers' do
582
+ mock_app do
583
+ controller :admin do
584
+ get(:index, :with => :id){ params[:id] }
585
+ get(:show, :with => :id){ "show #{params[:id]}" }
586
+ end
587
+ controllers :foo, :bar do
588
+ get(:index){ "foo_bar_index" }
589
+ end
590
+ end
591
+ get "/admin/1"
592
+ assert_equal "1", body
593
+ get "/admin/show/1"
594
+ assert_equal "show 1", body
595
+ assert_equal "/admin/1", @app.url(:admin_index, :id => 1)
596
+ assert_equal "/admin/show/1", @app.url(:admin_show, :id => 1)
597
+ get "/foo/bar"
598
+ assert_equal "foo_bar_index", body
599
+ end
600
+
601
+ should 'use map and with' do
602
+ mock_app do
603
+ get :index, :map => '/bugs', :with => :id do
604
+ params[:id]
605
+ end
606
+ end
607
+ get '/bugs/4'
608
+ assert_equal '4', body
609
+ assert_equal "/bugs/4", @app.url(:index, :id => 4)
610
+ end
611
+
612
+ should "ignore trailing delimiters within a named controller" do
613
+ mock_app do
614
+ controller :posts do
615
+ get(:index, :provides => [:html, :js]){ "index" }
616
+ get(:new) { "new" }
617
+ get(:show, :with => :id){ "show #{params[:id]}" }
618
+ end
619
+ end
620
+ get "/posts"
621
+ assert_equal "index", body
622
+ get "/posts/"
623
+ assert_equal "index", body
624
+ get "/posts.js"
625
+ assert_equal "index", body
626
+ get "/posts.js/"
627
+ assert_equal "index", body
628
+ get "/posts/new"
629
+ assert_equal "new", body
630
+ get "/posts/new/"
631
+ assert_equal "new", body
632
+ end
633
+
634
+ should "ignore trailing delimiters within a named controller for unnamed actions" do
635
+ mock_app do
636
+ controller :accounts do
637
+ get("/") { "account_index" }
638
+ get("/new") { "new" }
639
+ end
640
+ controller :votes do
641
+ get("/") { "vote_index" }
642
+ end
643
+ end
644
+ get "/accounts"
645
+ assert_equal "account_index", body
646
+ get "/accounts/"
647
+ assert_equal "account_index", body
648
+ get "/accounts/new"
649
+ assert_equal "new", body
650
+ get "/accounts/new/"
651
+ assert_equal "new", body
652
+ get "/votes"
653
+ assert_equal "vote_index", body
654
+ get "/votes/"
655
+ assert_equal "vote_index", body
656
+ end
657
+
658
+ should 'use named controllers with array routes' do
659
+ mock_app do
660
+ controller :admin do
661
+ get(:index){ "index" }
662
+ get(:show, :with => :id){ "show #{params[:id]}" }
663
+ end
664
+ controllers :foo, :bar do
665
+ get(:index){ "foo_bar_index" }
666
+ end
667
+ end
668
+ get "/admin"
669
+ assert_equal "index", body
670
+ get "/admin/show/1"
671
+ assert_equal "show 1", body
672
+ assert_equal "/admin", @app.url(:admin, :index)
673
+ assert_equal "/admin/show/1", @app.url(:admin, :show, :id => 1)
674
+ get "/foo/bar"
675
+ assert_equal "foo_bar_index", body
676
+ end
677
+
678
+ should "support a reindex action and remove index inside controller" do
679
+ mock_app do
680
+ controller :posts do
681
+ get(:index){ "index" }
682
+ get(:reindex){ "reindex" }
683
+ end
684
+ end
685
+ get "/posts"
686
+ assert_equal "index", body
687
+ get "/posts/reindex"
688
+ assert_equal "/posts/reindex", @app.url(:posts, :reindex)
689
+ assert_equal "reindex", body
690
+ end
691
+
692
+ should 'use uri_root' do
693
+ mock_app do
694
+ get(:foo){ "foo" }
695
+ end
696
+ @app.uri_root = '/'
697
+ assert_equal "/foo", @app.url(:foo)
698
+ @app.uri_root = '/testing'
699
+ assert_equal "/testing/foo", @app.url(:foo)
700
+ @app.uri_root = '/testing/'
701
+ assert_equal "/testing/foo", @app.url(:foo)
702
+ @app.uri_root = 'testing/bar///'
703
+ assert_equal "/testing/bar/foo", @app.url(:foo)
704
+ end
705
+
706
+ should 'use uri_root with controllers' do
707
+ mock_app do
708
+ controller :foo do
709
+ get(:bar){ "bar" }
710
+ end
711
+ end
712
+ @app.uri_root = '/testing'
713
+ assert_equal "/testing/foo/bar", @app.url(:foo, :bar)
714
+ end
715
+
716
+ should 'use RACK_BASE_URI' do
717
+ mock_app do
718
+ get(:foo){ "foo" }
719
+ end
720
+ # Wish there was a side-effect free way to test this...
721
+ ENV['RACK_BASE_URI'] = '/'
722
+ assert_equal "/foo", @app.url(:foo)
723
+ ENV['RACK_BASE_URI'] = '/testing'
724
+ assert_equal "/testing/foo", @app.url(:foo)
725
+ ENV['RACK_BASE_URI'] = nil
726
+ end
727
+
728
+ should 'reset routes' do
729
+ mock_app do
730
+ get("/"){ "foo" }
731
+ reset_router!
732
+ end
733
+ get "/"
734
+ assert_equal 404, status
735
+ end
736
+
737
+ should 'respect priorities' do
738
+ route_order = []
739
+ mock_app do
740
+ get(:index, :priority => :normal) { route_order << :normal; pass }
741
+ get(:index, :priority => :low) { route_order << :low; "hello" }
742
+ get(:index, :priority => :high) { route_order << :high; pass }
743
+ end
744
+ get '/'
745
+ assert_equal [:high, :normal, :low], route_order
746
+ assert_equal "hello", body
747
+ end
748
+
749
+ should 'allow optionals' do
750
+ mock_app do
751
+ get(:show, :map => "/stories/:type(/:category)") do
752
+ "#{params[:type]}/#{params[:category]}"
753
+ end
754
+ end
755
+ get "/stories/foo"
756
+ assert_equal "foo/", body
757
+ get "/stories/foo/bar"
758
+ assert_equal "foo/bar", body
759
+ end
760
+
761
+ should 'apply maps' do
762
+ mock_app do
763
+ controllers :admin do
764
+ get(:index, :map => "/"){ "index" }
765
+ get(:show, :with => :id, :map => "/show"){ "show #{params[:id]}" }
766
+ get(:edit, :map => "/edit/:id/product"){ "edit #{params[:id]}" }
767
+ get(:wacky, :map => "/wacky-:id-:product_id"){ "wacky #{params[:id]}-#{params[:product_id]}" }
768
+ end
769
+ end
770
+ get "/"
771
+ assert_equal "index", body
772
+ get @app.url(:admin, :index)
773
+ assert_equal "index", body
774
+ get "/show/1"
775
+ assert_equal "show 1", body
776
+ get "/edit/1/product"
777
+ assert_equal "edit 1", body
778
+ get "/wacky-1-2"
779
+ assert_equal "wacky 1-2", body
780
+ end
781
+
782
+ should 'apply maps when given path is kind of hash' do
783
+ mock_app do
784
+ controllers :admin do
785
+ get(:foobar, "/foo/bar"){ "foobar" }
786
+ end
787
+ end
788
+ get "/foo/bar"
789
+ assert_equal "foobar", body
790
+ end
791
+
792
+ should "apply parent to route" do
793
+ mock_app do
794
+ controllers :project do
795
+ get(:index, :parent => :user) { "index #{params[:user_id]}" }
796
+ get(:index, :parent => [:user, :section]) { "index #{params[:user_id]} #{params[:section_id]}" }
797
+ get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"}
798
+ get(:show, :with => :id, :parent => [:user, :product]) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"}
799
+ end
800
+ end
801
+ get "/user/1/project"
802
+ assert_equal "index 1", body
803
+ get "/user/1/section/3/project"
804
+ assert_equal "index 1 3", body
805
+ get "/user/1/project/edit/2"
806
+ assert_equal "edit 2 1", body
807
+ get "/user/1/product/2/project/show/3"
808
+ assert_equal "show 3 1 2", body
809
+ end
810
+
811
+ should "apply parent to controller" do
812
+ mock_app do
813
+ controller :project, :parent => :user do
814
+ get(:index) { "index #{params[:user_id]}"}
815
+ get(:edit, :with => :id, :parent => :user) { "edit #{params[:id]} #{params[:user_id]}"}
816
+ get(:show, :with => :id, :parent => :product) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]}"}
817
+ end
818
+ end
819
+
820
+ user_project_url = "/user/1/project"
821
+ get user_project_url
822
+ assert_equal "index 1", body
823
+ assert_equal user_project_url, @app.url(:project, :index, :user_id => 1)
824
+
825
+ user_project_edit_url = "/user/1/project/edit/2"
826
+ get user_project_edit_url
827
+ assert_equal "edit 2 1", body
828
+ assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2)
829
+
830
+ user_product_project_url = "/user/1/product/2/project/show/3"
831
+ get user_product_project_url
832
+ assert_equal "show 3 1 2", body
833
+ assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3)
834
+ end
835
+
836
+ should "apply parent with shallowing to controller" do
837
+ mock_app do
838
+ controller :project do
839
+ parent :user
840
+ parent :shop, :optional => true
841
+ get(:index) { "index #{params[:user_id]} #{params[:shop_id]}" }
842
+ get(:edit, :with => :id) { "edit #{params[:id]} #{params[:user_id]} #{params[:shop_id]}" }
843
+ get(:show, :with => :id, :parent => :product) { "show #{params[:id]} #{params[:user_id]} #{params[:product_id]} #{params[:shop_id]}" }
844
+ end
845
+ end
846
+
847
+ assert_equal "/user/1/project", @app.url(:project, :index, :user_id => 1, :shop_id => nil)
848
+ assert_equal "/user/1/shop/23/project", @app.url(:project, :index, :user_id => 1, :shop_id => 23)
849
+
850
+ user_project_url = "/user/1/project"
851
+ get user_project_url
852
+ assert_equal "index 1 ", body
853
+ assert_equal user_project_url, @app.url(:project, :index, :user_id => 1)
854
+
855
+ user_project_edit_url = "/user/1/project/edit/2"
856
+ get user_project_edit_url
857
+ assert_equal "edit 2 1 ", body
858
+ assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2)
859
+
860
+ user_product_project_url = "/user/1/product/2/project/show/3"
861
+ get user_product_project_url
862
+ assert_equal "show 3 1 2 ", body
863
+ assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3)
864
+
865
+ user_project_url = "/user/1/shop/1/project"
866
+ get user_project_url
867
+ assert_equal "index 1 1", body
868
+ assert_equal user_project_url, @app.url(:project, :index, :user_id => 1, :shop_id => 1)
869
+
870
+ user_project_edit_url = "/user/1/shop/1/project/edit/2"
871
+ get user_project_edit_url
872
+ assert_equal "edit 2 1 1", body
873
+ assert_equal user_project_edit_url, @app.url(:project, :edit, :user_id => 1, :id => 2, :shop_id => 1)
874
+
875
+ user_product_project_url = "/user/1/shop/1/product/2/project/show/3"
876
+ get user_product_project_url
877
+ assert_equal "show 3 1 2 1", body
878
+ assert_equal user_product_project_url, @app.url(:project, :show, :user_id => 1, :product_id => 2, :id => 3, :shop_id => 1)
879
+ end
880
+
881
+ should "respect map in parents with shallowing" do
882
+ mock_app do
883
+ controller :project do
884
+ parent :shop, :map => "/foo/bar"
885
+ get(:index) { "index #{params[:shop_id]}" }
886
+ end
887
+ end
888
+
889
+ shop_project_url = "/foo/bar/1/project"
890
+ get shop_project_url
891
+ assert_equal "index 1", body
892
+ assert_equal shop_project_url, @app.url(:project, :index, :shop_id => 1)
893
+ end
894
+
895
+ should "use default values" do
896
+ mock_app do
897
+ controller :lang => :it do
898
+ get(:index, :map => "/:lang") { "lang is #{params[:lang]}" }
899
+ end
900
+ # This is only for be sure that default values
901
+ # work only for the given controller
902
+ get(:foo, :map => "/foo") {}
903
+ end
904
+ assert_equal "/it", @app.url(:index)
905
+ assert_equal "/foo", @app.url(:foo)
906
+ get "/en"
907
+ assert_equal "lang is en", body
908
+ end
909
+
910
+ should "transitions to the next matching route on pass" do
911
+ mock_app do
912
+ get '/:foo' do
913
+ pass
914
+ 'Hello Foo'
915
+ end
916
+ get '/:bar' do
917
+ 'Hello World'
918
+ end
919
+ end
920
+
921
+ get '/za'
922
+ assert_equal 'Hello World', body
923
+ end
924
+
925
+ should "filters by accept header" do
926
+ mock_app do
927
+ get '/foo', :provides => [:xml, :js] do
928
+ request.env['HTTP_ACCEPT']
929
+ end
930
+ end
931
+
932
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
933
+ assert ok?
934
+ assert_equal 'application/xml', body
935
+ assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
936
+
937
+ get '/foo.xml'
938
+ assert ok?
939
+ assert_equal 'application/xml;charset=utf-8', response.headers['Content-Type']
940
+
941
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript' }
942
+ assert ok?
943
+ assert_equal 'application/javascript', body
944
+ assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type']
945
+
946
+ get '/foo.js'
947
+ assert ok?
948
+ assert_equal 'application/javascript;charset=utf-8', response.headers['Content-Type']
949
+
950
+ get '/foo', {}, { "HTTP_ACCEPT" => 'text/html' }
951
+ assert_equal 406, status
952
+ end
953
+
954
+ should "does not allow global provides" do
955
+ mock_app do
956
+ provides :xml
957
+
958
+ get("/foo"){ "Foo in #{content_type}" }
959
+ get("/bar"){ "Bar in #{content_type}" }
960
+ end
961
+
962
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
963
+ assert_equal 'Foo in xml', body
964
+ get '/foo'
965
+ assert_equal 'Foo in xml', body
966
+
967
+ get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
968
+ assert_equal 'Bar in html', body
969
+ end
970
+
971
+ should "does not allow global provides in controller" do
972
+ mock_app do
973
+ controller :base do
974
+ provides :xml
975
+
976
+ get(:foo, "/foo"){ "Foo in #{content_type}" }
977
+ get(:bar, "/bar"){ "Bar in #{content_type}" }
978
+ end
979
+ end
980
+
981
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'application/xml' }
982
+ assert_equal 'Foo in xml', body
983
+ get '/foo'
984
+ assert_equal 'Foo in xml', body
985
+
986
+ get '/bar', {}, { 'HTTP_ACCEPT' => 'application/xml' }
987
+ assert_equal 'Bar in html', body
988
+ end
989
+
990
+ should "map non named routes in controllers" do
991
+ mock_app do
992
+ controller :base do
993
+ get("/foo") { "ok" }
994
+ get("/bar") { "ok" }
995
+ end
996
+ end
997
+
998
+ get "/base/foo"
999
+ assert ok?
1000
+ get "/base/bar"
1001
+ assert ok?
1002
+ end
1003
+
1004
+ should "set content_type to :html for both empty Accept as well as Accept text/html" do
1005
+ mock_app do
1006
+ provides :html
1007
+
1008
+ get("/foo"){ content_type.to_s }
1009
+ end
1010
+
1011
+ get '/foo', {}, {}
1012
+ assert_equal 'html', body
1013
+
1014
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'text/html' }
1015
+ assert_equal 'html', body
1016
+ end
1017
+
1018
+ should "set content_type to :html if Accept */*" do
1019
+ mock_app do
1020
+ get("/foo", :provides => [:html, :js]) { content_type.to_s }
1021
+ end
1022
+ get '/foo', {}, {}
1023
+ assert_equal 'html', body
1024
+
1025
+ get '/foo', {}, { 'HTTP_ACCEPT' => '*/*;q=0.5' }
1026
+ assert_equal 'html', body
1027
+ end
1028
+
1029
+ should "set content_type to :js if Accept includes both application/javascript and */*;q=0.5" do
1030
+ mock_app do
1031
+ get("/foo", :provides => [:html, :js]) { content_type.to_s }
1032
+ end
1033
+ get '/foo', {}, { 'HTTP_ACCEPT' => 'application/javascript, */*;q=0.5' }
1034
+ assert_equal 'js', body
1035
+ end
1036
+
1037
+ should 'allows custom route-conditions to be set via route options and halt' do
1038
+ protector = Module.new do
1039
+ def protect(*args)
1040
+ condition {
1041
+ unless authorize(params["user"], params["password"])
1042
+ halt 403, "go away"
1043
+ end
1044
+ }
1045
+ end
1046
+ end
1047
+
1048
+ mock_app do
1049
+ register protector
1050
+
1051
+ helpers do
1052
+ def authorize(username, password)
1053
+ username == "foo" && password == "bar"
1054
+ end
1055
+ end
1056
+
1057
+ get "/", :protect => true do
1058
+ "hey"
1059
+ end
1060
+ end
1061
+
1062
+ get "/"
1063
+ assert forbidden?
1064
+ assert_equal "go away", body
1065
+
1066
+ get "/", :user => "foo", :password => "bar"
1067
+ assert ok?
1068
+ assert_equal "hey", body
1069
+ end
1070
+
1071
+ should 'allows custom route-conditions to be set via route options using two routes' do
1072
+ protector = Module.new do
1073
+ def protect(*args)
1074
+ condition { authorize(params["user"], params["password"]) }
1075
+ end
1076
+ end
1077
+
1078
+ mock_app do
1079
+ register protector
1080
+
1081
+ helpers do
1082
+ def authorize(username, password)
1083
+ username == "foo" && password == "bar"
1084
+ end
1085
+ end
1086
+
1087
+ get "/", :protect => true do
1088
+ "hey"
1089
+ end
1090
+
1091
+ get "/" do
1092
+ "go away"
1093
+ end
1094
+ end
1095
+
1096
+ get "/"
1097
+ assert_equal "go away", body
1098
+
1099
+ get "/", :user => "foo", :password => "bar"
1100
+ assert ok?
1101
+ assert_equal "hey", body
1102
+ end
1103
+
1104
+ should "allow concise routing" do
1105
+ mock_app do
1106
+ get :index, ":id" do
1107
+ params[:id]
1108
+ end
1109
+
1110
+ get :map, "route/:id" do
1111
+ params[:id]
1112
+ end
1113
+ end
1114
+
1115
+ get "/123"
1116
+ assert_equal "123", body
1117
+
1118
+ get "/route/123"
1119
+ assert_equal "123", body
1120
+ end
1121
+
1122
+ should "support halting with 404 and message" do
1123
+ mock_app do
1124
+ controller do
1125
+ get :index do
1126
+ halt 404, "not found"
1127
+ end
1128
+ end
1129
+ end
1130
+
1131
+ get "/"
1132
+ assert_equal 404, status
1133
+ assert_equal "not found", body
1134
+ end
1135
+
1136
+ should "allow passing & halting in before filters" do
1137
+ mock_app do
1138
+ controller do
1139
+ before { env['QUERY_STRING'] == 'secret' or pass }
1140
+ get :index do
1141
+ "secret index"
1142
+ end
1143
+ end
1144
+
1145
+ controller do
1146
+ before { env['QUERY_STRING'] == 'halt' and halt 401, 'go away!' }
1147
+ get :index do
1148
+ "index"
1149
+ end
1150
+ end
1151
+ end
1152
+
1153
+ get "/?secret"
1154
+ assert_equal "secret index", body
1155
+
1156
+ get "/?halt"
1157
+ assert_equal "go away!", body
1158
+ assert_equal 401, status
1159
+
1160
+ get "/"
1161
+ assert_equal "index", body
1162
+ end
1163
+
1164
+ should 'scope filters in the given controller' do
1165
+ mock_app do
1166
+ before { @global = 'global' }
1167
+ after { @global = nil }
1168
+
1169
+ controller :foo do
1170
+ before { @foo = :foo }
1171
+ after { @foo = nil }
1172
+ get("/") { [@foo, @bar, @global].compact.join(" ") }
1173
+ end
1174
+
1175
+ get("/") { [@foo, @bar, @global].compact.join(" ") }
1176
+
1177
+ controller :bar do
1178
+ before { @bar = :bar }
1179
+ after { @bar = nil }
1180
+ get("/") { [@foo, @bar, @global].compact.join(" ") }
1181
+ end
1182
+ end
1183
+
1184
+ get "/bar"
1185
+ assert_equal "bar global", body
1186
+
1187
+ get "/foo"
1188
+ assert_equal "foo global", body
1189
+
1190
+ get "/"
1191
+ assert_equal "global", body
1192
+ end
1193
+
1194
+ should 'works with optionals params' do
1195
+ mock_app do
1196
+ get("/foo(/:bar)") { params[:bar] }
1197
+ end
1198
+
1199
+ get "/foo/bar"
1200
+ assert_equal "bar", body
1201
+
1202
+ get "/foo"
1203
+ assert_equal "", body
1204
+ end
1205
+
1206
+ should 'work with multiple dashed params' do
1207
+ mock_app do
1208
+ get "/route/:foo/:bar/:baz", :provides => :html do
1209
+ "#{params[:foo]};#{params[:bar]};#{params[:baz]}"
1210
+ end
1211
+ end
1212
+
1213
+ get "/route/foo/bar/baz"
1214
+ assert_equal 'foo;bar;baz', body
1215
+
1216
+ get "/route/foo/bar-whatever/baz"
1217
+ assert_equal 'foo;bar-whatever;baz', body
1218
+ end
1219
+
1220
+ should 'work with arbitrary params' do
1221
+ mock_app do
1222
+ get(:testing) { params[:foo] }
1223
+ end
1224
+
1225
+ url = @app.url(:testing, :foo => 'bar')
1226
+ assert_equal "/testing?foo=bar", url
1227
+ get url
1228
+ assert_equal "bar", body
1229
+ end
1230
+
1231
+ should 'ignore nil params' do
1232
+ mock_app do
1233
+ get(:testing, :provides => [:html, :json]) do
1234
+ end
1235
+ end
1236
+ assert_equal '/testing.html', @app.url(:testing, :format => :html)
1237
+ assert_equal '/testing', @app.url(:testing, :format => nil)
1238
+ end
1239
+
1240
+ should 'be able to access params in a before filter' do
1241
+ username_from_before_filter = nil
1242
+
1243
+ mock_app do
1244
+ before do
1245
+ username_from_before_filter = params[:username]
1246
+ end
1247
+
1248
+ get :users, :with => :username do
1249
+ end
1250
+ end
1251
+ get '/users/josh'
1252
+ assert_equal 'josh', username_from_before_filter
1253
+ end
1254
+
1255
+ should "be able to access params normally when a before filter is specified" do
1256
+ mock_app do
1257
+ before { }
1258
+ get :index do
1259
+ params.inspect
1260
+ end
1261
+ end
1262
+ get '/?test=what'
1263
+ assert_equal '{"test"=>"what"}', body
1264
+ end
1265
+
1266
+ should 'work with controller and arbitrary params' do
1267
+ mock_app do
1268
+ get(:testing) { params[:foo] }
1269
+ controller :test1 do
1270
+ get(:url1) { params[:foo] }
1271
+ get(:url2, :provides => [:html, :json]) { params[:foo] }
1272
+ end
1273
+ end
1274
+
1275
+ url = @app.url(:test1, :url1, :foo => 'bar1')
1276
+ assert_equal "/test1/url1?foo=bar1", url
1277
+ get url
1278
+ assert_equal "bar1", body
1279
+
1280
+ url = @app.url(:test1, :url2, :foo => 'bar2')
1281
+ assert_equal "/test1/url2?foo=bar2", url
1282
+ get url
1283
+ assert_equal "bar2", body
1284
+ end
1285
+
1286
+ should "parse two routes with the same path but different http verbs" do
1287
+ mock_app do
1288
+ get(:index) { "This is the get index" }
1289
+ post(:index) { "This is the post index" }
1290
+ end
1291
+ get "/"
1292
+ assert_equal "This is the get index", body
1293
+ post "/"
1294
+ assert_equal "This is the post index", body
1295
+ end
1296
+
1297
+ should "use optionals params" do
1298
+ mock_app do
1299
+ get(:index, :map => "/(:foo(/:bar))") { "#{params[:foo]}-#{params[:bar]}" }
1300
+ end
1301
+ get "/foo"
1302
+ assert_equal "foo-", body
1303
+ get "/foo/bar"
1304
+ assert_equal "foo-bar", body
1305
+ end
1306
+
1307
+ should "parse two routes with the same path but different http verbs and provides" do
1308
+ mock_app do
1309
+ get(:index, :provides => [:html, :json]) { "This is the get index.#{content_type}" }
1310
+ post(:index, :provides => [:html, :json]) { "This is the post index.#{content_type}" }
1311
+ end
1312
+ get "/"
1313
+ assert_equal "This is the get index.html", body
1314
+ post "/"
1315
+ assert_equal "This is the post index.html", body
1316
+ get "/.json"
1317
+ assert_equal "This is the get index.json", body
1318
+ get "/.js"
1319
+ assert_equal 405, status
1320
+ post "/.json"
1321
+ assert_equal "This is the post index.json", body
1322
+ post "/.js"
1323
+ assert_equal 405, status
1324
+ end
1325
+
1326
+ should "allow controller level mapping" do
1327
+ mock_app do
1328
+ controller :map => "controller-:id" do
1329
+ get(:url3) { "#{params[:id]}" }
1330
+ get(:url4, :map => 'test-:id2') { "#{params[:id]}, #{params[:id2]}" }
1331
+ end
1332
+ end
1333
+
1334
+ url = @app.url(:url3, :id => 1)
1335
+ assert_equal "/controller-1/url3", url
1336
+ get url
1337
+ assert_equal "1", body
1338
+
1339
+ url = @app.url(:url4, 1, 2)
1340
+ assert_equal "/controller-1/test-2", url
1341
+ get url
1342
+ assert_equal "1, 2", body
1343
+ end
1344
+
1345
+ should 'use absolute and relative maps' do
1346
+ mock_app do
1347
+ controller :one do
1348
+ parent :three
1349
+ get :index, :map => 'one' do; end
1350
+ get :index2, :map => '/one' do; end
1351
+ end
1352
+
1353
+ controller :two, :map => 'two' do
1354
+ parent :three
1355
+ get :index, :map => 'two' do; end
1356
+ get :index2, :map => '/two', :with => :id do; end
1357
+ end
1358
+ end
1359
+ assert_equal "/three/three_id/one", @app.url(:one, :index, 'three_id')
1360
+ assert_equal "/one", @app.url(:one, :index2)
1361
+ assert_equal "/two/three/three_id/two", @app.url(:two, :index, 'three_id')
1362
+ assert_equal "/two/four_id", @app.url(:two, :index2, 'four_id')
1363
+ end
1364
+
1365
+ should "work with params and parent options" do
1366
+ mock_app do
1367
+ controller :test2, :parent => :parent1, :parent1_id => 1 do
1368
+ get(:url3) { params[:foo] }
1369
+ get(:url4, :with => :with1) { params[:foo] }
1370
+ get(:url5, :with => :with2, :provides => [:html]) { params[:foo] }
1371
+ end
1372
+ end
1373
+
1374
+ url = @app.url(:test2, :url3, :foo => 'bar3')
1375
+ assert_equal "/parent1/1/test2/url3?foo=bar3", url
1376
+ get url
1377
+ assert_equal "bar3", body
1378
+
1379
+ url = @app.url(:test2, :url4, :with1 => 'awith1', :foo => 'bar4')
1380
+ assert_equal "/parent1/1/test2/url4/awith1?foo=bar4", url
1381
+ get url
1382
+ assert_equal "bar4", body
1383
+
1384
+ url = @app.url(:test2, :url5, :with2 => 'awith1', :foo => 'bar5')
1385
+ assert_equal "/parent1/1/test2/url5/awith1?foo=bar5", url
1386
+ get url
1387
+ assert_equal "bar5", body
1388
+ end
1389
+
1390
+ should "parse params without explicit provides for every matching route" do
1391
+ mock_app do
1392
+ get(:index, :map => "/foos/:bar") { "get bar = #{params[:bar]}" }
1393
+ post :create, :map => "/foos/:bar", :provides => [:html, :js] do
1394
+ "post bar = #{params[:bar]}"
1395
+ end
1396
+ end
1397
+
1398
+ get "/foos/hello"
1399
+ assert_equal "get bar = hello", body
1400
+ post "/foos/hello"
1401
+ assert_equal "post bar = hello", body
1402
+ post "/foos/hello.js"
1403
+ assert_equal "post bar = hello", body
1404
+ end
1405
+
1406
+ should "properly route to first foo with two similar routes" do
1407
+ mock_app do
1408
+ controllers do
1409
+ get('/foo/') { "this is foo" }
1410
+ get(:show, :map => "/foo/:bar/:id") { "/foo/#{params[:bar]}/#{params[:id]}" }
1411
+ end
1412
+ end
1413
+ get "/foo"
1414
+ assert_equal "this is foo", body
1415
+ get "/foo/"
1416
+ assert_equal "this is foo", body
1417
+ get '/foo/5/10'
1418
+ assert_equal "/foo/5/10", body
1419
+ end
1420
+
1421
+ should "index routes should be optional when nested" do
1422
+ mock_app do
1423
+ controller '/users', :provides => [:json] do
1424
+ get '/' do
1425
+ "foo"
1426
+ end
1427
+ end
1428
+ end
1429
+ get "/users.json"
1430
+ assert_equal "foo", body
1431
+ end
1432
+
1433
+ should "use provides as conditional" do
1434
+ mock_app do
1435
+ provides :json
1436
+ get "/" do
1437
+ "foo"
1438
+ end
1439
+ end
1440
+ get "/.json"
1441
+ assert_equal "foo", body
1442
+ end
1443
+
1444
+ should "pass controller conditions to each route" do
1445
+ counter = 0
1446
+
1447
+ mock_app do
1448
+ self.class.send(:define_method, :increment!) do |*args|
1449
+ condition { counter += 1 }
1450
+ end
1451
+
1452
+ controller :posts, :conditions => {:increment! => true} do
1453
+ get("/foo") { "foo" }
1454
+ get("/bar") { "bar" }
1455
+ end
1456
+
1457
+ end
1458
+
1459
+ get "/posts/foo"
1460
+ get "/posts/bar"
1461
+ assert_equal 2, counter
1462
+ end
1463
+
1464
+ should "allow controller conditions to be overridden" do
1465
+ counter = 0
1466
+
1467
+ mock_app do
1468
+ self.class.send(:define_method, :increment!) do |increment|
1469
+ condition { counter += 1 } if increment
1470
+ end
1471
+
1472
+ controller :posts, :conditions => {:increment! => true} do
1473
+ get("/foo") { "foo" }
1474
+ get("/bar", :increment! => false) { "bar" }
1475
+ end
1476
+
1477
+ end
1478
+
1479
+ get "/posts/foo"
1480
+ get "/posts/bar"
1481
+ assert_equal 1, counter
1482
+ end
1483
+
1484
+ should "parse params with class level provides" do
1485
+ mock_app do
1486
+ controllers :posts, :provides => [:html, :js] do
1487
+ post(:create, :map => "/foo/:bar/:baz/:id") {
1488
+ "POST CREATE #{params[:bar]} - #{params[:baz]} - #{params[:id]}"
1489
+ }
1490
+ end
1491
+ controllers :topics, :provides => [:js, :html] do
1492
+ get(:show, :map => "/foo/:bar/:baz/:id") { render "topics/show" }
1493
+ post(:create, :map => "/foo/:bar/:baz") { "TOPICS CREATE #{params[:bar]} - #{params[:baz]}" }
1494
+ end
1495
+ end
1496
+ post "/foo/bar/baz.js"
1497
+ assert_equal "TOPICS CREATE bar - baz", body, "should parse params with explicit .js"
1498
+ post @app.url(:topics, :create, :format => :js, :bar => 'bar', :baz => 'baz')
1499
+ assert_equal "TOPICS CREATE bar - baz", body, "should parse params from generated url"
1500
+ post "/foo/bar/baz/5.js"
1501
+ assert_equal "POST CREATE bar - baz - 5", body
1502
+ post @app.url(:posts, :create, :format => :js, :bar => 'bar', :baz => 'baz', :id => 5)
1503
+ assert_equal "POST CREATE bar - baz - 5", body
1504
+ end
1505
+
1506
+ should "parse params properly with inline provides" do
1507
+ mock_app do
1508
+ controllers :posts do
1509
+ post(:create, :map => "/foo/:bar/:baz/:id", :provides => [:html, :js]) {
1510
+ "POST CREATE #{params[:bar]} - #{params[:baz]} - #{params[:id]}"
1511
+ }
1512
+ end
1513
+ controllers :topics do
1514
+ get(:show, :map => "/foo/:bar/:baz/:id", :provides => [:html, :js]) { render "topics/show" }
1515
+ post(:create, :map => "/foo/:bar/:baz", :provides => [:html, :js]) { "TOPICS CREATE #{params[:bar]} - #{params[:baz]}" }
1516
+ end
1517
+ end
1518
+ post @app.url(:topics, :create, :format => :js, :bar => 'bar', :baz => 'baz')
1519
+ assert_equal "TOPICS CREATE bar - baz", body, "should properly post to topics create action"
1520
+ post @app.url(:posts, :create, :format => :js, :bar => 'bar', :baz => 'baz', :id => 5)
1521
+ assert_equal "POST CREATE bar - baz - 5", body, "should properly post to create action"
1522
+ end
1523
+
1524
+ should "have overideable format" do
1525
+ mock_app do
1526
+ ::Rack::Mime::MIME_TYPES[".other"] = "text/html"
1527
+ before do
1528
+ params[:format] ||= :other
1529
+ end
1530
+ get("/format_test", :provides => [:html, :other]){ content_type.to_s }
1531
+ end
1532
+ get "/format_test"
1533
+ assert_equal "other", body
1534
+ end
1535
+
1536
+ should 'invokes handlers registered with ::error when raised' do
1537
+ mock_app do
1538
+ set :raise_errors, false
1539
+ error(FooError) { 'Foo!' }
1540
+ get '/' do
1541
+ raise FooError
1542
+ end
1543
+ end
1544
+ get '/'
1545
+ assert_equal 500, status
1546
+ assert_equal 'Foo!', body
1547
+ end
1548
+
1549
+ should 'have MethodOverride middleware' do
1550
+ mock_app do
1551
+ put('/') { 'okay' }
1552
+ end
1553
+ assert @app.method_override?
1554
+ post '/', {'_method'=>'PUT'}, {}
1555
+ assert_equal 200, status
1556
+ assert_equal 'okay', body
1557
+ end
1558
+
1559
+ should 'return value from params' do
1560
+ mock_app do
1561
+ get("/foo/:bar"){ raise "'bar' should be a string" unless params[:bar].kind_of? String}
1562
+ end
1563
+ get "/foo/50"
1564
+ assert ok?
1565
+ end
1566
+
1567
+ should 'have MethodOverride middleware with more options' do
1568
+ mock_app do
1569
+ put('/hi', :provides => [:json]) { 'hi' }
1570
+ end
1571
+ post '/hi', {'_method'=>'PUT'}
1572
+ assert_equal 200, status
1573
+ assert_equal 'hi', body
1574
+ post '/hi.json', {'_method'=>'PUT'}
1575
+ assert_equal 200, status
1576
+ assert_equal 'hi', body
1577
+ post '/hi.json'
1578
+ assert_equal 405, status
1579
+ end
1580
+
1581
+ should 'parse nested params' do
1582
+ mock_app do
1583
+ get(:index) { "%s %s" % [params[:account][:name], params[:account][:surname]] }
1584
+ end
1585
+ get "/?account[name]=foo&account[surname]=bar"
1586
+ assert_equal 'foo bar', body
1587
+ get @app.url(:index, "account[name]" => "foo", "account[surname]" => "bar")
1588
+ assert_equal 'foo bar', body
1589
+ end
1590
+
1591
+ should 'render sinatra NotFound page' do
1592
+ mock_app { set :environment, :development }
1593
+ get "/"
1594
+ assert_equal 404, status
1595
+ assert_match %r{(Sinatra doesn&rsquo;t know this ditty.|<h1>Not Found</h1>)}, body
1596
+ end
1597
+
1598
+ should 'render a custom NotFound page' do
1599
+ mock_app do
1600
+ error(Sinatra::NotFound) { "not found" }
1601
+ end
1602
+ get "/"
1603
+ assert_equal 404, status
1604
+ assert_match /not found/, body
1605
+ end
1606
+
1607
+ should 'render a custom 404 page' do
1608
+ mock_app do
1609
+ error(404) { "not found" }
1610
+ end
1611
+ get "/"
1612
+ assert_equal 404, status
1613
+ assert_match /not found/, body
1614
+ end
1615
+
1616
+ should 'recognize paths' do
1617
+ mock_app do
1618
+ controller :foo do
1619
+ get(:bar, :map => "/my/:id/custom-route") { }
1620
+ end
1621
+ get(:simple, :map => "/simple/:id") { }
1622
+ get(:with_format, :with => :id, :provides => :js) { }
1623
+ end
1624
+ assert_equal [:foo_bar, { :id => "fantastic" }], @app.recognize_path(@app.url(:foo, :bar, :id => :fantastic))
1625
+ assert_equal [:foo_bar, { :id => "18" }], @app.recognize_path(@app.url(:foo, :bar, :id => 18))
1626
+ assert_equal [:simple, { :id => "bar" }], @app.recognize_path(@app.url(:simple, :id => "bar"))
1627
+ assert_equal [:simple, { :id => "true" }], @app.recognize_path(@app.url(:simple, :id => true))
1628
+ assert_equal [:simple, { :id => "9" }], @app.recognize_path(@app.url(:simple, :id => 9))
1629
+ assert_equal [:with_format, { :id => "bar", :format => "js" }], @app.recognize_path(@app.url(:with_format, :id => "bar", :format => :js))
1630
+ assert_equal [:with_format, { :id => "true", :format => "js" }], @app.recognize_path(@app.url(:with_format, :id => true, :format => "js"))
1631
+ assert_equal [:with_format, { :id => "9", :format => "js" }], @app.recognize_path(@app.url(:with_format, :id => 9, :format => :js))
1632
+ end
1633
+
1634
+ should 'have current_path' do
1635
+ mock_app do
1636
+ controller :foo do
1637
+ get(:index) { current_path }
1638
+ get :bar, :map => "/paginate/:page" do
1639
+ current_path
1640
+ end
1641
+ get(:after) { current_path }
1642
+ end
1643
+ end
1644
+ get "/paginate/10"
1645
+ assert_equal "/paginate/10", body
1646
+ get "/foo/after"
1647
+ assert_equal "/foo/after", body
1648
+ get "/foo"
1649
+ assert_equal "/foo", body
1650
+ end
1651
+
1652
+ should 'accept :map and :parent' do
1653
+ mock_app do
1654
+ controller :posts do
1655
+ get :show, :parent => :users, :map => "posts/:id" do
1656
+ "#{params[:user_id]}-#{params[:id]}"
1657
+ end
1658
+ end
1659
+ end
1660
+ get '/users/123/posts/321'
1661
+ assert_equal "123-321", body
1662
+ end
1663
+
1664
+ should 'change params in current_path' do
1665
+ mock_app do
1666
+ get :index, :map => "/paginate/:page" do
1667
+ current_path(:page => 66)
1668
+ end
1669
+ end
1670
+ get @app.url(:index, :page => 10)
1671
+ assert_equal "/paginate/66", body
1672
+ end
1673
+ end