sproutcore 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. data/History.txt +4 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +269 -0
  4. data/README.txt +67 -0
  5. data/Rakefile +4 -0
  6. data/app_generators/sproutcore/USAGE +5 -0
  7. data/app_generators/sproutcore/sproutcore_generator.rb +66 -0
  8. data/app_generators/sproutcore/templates/README +77 -0
  9. data/app_generators/sproutcore/templates/environment.yml +4 -0
  10. data/bin/sc-build +145 -0
  11. data/bin/sc-gen +24 -0
  12. data/bin/sc-server +63 -0
  13. data/bin/sproutcore +21 -0
  14. data/clients/sc_docs/controllers/docs.js +118 -0
  15. data/clients/sc_docs/core.js +19 -0
  16. data/clients/sc_docs/english.lproj/body.css +159 -0
  17. data/clients/sc_docs/english.lproj/body.rhtml +33 -0
  18. data/clients/sc_docs/english.lproj/controls.css +0 -0
  19. data/clients/sc_docs/english.lproj/icons/small/next.png +0 -0
  20. data/clients/sc_docs/english.lproj/icons/small/reset.png +0 -0
  21. data/clients/sc_docs/english.lproj/images/gradients.png +0 -0
  22. data/clients/sc_docs/english.lproj/images/indicator.gif +0 -0
  23. data/clients/sc_docs/english.lproj/images/toolbar.png +0 -0
  24. data/clients/sc_docs/english.lproj/no_docs.rhtml +7 -0
  25. data/clients/sc_docs/english.lproj/strings.js +14 -0
  26. data/clients/sc_docs/english.lproj/warning.rhtml +6 -0
  27. data/clients/sc_docs/fixtures/doc.js +11 -0
  28. data/clients/sc_docs/main.js +21 -0
  29. data/clients/sc_docs/models/doc.js +9 -0
  30. data/clients/sc_docs/tests/controllers/docs.rhtml +21 -0
  31. data/clients/sc_docs/tests/models/doc.rhtml +21 -0
  32. data/clients/sc_docs/tests/views/doc_frame.rhtml +21 -0
  33. data/clients/sc_docs/tests/views/doc_label_view.rhtml +21 -0
  34. data/clients/sc_docs/views/doc_frame.js +33 -0
  35. data/clients/sc_docs/views/doc_label.js +20 -0
  36. data/clients/sc_test_runner/controllers/runner.js +175 -0
  37. data/clients/sc_test_runner/core.js +19 -0
  38. data/clients/sc_test_runner/english.lproj/body.css +151 -0
  39. data/clients/sc_test_runner/english.lproj/body.rhtml +35 -0
  40. data/clients/sc_test_runner/english.lproj/controls.css +0 -0
  41. data/clients/sc_test_runner/english.lproj/icons/small/next.png +0 -0
  42. data/clients/sc_test_runner/english.lproj/icons/small/reset.png +0 -0
  43. data/clients/sc_test_runner/english.lproj/images/gradients.png +0 -0
  44. data/clients/sc_test_runner/english.lproj/images/indicator.gif +0 -0
  45. data/clients/sc_test_runner/english.lproj/images/toolbar.png +0 -0
  46. data/clients/sc_test_runner/english.lproj/no_tests.rhtml +6 -0
  47. data/clients/sc_test_runner/english.lproj/strings.js +14 -0
  48. data/clients/sc_test_runner/english.lproj/warning.rhtml +6 -0
  49. data/clients/sc_test_runner/fixtures/test.js +12 -0
  50. data/clients/sc_test_runner/main.js +26 -0
  51. data/clients/sc_test_runner/models/test.js +11 -0
  52. data/clients/sc_test_runner/views/runner_frame.js +72 -0
  53. data/clients/sc_test_runner/views/test_label.js +20 -0
  54. data/config/hoe.rb +70 -0
  55. data/config/requirements.rb +17 -0
  56. data/environment.yml +9 -0
  57. data/frameworks/prototype/prototype.js +4186 -0
  58. data/frameworks/sproutcore/Core.js +378 -0
  59. data/frameworks/sproutcore/README +3 -0
  60. data/frameworks/sproutcore/controllers/array.js +236 -0
  61. data/frameworks/sproutcore/controllers/collection.js +305 -0
  62. data/frameworks/sproutcore/controllers/controller.js +323 -0
  63. data/frameworks/sproutcore/controllers/object.js +372 -0
  64. data/frameworks/sproutcore/drag/drag.js +549 -0
  65. data/frameworks/sproutcore/drag/drag_data_source.js +32 -0
  66. data/frameworks/sproutcore/drag/drag_source.js +64 -0
  67. data/frameworks/sproutcore/drag/drop_target.js +153 -0
  68. data/frameworks/sproutcore/english.lproj/blank.gif +0 -0
  69. data/frameworks/sproutcore/english.lproj/buttons.css +589 -0
  70. data/frameworks/sproutcore/english.lproj/buttons.png +0 -0
  71. data/frameworks/sproutcore/english.lproj/inline_text_editor.css +21 -0
  72. data/frameworks/sproutcore/english.lproj/menu.css +121 -0
  73. data/frameworks/sproutcore/english.lproj/panels/background-fat.jpg +0 -0
  74. data/frameworks/sproutcore/english.lproj/panels/background-thin.jpg +0 -0
  75. data/frameworks/sproutcore/english.lproj/panels/bottom-edge.png +0 -0
  76. data/frameworks/sproutcore/english.lproj/panels/bottom-left-corner.png +0 -0
  77. data/frameworks/sproutcore/english.lproj/panels/bottom-right-corner.png +0 -0
  78. data/frameworks/sproutcore/english.lproj/panels/left-edge.png +0 -0
  79. data/frameworks/sproutcore/english.lproj/panels/overlay.png +0 -0
  80. data/frameworks/sproutcore/english.lproj/panels/right-edge.png +0 -0
  81. data/frameworks/sproutcore/english.lproj/panels/top-edge.png +0 -0
  82. data/frameworks/sproutcore/english.lproj/panels/top-left-corner.png +0 -0
  83. data/frameworks/sproutcore/english.lproj/panels/top-right-corner.png +0 -0
  84. data/frameworks/sproutcore/english.lproj/panes.css +155 -0
  85. data/frameworks/sproutcore/english.lproj/picker.css +22 -0
  86. data/frameworks/sproutcore/english.lproj/strings.js +15 -0
  87. data/frameworks/sproutcore/english.lproj/tab.css +23 -0
  88. data/frameworks/sproutcore/english.lproj/tests.css +67 -0
  89. data/frameworks/sproutcore/english.lproj/theme.css +77 -0
  90. data/frameworks/sproutcore/foundation/animator.js +670 -0
  91. data/frameworks/sproutcore/foundation/application.js +199 -0
  92. data/frameworks/sproutcore/foundation/array.js +348 -0
  93. data/frameworks/sproutcore/foundation/benchmark.js +211 -0
  94. data/frameworks/sproutcore/foundation/binding.js +384 -0
  95. data/frameworks/sproutcore/foundation/date.js +357 -0
  96. data/frameworks/sproutcore/foundation/error.js +39 -0
  97. data/frameworks/sproutcore/foundation/input_manager.js +153 -0
  98. data/frameworks/sproutcore/foundation/json.js +296 -0
  99. data/frameworks/sproutcore/foundation/mock.js +42 -0
  100. data/frameworks/sproutcore/foundation/node_descriptor.js +56 -0
  101. data/frameworks/sproutcore/foundation/object.js +777 -0
  102. data/frameworks/sproutcore/foundation/observable.js +451 -0
  103. data/frameworks/sproutcore/foundation/page.js +63 -0
  104. data/frameworks/sproutcore/foundation/path_module.js +413 -0
  105. data/frameworks/sproutcore/foundation/responder.js +310 -0
  106. data/frameworks/sproutcore/foundation/routes.js +371 -0
  107. data/frameworks/sproutcore/foundation/run_loop.js +21 -0
  108. data/frameworks/sproutcore/foundation/server.js +491 -0
  109. data/frameworks/sproutcore/foundation/set.js +96 -0
  110. data/frameworks/sproutcore/foundation/string.js +149 -0
  111. data/frameworks/sproutcore/foundation/undo_manager.js +186 -0
  112. data/frameworks/sproutcore/foundation/unittest.js +622 -0
  113. data/frameworks/sproutcore/foundation/utils.js +61 -0
  114. data/frameworks/sproutcore/globals/panels.js +182 -0
  115. data/frameworks/sproutcore/globals/popups.js +60 -0
  116. data/frameworks/sproutcore/globals/window.js +381 -0
  117. data/frameworks/sproutcore/lib/index.rhtml +66 -0
  118. data/frameworks/sproutcore/models/collection.js +395 -0
  119. data/frameworks/sproutcore/models/record.js +622 -0
  120. data/frameworks/sproutcore/models/store.js +295 -0
  121. data/frameworks/sproutcore/panes/dialog.js +16 -0
  122. data/frameworks/sproutcore/panes/manager.js +164 -0
  123. data/frameworks/sproutcore/panes/menu.js +45 -0
  124. data/frameworks/sproutcore/panes/overlay.js +231 -0
  125. data/frameworks/sproutcore/panes/pane.js +90 -0
  126. data/frameworks/sproutcore/panes/panel.js +19 -0
  127. data/frameworks/sproutcore/panes/picker.js +45 -0
  128. data/frameworks/sproutcore/tests/controllers/array.rhtml +86 -0
  129. data/frameworks/sproutcore/tests/controllers/controller.rhtml +273 -0
  130. data/frameworks/sproutcore/tests/controllers/object.rhtml +327 -0
  131. data/frameworks/sproutcore/tests/foundation/application.rhtml +125 -0
  132. data/frameworks/sproutcore/tests/foundation/array.rhtml +221 -0
  133. data/frameworks/sproutcore/tests/foundation/object.rhtml +69 -0
  134. data/frameworks/sproutcore/tests/globals/window.rhtml +45 -0
  135. data/frameworks/sproutcore/tests/panes/pane.rhtml +88 -0
  136. data/frameworks/sproutcore/tests/views/collection.rhtml +137 -0
  137. data/frameworks/sproutcore/tests/views/popup_button.rhtml +115 -0
  138. data/frameworks/sproutcore/tests/views/text_field.rhtml +37 -0
  139. data/frameworks/sproutcore/validators/credit_card.js +92 -0
  140. data/frameworks/sproutcore/validators/date.js +36 -0
  141. data/frameworks/sproutcore/validators/email.js +29 -0
  142. data/frameworks/sproutcore/validators/not_empty.js +24 -0
  143. data/frameworks/sproutcore/validators/number.js +55 -0
  144. data/frameworks/sproutcore/validators/password.js +78 -0
  145. data/frameworks/sproutcore/validators/validator.js +304 -0
  146. data/frameworks/sproutcore/views/button.js +425 -0
  147. data/frameworks/sproutcore/views/checkbox_field.js +30 -0
  148. data/frameworks/sproutcore/views/collection.js +1521 -0
  149. data/frameworks/sproutcore/views/container.js +62 -0
  150. data/frameworks/sproutcore/views/error_explanation.js +45 -0
  151. data/frameworks/sproutcore/views/field.js +214 -0
  152. data/frameworks/sproutcore/views/filter_button.js +29 -0
  153. data/frameworks/sproutcore/views/form.js +591 -0
  154. data/frameworks/sproutcore/views/image.js +141 -0
  155. data/frameworks/sproutcore/views/inline_text_editor.js +96 -0
  156. data/frameworks/sproutcore/views/label.js +176 -0
  157. data/frameworks/sproutcore/views/menu_item.js +90 -0
  158. data/frameworks/sproutcore/views/pagination.js +54 -0
  159. data/frameworks/sproutcore/views/popup_button.js +86 -0
  160. data/frameworks/sproutcore/views/popup_menu.js +137 -0
  161. data/frameworks/sproutcore/views/progress.js +100 -0
  162. data/frameworks/sproutcore/views/radio_field.js +107 -0
  163. data/frameworks/sproutcore/views/radio_group.js +48 -0
  164. data/frameworks/sproutcore/views/segmented.js +80 -0
  165. data/frameworks/sproutcore/views/select_field.js +272 -0
  166. data/frameworks/sproutcore/views/spinner.js +11 -0
  167. data/frameworks/sproutcore/views/tab.js +126 -0
  168. data/frameworks/sproutcore/views/text_field.js +179 -0
  169. data/frameworks/sproutcore/views/textarea_field.js +14 -0
  170. data/frameworks/sproutcore/views/toolbar.js +29 -0
  171. data/frameworks/sproutcore/views/view.js +1389 -0
  172. data/frameworks/sproutcore/views/workspace.js +170 -0
  173. data/generators/client/README +3 -0
  174. data/generators/client/USAGE +12 -0
  175. data/generators/client/client_generator.rb +53 -0
  176. data/generators/client/templates/core.js +19 -0
  177. data/generators/client/templates/english.lproj/body.css +0 -0
  178. data/generators/client/templates/english.lproj/body.rhtml +3 -0
  179. data/generators/client/templates/english.lproj/controls.css +0 -0
  180. data/generators/client/templates/english.lproj/strings.js +14 -0
  181. data/generators/client/templates/main.js +37 -0
  182. data/generators/controller/USAGE +16 -0
  183. data/generators/controller/controller_generator.rb +51 -0
  184. data/generators/controller/templates/controller.js +21 -0
  185. data/generators/controller/templates/test.rhtml +21 -0
  186. data/generators/framework/README +7 -0
  187. data/generators/framework/USAGE +12 -0
  188. data/generators/framework/framework_generator.rb +53 -0
  189. data/generators/framework/templates/core.js +20 -0
  190. data/generators/framework/templates/english.lproj/body.css +0 -0
  191. data/generators/framework/templates/english.lproj/body.rhtml +3 -0
  192. data/generators/framework/templates/english.lproj/controls.css +0 -0
  193. data/generators/framework/templates/english.lproj/strings.js +14 -0
  194. data/generators/language/USAGE +16 -0
  195. data/generators/language/language_generator.rb +47 -0
  196. data/generators/language/templates/strings.js +10 -0
  197. data/generators/model/USAGE +24 -0
  198. data/generators/model/model_generator.rb +55 -0
  199. data/generators/model/templates/fixture.js +11 -0
  200. data/generators/model/templates/model.js +20 -0
  201. data/generators/model/templates/test.rhtml +21 -0
  202. data/generators/test/USAGE +16 -0
  203. data/generators/test/templates/test.rhtml +21 -0
  204. data/generators/test/test_generator.rb +47 -0
  205. data/generators/view/USAGE +16 -0
  206. data/generators/view/templates/test.rhtml +21 -0
  207. data/generators/view/templates/view.js +20 -0
  208. data/generators/view/view_generator.rb +51 -0
  209. data/jsdoc/README.txt +119 -0
  210. data/jsdoc/app/DocFile.js +137 -0
  211. data/jsdoc/app/DocTag.js +110 -0
  212. data/jsdoc/app/Doclet.js +63 -0
  213. data/jsdoc/app/Dumper.js +143 -0
  214. data/jsdoc/app/JsDoc.js +103 -0
  215. data/jsdoc/app/JsHilite.js +45 -0
  216. data/jsdoc/app/JsIO.js +163 -0
  217. data/jsdoc/app/JsParse.js +385 -0
  218. data/jsdoc/app/JsPlate.js +130 -0
  219. data/jsdoc/app/JsTestrun.js +129 -0
  220. data/jsdoc/app/JsToke.js +564 -0
  221. data/jsdoc/app/Symbol.js +298 -0
  222. data/jsdoc/app/Transformer.js +14 -0
  223. data/jsdoc/app/Util.js +97 -0
  224. data/jsdoc/app/js.jar +0 -0
  225. data/jsdoc/app/run.js +144 -0
  226. data/jsdoc/plugins/min.js +316 -0
  227. data/jsdoc/plugins/strip.js +20 -0
  228. data/jsdoc/templates/sproutcore/class.tmpl +438 -0
  229. data/jsdoc/templates/sproutcore/default.css +241 -0
  230. data/jsdoc/templates/sproutcore/index.html +13 -0
  231. data/jsdoc/templates/sproutcore/index.tmpl +21 -0
  232. data/jsdoc/templates/sproutcore/prototype.js +4186 -0
  233. data/jsdoc/templates/sproutcore/publish.js +236 -0
  234. data/jsdoc/templates/sproutcore/splash.html +7 -0
  235. data/lib/sproutcore/build_tools/html_builder.rb +88 -0
  236. data/lib/sproutcore/build_tools/resource_builder.rb +194 -0
  237. data/lib/sproutcore/build_tools.rb +44 -0
  238. data/lib/sproutcore/bundle.rb +517 -0
  239. data/lib/sproutcore/bundle_manifest.rb +397 -0
  240. data/lib/sproutcore/generator_helper.rb +170 -0
  241. data/lib/sproutcore/helpers/capture_helper.rb +42 -0
  242. data/lib/sproutcore/helpers/static_helper.rb +80 -0
  243. data/lib/sproutcore/helpers/tag_helper.rb +110 -0
  244. data/lib/sproutcore/helpers/text_helper.rb +336 -0
  245. data/lib/sproutcore/helpers.rb +3 -0
  246. data/lib/sproutcore/jsdoc.rb +40 -0
  247. data/lib/sproutcore/jsmin.rb +247 -0
  248. data/lib/sproutcore/library.rb +258 -0
  249. data/lib/sproutcore/merb/bundle_controller.rb +179 -0
  250. data/lib/sproutcore/merb/router.rb +43 -0
  251. data/lib/sproutcore/merb.rb +27 -0
  252. data/lib/sproutcore/version.rb +9 -0
  253. data/lib/sproutcore/view_helpers/button_views.rb +302 -0
  254. data/lib/sproutcore/view_helpers/core_views.rb +284 -0
  255. data/lib/sproutcore/view_helpers/form_views.rb +258 -0
  256. data/lib/sproutcore/view_helpers/menu_views.rb +94 -0
  257. data/lib/sproutcore/view_helpers.rb +628 -0
  258. data/lib/sproutcore.rb +30 -0
  259. data/script/destroy +14 -0
  260. data/script/generate +14 -0
  261. data/script/txt2html +74 -0
  262. data/setup.rb +1585 -0
  263. data/spec/spec.opts +1 -0
  264. data/spec/spec_helper.rb +7 -0
  265. data/spec/sproutcore_spec.rb +11 -0
  266. data/tasks/deployment.rake +34 -0
  267. data/tasks/environment.rake +7 -0
  268. data/tasks/rspec.rake +21 -0
  269. data/tasks/website.rake +17 -0
  270. metadata +365 -0
@@ -0,0 +1,622 @@
1
+ // script.aculo.us unittest.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
2
+
3
+ // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
4
+ // (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
5
+ // (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/)
6
+ //
7
+ // script.aculo.us is freely distributable under the terms of an MIT-style license.
8
+ // For details, see the script.aculo.us web site: http://script.aculo.us/
9
+
10
+ // experimental, Firefox-only
11
+ Event.simulateMouse = function(element, eventName) {
12
+ var options = Object.extend({
13
+ pointerX: 0,
14
+ pointerY: 0,
15
+ buttons: 0,
16
+ ctrlKey: false,
17
+ altKey: false,
18
+ shiftKey: false,
19
+ metaKey: false
20
+ }, arguments[2] || {});
21
+ var oEvent = document.createEvent("MouseEvents");
22
+ oEvent.initMouseEvent(eventName, true, true, document.defaultView,
23
+ options.buttons, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
24
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, $(element));
25
+
26
+ if(this.mark) Element.remove(this.mark);
27
+ this.mark = document.createElement('div');
28
+ this.mark.appendChild(document.createTextNode(" "));
29
+ document.body.appendChild(this.mark);
30
+ this.mark.style.position = 'absolute';
31
+ this.mark.style.top = options.pointerY + "px";
32
+ this.mark.style.left = options.pointerX + "px";
33
+ this.mark.style.width = "5px";
34
+ this.mark.style.height = "5px;";
35
+ this.mark.style.borderTop = "1px solid red;" ;
36
+ this.mark.style.borderLeft = "1px solid red;" ;
37
+
38
+ if(this.step)
39
+ alert('['+new Date().getTime().toString()+'] '+eventName+'/'+Test.Unit.inspect(options));
40
+
41
+ $(element).dispatchEvent(oEvent);
42
+ };
43
+
44
+ // Note: Due to a fix in Firefox 1.0.5/6 that probably fixed "too much", this doesn't work in 1.0.6 or DP2.
45
+ // You need to downgrade to 1.0.4 for now to get this working
46
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=289940 for the fix that fixed too much
47
+ Event.simulateKey = function(element, eventName) {
48
+ var options = Object.extend({
49
+ ctrlKey: false,
50
+ altKey: false,
51
+ shiftKey: false,
52
+ metaKey: false,
53
+ keyCode: 0,
54
+ charCode: 0
55
+ }, arguments[2] || {});
56
+
57
+ var oEvent = document.createEvent("KeyEvents");
58
+ oEvent.initKeyEvent(eventName, true, true, window,
59
+ options.ctrlKey, options.altKey, options.shiftKey, options.metaKey,
60
+ options.keyCode, options.charCode );
61
+ $(element).dispatchEvent(oEvent);
62
+ };
63
+
64
+ Event.simulateKeys = function(element, command) {
65
+ for(var i=0; i<command.length; i++) {
66
+ Event.simulateKey(element,'keypress',{charCode:command.charCodeAt(i)});
67
+ }
68
+ };
69
+
70
+ var Test = {} ;
71
+ Test.Unit = {};
72
+
73
+ // security exception workaround
74
+ Test.Unit.inspect = Object.inspect;
75
+
76
+ Test.Unit.Logger = Class.create();
77
+ Test.Unit.Logger.prototype = {
78
+ initialize: function(log) {
79
+ this.log = $(log);
80
+ this.logId = this.log.id || 'x';
81
+ if (this.log) {
82
+ this._createLogTable();
83
+ }
84
+ },
85
+ start: function(testName) {
86
+ if (!this.log) return;
87
+ this.testName = testName;
88
+ this.lastLogLine = document.createElement('tr');
89
+ this.statusCell = document.createElement('td');
90
+ this.nameCell = document.createElement('td');
91
+ this.nameCell.className = "nameCell";
92
+ this.nameCell.appendChild(document.createTextNode(testName));
93
+ this.messageCell = document.createElement('td');
94
+ this.lastLogLine.appendChild(this.statusCell);
95
+ this.lastLogLine.appendChild(this.nameCell);
96
+ this.lastLogLine.appendChild(this.messageCell);
97
+ this.loglines.appendChild(this.lastLogLine);
98
+ },
99
+ finish: function(status, summary) {
100
+ if (!this.log) return;
101
+ this.lastLogLine.className = status;
102
+ this.statusCell.innerHTML = status;
103
+ this.messageCell.innerHTML = this._toHTML(summary);
104
+ this.addLinksToResults();
105
+ },
106
+ message: function(message) {
107
+ if (!this.log) return;
108
+ this.messageCell.innerHTML = this._toHTML(message);
109
+ },
110
+ summary: function(summary) {
111
+ if (!this.log) return;
112
+ this.logsummary.innerHTML = this._toHTML(summary);
113
+ },
114
+ _createLogTable: function() {
115
+ this.log.innerHTML =
116
+ '<div id="' + this.logId + '-logsummary" class="logsummary"></div>' +
117
+ '<table id="' + this.logId + '-logtable">' +
118
+ '<thead><tr><th>Status</th><th>Test</th><th>Message</th></tr></thead>' +
119
+ '<tbody id="' + this.logId + '-loglines"></tbody>' +
120
+ '</table>';
121
+ this.logsummary = $(this.logId + '-logsummary') ;
122
+ this.loglines = $(this.logId + '-loglines');
123
+ },
124
+ _toHTML: function(txt) {
125
+ return txt.escapeHTML().replace(/\n/g,"<br/>");
126
+ },
127
+ addLinksToResults: function(){
128
+ $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
129
+ td.title = "Run only this test" ;
130
+ Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
131
+ });
132
+ $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
133
+ td.title = "Run all tests" ;
134
+ Event.observe(td, 'click', function(){ window.location.search = "";});
135
+ });
136
+ }
137
+ } ;
138
+
139
+ document.incrementQueuedTests = function(amt) {
140
+ if (amt == undefined) amt = 1 ;
141
+ var cnt = document.queuedTests || 0 ;
142
+ document.queuedTests = cnt + amt ;
143
+ } ;
144
+
145
+
146
+ document.setTestStatus = function(stat) {
147
+ var cur = document.testStatus || 'SUCCESS' ;
148
+ document.testStatus = (cur == 'SUCCESS') ? stat : cur ;
149
+ };
150
+
151
+ Test.Unit.Runner = Class.create();
152
+ Test.Unit.Runner.prototype = {
153
+ initialize: function(testcases) {
154
+ this.options = Object.extend({
155
+ testLog: 'testlog'
156
+ }, arguments[1] || {});
157
+ this.options.resultsURL = this.parseResultsURLQueryParameter();
158
+ this.options.tests = this.parseTestsQueryParameter();
159
+
160
+ if (this.options.testLog) {
161
+ var testLogElement = $(this.options.testLog) || null;
162
+
163
+ // if the testLog was not found, then build it.
164
+ // if root log is not found, create and add it.
165
+ var rootLog = $('test-log') ;
166
+ if (!rootLog) {
167
+ var el = document.createElement('div') ;
168
+ el.id = 'test-log' ;
169
+ el.addClassName('testlog') ;
170
+ var body = document.getElementsByTagName('body')[0] ;
171
+ body.insertBefore(el, body.firstChild) ;
172
+ rootLog = el ;
173
+ }
174
+
175
+ if (rootLog) {
176
+ var el = document.createElement('div') ;
177
+ el.id = this.options.testLog ;
178
+ rootLog.appendChild(el) ;
179
+ testLogElement = el ;
180
+ }
181
+
182
+ this.options.testLog = testLogElement ;
183
+
184
+ }
185
+
186
+ if(this.options.tests) {
187
+ this.tests = [];
188
+ for(var i = 0; i < this.options.tests.length; i++) {
189
+ if(/^test/.test(this.options.tests[i])) {
190
+ this.tests.push(new Test.Unit.Testcase(this.options.tests[i], testcases[this.options.tests[i]], testcases["setup"], testcases["teardown"]));
191
+ }
192
+ }
193
+ } else {
194
+ if (this.options.test) {
195
+ this.tests = [new Test.Unit.Testcase(this.options.test, testcases[this.options.test], testcases["setup"], testcases["teardown"])];
196
+ } else {
197
+ this.tests = [];
198
+ for(var testcase in testcases) {
199
+ if(/^test/.test(testcase)) {
200
+ this.tests.push(
201
+ new Test.Unit.Testcase(
202
+ this.options.context ? ' -> ' + this.options.titles[testcase] : testcase,
203
+ testcases[testcase], testcases["setup"], testcases["teardown"]
204
+ ));
205
+ }
206
+ }
207
+ }
208
+ }
209
+ this.currentTest = 0;
210
+ this.logger = new Test.Unit.Logger(this.options.testLog);
211
+ document.incrementQueuedTests(1) ;
212
+ setTimeout(this.runTests.bind(this), 1000);
213
+ },
214
+ parseResultsURLQueryParameter: function() {
215
+ return window.location.search.parseQuery()["resultsURL"];
216
+ },
217
+ parseTestsQueryParameter: function(){
218
+ if (window.location.search.parseQuery()["tests"]){
219
+ return window.location.search.parseQuery()["tests"].split(',');
220
+ };
221
+ },
222
+ // Returns:
223
+ // "ERROR" if there was an error,
224
+ // "FAILURE" if there was a failure, or
225
+ // "SUCCESS" if there was neither
226
+ getResult: function() {
227
+ var hasFailure = false;
228
+ for(var i=0;i<this.tests.length;i++) {
229
+ if (this.tests[i].errors > 0) {
230
+ return "ERROR";
231
+ }
232
+ if (this.tests[i].failures > 0) {
233
+ hasFailure = true;
234
+ }
235
+ }
236
+ if (hasFailure) {
237
+ return "FAILURE";
238
+ } else {
239
+ return "SUCCESS";
240
+ }
241
+ },
242
+ postResults: function() {
243
+ if (this.options.resultsURL) {
244
+ new Ajax.Request(this.options.resultsURL,
245
+ { method: 'get', parameters: 'result=' + this.getResult(), asynchronous: false });
246
+ }
247
+ },
248
+ runTests: function() {
249
+ var test = this.tests[this.currentTest];
250
+ if (!test) {
251
+ // finished!
252
+ this.postResults();
253
+ this.logger.summary(this.summary());
254
+ document.incrementQueuedTests(-1) ;
255
+ document.setTestStatus(this.getResult()) ;
256
+ return;
257
+ }
258
+ if(!test.isWaiting) {
259
+ this.logger.start(test.name);
260
+ }
261
+ test.run();
262
+ if(test.isWaiting) {
263
+ this.logger.message("Waiting for " + test.timeToWait + "ms");
264
+ setTimeout(this.runTests.bind(this), test.timeToWait || 1000);
265
+ } else {
266
+ this.logger.finish(test.status(), test.summary());
267
+ this.currentTest++;
268
+ // tail recursive, hopefully the browser will skip the stackframe
269
+ this.runTests();
270
+ }
271
+ },
272
+ summary: function() {
273
+ var assertions = 0;
274
+ var failures = 0;
275
+ var errors = 0;
276
+ var messages = [];
277
+ for(var i=0;i<this.tests.length;i++) {
278
+ assertions += this.tests[i].assertions;
279
+ failures += this.tests[i].failures;
280
+ errors += this.tests[i].errors;
281
+ }
282
+ return (
283
+ (this.options.context ? this.options.context + ': ': '') +
284
+ this.tests.length + " tests, " +
285
+ assertions + " assertions, " +
286
+ failures + " failures, " +
287
+ errors + " errors");
288
+ }
289
+ } ;
290
+
291
+ Test.Unit.Assertions = Class.create();
292
+ Test.Unit.Assertions.prototype = {
293
+ initialize: function() {
294
+ this.assertions = 0;
295
+ this.failures = 0;
296
+ this.errors = 0;
297
+ this.messages = [];
298
+ },
299
+ summary: function() {
300
+ return (
301
+ this.assertions + " assertions, " +
302
+ this.failures + " failures, " +
303
+ this.errors + " errors" + "\n" +
304
+ this.messages.join("\n"));
305
+ },
306
+ pass: function() {
307
+ this.assertions++;
308
+ },
309
+ fail: function(message) {
310
+ this.failures++;
311
+ this.messages.push("Failure: " + message);
312
+ },
313
+ info: function(message) {
314
+ this.messages.push("Info: " + message);
315
+ },
316
+ error: function(error) {
317
+ this.errors++;
318
+ this.messages.push(error.name + ": "+ error.message + "(" + Test.Unit.inspect(error) +")");
319
+ },
320
+ status: function() {
321
+ if (this.failures > 0) return 'failed';
322
+ if (this.errors > 0) return 'error';
323
+ return 'passed';
324
+ },
325
+ assert: function(expression) {
326
+ var message = arguments[1] || 'assert: got "' + Test.Unit.inspect(expression) + '"';
327
+ try { expression ? this.pass() :
328
+ this.fail(message); }
329
+ catch(e) { this.error(e); }
330
+ },
331
+ assertEqual: function(expected, actual) {
332
+ var message = arguments[2] || "assertEqual";
333
+ try { (expected == actual) ? this.pass() :
334
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
335
+ '", actual "' + Test.Unit.inspect(actual) + '"'); }
336
+ catch(e) { this.error(e); }
337
+ },
338
+ assertInspect: function(expected, actual) {
339
+ var message = arguments[2] || "assertInspect";
340
+ try { (expected == actual.inspect()) ? this.pass() :
341
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
342
+ '", actual "' + Test.Unit.inspect(actual) + '"'); }
343
+ catch(e) { this.error(e); }
344
+ },
345
+ assertEnumEqual: function(expected, actual) {
346
+ var message = arguments[2] || "assertEnumEqual";
347
+ try { $A(expected).length == $A(actual).length &&
348
+ expected.zip(actual).all(function(pair) { return pair[0] == pair[1]; }) ?
349
+ this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
350
+ ', actual ' + Test.Unit.inspect(actual)); }
351
+ catch(e) { this.error(e); }
352
+ },
353
+ assertNotEqual: function(expected, actual) {
354
+ var message = arguments[2] || "assertNotEqual";
355
+ try { (expected != actual) ? this.pass() :
356
+ this.fail(message + ': got "' + Test.Unit.inspect(actual) + '"'); }
357
+ catch(e) { this.error(e); }
358
+ },
359
+ assertIdentical: function(expected, actual) {
360
+ var message = arguments[2] || "assertIdentical";
361
+ try { (expected === actual) ? this.pass() :
362
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
363
+ '", actual "' + Test.Unit.inspect(actual) + '"'); }
364
+ catch(e) { this.error(e); }
365
+ },
366
+ assertNotIdentical: function(expected, actual) {
367
+ var message = arguments[2] || "assertNotIdentical";
368
+ try { !(expected === actual) ? this.pass() :
369
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
370
+ '", actual "' + Test.Unit.inspect(actual) + '"'); }
371
+ catch(e) { this.error(e); }
372
+ },
373
+ assertNull: function(obj) {
374
+ var message = arguments[1] || 'assertNull' ;
375
+ try { (obj==null) ? this.pass() :
376
+ this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
377
+ catch(e) { this.error(e); }
378
+ },
379
+ assertMatch: function(expected, actual) {
380
+ var message = arguments[2] || 'assertMatch';
381
+ var regex = new RegExp(expected);
382
+ try { (regex.exec(actual)) ? this.pass() :
383
+ this.fail(message + ' : regex: "' + Test.Unit.inspect(expected) + ' did not match: ' + Test.Unit.inspect(actual) + '"'); }
384
+ catch(e) { this.error(e); }
385
+ },
386
+ assertHidden: function(element) {
387
+ var message = arguments[1] || 'assertHidden';
388
+ this.assertEqual("none", element.style.display, message);
389
+ },
390
+ assertNotNull: function(object) {
391
+ var message = arguments[1] || 'assertNotNull';
392
+ this.assert(object != null, message);
393
+ },
394
+ assertType: function(expected, actual) {
395
+ var message = arguments[2] || 'assertType';
396
+ try {
397
+ (actual.constructor == expected) ? this.pass() :
398
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
399
+ '", actual "' + (actual.constructor) + '"'); }
400
+ catch(e) { this.error(e); }
401
+ },
402
+ assertNotOfType: function(expected, actual) {
403
+ var message = arguments[2] || 'assertNotOfType';
404
+ try {
405
+ (actual.constructor != expected) ? this.pass() :
406
+ this.fail(message + ': expected "' + Test.Unit.inspect(expected) +
407
+ '", actual "' + (actual.constructor) + '"'); }
408
+ catch(e) { this.error(e); }
409
+ },
410
+ assertInstanceOf: function(expected, actual) {
411
+ var message = arguments[2] || 'assertInstanceOf';
412
+ try {
413
+ (actual instanceof expected) ? this.pass() :
414
+ this.fail(message + ": object was not an instance of the expected type"); }
415
+ catch(e) { this.error(e); }
416
+ },
417
+ assertNotInstanceOf: function(expected, actual) {
418
+ var message = arguments[2] || 'assertNotInstanceOf';
419
+ try {
420
+ !(actual instanceof expected) ? this.pass() :
421
+ this.fail(message + ": object was an instance of the not expected type"); }
422
+ catch(e) { this.error(e); }
423
+ },
424
+ assertRespondsTo: function(method, obj) {
425
+ var message = arguments[2] || 'assertRespondsTo';
426
+ try {
427
+ (obj[method] && typeof obj[method] == 'function') ? this.pass() :
428
+ this.fail(message + ": object doesn't respond to [" + method + "]"); }
429
+ catch(e) { this.error(e); }
430
+ },
431
+ assertReturnsTrue: function(method, obj) {
432
+ var message = arguments[2] || 'assertReturnsTrue';
433
+ try {
434
+ var m = obj[method];
435
+ if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
436
+ m() ? this.pass() :
437
+ this.fail(message + ": method returned false"); }
438
+ catch(e) { this.error(e); }
439
+ },
440
+ assertReturnsFalse: function(method, obj) {
441
+ var message = arguments[2] || 'assertReturnsFalse';
442
+ try {
443
+ var m = obj[method];
444
+ if(!m) m = obj['is'+method.charAt(0).toUpperCase()+method.slice(1)];
445
+ !m() ? this.pass() :
446
+ this.fail(message + ": method returned true"); }
447
+ catch(e) { this.error(e); }
448
+ },
449
+ assertRaise: function(exceptionName, method) {
450
+ var message = arguments[2] || 'assertRaise';
451
+ try {
452
+ method();
453
+ this.fail(message + ": exception expected but none was raised"); }
454
+ catch(e) {
455
+ ((exceptionName == null) || (e.name==exceptionName)) ? this.pass() : this.error(e);
456
+ }
457
+ },
458
+ assertElementsMatch: function() {
459
+ var expressions = $A(arguments), elements = $A(expressions.shift());
460
+ if (elements.length != expressions.length) {
461
+ this.fail('assertElementsMatch: size mismatch: ' + elements.length + ' elements, ' + expressions.length + ' expressions');
462
+ return false;
463
+ }
464
+ elements.zip(expressions).all(function(pair, index) {
465
+ var element = $(pair.first()), expression = pair.last();
466
+ if (element.match(expression)) return true;
467
+ this.fail('assertElementsMatch: (in index ' + index + ') expected ' + expression.inspect() + ' but got ' + element.inspect());
468
+ }.bind(this)) && this.pass();
469
+ },
470
+ assertElementMatches: function(element, expression) {
471
+ this.assertElementsMatch([element], expression);
472
+ },
473
+ benchmark: function(operation, iterations) {
474
+ var startAt = new Date();
475
+ (iterations || 1).times(operation);
476
+ var timeTaken = ((new Date())-startAt);
477
+ this.info((arguments[2] || 'Operation') + ' finished ' +
478
+ iterations + ' iterations in ' + (timeTaken/1000)+'s' );
479
+ return timeTaken;
480
+ },
481
+ _isVisible: function(element) {
482
+ element = $(element);
483
+ if(!element.parentNode) return true;
484
+ this.assertNotNull(element);
485
+ if(element.style && Element.getStyle(element, 'display') == 'none')
486
+ return false;
487
+
488
+ return this._isVisible(element.parentNode);
489
+ },
490
+ assertNotVisible: function(element) {
491
+ this.assert(!this._isVisible(element), Test.Unit.inspect(element) + " was not hidden and didn't have a hidden parent either. " + ("" || arguments[1]));
492
+ },
493
+ assertVisible: function(element) {
494
+ this.assert(this._isVisible(element), Test.Unit.inspect(element) + " was not visible. " + ("" || arguments[1]));
495
+ },
496
+ benchmark: function(operation, iterations) {
497
+ var startAt = new Date();
498
+ (iterations || 1).times(operation);
499
+ var timeTaken = ((new Date())-startAt);
500
+ this.info((arguments[2] || 'Operation') + ' finished ' +
501
+ iterations + ' iterations in ' + (timeTaken/1000)+'s' );
502
+ return timeTaken;
503
+ }
504
+ } ;
505
+
506
+ Test.Unit.Testcase = Class.create();
507
+ Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.prototype), {
508
+ initialize: function(name, test, setup, teardown) {
509
+ Test.Unit.Assertions.prototype.initialize.bind(this)();
510
+ this.name = name;
511
+
512
+ if(typeof test == 'string') {
513
+ test = test.gsub(/(\.should[^\(]+\()/,'#{0}this,');
514
+ test = test.gsub(/(\.should[^\(]+)\(this,\)/,'#{1}(this)');
515
+ this.test = function() {
516
+ eval('with(this){'+test+'}');
517
+ } ;
518
+ } else {
519
+ this.test = test || function() {};
520
+ }
521
+
522
+ this.setup = setup || function() {};
523
+ this.teardown = teardown || function() {};
524
+ this.isWaiting = false;
525
+ this.timeToWait = 1000;
526
+ },
527
+ wait: function(time, nextPart) {
528
+ this.isWaiting = true;
529
+ this.test = nextPart;
530
+ this.timeToWait = time;
531
+ },
532
+ run: function() {
533
+ try {
534
+ try {
535
+ if (!this.isWaiting) this.setup.bind(this)();
536
+ this.isWaiting = false;
537
+ this.test.bind(this)();
538
+ } finally {
539
+ if(!this.isWaiting) {
540
+ this.teardown.bind(this)();
541
+ }
542
+ }
543
+ }
544
+ catch(e) { this.error(e); }
545
+ }
546
+ });
547
+
548
+ // *EXPERIMENTAL* BDD-style testing to please non-technical folk
549
+ // This draws many ideas from RSpec http://rspec.rubyforge.org/
550
+
551
+ Test.setupBDDExtensionMethods = function(){
552
+ var METHODMAP = {
553
+ shouldEqual: 'assertEqual',
554
+ shouldNotEqual: 'assertNotEqual',
555
+ shouldEqualEnum: 'assertEnumEqual',
556
+ shouldBeA: 'assertType',
557
+ shouldNotBeA: 'assertNotOfType',
558
+ shouldBeAn: 'assertType',
559
+ shouldNotBeAn: 'assertNotOfType',
560
+ shouldBeNull: 'assertNull',
561
+ shouldNotBeNull: 'assertNotNull',
562
+
563
+ shouldBe: 'assertReturnsTrue',
564
+ shouldNotBe: 'assertReturnsFalse',
565
+ shouldRespondTo: 'assertRespondsTo'
566
+ };
567
+ var makeAssertion = function(assertion, args, object) {
568
+ this[assertion].apply(this,(args || []).concat([object]));
569
+ } ;
570
+
571
+ Test.BDDMethods = {};
572
+ $H(METHODMAP).each(function(pair) {
573
+ Test.BDDMethods[pair.key] = function() {
574
+ var args = $A(arguments);
575
+ var scope = args.shift();
576
+ makeAssertion.apply(scope, [pair.value, args, this]); };
577
+ });
578
+
579
+ [Array.prototype, String.prototype, Number.prototype, Boolean.prototype].each(
580
+ function(p){ Object.extend(p, Test.BDDMethods); }
581
+ );
582
+ } ;
583
+
584
+ Test.context = function(name, spec, log){
585
+ Test.setupBDDExtensionMethods();
586
+
587
+ var compiledSpec = {};
588
+ var titles = {};
589
+ for(specName in spec) {
590
+ switch(specName){
591
+ case "setup":
592
+ case "teardown":
593
+ compiledSpec[specName] = spec[specName];
594
+ break;
595
+ default:
596
+ var testName = 'test'+specName.gsub(/\s+/,'-').camelize();
597
+ var body = spec[specName].toString().split('\n').slice(1);
598
+ if(/^\{/.test(body[0])) body = body.slice(1);
599
+ body.pop();
600
+ body = body.map(function(statement){
601
+ return statement.strip() ;
602
+ });
603
+ compiledSpec[testName] = body.join('\n');
604
+ titles[testName] = specName;
605
+ }
606
+ }
607
+
608
+ // create a DIV for the log if needed.
609
+ if (log === undefined) log = name.dasherize() ;
610
+
611
+ new Test.Unit.Runner(compiledSpec, { titles: titles, testLog: (log || 'testlog'), context: name });
612
+
613
+ };
614
+
615
+ Test.Observer = function()
616
+ {
617
+ return function() {
618
+ if (!arguments.callee.notified) arguments.callee.notified = 0;
619
+ return ++arguments.callee.notified;
620
+ };
621
+ }
622
+
@@ -0,0 +1,61 @@
1
+ // ==========================================================================
2
+ // SproutCore -- JavaScript Application Framework
3
+ // copyright 2006-2007, Sprout Systems, Inc. and contributors.
4
+ // ==========================================================================
5
+
6
+ // These are helpful utility functions.
7
+
8
+
9
+ Object.extend(SC,
10
+ /** @scope SC */
11
+ {
12
+
13
+ /** Return the left edge of the frame */
14
+ minX: function(frame) {
15
+ return frame.x;
16
+ },
17
+
18
+ /** Return the right edge of the frame. */
19
+ maxX: function(frame) {
20
+ return frame.x + frame.width;
21
+ },
22
+
23
+ /** Return the midpoint of the frame. */
24
+ midX: function(frame) {
25
+ return frame.x + (frame.width / 2) ;
26
+ },
27
+
28
+ /** Return the top edge of the frame */
29
+ minY: function(frame) {
30
+ return frame.y ;
31
+ },
32
+
33
+ /** Return the bottom edge of the frame */
34
+ maxY: function(frame) {
35
+ return frame.y + frame.height ;
36
+ },
37
+
38
+ /** Return the midpoint of the frame */
39
+ midY: function(frame) {
40
+ return frame.y + (frame.height / 2) ;
41
+ },
42
+
43
+ /** Returns the point that will center the frame X within the passed frame. */
44
+ centerX: function(innerFrame, outerFrame) {
45
+ return (outerFrame.width - innerFrame.width) / 2 ;
46
+ },
47
+
48
+ /** Return the point that will center the frame Y within the passed frame. */
49
+ centerY: function(innerFrame, outerFrame) {
50
+ return (outerFrame.width - innerFrame.width) /2 ;
51
+ },
52
+
53
+ /** Check if the given point is inside the rect. */
54
+ pointInRect: function(point, f) {
55
+ return (point.x >= SC.minX(f)) &&
56
+ (point.y >= SC.minY(f)) &&
57
+ (point.x <= SC.maxX(f)) &&
58
+ (point.y <= SC.maxY(f)) ;
59
+ }
60
+
61
+ }) ;