aura 0.0.1.pre10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. data/.gitignore +6 -0
  2. data/.travis.yml +3 -0
  3. data/Gemfile +2 -0
  4. data/HISTORY.md +95 -0
  5. data/README.md +53 -0
  6. data/Rakefile +27 -0
  7. data/Scribefile +8 -0
  8. data/app/css/_utilities.scss +88 -0
  9. data/app/css/admin.scss +21 -0
  10. data/app/css/admin/_settings.scss +136 -0
  11. data/app/css/admin/chrome.scss +208 -0
  12. data/app/css/admin/common.scss +78 -0
  13. data/app/css/admin/forms.scss +342 -0
  14. data/app/css/admin/jquery_wysiwyg.scss +96 -0
  15. data/app/css/admin/loading.scss +18 -0
  16. data/app/css/admin/meta.scss +42 -0
  17. data/app/css/admin/reset.scss +46 -0
  18. data/app/css/admin/sections.scss +79 -0
  19. data/app/css/admin/setup.scss +22 -0
  20. data/app/css/admin/sidebar.scss +136 -0
  21. data/app/css/admin/slug.scss +78 -0
  22. data/app/css/admin/uiscreen.scss +22 -0
  23. data/app/css/admin/wysiwyg_field.scss +11 -0
  24. data/app/css/admin_watermark.scss +23 -0
  25. data/app/css/default_home_page.scss +13 -0
  26. data/app/css/login.scss +47 -0
  27. data/app/helpers/admin_helpers.rb +59 -0
  28. data/app/helpers/flash_helpers.rb +86 -0
  29. data/app/helpers/form_builder_helpers.rb +9 -0
  30. data/app/helpers/html_helpers.rb +27 -0
  31. data/app/helpers/jquery_helpers.rb +26 -0
  32. data/app/helpers/main_helpers.rb +67 -0
  33. data/app/helpers/page_helpers.rb +92 -0
  34. data/app/helpers/template_helpers.rb +94 -0
  35. data/app/helpers/user_helpers.rb +45 -0
  36. data/app/init/admin.rb +34 -0
  37. data/app/init/extensions.rb +18 -0
  38. data/app/init/pistol.rb +11 -0
  39. data/app/init/sequel.rb +11 -0
  40. data/app/main.rb +106 -0
  41. data/app/migrations/page.rb +29 -0
  42. data/app/migrations/settings.rb +11 -0
  43. data/app/migrations/user.rb +13 -0
  44. data/app/models/page.rb +116 -0
  45. data/app/models/page_seed.rb +47 -0
  46. data/app/models/settings.rb +59 -0
  47. data/app/models/user.rb +60 -0
  48. data/app/routes/admin.rb +44 -0
  49. data/app/routes/css_js.rb +53 -0
  50. data/app/routes/design_tests.rb +15 -0
  51. data/app/routes/editor.rb +152 -0
  52. data/app/routes/site.rb +33 -0
  53. data/app/routes/user.rb +48 -0
  54. data/app/views/admin/_back_to_dashboard.haml +3 -0
  55. data/app/views/admin/dashboard.haml +46 -0
  56. data/app/views/admin/layout.haml +73 -0
  57. data/app/views/admin/settings.haml +40 -0
  58. data/app/views/admin/settings/database.haml +42 -0
  59. data/app/views/base/crumbs.haml +50 -0
  60. data/app/views/base/delete.haml +19 -0
  61. data/app/views/base/edit.haml +61 -0
  62. data/app/views/base/errors.haml +10 -0
  63. data/app/views/base/form.haml +11 -0
  64. data/app/views/base/list.haml +14 -0
  65. data/app/views/base/list_actions.haml +4 -0
  66. data/app/views/base/list_item.haml +7 -0
  67. data/app/views/base/nav.haml +36 -0
  68. data/app/views/base/new.haml +36 -0
  69. data/app/views/base/preview.haml +28 -0
  70. data/app/views/base/tabs.haml +12 -0
  71. data/app/views/default_home_page.haml +15 -0
  72. data/app/views/design_tests/admin_styles.haml +58 -0
  73. data/app/views/form_builder/builder.haml +29 -0
  74. data/app/views/page/edit.haml +29 -0
  75. data/app/views/page/form.haml +22 -0
  76. data/app/views/page/meta_form.haml +22 -0
  77. data/app/views/page/new.haml +26 -0
  78. data/app/views/user/edit.haml +52 -0
  79. data/app/views/user/form.haml +43 -0
  80. data/app/views/user/list.haml +11 -0
  81. data/app/views/user/login.haml +33 -0
  82. data/app/views/user/new.haml +25 -0
  83. data/app/views/user/welcome.haml +29 -0
  84. data/app/views/watermark/watermark.haml +16 -0
  85. data/aura.gemspec +36 -0
  86. data/bin/aura +8 -0
  87. data/config/database.rb +12 -0
  88. data/config/extensions.rb +5 -0
  89. data/config/scss.rb +14 -0
  90. data/config/user.rb +10 -0
  91. data/default/.gitignore +6 -0
  92. data/default/Gemfile +11 -0
  93. data/default/README.md +24 -0
  94. data/default/Rakefile +8 -0
  95. data/default/app/README +3 -0
  96. data/default/app/css/.gitignore +0 -0
  97. data/default/app/helpers/helpers.rb.example +9 -0
  98. data/default/app/js/.gitignore +0 -0
  99. data/default/app/migrations/model.rb.example +20 -0
  100. data/default/app/models/model.rb.example +11 -0
  101. data/default/app/models/page-ext.rb.example +17 -0
  102. data/default/app/routes/site.rb.example +5 -0
  103. data/default/app/views/hello.haml.example +1 -0
  104. data/default/config.ru +3 -0
  105. data/default/config/.gitignore +0 -0
  106. data/default/config/database.rb.example +30 -0
  107. data/default/config/extensions.rb +5 -0
  108. data/default/config/user.rb.example +10 -0
  109. data/default/db/.gitignore +0 -0
  110. data/default/init.rb +15 -0
  111. data/default/public/.gitignore +0 -0
  112. data/extensions/contact_form/migrations/contact_form.rb +13 -0
  113. data/extensions/contact_form/models/contact_form.rb +13 -0
  114. data/extensions/contact_form/routes/contact_form.rb +11 -0
  115. data/extensions/contact_form/views/contact_form/edit.haml +8 -0
  116. data/extensions/contact_form/views/contact_form/form.haml +3 -0
  117. data/extensions/contact_form/views/contact_form/nav.haml +42 -0
  118. data/extensions/contact_form/views/contact_form/responses.haml +20 -0
  119. data/extensions/contact_form/views/contact_form/tabs.haml +8 -0
  120. data/extensions/default_theme/css/theme/_settings.scss +3 -0
  121. data/extensions/default_theme/css/theme/chrome.scss +66 -0
  122. data/extensions/default_theme/css/theme/reset.scss +34 -0
  123. data/extensions/default_theme/css/theme/style.scss +3 -0
  124. data/extensions/default_theme/info.yml +2 -0
  125. data/extensions/default_theme/public/browse.png +0 -0
  126. data/extensions/default_theme/views/base/id_portfolio.haml +32 -0
  127. data/extensions/default_theme/views/base/show.haml +31 -0
  128. data/extensions/default_theme/views/errors/error.haml +9 -0
  129. data/extensions/default_theme/views/errors/not_found.haml +11 -0
  130. data/extensions/default_theme/views/layout.haml +33 -0
  131. data/lib/aura.rb +315 -0
  132. data/lib/aura/admin.rb +41 -0
  133. data/lib/aura/app.rb +4 -0
  134. data/lib/aura/cli.rb +19 -0
  135. data/lib/aura/cli/base.rb +89 -0
  136. data/lib/aura/cli/helpers.rb +32 -0
  137. data/lib/aura/editor.rb +30 -0
  138. data/lib/aura/extension.rb +189 -0
  139. data/lib/aura/files.rb +38 -0
  140. data/lib/aura/menu.rb +142 -0
  141. data/lib/aura/models.rb +80 -0
  142. data/lib/aura/public.rb +68 -0
  143. data/lib/aura/rendering.rb +134 -0
  144. data/lib/aura/seeder.rb +38 -0
  145. data/lib/aura/slugs.rb +87 -0
  146. data/lib/aura/subtype.rb +48 -0
  147. data/lib/aura/tasks.rb +24 -0
  148. data/lib/aura/tasks/common.rb +17 -0
  149. data/lib/aura/tasks/db.rake +54 -0
  150. data/lib/aura/utils.rb +81 -0
  151. data/lib/aura/version.rb +25 -0
  152. data/lib/core/hasharray.rb +65 -0
  153. data/lib/core/object_ext.rb +9 -0
  154. data/lib/sequel/plugins/aura_custom.rb +16 -0
  155. data/lib/sequel/plugins/aura_editable.rb +39 -0
  156. data/lib/sequel/plugins/aura_hierarchy.rb +82 -0
  157. data/lib/sequel/plugins/aura_model.rb +271 -0
  158. data/lib/sequel/plugins/aura_renderable.rb +42 -0
  159. data/lib/sequel/plugins/aura_sluggable.rb +103 -0
  160. data/lib/sequel/plugins/aura_subtyped.rb +83 -0
  161. data/lib/terra.rb +185 -0
  162. data/lib/terra/ext.rb +16 -0
  163. data/lib/terra/field.rb +98 -0
  164. data/lib/terra/fields.rb +122 -0
  165. data/lib/terra/fieldset.rb +93 -0
  166. data/lib/terra/form.rb +111 -0
  167. data/manual/configuration.md +42 -0
  168. data/manual/extensions.md +45 -0
  169. data/manual/files.md +70 -0
  170. data/manual/helpers.md +39 -0
  171. data/manual/index.md +65 -0
  172. data/manual/models.md +58 -0
  173. data/manual/recipes.md +38 -0
  174. data/manual/recipes/bundling_sample_data.md +30 -0
  175. data/manual/recipes/creating_themes.md +10 -0
  176. data/manual/recipes/using_markdown_or_textile.md +24 -0
  177. data/manual/routes.md +39 -0
  178. data/manual/theming.md +55 -0
  179. data/manual/views.md +128 -0
  180. data/public/hi.html +0 -0
  181. data/public/images/admin/back.png +0 -0
  182. data/public/images/admin/browse.png +0 -0
  183. data/public/images/admin/mock-bg.png +0 -0
  184. data/public/images/admin/top-loader.gif +0 -0
  185. data/public/images/admin/uiscreen-loader.gif +0 -0
  186. data/public/images/admin_icons/add.png +0 -0
  187. data/public/images/admin_icons/contact.png +0 -0
  188. data/public/images/admin_icons/dashboard.png +0 -0
  189. data/public/images/admin_icons/generic.png +0 -0
  190. data/public/images/admin_icons/home-12.png +0 -0
  191. data/public/images/admin_icons/page.png +0 -0
  192. data/public/images/admin_icons/settings.png +0 -0
  193. data/public/images/jquery.wysiwyg.gif +0 -0
  194. data/public/js/admin.form_builder.js +15 -0
  195. data/public/js/admin.js +62 -0
  196. data/public/js/admin.layout.js +53 -0
  197. data/public/js/admin.nav.js +241 -0
  198. data/public/js/admin.slug.js +46 -0
  199. data/public/js/admin.subpage.js +15 -0
  200. data/public/js/jquery.hashlisten.js +85 -0
  201. data/public/js/jquery.js +166 -0
  202. data/public/js/jquery.livenavigate.js +58 -0
  203. data/public/js/jquery.livequery.js +226 -0
  204. data/public/js/jquery.quickvalidate.js +164 -0
  205. data/public/js/jquery.tmpl.js +486 -0
  206. data/public/js/jquery.uiscreen.js +150 -0
  207. data/public/js/jquery.wysiwyg.js +2339 -0
  208. data/public/js/jqueryui.js +766 -0
  209. data/public/js/lib.dirty.js +11 -0
  210. data/public/js/lib.loading.js +23 -0
  211. data/public/js/lib.wysiwyg.js +155 -0
  212. data/public/js/underscore-1.1.7.js +27 -0
  213. data/test/app/app/css/test_raw.css +1 -0
  214. data/test/app/app/css/test_sass.sass +3 -0
  215. data/test/app/app/damogram.txt +1 -0
  216. data/test/app/app/js/test_coffee.coffee +4 -0
  217. data/test/app/app/js/test_javascript.js +4 -0
  218. data/test/app/init.rb +5 -0
  219. data/test/stories/admin_css_story.rb +18 -0
  220. data/test/stories/css_js_story.rb +29 -0
  221. data/test/stories/first_login_story.rb +29 -0
  222. data/test/stories/visit_story.rb +39 -0
  223. data/test/stories_helper.rb +58 -0
  224. data/test/test_cli_helper.rb +31 -0
  225. data/test/test_helper.rb +111 -0
  226. data/test/test_temp_helper.rb +9 -0
  227. data/test/unit/cli_test.rb +38 -0
  228. data/test/unit/dump_test.rb +14 -0
  229. data/test/unit/extensions_test.rb +18 -0
  230. data/test/unit/files_test.rb +14 -0
  231. data/test/unit/flash_helper_test.rb +36 -0
  232. data/test/unit/html_helper_test.rb +29 -0
  233. data/test/unit/jquery_helper_test.rb +18 -0
  234. data/test/unit/model_test.rb +34 -0
  235. data/test/unit/page_helpers_test.rb +36 -0
  236. data/test/unit/seeder_test.rb +15 -0
  237. data/test/unit/settings_test.rb +29 -0
  238. data/test/unit/slug_test.rb +39 -0
  239. data/test/unit/ss_migration_test.rb +14 -0
  240. data/test/unit/terra_test.rb +125 -0
  241. data/test/unit/utils_test.rb +11 -0
  242. data/vendor/sinatra-sequel/.gitignore +3 -0
  243. data/vendor/sinatra-sequel/COPYING +18 -0
  244. data/vendor/sinatra-sequel/README.md +84 -0
  245. data/vendor/sinatra-sequel/Rakefile +67 -0
  246. data/vendor/sinatra-sequel/lib/sinatra/sequel.rb +73 -0
  247. data/vendor/sinatra-sequel/sinatra-sequel.gemspec +39 -0
  248. data/vendor/sinatra-sequel/spec/spec_sinatra_sequel.rb +70 -0
  249. metadata +536 -0
@@ -0,0 +1,11 @@
1
+ ;(function ($) {
2
+ var dirty = false;
3
+
4
+ $("input, textarea, select").live('change', function () {
5
+ if (dirty) { return; }
6
+ if ($(this).is('.neutral')) { return; }
7
+
8
+ dirty = true;
9
+ $('body').addClass('dirty').trigger('dirty');
10
+ });
11
+ })(jQuery);
@@ -0,0 +1,23 @@
1
+ ;(function ($) {
2
+ function $loader() {
3
+ if ($('#loader').length) { return $('#loader'); }
4
+
5
+ var $loader = $("<div id='loader'>Loading...</div>");
6
+ $("#top").append($loader);
7
+ return $loader;
8
+ }
9
+
10
+ $.loading = {
11
+ start: function () {
12
+ $('body').addClass('loading');
13
+ $loader().show();
14
+ },
15
+
16
+ finish: function () {
17
+ $('body').removeClass('loading');
18
+ $loader().fadeOut('fast');
19
+ $('body').show();
20
+ $.unscreen();
21
+ }
22
+ };
23
+ })(jQuery);
@@ -0,0 +1,155 @@
1
+ ;(function ($) {
2
+ // iFrame focus
3
+ $("div.wysiwyg iframe").livequery(function () {
4
+ var $p = $(this).closest('p');
5
+
6
+ function callback () {
7
+ $p.trigger('focus');
8
+ }
9
+
10
+ this.contentWindow.document.onfocus = callback;
11
+ this.contentWindow.onfocus = callback;
12
+ $p.bind('click', callback);
13
+ });
14
+
15
+ $("p.html").live('focus', function () {
16
+ var $p = $(this);
17
+ var $form = $p.closest('form');
18
+
19
+ $form.find('.focus').removeClass('focus');
20
+ $p.addClass('focus');
21
+
22
+ var $area = $('#area');
23
+ var top = 0;
24
+
25
+ if ($('.message').length) {
26
+ top = $('.message').outerHeight() + $('.message').position().top;
27
+ }
28
+ else if ($('section.crumbs').length) {
29
+ top = $('section.crumbs').outerHeight();
30
+ }
31
+
32
+ if ($area.scrollTop() < top)
33
+ $area.animate({ scrollTop: top });
34
+ });
35
+
36
+ $.fn.auraWysiwyg = function () {
37
+ var w = $(this).wysiwyg({
38
+ css: '/css/admin/wysiwyg_field.css',
39
+ rmUnusedControls: true,
40
+ initialContent: '',
41
+ controls: {
42
+ bold: { visible: true },
43
+ italic: { visible: true },
44
+ underline: { visible: true },
45
+ indent: { visible: true },
46
+ outdent: { visible: true },
47
+ insertOrderedList: { visible: true },
48
+ insertUnorderedList: { visible: true },
49
+ h2: { visible: true },
50
+ h3: { visible: true },
51
+ paragraph: { visible: true },
52
+ html: {
53
+ visible: true,
54
+ exec: function() {
55
+ var elementHeight;
56
+
57
+ if (this.options.resizeOptions && $.fn.resizable) {
58
+ elementHeight = this.element.height();
59
+ }
60
+
61
+ if (this.viewHTML) {
62
+ this.setContent(this.original.value);
63
+
64
+ $(this.original).hide();
65
+ this.editor.show();
66
+
67
+ if (this.options.resizeOptions && $.fn.resizable) {
68
+ // if element.height still the same after frame was shown
69
+ if (elementHeight === this.element.height()) {
70
+ this.element.height(elementHeight + this.editor.height());
71
+ }
72
+
73
+ this.element.resizable($.extend(true, {
74
+ alsoResize: this.editor
75
+ }, this.options.resizeOptions));
76
+ }
77
+
78
+ $(this.element).find('.toolbar-two').hide();
79
+ $(this.element).find('.toolbar').show();
80
+
81
+ // this.ui.toolbar.find("li").each(function () {
82
+ // var li = $(this);
83
+
84
+ // if (li.hasClass("html")) {
85
+ // li.removeClass("active");
86
+ // } else {
87
+ // li.removeClass('disabled');
88
+ // }
89
+ // });
90
+ } else {
91
+ this.saveContent();
92
+
93
+ $(this.original).css({
94
+ width: this.element.outerWidth(),
95
+ height: this.element.height() - this.ui.toolbar.height() - 10,
96
+ resize: "none"
97
+ }).show().css({ display: 'block' });
98
+ this.editor.hide();
99
+
100
+ var self = this;
101
+
102
+ setTimeout(function() { $(self.original).focus(); }, 1);
103
+
104
+ if (this.options.resizeOptions && $.fn.resizable) {
105
+ // if element.height still the same after frame was hidden
106
+ if (elementHeight === this.element.height()) {
107
+ this.element.height(this.ui.toolbar.height());
108
+ }
109
+
110
+ this.element.resizable("destroy");
111
+ }
112
+
113
+ $(this.element).find('.toolbar').hide();
114
+ $(this.element).find('.toolbar-two').show();
115
+ // this.ui.toolbar.find("li").each(function () {
116
+ // var li = $(this);
117
+
118
+ // if (li.hasClass("html")) {
119
+ // li.addClass("active");
120
+ // } else {
121
+ // if (false === li.hasClass("fullscreen")) {
122
+ // li.removeClass("active").addClass('disabled');
123
+ // }
124
+ // }
125
+ // });
126
+ }
127
+
128
+ this.viewHTML = !(this.viewHTML);
129
+ }
130
+ }
131
+ }
132
+ });
133
+
134
+ var $div = $(this).closest('p').find('div.wysiwyg');
135
+
136
+ // Make toolbar 2
137
+ var $a = $("<a class='back-to-rtf'>");
138
+ var $tool2 = $("<div class='toolbar-two'>");
139
+ $tool2.append("<span>You are editing raw HTML. </span>");
140
+ $tool2.append($a);
141
+ $a.html("Back to WYSIWYG");
142
+ $a.click(function() {
143
+ $div.find('.toolbar .html').trigger('click');
144
+ });
145
+
146
+ $div.prepend($tool2);
147
+ $tool2.hide();
148
+
149
+ // Default to HTML view if it's a textile/markdown thing
150
+ if ($(this).val().match(/format=/)) {
151
+ $div.find('.toolbar .html').trigger('click');
152
+ $(this).val($(this).val().replace(/<p><\/p>/g, ''));
153
+ }
154
+ };
155
+ })(jQuery);
@@ -0,0 +1,27 @@
1
+ // Underscore.js 1.1.7
2
+ // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
3
+ // Underscore is freely distributable under the MIT license.
4
+ // Portions of Underscore are inspired or borrowed from Prototype,
5
+ // Oliver Steele's Functional, and John Resig's Micro-Templating.
6
+ // For all details and documentation:
7
+ // http://documentcloud.github.com/underscore
8
+ (function(){var p=this,C=p._,m={},i=Array.prototype,n=Object.prototype,f=i.slice,D=i.unshift,E=n.toString,l=n.hasOwnProperty,s=i.forEach,t=i.map,u=i.reduce,v=i.reduceRight,w=i.filter,x=i.every,y=i.some,o=i.indexOf,z=i.lastIndexOf;n=Array.isArray;var F=Object.keys,q=Function.prototype.bind,b=function(a){return new j(a)};typeof module!=="undefined"&&module.exports?(module.exports=b,b._=b):p._=b;b.VERSION="1.1.7";var h=b.each=b.forEach=function(a,c,b){if(a!=null)if(s&&a.forEach===s)a.forEach(c,b);else if(a.length===
9
+ +a.length)for(var e=0,k=a.length;e<k;e++){if(e in a&&c.call(b,a[e],e,a)===m)break}else for(e in a)if(l.call(a,e)&&c.call(b,a[e],e,a)===m)break};b.map=function(a,c,b){var e=[];if(a==null)return e;if(t&&a.map===t)return a.map(c,b);h(a,function(a,g,G){e[e.length]=c.call(b,a,g,G)});return e};b.reduce=b.foldl=b.inject=function(a,c,d,e){var k=d!==void 0;a==null&&(a=[]);if(u&&a.reduce===u)return e&&(c=b.bind(c,e)),k?a.reduce(c,d):a.reduce(c);h(a,function(a,b,f){k?d=c.call(e,d,a,b,f):(d=a,k=!0)});if(!k)throw new TypeError("Reduce of empty array with no initial value");
10
+ return d};b.reduceRight=b.foldr=function(a,c,d,e){a==null&&(a=[]);if(v&&a.reduceRight===v)return e&&(c=b.bind(c,e)),d!==void 0?a.reduceRight(c,d):a.reduceRight(c);a=(b.isArray(a)?a.slice():b.toArray(a)).reverse();return b.reduce(a,c,d,e)};b.find=b.detect=function(a,c,b){var e;A(a,function(a,g,f){if(c.call(b,a,g,f))return e=a,!0});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(w&&a.filter===w)return a.filter(c,b);h(a,function(a,g,f){c.call(b,a,g,f)&&(e[e.length]=a)});return e};
11
+ b.reject=function(a,c,b){var e=[];if(a==null)return e;h(a,function(a,g,f){c.call(b,a,g,f)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=!0;if(a==null)return e;if(x&&a.every===x)return a.every(c,b);h(a,function(a,g,f){if(!(e=e&&c.call(b,a,g,f)))return m});return e};var A=b.some=b.any=function(a,c,d){c=c||b.identity;var e=!1;if(a==null)return e;if(y&&a.some===y)return a.some(c,d);h(a,function(a,b,f){if(e|=c.call(d,a,b,f))return m});return!!e};b.include=b.contains=function(a,c){var b=
12
+ !1;if(a==null)return b;if(o&&a.indexOf===o)return a.indexOf(c)!=-1;A(a,function(a){if(b=a===c)return!0});return b};b.invoke=function(a,c){var d=f.call(arguments,2);return b.map(a,function(a){return(c.call?c||a:a[c]).apply(a,d)})};b.pluck=function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);var e={computed:-Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,
13
+ c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;b<e.computed&&(e={value:a,computed:b})});return e.value};b.sortBy=function(a,c,d){return b.pluck(b.map(a,function(a,b,f){return{value:a,criteria:c.call(d,a,b,f)}}).sort(function(a,b){var c=a.criteria,d=b.criteria;return c<d?-1:c>d?1:0}),"value")};b.groupBy=function(a,b){var d={};h(a,function(a,f){var g=b(a,f);(d[g]||(d[g]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d||
14
+ (d=b.identity);for(var e=0,f=a.length;e<f;){var g=e+f>>1;d(a[g])<d(c)?e=g+1:f=g}return e};b.toArray=function(a){if(!a)return[];if(a.toArray)return a.toArray();if(b.isArray(a))return f.call(a);if(b.isArguments(a))return f.call(a);return b.values(a)};b.size=function(a){return b.toArray(a).length};b.first=b.head=function(a,b,d){return b!=null&&!d?f.call(a,0,b):a[0]};b.rest=b.tail=function(a,b,d){return f.call(a,b==null||d?1:b)};b.last=function(a){return a[a.length-1]};b.compact=function(a){return b.filter(a,
15
+ function(a){return!!a})};b.flatten=function(a){return b.reduce(a,function(a,d){if(b.isArray(d))return a.concat(b.flatten(d));a[a.length]=d;return a},[])};b.without=function(a){return b.difference(a,f.call(arguments,1))};b.uniq=b.unique=function(a,c){return b.reduce(a,function(a,e,f){if(0==f||(c===!0?b.last(a)!=e:!b.include(a,e)))a[a.length]=e;return a},[])};b.union=function(){return b.uniq(b.flatten(arguments))};b.intersection=b.intersect=function(a){var c=f.call(arguments,1);return b.filter(b.uniq(a),
16
+ function(a){return b.every(c,function(c){return b.indexOf(c,a)>=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=f.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e<c;e++)d[e]=b.pluck(a,""+e);return d};b.indexOf=function(a,c,d){if(a==null)return-1;var e;if(d)return d=b.sortedIndex(a,c),a[d]===c?d:-1;if(o&&a.indexOf===o)return a.indexOf(c);d=0;for(e=a.length;d<e;d++)if(a[d]===c)return d;return-1};b.lastIndexOf=function(a,
17
+ b){if(a==null)return-1;if(z&&a.lastIndexOf===z)return a.lastIndexOf(b);for(var d=a.length;d--;)if(a[d]===b)return d;return-1};b.range=function(a,b,d){arguments.length<=1&&(b=a||0,a=0);d=arguments[2]||1;for(var e=Math.max(Math.ceil((b-a)/d),0),f=0,g=Array(e);f<e;)g[f++]=a,a+=d;return g};b.bind=function(a,b){if(a.bind===q&&q)return q.apply(a,f.call(arguments,1));var d=f.call(arguments,2);return function(){return a.apply(b,d.concat(f.call(arguments)))}};b.bindAll=function(a){var c=f.call(arguments,1);
18
+ c.length==0&&(c=b.functions(a));h(c,function(c){a[c]=b.bind(a[c],a)});return a};b.memoize=function(a,c){var d={};c||(c=b.identity);return function(){var b=c.apply(this,arguments);return l.call(d,b)?d[b]:d[b]=a.apply(this,arguments)}};b.delay=function(a,b){var d=f.call(arguments,2);return setTimeout(function(){return a.apply(a,d)},b)};b.defer=function(a){return b.delay.apply(b,[a,1].concat(f.call(arguments,1)))};var B=function(a,b,d){var e;return function(){var f=this,g=arguments,h=function(){e=null;
19
+ a.apply(f,g)};d&&clearTimeout(e);if(d||!e)e=setTimeout(h,b)}};b.throttle=function(a,b){return B(a,b,!1)};b.debounce=function(a,b){return B(a,b,!0)};b.once=function(a){var b=!1,d;return function(){if(b)return d;b=!0;return d=a.apply(this,arguments)}};b.wrap=function(a,b){return function(){var d=[a].concat(f.call(arguments));return b.apply(this,d)}};b.compose=function(){var a=f.call(arguments);return function(){for(var b=f.call(arguments),d=a.length-1;d>=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after=
20
+ function(a,b){return function(){if(--a<1)return b.apply(this,arguments)}};b.keys=F||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)l.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){h(f.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){h(f.call(arguments,
21
+ 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,c){if(a===c)return!0;var d=typeof a;if(d!=typeof c)return!1;if(a==c)return!0;if(!a&&c||a&&!c)return!1;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual)return a.isEqual(c);if(c.isEqual)return c.isEqual(a);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return!1;
22
+ if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return!1;if(a.length&&a.length!==c.length)return!1;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return!1;for(var f in a)if(!(f in c)||!b.isEqual(a[f],c[f]))return!1;return!0};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(l.call(a,c))return!1;return!0};b.isElement=function(a){return!!(a&&a.nodeType==
23
+ 1)};b.isArray=n||function(a){return E.call(a)==="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return!(!a||!l.call(a,"callee"))};b.isFunction=function(a){return!(!a||!a.constructor||!a.call||!a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===!0||a===!1};b.isDate=function(a){return!(!a||!a.getTimezoneOffset||
24
+ !a.setUTCFullYear)};b.isRegExp=function(a){return!(!a||!a.test||!a.exec||!(a.ignoreCase||a.ignoreCase===!1))};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){p._=C;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e<a;e++)b.call(d,e)};b.mixin=function(a){h(b.functions(a),function(c){H(c,b[c]=a[c])})};var I=0;b.uniqueId=function(a){var b=I++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g};
25
+ b.template=function(a,c){var d=b.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return c?d(c):d};
26
+ var j=function(a){this._wrapped=a};b.prototype=j.prototype;var r=function(a,c){return c?b(a).chain():a},H=function(a,c){j.prototype[a]=function(){var a=f.call(arguments);D.call(a,this._wrapped);return r(c.apply(b,a),this._chain)}};b.mixin(b);h(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=i[a];j.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});h(["concat","join","slice"],function(a){var b=i[a];j.prototype[a]=function(){return r(b.apply(this._wrapped,
27
+ arguments),this._chain)}});j.prototype.chain=function(){this._chain=!0;return this};j.prototype.value=function(){return this._wrapped}})();
@@ -0,0 +1 @@
1
+ div { color: red }
@@ -0,0 +1,3 @@
1
+ $x: #123456
2
+ div
3
+ color: $x
@@ -0,0 +1 @@
1
+ Beedlebrox!
@@ -0,0 +1,4 @@
1
+ @x =
2
+ a: 1
3
+ b: 2
4
+ c: "Skittles"
@@ -0,0 +1,4 @@
1
+ (function () {
2
+ return true;
3
+ })();
4
+
@@ -0,0 +1,5 @@
1
+ # This file is here for testing purposes only
2
+ ENV['APP_FILE'] = __FILE__
3
+ $:.unshift File.expand_path('../../../lib', __FILE__)
4
+
5
+ require 'aura/app'
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../../stories_helper', __FILE__)
2
+
3
+ class AdminCssStory < Story
4
+ test "x" do
5
+ login!
6
+
7
+ assert page.body.include?("<link href='/css/admin.css' media='screen' rel='stylesheet' type='text/css'")
8
+ end
9
+
10
+ test "add" do
11
+ Aura.admin.css << {:href => '/css/admin-ext.css'}
12
+
13
+ login!
14
+
15
+ assert page.body.include?("<link href='/css/admin-ext.css' media='screen' rel='stylesheet' type='text/css'")
16
+ assert page.body =~ /admin\.css.*admin-ext.css/m
17
+ end
18
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../../stories_helper', __FILE__)
2
+
3
+ class CssJsStory < Story
4
+ test "Raw" do
5
+ visit '/css/test_raw.css'
6
+ assert page.body.strip == "div { color: red }"
7
+ end
8
+
9
+ test "Sass" do
10
+ visit '/css/test_sass.css'
11
+ assert page.body.strip =~ /div.*color.*123456/m
12
+ end
13
+
14
+ test "admin.css" do
15
+ visit '/css/admin.css'
16
+ assert page.body.include?("display")
17
+ assert page.body.include?("margin")
18
+ end
19
+
20
+ test "javascript" do
21
+ visit '/js/test_javascript.js'
22
+ assert page.body.include?('return true')
23
+ end
24
+
25
+ test "javascript" do
26
+ visit '/js/test_coffee.js'
27
+ assert page.body.include?('Skittles')
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../../stories_helper', __FILE__)
2
+
3
+ class FirstLoginStory < Story
4
+ test "First login" do
5
+ visit '/logout'
6
+ visit '/login'
7
+
8
+ assert_location '/login'
9
+ assert page.has_content?('Login')
10
+ assert page.has_css?('form')
11
+
12
+ fill_in 'username', :with => 'test@sinefunc.com'
13
+ fill_in 'password', :with => 'massive'
14
+
15
+ click_button 'Login'
16
+
17
+ # Go back to login page
18
+ assert_location '/login'
19
+ assert page.has_content?('Try again!')
20
+
21
+ fill_in 'username', :with => Main.default_user
22
+ fill_in 'password', :with => Main.default_password
23
+
24
+ click_button 'Login'
25
+
26
+ # First visit!
27
+ assert_location '/admin/welcome'
28
+ end
29
+ end
@@ -0,0 +1,39 @@
1
+ require File.expand_path('../../stories_helper', __FILE__)
2
+
3
+ class Main
4
+ get '/lalala' do
5
+ raise "Yo"
6
+ end
7
+ end
8
+
9
+ class VisitStory < Story
10
+ test "Pages should not have errors" do
11
+ Main.seed :sample
12
+
13
+ # Always do this in rack_test -- no need to do this in a real browser.
14
+ # We're just here to verify that these URLs don't throw errors or
15
+ # do anything funny.
16
+ s = Capybara::Session.new(:rack_test, Main)
17
+ s.reset!
18
+
19
+ s.visit '/logout'
20
+ s.visit '/login'
21
+ s.fill_in 'username', :with => Main.default_user
22
+ s.fill_in 'password', :with => Main.default_password
23
+ s.click_button 'Login'
24
+
25
+ assert_admin '/admin', s
26
+ assert_admin '/admin/settings', s
27
+ assert_admin '/admin/settings/database', s
28
+ assert_admin '/user/me/edit', s
29
+ assert_admin '/user/list', s
30
+ assert_admin '/user/1/edit', s
31
+
32
+ assert_front '/home', s
33
+ assert_front '/', s
34
+ assert_front '/about-us', s
35
+
36
+ assert_404 '/jigglesphinx', s
37
+ assert_404 '/admin/sodapop', s
38
+ end
39
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ require "capybara"
4
+ require "capybara/dsl"
5
+
6
+ Capybara.app = Main
7
+
8
+ if ENV['driver'] == 'chrome'
9
+ Capybara.default_driver = (ENV['driver'] || :chrome).to_sym
10
+ Capybara.register_driver :chrome do |app|
11
+ Capybara::Driver::Selenium.new(app, :browser => :chrome)
12
+ end
13
+ end
14
+
15
+ class Story < Test::Unit::TestCase
16
+ include Capybara
17
+
18
+ setup do
19
+ end
20
+
21
+ def status
22
+ p "Current path", current_path
23
+ end
24
+
25
+ def assert_location(loc)
26
+ assert_equal loc, current_path
27
+ end
28
+
29
+ def login!
30
+ visit '/logout'
31
+ visit '/login'
32
+
33
+ fill_in 'username', :with => Main.default_user
34
+ fill_in 'password', :with => Main.default_password
35
+ click_button 'Login'
36
+
37
+ assert ! page.has_content?('Login'), 'Login failed.'
38
+ end
39
+
40
+ # Checks that the given URL is an admin area.
41
+ def assert_admin(url, session=self)
42
+ session.visit url
43
+ assert ! session.has_content?('Login'), 'Ended up in a login page.'
44
+ assert session.has_content?('TESTSITE')
45
+ assert session.has_css?('#top')
46
+ assert session.has_css?('aside#nav')
47
+ end
48
+
49
+ def assert_front(url, session=self)
50
+ session.visit url
51
+ assert ! session.has_content?('Login'), 'Ended up in a login page.'
52
+ end
53
+
54
+ def assert_404(url=nil, s=self)
55
+ s.visit url unless url.nil?
56
+ assert (s.has_content?('Not found') || s.has_content?('know this ditty'))
57
+ end
58
+ end
@@ -0,0 +1,31 @@
1
+ module CliHelper
2
+ # Capture stdout and stderr
3
+ def capture(&blk)
4
+ previous_stderr, $stderr = $stderr, StringIO.new
5
+ previous_stdout, $stdout = $stdout, StringIO.new
6
+
7
+ yield
8
+
9
+ return [$stdout.string, $stderr.string]
10
+ ensure
11
+ $stderr = previous_stderr
12
+ $stdout = previous_stdout
13
+ end
14
+
15
+ # Runs a CLI runner and captures output
16
+ def cli(&blk)
17
+ @stdout, @stderr = capture { yield }
18
+ end
19
+
20
+ def stdout
21
+ @stdout
22
+ end
23
+
24
+ def stderr
25
+ @stderr
26
+ end
27
+
28
+ # def aura(cmd)
29
+ # cli { Aura::CLI.run *cmd.split(' ') }
30
+ # end
31
+ end