spontaneous 0.1.0.alpha1

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 (556) hide show
  1. data/Gemfile +49 -0
  2. data/Gemfile.lock +146 -0
  3. data/LICENSE +0 -0
  4. data/README +0 -0
  5. data/Rakefile +284 -0
  6. data/Readme.markdown +7 -0
  7. data/application/css/add_alias_dialogue.scss +27 -0
  8. data/application/css/definitions.scss +249 -0
  9. data/application/css/developer.scss +9 -0
  10. data/application/css/editing.scss +649 -0
  11. data/application/css/login.scss +91 -0
  12. data/application/css/min/54ee0ed3c7fac7632bd5c020d69e9a2503e0c88c.css +1 -0
  13. data/application/css/min/c256adc144e2bdd0b0539356b04eb62db01e1dc3.css +1 -0
  14. data/application/css/popover.scss +335 -0
  15. data/application/css/schema_error.scss +90 -0
  16. data/application/css/spontaneous.scss +111 -0
  17. data/application/css/unsupported.scss +16 -0
  18. data/application/css/v2.scss +1606 -0
  19. data/application/css/variables.scss +80 -0
  20. data/application/js/add_alias_dialogue.js +59 -0
  21. data/application/js/add_home_dialogue.js +59 -0
  22. data/application/js/ajax.js +99 -0
  23. data/application/js/authentication.js +22 -0
  24. data/application/js/box.js +104 -0
  25. data/application/js/box_container.js +82 -0
  26. data/application/js/compatibility.js +132 -0
  27. data/application/js/conflicted_field_dialogue.js +92 -0
  28. data/application/js/content.js +224 -0
  29. data/application/js/content_area.js +44 -0
  30. data/application/js/dialogue.js +196 -0
  31. data/application/js/dom.js +71 -0
  32. data/application/js/edit_dialogue.js +137 -0
  33. data/application/js/edit_panel.js +232 -0
  34. data/application/js/editing.js +42 -0
  35. data/application/js/entry.js +13 -0
  36. data/application/js/extensions.js +104 -0
  37. data/application/js/field.js +4 -0
  38. data/application/js/field_preview.js +55 -0
  39. data/application/js/field_types/date_field.js +16 -0
  40. data/application/js/field_types/file_field.js +71 -0
  41. data/application/js/field_types/image_field.js +358 -0
  42. data/application/js/field_types/markdown_field.js +656 -0
  43. data/application/js/field_types/string_field.js +185 -0
  44. data/application/js/image.js +72 -0
  45. data/application/js/init.js +34 -0
  46. data/application/js/load.js +4 -0
  47. data/application/js/location.js +157 -0
  48. data/application/js/login.js +53 -0
  49. data/application/js/min/492a209de8ee955fa9c729a765377495001e11b1.js +17 -0
  50. data/application/js/min/80f684d77c940887a1d4a63e3a96102e993baa98.js +88 -0
  51. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +2 -0
  52. data/application/js/min/c7140ec9475e5bf868b901e0621338d7d162358b.js +3 -0
  53. data/application/js/min/f07f2bd6630ee31e1c2288ec223383d8f0658ba6.js +2 -0
  54. data/application/js/page.js +43 -0
  55. data/application/js/page_browser.js +147 -0
  56. data/application/js/page_entry.js +47 -0
  57. data/application/js/popover.js +99 -0
  58. data/application/js/popover_view.js +56 -0
  59. data/application/js/preview.js +64 -0
  60. data/application/js/progress.js +358 -0
  61. data/application/js/properties.js +90 -0
  62. data/application/js/publish.js +187 -0
  63. data/application/js/require.js +129 -0
  64. data/application/js/sharded_upload.js +206 -0
  65. data/application/js/side_bar.js +30 -0
  66. data/application/js/spontaneous.js +6 -0
  67. data/application/js/state.js +64 -0
  68. data/application/js/status_bar.js +47 -0
  69. data/application/js/top_bar.js +368 -0
  70. data/application/js/types.js +98 -0
  71. data/application/js/upload.js +88 -0
  72. data/application/js/upload_manager.js +319 -0
  73. data/application/js/user.js +37 -0
  74. data/application/js/vendor/.DS_Store +0 -0
  75. data/application/js/vendor/JS.Class-2.1.5/CHANGELOG +283 -0
  76. data/application/js/vendor/JS.Class-2.1.5/MIT-LICENSE +30 -0
  77. data/application/js/vendor/JS.Class-2.1.5/README +30 -0
  78. data/application/js/vendor/JS.Class-2.1.5/min/command.js +1 -0
  79. data/application/js/vendor/JS.Class-2.1.5/min/comparable.js +1 -0
  80. data/application/js/vendor/JS.Class-2.1.5/min/constant_scope.js +1 -0
  81. data/application/js/vendor/JS.Class-2.1.5/min/core.js +1 -0
  82. data/application/js/vendor/JS.Class-2.1.5/min/decorator.js +1 -0
  83. data/application/js/vendor/JS.Class-2.1.5/min/enumerable.js +1 -0
  84. data/application/js/vendor/JS.Class-2.1.5/min/forwardable.js +1 -0
  85. data/application/js/vendor/JS.Class-2.1.5/min/hash.js +1 -0
  86. data/application/js/vendor/JS.Class-2.1.5/min/linked_list.js +1 -0
  87. data/application/js/vendor/JS.Class-2.1.5/min/loader.js +1 -0
  88. data/application/js/vendor/JS.Class-2.1.5/min/method_chain.js +1 -0
  89. data/application/js/vendor/JS.Class-2.1.5/min/observable.js +1 -0
  90. data/application/js/vendor/JS.Class-2.1.5/min/package.js +1 -0
  91. data/application/js/vendor/JS.Class-2.1.5/min/proxy.js +1 -0
  92. data/application/js/vendor/JS.Class-2.1.5/min/ruby.js +1 -0
  93. data/application/js/vendor/JS.Class-2.1.5/min/set.js +1 -0
  94. data/application/js/vendor/JS.Class-2.1.5/min/stack_trace.js +1 -0
  95. data/application/js/vendor/JS.Class-2.1.5/min/state.js +1 -0
  96. data/application/js/vendor/JS.Class-2.1.5/min/stdlib.js +16 -0
  97. data/application/js/vendor/JS.Class-2.1.5/src/command.js +93 -0
  98. data/application/js/vendor/JS.Class-2.1.5/src/comparable.js +37 -0
  99. data/application/js/vendor/JS.Class-2.1.5/src/constant_scope.js +48 -0
  100. data/application/js/vendor/JS.Class-2.1.5/src/core.js +1060 -0
  101. data/application/js/vendor/JS.Class-2.1.5/src/decorator.js +50 -0
  102. data/application/js/vendor/JS.Class-2.1.5/src/enumerable.js +505 -0
  103. data/application/js/vendor/JS.Class-2.1.5/src/forwardable.js +22 -0
  104. data/application/js/vendor/JS.Class-2.1.5/src/hash.js +334 -0
  105. data/application/js/vendor/JS.Class-2.1.5/src/linked_list.js +114 -0
  106. data/application/js/vendor/JS.Class-2.1.5/src/loader.js +553 -0
  107. data/application/js/vendor/JS.Class-2.1.5/src/method_chain.js +172 -0
  108. data/application/js/vendor/JS.Class-2.1.5/src/observable.js +55 -0
  109. data/application/js/vendor/JS.Class-2.1.5/src/package.js +472 -0
  110. data/application/js/vendor/JS.Class-2.1.5/src/proxy.js +58 -0
  111. data/application/js/vendor/JS.Class-2.1.5/src/ruby.js +44 -0
  112. data/application/js/vendor/JS.Class-2.1.5/src/set.js +332 -0
  113. data/application/js/vendor/JS.Class-2.1.5/src/stack_trace.js +151 -0
  114. data/application/js/vendor/JS.Class-2.1.5/src/state.js +95 -0
  115. data/application/js/vendor/JS.Class-2.1.5/src/stdlib.js +2612 -0
  116. data/application/js/vendor/crypto-2.3.0-crypto.js +160 -0
  117. data/application/js/vendor/crypto-2.3.0-sha1.js +91 -0
  118. data/application/js/vendor/diff_match_patch.js +2153 -0
  119. data/application/js/vendor/jquery-1.4.2.min.js +154 -0
  120. data/application/js/vendor/jquery-1.4.3.min.js +166 -0
  121. data/application/js/vendor/jquery-1.5.1.min.js +16 -0
  122. data/application/js/vendor/jquery-1.5.1rc1.min.js +24 -0
  123. data/application/js/vendor/jquery-1.6.2.min.js +18 -0
  124. data/application/js/vendor/jquery-ui-1.8.6.custom.min.js +265 -0
  125. data/application/js/vendor/jquery-ui-1.8.9.custom.min.js +415 -0
  126. data/application/js/vendor/jquery-ui-1.8.custom.min.js +106 -0
  127. data/application/js/vendor/jquery.hotkeys-0.7.9.js +248 -0
  128. data/application/js/vendor/jquery.hotkeys-0.7.9.min.js +19 -0
  129. data/application/js/vendor/jsdiff.js +169 -0
  130. data/application/js/views/box_view.js +229 -0
  131. data/application/js/views/page_piece_view.js +45 -0
  132. data/application/js/views/page_view.js +238 -0
  133. data/application/js/views/piece_view.js +178 -0
  134. data/application/js/views.js +110 -0
  135. data/application/static/editing-0-noise.png +0 -0
  136. data/application/static/editing-1-noise.png +0 -0
  137. data/application/static/editing-texture-1.png +0 -0
  138. data/application/static/editing-texture.png +0 -0
  139. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  140. data/application/static/editing-toolbar-shadow-top.png +0 -0
  141. data/application/static/favicon.ico +0 -0
  142. data/application/static/inner-glow.png +0 -0
  143. data/application/static/item-buttons.png +0 -0
  144. data/application/static/location-arrow.png +0 -0
  145. data/application/static/logo-400px-transparent.png +0 -0
  146. data/application/static/missing.png +0 -0
  147. data/application/static/orange-down-arrow.png +0 -0
  148. data/application/static/page-browser-next.png +0 -0
  149. data/application/static/paper-texture-dark.png +0 -0
  150. data/application/static/px.gif +0 -0
  151. data/application/static/select-arrow-root.png +0 -0
  152. data/application/static/select-arrow.png +0 -0
  153. data/application/static/slot-down-arrow.png +0 -0
  154. data/application/static/splash.png +0 -0
  155. data/application/static/spontaneous.png +0 -0
  156. data/application/static/spot.png +0 -0
  157. data/application/static/spot.svg +40 -0
  158. data/application/static/texture.png +0 -0
  159. data/application/views/index.erubis +46 -0
  160. data/application/views/login.erubis +69 -0
  161. data/application/views/schema_modification_error.html.erb +61 -0
  162. data/application/views/unsupported.erubis +23 -0
  163. data/bin/limit-upload +5 -0
  164. data/bin/spot +10 -0
  165. data/bin/unlimit-upload +3 -0
  166. data/config/nginx.conf +60 -0
  167. data/db/migrations/20100610142136_init.rb +66 -0
  168. data/db/migrations/20101130104334_timestamps.rb +44 -0
  169. data/db/migrations/20101202113205_site_publishing_flags.rb +12 -0
  170. data/db/migrations/20101206124543_aliases.rb +16 -0
  171. data/db/migrations/20110201133550_visibility.rb +27 -0
  172. data/db/migrations/20110209152710_users_and_groups.rb +58 -0
  173. data/db/migrations/20110215133910_boxes.rb +25 -0
  174. data/db/migrations/20110521114145_remove_slots_and_entries.rb +21 -0
  175. data/db/migrations/20110604192145_rename_schema_id_columns.rb +22 -0
  176. data/db/migrations/20110805141925_rename_site_to_state.rb +11 -0
  177. data/lib/cutaneous/context_helper.rb +82 -0
  178. data/lib/cutaneous/first_pass_parser.rb +23 -0
  179. data/lib/cutaneous/first_pass_renderer.rb +18 -0
  180. data/lib/cutaneous/parser_core.rb +18 -0
  181. data/lib/cutaneous/preview_context.rb +31 -0
  182. data/lib/cutaneous/preview_renderer.rb +15 -0
  183. data/lib/cutaneous/publish_context.rb +9 -0
  184. data/lib/cutaneous/renderer.rb +122 -0
  185. data/lib/cutaneous/request_context.rb +8 -0
  186. data/lib/cutaneous/second_pass_parser.rb +23 -0
  187. data/lib/cutaneous/second_pass_renderer.rb +18 -0
  188. data/lib/cutaneous.rb +47 -0
  189. data/lib/sequel/plugins/content_table_inheritance.rb +196 -0
  190. data/lib/sequel/plugins/yajl_serialization.rb +154 -0
  191. data/lib/spontaneous/application/feature.rb +9 -0
  192. data/lib/spontaneous/application/plugin.rb +13 -0
  193. data/lib/spontaneous/application.rb +8 -0
  194. data/lib/spontaneous/box.rb +232 -0
  195. data/lib/spontaneous/box_style.rb +64 -0
  196. data/lib/spontaneous/change.rb +107 -0
  197. data/lib/spontaneous/cli/adapter.rb +13 -0
  198. data/lib/spontaneous/cli/base.rb +184 -0
  199. data/lib/spontaneous/cli/console.rb +0 -0
  200. data/lib/spontaneous/cli/media.rb +13 -0
  201. data/lib/spontaneous/cli/server.rb +50 -0
  202. data/lib/spontaneous/cli/site.rb +46 -0
  203. data/lib/spontaneous/cli/sync.rb +42 -0
  204. data/lib/spontaneous/cli/tasks.rb +9 -0
  205. data/lib/spontaneous/cli.rb +83 -0
  206. data/lib/spontaneous/collections/box_set.rb +56 -0
  207. data/lib/spontaneous/collections/change_set.rb +43 -0
  208. data/lib/spontaneous/collections/entry_set.rb +83 -0
  209. data/lib/spontaneous/collections/field_set.rb +53 -0
  210. data/lib/spontaneous/collections/prototype_set.rb +131 -0
  211. data/lib/spontaneous/collections/style_set.rb +13 -0
  212. data/lib/spontaneous/config.rb +156 -0
  213. data/lib/spontaneous/constants.rb +24 -0
  214. data/lib/spontaneous/content.rb +113 -0
  215. data/lib/spontaneous/content_query.rb +17 -0
  216. data/lib/spontaneous/errors.rb +48 -0
  217. data/lib/spontaneous/extensions/array.rb +18 -0
  218. data/lib/spontaneous/extensions/class.rb +17 -0
  219. data/lib/spontaneous/extensions/hash.rb +18 -0
  220. data/lib/spontaneous/extensions/json.rb +26 -0
  221. data/lib/spontaneous/extensions/kernel.rb +7 -0
  222. data/lib/spontaneous/extensions/object.rb +30 -0
  223. data/lib/spontaneous/extensions/object_space.rb +12 -0
  224. data/lib/spontaneous/extensions/string.rb +44 -0
  225. data/lib/spontaneous/facet.rb +47 -0
  226. data/lib/spontaneous/field_types/date_field.rb +12 -0
  227. data/lib/spontaneous/field_types/field.rb +252 -0
  228. data/lib/spontaneous/field_types/image_field.rb +329 -0
  229. data/lib/spontaneous/field_types/markdown_field.rb +37 -0
  230. data/lib/spontaneous/field_types/string_field.rb +14 -0
  231. data/lib/spontaneous/field_types.rb +40 -0
  232. data/lib/spontaneous/generators/page/inline.html.cut +1 -0
  233. data/lib/spontaneous/generators/page/page.html.cut.tt +4 -0
  234. data/lib/spontaneous/generators/page/page.rb.tt +9 -0
  235. data/lib/spontaneous/generators/page.rb +38 -0
  236. data/lib/spontaneous/generators/site/.gitignore +4 -0
  237. data/lib/spontaneous/generators/site/Gemfile.tt +31 -0
  238. data/lib/spontaneous/generators/site/Rakefile.tt +6 -0
  239. data/lib/spontaneous/generators/site/config/back.ru +7 -0
  240. data/lib/spontaneous/generators/site/config/boot.rb +19 -0
  241. data/lib/spontaneous/generators/site/config/database.yml.tt +21 -0
  242. data/lib/spontaneous/generators/site/config/deploy.rb.tt +0 -0
  243. data/lib/spontaneous/generators/site/config/environment.rb.tt +8 -0
  244. data/lib/spontaneous/generators/site/config/environments/development.rb.tt +15 -0
  245. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +5 -0
  246. data/lib/spontaneous/generators/site/config/front.ru +8 -0
  247. data/lib/spontaneous/generators/site/config/user_levels.yml +22 -0
  248. data/lib/spontaneous/generators/site/lib/site.rb.tt +4 -0
  249. data/lib/spontaneous/generators/site/lib/tasks/site.rake.tt +8 -0
  250. data/lib/spontaneous/generators/site/public/css/site.css +0 -0
  251. data/lib/spontaneous/generators/site/public/favicon.ico +0 -0
  252. data/lib/spontaneous/generators/site/public/js/.empty_directory +0 -0
  253. data/lib/spontaneous/generators/site/public/js/site.js +0 -0
  254. data/lib/spontaneous/generators/site/public/robots.txt +0 -0
  255. data/lib/spontaneous/generators/site/schema/.map +1 -0
  256. data/lib/spontaneous/generators/site/schema/page.rb.tt +8 -0
  257. data/lib/spontaneous/generators/site/schema/piece.rb.tt +4 -0
  258. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +13 -0
  259. data/lib/spontaneous/generators/site.rb +77 -0
  260. data/lib/spontaneous/generators.rb +23 -0
  261. data/lib/spontaneous/image_size.rb +117 -0
  262. data/lib/spontaneous/json.rb +33 -0
  263. data/lib/spontaneous/layout.rb +15 -0
  264. data/lib/spontaneous/loader.rb +280 -0
  265. data/lib/spontaneous/logger.rb +369 -0
  266. data/lib/spontaneous/media.rb +84 -0
  267. data/lib/spontaneous/page.rb +92 -0
  268. data/lib/spontaneous/page_controller.rb +18 -0
  269. data/lib/spontaneous/page_piece.rb +77 -0
  270. data/lib/spontaneous/paths.rb +30 -0
  271. data/lib/spontaneous/permissions/access_group.rb +50 -0
  272. data/lib/spontaneous/permissions/access_key.rb +35 -0
  273. data/lib/spontaneous/permissions/user.rb +167 -0
  274. data/lib/spontaneous/permissions/user_level.rb +177 -0
  275. data/lib/spontaneous/permissions.rb +55 -0
  276. data/lib/spontaneous/piece.rb +30 -0
  277. data/lib/spontaneous/plugins/aliases.rb +128 -0
  278. data/lib/spontaneous/plugins/allowed_types.rb +173 -0
  279. data/lib/spontaneous/plugins/application/facets.rb +25 -0
  280. data/lib/spontaneous/plugins/application/paths.rb +137 -0
  281. data/lib/spontaneous/plugins/application/render.rb +29 -0
  282. data/lib/spontaneous/plugins/application/serialisation.rb +16 -0
  283. data/lib/spontaneous/plugins/application/state.rb +86 -0
  284. data/lib/spontaneous/plugins/boxes.rb +84 -0
  285. data/lib/spontaneous/plugins/controllers.rb +52 -0
  286. data/lib/spontaneous/plugins/entries.rb +193 -0
  287. data/lib/spontaneous/plugins/entry.rb +51 -0
  288. data/lib/spontaneous/plugins/fields.rb +103 -0
  289. data/lib/spontaneous/plugins/instance_code.rb +18 -0
  290. data/lib/spontaneous/plugins/layouts.rb +87 -0
  291. data/lib/spontaneous/plugins/media.rb +41 -0
  292. data/lib/spontaneous/plugins/page/formats.rb +67 -0
  293. data/lib/spontaneous/plugins/page/request.rb +89 -0
  294. data/lib/spontaneous/plugins/page_search.rb +64 -0
  295. data/lib/spontaneous/plugins/page_tree.rb +25 -0
  296. data/lib/spontaneous/plugins/paths.rb +125 -0
  297. data/lib/spontaneous/plugins/permissions.rb +63 -0
  298. data/lib/spontaneous/plugins/prototypes.rb +84 -0
  299. data/lib/spontaneous/plugins/publishing.rb +255 -0
  300. data/lib/spontaneous/plugins/render.rb +24 -0
  301. data/lib/spontaneous/plugins/schema_hierarchy.rb +76 -0
  302. data/lib/spontaneous/plugins/schema_id.rb +60 -0
  303. data/lib/spontaneous/plugins/schema_title.rb +33 -0
  304. data/lib/spontaneous/plugins/serialisation.rb +67 -0
  305. data/lib/spontaneous/plugins/site/instance.rb +22 -0
  306. data/lib/spontaneous/plugins/site/map.rb +19 -0
  307. data/lib/spontaneous/plugins/site/publishing.rb +74 -0
  308. data/lib/spontaneous/plugins/site/revisions.rb +28 -0
  309. data/lib/spontaneous/plugins/site/selectors.rb +41 -0
  310. data/lib/spontaneous/plugins/site_map.rb +34 -0
  311. data/lib/spontaneous/plugins/styles.rb +119 -0
  312. data/lib/spontaneous/plugins/supertype.rb +11 -0
  313. data/lib/spontaneous/plugins/visibility.rb +151 -0
  314. data/lib/spontaneous/plugins.rb +20 -0
  315. data/lib/spontaneous/prototypes/box_prototype.rb +168 -0
  316. data/lib/spontaneous/prototypes/field_prototype.rb +112 -0
  317. data/lib/spontaneous/prototypes/layout_prototype.rb +17 -0
  318. data/lib/spontaneous/prototypes/style_prototype.rb +42 -0
  319. data/lib/spontaneous/proxy_object.rb +12 -0
  320. data/lib/spontaneous/publishing/fire_and_forget.rb +57 -0
  321. data/lib/spontaneous/publishing/immediate.rb +197 -0
  322. data/lib/spontaneous/publishing/threaded.rb +25 -0
  323. data/lib/spontaneous/publishing.rb +10 -0
  324. data/lib/spontaneous/rack/around_back.rb +44 -0
  325. data/lib/spontaneous/rack/around_front.rb +29 -0
  326. data/lib/spontaneous/rack/around_preview.rb +26 -0
  327. data/lib/spontaneous/rack/assets.rb +98 -0
  328. data/lib/spontaneous/rack/back.rb +729 -0
  329. data/lib/spontaneous/rack/front.rb +41 -0
  330. data/lib/spontaneous/rack/http.rb +18 -0
  331. data/lib/spontaneous/rack/media.rb +29 -0
  332. data/lib/spontaneous/rack/public.rb +232 -0
  333. data/lib/spontaneous/rack/reloader.rb +42 -0
  334. data/lib/spontaneous/rack/static.rb +25 -0
  335. data/lib/spontaneous/rack.rb +55 -0
  336. data/lib/spontaneous/render/context.rb +100 -0
  337. data/lib/spontaneous/render/development_renderer.rb +14 -0
  338. data/lib/spontaneous/render/engine.rb +19 -0
  339. data/lib/spontaneous/render/format/html.rb +5 -0
  340. data/lib/spontaneous/render/format.rb +70 -0
  341. data/lib/spontaneous/render/preview_renderer.rb +18 -0
  342. data/lib/spontaneous/render/published_renderer.rb +54 -0
  343. data/lib/spontaneous/render/publishing_renderer.rb +13 -0
  344. data/lib/spontaneous/render/renderer.rb +46 -0
  345. data/lib/spontaneous/render.rb +173 -0
  346. data/lib/spontaneous/revision.rb +7 -0
  347. data/lib/spontaneous/schema/schema_modification.rb +260 -0
  348. data/lib/spontaneous/schema/uid.rb +221 -0
  349. data/lib/spontaneous/schema.rb +295 -0
  350. data/lib/spontaneous/server.rb +65 -0
  351. data/lib/spontaneous/site.rb +87 -0
  352. data/lib/spontaneous/state.rb +53 -0
  353. data/lib/spontaneous/style.rb +144 -0
  354. data/lib/spontaneous/tasks/database.rake +9 -0
  355. data/lib/spontaneous/tasks.rb +5 -0
  356. data/lib/spontaneous/version.rb +6 -0
  357. data/lib/spontaneous.rb +179 -0
  358. data/spontaneous.gemspec.tmpl +66 -0
  359. data/test/disabled/test_slots.rb +287 -0
  360. data/test/experimental/test_formats.rb +92 -0
  361. data/test/experimental/test_plugins.rb +64 -0
  362. data/test/fixtures/application/css/test.less +5 -0
  363. data/test/fixtures/application/js/test.js +1 -0
  364. data/test/fixtures/application/static/favicon.ico +1 -0
  365. data/test/fixtures/application/static/test.html +1 -0
  366. data/test/fixtures/application/views/index.erubis +1 -0
  367. data/test/fixtures/back/public/test.html +1 -0
  368. data/test/fixtures/back/templates/layouts/standard.html.cut +1 -0
  369. data/test/fixtures/config/config/environment.rb +4 -0
  370. data/test/fixtures/config/config/environments/development.rb +13 -0
  371. data/test/fixtures/config/config/environments/production.rb +22 -0
  372. data/test/fixtures/config/config/environments/staging.rb +2 -0
  373. data/test/fixtures/example_application/Gemfile +6 -0
  374. data/test/fixtures/example_application/Gemfile.lock +76 -0
  375. data/test/fixtures/example_application/Rakefile +6 -0
  376. data/test/fixtures/example_application/config/back.rb +15 -0
  377. data/test/fixtures/example_application/config/back.ru +8 -0
  378. data/test/fixtures/example_application/config/back.yml +8 -0
  379. data/test/fixtures/example_application/config/boot.rb +16 -0
  380. data/test/fixtures/example_application/config/database.yml +24 -0
  381. data/test/fixtures/example_application/config/environment.rb +4 -0
  382. data/test/fixtures/example_application/config/environments/development.rb +16 -0
  383. data/test/fixtures/example_application/config/environments/production.rb +21 -0
  384. data/test/fixtures/example_application/config/environments/staging.rb +1 -0
  385. data/test/fixtures/example_application/config/front.rb +8 -0
  386. data/test/fixtures/example_application/config/front.ru +8 -0
  387. data/test/fixtures/example_application/config/front.yml +8 -0
  388. data/test/fixtures/example_application/config/schema.yml +48 -0
  389. data/test/fixtures/example_application/config/unicorn.rb +1 -0
  390. data/test/fixtures/example_application/config/user_levels.yml +19 -0
  391. data/test/fixtures/example_application/public/css/test.css +0 -0
  392. data/test/fixtures/example_application/public/favicon.ico +1 -0
  393. data/test/fixtures/example_application/public/js/test.js +0 -0
  394. data/test/fixtures/example_application/public/test.html +1 -0
  395. data/test/fixtures/example_application/schema/client_project.rb +18 -0
  396. data/test/fixtures/example_application/schema/client_projects.rb +8 -0
  397. data/test/fixtures/example_application/schema/home_page.rb +22 -0
  398. data/test/fixtures/example_application/schema/info_page.rb +13 -0
  399. data/test/fixtures/example_application/schema/inline_image.rb +11 -0
  400. data/test/fixtures/example_application/schema/page.rb +4 -0
  401. data/test/fixtures/example_application/schema/piece.rb +3 -0
  402. data/test/fixtures/example_application/schema/project.rb +21 -0
  403. data/test/fixtures/example_application/schema/project_image.rb +18 -0
  404. data/test/fixtures/example_application/schema/projects_page.rb +12 -0
  405. data/test/fixtures/example_application/schema/text.rb +8 -0
  406. data/test/fixtures/example_application/templates/client_project/images.html.cut +1 -0
  407. data/test/fixtures/example_application/templates/client_project.html.cut +4 -0
  408. data/test/fixtures/example_application/templates/client_projects.html.cut +6 -0
  409. data/test/fixtures/example_application/templates/info_page/inline.html.cut +0 -0
  410. data/test/fixtures/example_application/templates/inline_image.html.cut +1 -0
  411. data/test/fixtures/example_application/templates/layouts/home.html.cut +15 -0
  412. data/test/fixtures/example_application/templates/layouts/info.html.cut +3 -0
  413. data/test/fixtures/example_application/templates/layouts/project.html.cut +13 -0
  414. data/test/fixtures/example_application/templates/layouts/projects.html.cut +11 -0
  415. data/test/fixtures/example_application/templates/layouts/standard.html.cut +0 -0
  416. data/test/fixtures/example_application/templates/project/inline.html.cut +5 -0
  417. data/test/fixtures/example_application/templates/project.html.cut +5 -0
  418. data/test/fixtures/example_application/templates/project_image.html.cut +1 -0
  419. data/test/fixtures/example_application/templates/text.html.cut +1 -0
  420. data/test/fixtures/images/rose.greyscale.jpg +0 -0
  421. data/test/fixtures/images/rose.jpg +0 -0
  422. data/test/fixtures/images/size.gif +0 -0
  423. data/test/fixtures/images/size.jpg +0 -0
  424. data/test/fixtures/images/size.png24 +0 -0
  425. data/test/fixtures/images/size.png8 +0 -0
  426. data/test/fixtures/layouts/layouts/custom1.html.cut +1 -0
  427. data/test/fixtures/layouts/layouts/custom1.pdf.cut +0 -0
  428. data/test/fixtures/layouts/layouts/custom1.xml.cut +0 -0
  429. data/test/fixtures/layouts/layouts/custom2.html.cut +1 -0
  430. data/test/fixtures/layouts/layouts/custom3.html.cut +0 -0
  431. data/test/fixtures/layouts/layouts/standard.html.cut +1 -0
  432. data/test/fixtures/media/101/003/rose.jpg +0 -0
  433. data/test/fixtures/permissions/config/user_levels.yml +9 -0
  434. data/test/fixtures/permissions/media/image.jpg +0 -0
  435. data/test/fixtures/plugins/schema_plugin/init.rb +1 -0
  436. data/test/fixtures/plugins/schema_plugin/schema/external.rb +5 -0
  437. data/test/fixtures/plugins/schema_plugin/templates/external.html.cut +1 -0
  438. data/test/fixtures/plugins/schema_plugin/templates/from_plugin.html.cut +0 -0
  439. data/test/fixtures/plugins/schema_plugin/templates/layouts/from_plugin.html.cut +0 -0
  440. data/test/fixtures/public/templates/layouts/default.html.cut +1 -0
  441. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -0
  442. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -0
  443. data/test/fixtures/public/templates/layouts/dynamic.html.cut +1 -0
  444. data/test/fixtures/public/templates/layouts/standard.html.cut +0 -0
  445. data/test/fixtures/schema/before.yml +24 -0
  446. data/test/fixtures/schema/resolvable.yml +12 -0
  447. data/test/fixtures/schema/schema.yml +7 -0
  448. data/test/fixtures/serialisation/class_hash.yaml.erb +53 -0
  449. data/test/fixtures/serialisation/root_hash.yaml.erb +184 -0
  450. data/test/fixtures/sharding/rose.jpg +0 -0
  451. data/test/fixtures/sharding/xaa +0 -0
  452. data/test/fixtures/sharding/xab +0 -0
  453. data/test/fixtures/sharding/xac +0 -0
  454. data/test/fixtures/sharding/xad +0 -0
  455. data/test/fixtures/sharding/xae +0 -0
  456. data/test/fixtures/sharding/xaf +0 -0
  457. data/test/fixtures/sharding/xag +0 -0
  458. data/test/fixtures/styles/box_a/runny.html.cut +0 -0
  459. data/test/fixtures/styles/box_a.html.cut +1 -0
  460. data/test/fixtures/styles/named2.html.cut +1 -0
  461. data/test/fixtures/styles/orange/apple.html.cut +1 -0
  462. data/test/fixtures/styles/template_class/named1.html.cut +1 -0
  463. data/test/fixtures/styles/template_class/results.html.cut +1 -0
  464. data/test/fixtures/styles/template_class/walky.html.cut +0 -0
  465. data/test/fixtures/styles/template_class.epub.cut +0 -0
  466. data/test/fixtures/styles/template_class.html.cut +1 -0
  467. data/test/fixtures/styles/template_class.pdf.cut +0 -0
  468. data/test/fixtures/styles/template_sub_class1.html.cut +1 -0
  469. data/test/fixtures/templates/aliases/a/a_style.html.cut +0 -0
  470. data/test/fixtures/templates/aliases/a/page.html.cut +0 -0
  471. data/test/fixtures/templates/aliases/a_alias/a_alias_style.html.cut +0 -0
  472. data/test/fixtures/templates/aliases/layouts/b.html.cut +1 -0
  473. data/test/fixtures/templates/aliases/layouts/b_alias.html.cut +1 -0
  474. data/test/fixtures/templates/aliases/layouts/c_alias.html.cut +1 -0
  475. data/test/fixtures/templates/boxes/blank_content/things.html.cut +1 -0
  476. data/test/fixtures/templates/boxes/my_box_class/christy.html.cut +1 -0
  477. data/test/fixtures/templates/boxes/thangs.html.cut +1 -0
  478. data/test/fixtures/templates/boxes/with_template_box.html.cut +1 -0
  479. data/test/fixtures/templates/content/include.html.cut +1 -0
  480. data/test/fixtures/templates/content/include_dir.html.cut +1 -0
  481. data/test/fixtures/templates/content/included.epub.cut +1 -0
  482. data/test/fixtures/templates/content/included.html.cut +1 -0
  483. data/test/fixtures/templates/content/partial/included.html.cut +1 -0
  484. data/test/fixtures/templates/content/preprocess.html.cut +1 -0
  485. data/test/fixtures/templates/content/second.html.cut +1 -0
  486. data/test/fixtures/templates/content/template.epub.cut +1 -0
  487. data/test/fixtures/templates/content/template.html.cut +1 -0
  488. data/test/fixtures/templates/default_style_class.html.cut +1 -0
  489. data/test/fixtures/templates/direct.html.cut +1 -0
  490. data/test/fixtures/templates/extended/grandparent.html.cut +10 -0
  491. data/test/fixtures/templates/extended/main.html.cut +6 -0
  492. data/test/fixtures/templates/extended/parent.html.cut +10 -0
  493. data/test/fixtures/templates/layouts/entries.html.cut +7 -0
  494. data/test/fixtures/templates/layouts/page_style.html.cut +1 -0
  495. data/test/fixtures/templates/layouts/params.html.cut +1 -0
  496. data/test/fixtures/templates/layouts/preview_render.html.cut +2 -0
  497. data/test/fixtures/templates/layouts/standard_page.html.cut +1 -0
  498. data/test/fixtures/templates/layouts/subdir_style.html.cut +1 -0
  499. data/test/fixtures/templates/layouts/template_params.html.cut +1 -0
  500. data/test/fixtures/templates/page_class/inline_style.html.cut +1 -0
  501. data/test/fixtures/templates/preview_render/inline.html.cut +0 -0
  502. data/test/fixtures/templates/publishing/layouts/dynamic.html.cut +1 -0
  503. data/test/fixtures/templates/publishing/layouts/static.html.cut +1 -0
  504. data/test/fixtures/templates/template_class/anonymous_style.html.cut +4 -0
  505. data/test/fixtures/templates/template_class/another_template.html.cut +0 -0
  506. data/test/fixtures/templates/template_class/complex_template.html.cut +6 -0
  507. data/test/fixtures/templates/template_class/complex_template.pdf.cut +6 -0
  508. data/test/fixtures/templates/template_class/default_template_style.html.cut +4 -0
  509. data/test/fixtures/templates/template_class/images_with_template.html.cut +5 -0
  510. data/test/fixtures/templates/template_class/slots_template.html.cut +5 -0
  511. data/test/fixtures/templates/template_class/slots_template.pdf.cut +5 -0
  512. data/test/fixtures/templates/template_class/this_template.epub.cut +1 -0
  513. data/test/fixtures/templates/template_class/this_template.html.cut +1 -0
  514. data/test/fixtures/templates/template_class/this_template.pdf.cut +1 -0
  515. data/test/fixtures/templates/with_default_style_class.html.cut +1 -0
  516. data/test/functional/test_application.rb +176 -0
  517. data/test/functional/test_back.rb +902 -0
  518. data/test/functional/test_front.rb +571 -0
  519. data/test/javascript/test_dom.rb +94 -0
  520. data/test/javascript/test_markdown.rb +97 -0
  521. data/test/slow/test_publishing.rb +987 -0
  522. data/test/slow/test_visibility.rb +250 -0
  523. data/test/support/custom_matchers.rb +77 -0
  524. data/test/support/timing.rb +23 -0
  525. data/test/test_helper.rb +164 -0
  526. data/test/test_javascript.rb +34 -0
  527. data/test/ui/test_page_editing.rb +167 -0
  528. data/test/ui_helper.rb +114 -0
  529. data/test/unit/test_alias.rb +254 -0
  530. data/test/unit/test_authentication.rb +510 -0
  531. data/test/unit/test_boxes.rb +497 -0
  532. data/test/unit/test_config.rb +156 -0
  533. data/test/unit/test_content.rb +221 -0
  534. data/test/unit/test_content_inheritance.rb +103 -0
  535. data/test/unit/test_extensions.rb +14 -0
  536. data/test/unit/test_fields.rb +392 -0
  537. data/test/unit/test_generators.rb +97 -0
  538. data/test/unit/test_image_size.rb +25 -0
  539. data/test/unit/test_images.rb +265 -0
  540. data/test/unit/test_layouts.rb +111 -0
  541. data/test/unit/test_logger.rb +80 -0
  542. data/test/unit/test_media.rb +70 -0
  543. data/test/unit/test_page.rb +244 -0
  544. data/test/unit/test_permissions.rb +834 -0
  545. data/test/unit/test_piece.rb +80 -0
  546. data/test/unit/test_prototype_set.rb +192 -0
  547. data/test/unit/test_prototypes.rb +102 -0
  548. data/test/unit/test_render.rb +359 -0
  549. data/test/unit/test_schema.rb +1009 -0
  550. data/test/unit/test_serialisation.rb +215 -0
  551. data/test/unit/test_site.rb +145 -0
  552. data/test/unit/test_structure.rb +85 -0
  553. data/test/unit/test_styles.rb +417 -0
  554. data/test/unit/test_templates.rb +224 -0
  555. data/test/unit/test_type_hierarchy.rb +28 -0
  556. metadata +1017 -0
@@ -0,0 +1,571 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'test_helper'
4
+
5
+ ENV['RACK_ENV'] = 'test'
6
+
7
+
8
+ class FrontTest < MiniTest::Spec
9
+ include ::Rack::Test::Methods
10
+
11
+ def self.startup
12
+ end
13
+
14
+ def self.shutdown
15
+ end
16
+
17
+ def setup
18
+ @saved_template_root = Spontaneous.template_root
19
+ Site.publishing_method = :immediate
20
+ end
21
+
22
+ def teardown
23
+ Spontaneous.template_root = @saved_template_root
24
+ end
25
+
26
+ def app
27
+ Spontaneous::Rack::Front.application
28
+ end
29
+
30
+ def root
31
+ @root
32
+ end
33
+
34
+ def about
35
+ @about
36
+ end
37
+
38
+ def news
39
+ @news
40
+ end
41
+
42
+ def subpage
43
+ @sub
44
+ end
45
+
46
+ def dynamic
47
+ @dynamic
48
+ end
49
+
50
+ def revision_root
51
+ @revision_root
52
+ end
53
+
54
+ def session
55
+ last_request.env['rack.session']
56
+ end
57
+
58
+ context "Public pages" do
59
+ setup do
60
+ Spot::Schema.reset!
61
+
62
+ @saved_revision_root = Spontaneous.revision_root
63
+ @saved_root = Spontaneous.root
64
+
65
+ root = File.expand_path('../../fixtures/example_application', __FILE__)
66
+ Spontaneous.root = root
67
+
68
+ Spontaneous.init(:environment => :test, :mode => :front)
69
+
70
+ Site.publishing_method = :immediate
71
+ State.delete
72
+ Content.delete
73
+ Change.delete
74
+
75
+ class ::SitePage < Spontaneous::Page
76
+ layout :default
77
+ layout :dynamic
78
+ box :pages
79
+
80
+ attr_accessor :status
81
+ end
82
+
83
+ class ::SubPage < SitePage; end
84
+
85
+
86
+ # see http://benprew.posterous.com/testing-sessions-with-sinatra
87
+ app.send(:set, :sessions, false)
88
+
89
+ @revision_root = "#{Dir.tmpdir}/spontaneous-tests/#{Time.now.to_i}"
90
+ `mkdir -p #{@revision_root}`
91
+ Spontaneous.revision_root = @revision_root
92
+
93
+ self.template_root = File.expand_path("../../fixtures/public/templates", __FILE__)
94
+
95
+ @root = ::SitePage.create
96
+ @about = ::SitePage.create(:slug => "about", :uid => "about")
97
+ @sub = ::SubPage.create(:slug => "now", :uid => "now")
98
+ @news = ::SitePage.create(:slug => "news", :uid => "news")
99
+ @dynamic = ::SitePage.create(:slug => "dynamic", :uid => "dynamic")
100
+ @dynamic.layout = :dynamic
101
+ @root.pages << @about
102
+ @root.pages << @news
103
+ @root.pages << @dynamic
104
+ @about.pages << @sub
105
+ @root.save
106
+
107
+ Content.delete_revision(1) rescue nil
108
+
109
+ Spontaneous.logger.silent! {
110
+ Site.publish_all
111
+ }
112
+ end
113
+
114
+ teardown do
115
+ Object.send(:remove_const, :SitePage) rescue nil
116
+ Object.send(:remove_const, :SubPage) rescue nil
117
+ Content.delete
118
+ State.delete
119
+ Content.delete_revision(1)
120
+ Spontaneous.revision_root = @saved_revision_root
121
+ Spontaneous.root = @saved_root
122
+ FileUtils.rm_rf(@revision_root)
123
+ end
124
+
125
+ should "return a 404 if asked for a non-existant page" do
126
+ get '/not-bloody-likely'
127
+ assert last_response.status == 404
128
+ end
129
+
130
+ should "provide root when asked" do
131
+ get '/'
132
+ assert last_response.ok?
133
+ last_response.body.should == "/.html\n"
134
+ end
135
+
136
+ should "be available through their path" do
137
+ get '/about'
138
+ assert last_response.ok?
139
+ last_response.body.should == "/about.html\n"
140
+ last_response.content_type.should == "text/html;charset=utf-8"
141
+ end
142
+
143
+ should "be available through their path with explicit format" do
144
+ get '/about.html'
145
+ assert last_response.ok?
146
+ last_response.body.should == "/about.html\n"
147
+ last_response.content_type.should == "text/html;charset=utf-8"
148
+ end
149
+
150
+ should "honor the format of the request" do
151
+ @about.class.stubs(:formats).returns([:html, :pdf])
152
+ get '/about.pdf'
153
+ assert last_response.ok?
154
+ last_response.body.should == "/about.pdf\n"
155
+ last_response.content_type.should == "application/pdf;charset=utf-8"
156
+ end
157
+
158
+ should "provide the default format of the page if none is explicitly given" do
159
+ @about.class.stubs(:formats).returns([:rss, :html])
160
+ get '/about'
161
+ assert last_response.ok?
162
+ last_response.content_type.should == ::Rack::Mime.mime_type('.rss') + ";charset=utf-8"
163
+ last_response.body.should == "/about.rss\n"
164
+ end
165
+
166
+ should "return a custom content type if one is defined" do
167
+ @about.class.formats [{:html => "application/xhtml+xml"}]
168
+ get '/about'
169
+ assert last_response.ok?
170
+ last_response.content_type.should == "application/xhtml+xml;charset=utf-8"
171
+ last_response.body.should == "/about.html\n"
172
+ end
173
+
174
+
175
+ should "raise a 404 if asked for a format not provided by the page" do
176
+ get '/about.time'
177
+ assert last_response.status == 404
178
+ end
179
+
180
+ context "Showing alternate content" do
181
+ setup do
182
+ Page.stubs(:path).with("/about").returns(about)
183
+ Page.stubs(:path).with("/news").returns(news)
184
+ # puts ">"*50
185
+ end
186
+ teardown do
187
+ # puts "<"*50
188
+ end
189
+
190
+ should "render an alternate page if passed a page" do
191
+ # about.stubs(:request_show).returns(news)
192
+ SitePage.request do
193
+ show Site['/news']
194
+ end
195
+ get '/about'
196
+ assert last_response.ok?
197
+ last_response.body.should == "/news.html\n"
198
+ end
199
+
200
+ should "render an alternate page if passed a path" do
201
+ # about.stubs(:request_show).returns("/news")
202
+ SitePage.request do
203
+ show "/news"
204
+ end
205
+ get '/about'
206
+ assert last_response.ok?
207
+ last_response.body.should == "/news.html\n"
208
+ end
209
+
210
+ should "render an alternate page if passed a uid with a #" do
211
+ # about.stubs(:request_show).returns("#news")
212
+ SitePage.request do
213
+ show "#news"
214
+ end
215
+ get '/about'
216
+ assert last_response.ok?
217
+ last_response.body.should == "/news.html\n"
218
+ end
219
+
220
+ should "render an alternate page if passed a uid" do
221
+ # about.stubs(:request_show).returns("news")
222
+ SitePage.request do
223
+ show "news"
224
+ end
225
+ get '/about'
226
+ assert last_response.ok?
227
+ last_response.body.should == "/news.html\n"
228
+ end
229
+
230
+ should "return not found of #request_show returns an invalid uid or path" do
231
+ # about.stubs(:request_show).returns("caterpillars")
232
+ SitePage.request do
233
+ show "caterpillars"
234
+ end
235
+ get '/about'
236
+ assert last_response.status == 404
237
+ end
238
+
239
+ should "return the right status code" do
240
+ SitePage.request do
241
+ show "#news", 404
242
+ end
243
+ get '/about'
244
+ assert last_response.status == 404
245
+ last_response.body.should == "/news.html\n"
246
+ end
247
+
248
+ should "allow handing POST requests" do
249
+ SitePage.request :post do
250
+ show "#news"
251
+ end
252
+ post '/about'
253
+ assert last_response.status == 200
254
+ last_response.body.should == "/news.html\n"
255
+ end
256
+
257
+ should "allow returning of any status code without altering content" do
258
+ SitePage.request do
259
+ 404
260
+ end
261
+ get '/about'
262
+ assert last_response.status == 404
263
+ last_response.body.should == "/about.html\n"
264
+ end
265
+
266
+ should "allow altering of headers" do
267
+ SitePage.request do
268
+ headers["X-Works"] = "Yes"
269
+ end
270
+ get '/about'
271
+ assert last_response.status == 200
272
+ last_response.body.should == "/about.html\n"
273
+ last_response.headers["X-Works"].should == "Yes"
274
+ end
275
+ # should "handle anything that responds to #render(format)" do
276
+ # show = mock()
277
+ # show.stubs(:render).returns("mocked")
278
+ # about.stubs(:request_show).returns(show)
279
+ # get '/about'
280
+ # last_response.body.should == "mocked"
281
+ # end
282
+ end
283
+
284
+ context "Redirects" do
285
+ setup do
286
+ Page.stubs(:path).with("/about").returns(about)
287
+ Page.stubs(:path).with("/news").returns(news)
288
+ end
289
+
290
+ should "respond appropriatly to redirects to path" do
291
+ SitePage.request do
292
+ redirect "/news"
293
+ end
294
+ get '/about'
295
+ assert last_response.status == 302
296
+ last_response.headers["Location"].should == "http://example.org/news"
297
+ end
298
+
299
+ should "respond appropriately to redirects to a Page instance" do
300
+ SitePage.request do
301
+ redirect Page.path("/news")
302
+ end
303
+ get '/about'
304
+ assert last_response.status == 302
305
+ last_response.headers["Location"].should == "http://example.org/news"
306
+ end
307
+
308
+ should "respond appropriately to redirects to a UID" do
309
+ SitePage.request do
310
+ redirect "#news"
311
+ end
312
+ get '/about'
313
+ assert last_response.status == 302
314
+ last_response.headers["Location"].should == "http://example.org/news"
315
+ end
316
+
317
+ should "recognise a :temporary redirect" do
318
+ SitePage.request do
319
+ redirect "/news", :temporary
320
+ end
321
+ get '/about'
322
+ assert last_response.status == 302
323
+ last_response.headers["Location"].should == "http://example.org/news"
324
+ end
325
+
326
+ should "recognise a :permanent redirect" do
327
+ SitePage.request do
328
+ redirect "/news", :permanent
329
+ end
330
+ get '/about'
331
+ assert last_response.status == 301
332
+ last_response.headers["Location"].should == "http://example.org/news"
333
+ end
334
+
335
+ should "correctly apply numeric status codes" do
336
+ SitePage.request do
337
+ redirect "/news", 307
338
+ end
339
+ get '/about'
340
+ last_response.headers["Location"].should == "http://example.org/news"
341
+ assert last_response.status == 307
342
+ end
343
+
344
+ end
345
+
346
+ context "Templates" do
347
+ setup do
348
+ # Page.stubs(:path).with("/about").returns(about)
349
+ # about.style = :dynamic
350
+ # about.save
351
+ end
352
+
353
+ teardown do
354
+ # about.style = :default
355
+ # about.save
356
+ end
357
+
358
+ should "have access to the params, request & session object" do
359
+ get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
360
+ assert last_response.ok?
361
+ last_response.body.should == "42/peter/example.org\n"
362
+ end
363
+
364
+ context "caching" do
365
+ setup do
366
+ Spontaneous::Render.cache_templates = true
367
+ @cache_file = "#{Spontaneous.revision_dir(1)}/html/dynamic/index.html.rb"
368
+ end
369
+
370
+ teardown do
371
+ Spontaneous::Render.cache_templates = false
372
+ end
373
+
374
+ should "use pre-rendered versions of the templates" do
375
+ dummy_content = 'cached-version/#{session[\'user_id\']}'
376
+ dummy_template = File.join(revision_root, "dummy.html.cut")
377
+ File.open(dummy_template, 'w') { |f| f.write(dummy_content) }
378
+ Spontaneous::Render.stubs(:output_path).returns(dummy_template)
379
+ get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
380
+ last_response.body.should == "cached-version/42"
381
+ end
382
+
383
+ should "cache templates as ruby files" do
384
+ @cache_file = "#{Spontaneous.revision_dir(1)}/html/dynamic/index.html.rb"
385
+ FileUtils.rm(@cache_file) if File.exists?(@cache_file)
386
+ File.exists?(@cache_file).should be_false
387
+ get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
388
+ # puts `ls -l #{File.dirname(@cache_file)}`
389
+ File.exists?(@cache_file).should be_true
390
+ File.open(@cache_file, 'w') { |f| f.write('_buf << %Q`@cache_filed-version/#{params[\'wendy\']}`;')}
391
+ get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
392
+ last_response.body.should == "@cache_filed-version/peter"
393
+ FileUtils.rm(@cache_file)
394
+ end
395
+
396
+ should "not cache templates if caching turned off" do
397
+ Spontaneous::Render.cache_templates = false
398
+ FileUtils.rm(@cache_file) if File.exists?(@cache_file)
399
+ File.exists?(@cache_file).should be_false
400
+ get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
401
+ File.exists?(@cache_file).should be_false
402
+ end
403
+ end
404
+ end
405
+
406
+ context "Model controllers" do
407
+ setup do
408
+ class ::TestController < Spontaneous::PageController
409
+ get '/' do
410
+ "Magic"
411
+ end
412
+ end
413
+ SitePage.controller :comments do
414
+ get '/' do
415
+ "Success"
416
+ end
417
+
418
+ get '/page' do
419
+ page
420
+ end
421
+ get '/format' do
422
+ format.to_s
423
+ end
424
+ end
425
+
426
+ SitePage.controller :status do
427
+ get '/:status' do
428
+ page.status = params[:status]
429
+ page
430
+ end
431
+
432
+ post '/:status' do
433
+ page.status = params[:status]
434
+ page
435
+ end
436
+ end
437
+
438
+ SitePage.controller :test, ::TestController
439
+
440
+ SitePage.controller :test2, ::TestController do
441
+ get "/block" do
442
+ "Block"
443
+ end
444
+ end
445
+
446
+ Page.stubs(:path).with("/about").returns(about)
447
+ Page.stubs(:path).with("/about/now").returns(subpage)
448
+ end
449
+
450
+ teardown do
451
+ SitePage.send(:remove_const, :StatusController) rescue nil
452
+ SitePage.send(:remove_const, :TestController) rescue nil
453
+ SitePage.send(:remove_const, :Test2Controller) rescue nil
454
+ Object.send(:remove_const, :TestController) rescue nil
455
+ end
456
+
457
+ should "not be used unless necessary" do
458
+ get "/about"
459
+ assert last_response.ok?
460
+ last_response.body.should == about.render
461
+ end
462
+
463
+ should "be recognised" do
464
+ get "/about/@comments"
465
+ assert last_response.ok?
466
+ last_response.body.should == "Success"
467
+ end
468
+
469
+ should "render the page correctly if action returns page object" do
470
+ get "/about/@comments/page"
471
+ assert last_response.ok?
472
+ last_response.body.should == about.render
473
+ end
474
+
475
+ should "return 404 if trying unknown namespace" do
476
+ get "/about/@missing/action"
477
+ assert last_response.status == 404
478
+ end
479
+
480
+ should "respond to multiple namespaces" do
481
+ get "/about/@status/good"
482
+ assert last_response.ok?
483
+ last_response.body.should == about.render
484
+ about.status.should == "good"
485
+ end
486
+
487
+ should "accept POST requests" do
488
+ post "/about/@status/good"
489
+ assert last_response.ok?
490
+ last_response.body.should == about.render
491
+ about.status.should == "good"
492
+ end
493
+
494
+ should "return 404 unless post request has an action" do
495
+ Page.expects(:path).with("/about").never
496
+ post "/about"
497
+ assert last_response.status == 404
498
+ end
499
+
500
+ should "return 404 for post requests to unknown actions" do
501
+ post "/about/@status/missing/action"
502
+ assert last_response.status == 404
503
+ end
504
+
505
+ # probably the wrong place to test this -- should be in units -- but what the heck
506
+ should "be able to generate urls for actions" do
507
+ about.action_url(:status, "/good").should == "/about/@status/good"
508
+ end
509
+
510
+ should "pass the format onto the page if the action returns it to the render call" do
511
+ about.stubs(:provides_format?).with(:'xml', anything).returns(true)
512
+ about.expects(:render).with(:'xml', anything).returns("/about.xml")
513
+ about.expects(:render).with(:'html', anything).never
514
+ get "/about/@comments/page.xml"
515
+ assert last_response.ok?
516
+ last_response.body.should == "/about.xml"
517
+ end
518
+
519
+ should "use the format within the action if required" do
520
+ get "/about/@comments/format.xml"
521
+ assert last_response.ok?
522
+ last_response.body.should == "xml"
523
+ end
524
+
525
+ should "be inherited by subclasses" do
526
+ get "/about/now/@comments"
527
+ assert last_response.ok?
528
+ last_response.body.should == "Success"
529
+ end
530
+
531
+ should "allow definition of controller using class" do
532
+ get "/about/@test"
533
+ assert last_response.ok?
534
+ last_response.body.should == "Magic"
535
+ end
536
+
537
+ should "allow definition of controller using class and extend it using block" do
538
+ get "/about/@test2/block"
539
+ assert last_response.ok?
540
+ last_response.body.should == "Block"
541
+ end
542
+
543
+ context "overriding base controller class" do
544
+ setup do
545
+ class ::PageController < S::PageController
546
+ get '/nothing' do
547
+ 'Something'
548
+ end
549
+ end
550
+
551
+ SitePage.controller :drummer do
552
+ get '/' do
553
+ "Success"
554
+ end
555
+ end
556
+
557
+ end
558
+
559
+ teardown do
560
+ Object.send(:remove_const, :PageController)
561
+ end
562
+
563
+ should "affect all controller actions" do
564
+ get "/about/@drummer/nothing"
565
+ assert last_response.ok?
566
+ last_response.body.should == "Something"
567
+ end
568
+ end
569
+ end
570
+ end
571
+ end
@@ -0,0 +1,94 @@
1
+
2
+ require 'test_helper'
3
+ require 'test_javascript'
4
+
5
+ class DomTest < MiniTest::Spec
6
+ include JavascriptTestBase
7
+
8
+ def setup
9
+ @page = page
10
+ end
11
+
12
+ def parse_selector(selector)
13
+ attrs = @page.x("Spontaneous.Dom.parse_selector(#{selector});")
14
+ Hash[attrs.to_ary]
15
+ end
16
+
17
+ def create_tag(tag_name, selector=nil, params="''")
18
+ selector += ', ' if selector
19
+ tag = @page.x("var t = Spontaneous.Dom.#{tag_name}(#{selector} #{params});t[0]")
20
+ end
21
+ context "selector parsing" do
22
+ should "work with ids & classes" do
23
+ attrs = parse_selector("'#the-id.class-1.class-2'")
24
+ attrs['id'].should == 'the-id'
25
+ attrs['class'].should == 'class-1 class-2'
26
+ end
27
+ should "work with just classes" do
28
+ attrs = parse_selector("'.class-1.class-2'")
29
+ attrs['class'].should == 'class-1 class-2'
30
+ attrs.has_key?('id').should be_false
31
+ end
32
+ should "work with just an id" do
33
+ attrs = parse_selector("'#the-id'")
34
+ attrs['id'].should == 'the-id'
35
+ attrs.has_key?('class').should be_false
36
+ end
37
+
38
+ should "work with multile classes without initial dot" do
39
+ attrs = parse_selector("'class-1.class-2'")
40
+ attrs['class'].should == 'class-1 class-2'
41
+ attrs.has_key?('id').should be_false
42
+ end
43
+ should "work with single class without initial dots" do
44
+ attrs = parse_selector("'class-1'")
45
+ attrs['class'].should == 'class-1'
46
+ attrs.has_key?('id').should be_false
47
+ end
48
+ should "convert string to id" do
49
+ id = @page.x("Spontaneous.Dom.id('the-thing')")
50
+ id.should == "#the-thing"
51
+ end
52
+
53
+ context "with arrays" do
54
+ should "recognise ids" do
55
+ attrs = parse_selector("[Spontaneous.Dom.id('the-id'), 'class-1', 'class-2']")
56
+ attrs['id'].should == 'the-id'
57
+ attrs['class'].should == 'class-1 class-2'
58
+ end
59
+ should "recognise classes with initial dot" do
60
+ attrs = parse_selector("[Spontaneous.Dom.id('the-id'), '.class-1', 'class-2']")
61
+ attrs['id'].should == 'the-id'
62
+ attrs['class'].should == 'class-1 class-2'
63
+ end
64
+ should "recognise joined dot style classes" do
65
+ attrs = parse_selector("[Spontaneous.Dom.id('the-id'), '.class-1.class-2', 'class-3']")
66
+ attrs['id'].should == 'the-id'
67
+ attrs['class'].should == 'class-1 class-2 class-3'
68
+ end
69
+ end
70
+ context "tag creation" do
71
+ should "work with selector strings" do
72
+ tag = create_tag('div', "'#fish.foul'")
73
+ tag['id'].should == 'fish'
74
+ tag['className'].should == 'foul'
75
+ end
76
+ should "work with selector arrays" do
77
+ tag = create_tag('div', "[Spontaneous.Dom.id('the-id'), 'class-1', 'class-2']")
78
+ tag['id'].should == 'the-id'
79
+ tag['className'].should == 'class-1 class-2'
80
+ end
81
+ should "work with selector arrays and params" do
82
+ tag = create_tag('div', "[Spontaneous.Dom.id('the-id'), 'class-1', 'class-2']", "{'style':'display: none'}")
83
+ tag['id'].should == 'the-id'
84
+ tag['className'].should == 'class-1 class-2'
85
+ tag.getAttribute('style').should == 'display: none'
86
+ end
87
+ should "work with just params" do
88
+ tag = create_tag('div', nil, "{'style':'display: none'}")
89
+ tag['id'].should be_nil
90
+ tag.getAttribute('style').should == 'display: none'
91
+ end
92
+ end
93
+ end
94
+ end