jazz-jss 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (215) hide show
  1. data/dist/handlebars/handlebars.js +1493 -0
  2. data/dist/hashchange/{jquery.ba-hashchange.js → hashchange.js} +0 -0
  3. data/dist/jazz/lib/controller.js +1 -1
  4. data/dist/jazz/lib/core.js +3 -0
  5. data/dist/jazz/lib/db.js +1 -1
  6. data/dist/jazz/lib/helper.js +2 -1
  7. data/dist/jazz/lib/model.js +11 -4
  8. data/dist/jazz/lib/view.js +1 -1
  9. data/dist/jazz/module.js +15 -0
  10. data/dist/jquery/jquery.js +0 -0
  11. data/dist/require/require.js +0 -0
  12. data/dist/require/template.js +98 -0
  13. data/dist/underscore/underscore.js +0 -0
  14. data/lib/jazz/app_detector.rb +6 -3
  15. data/lib/jazz/app_generator.rb +12 -8
  16. data/lib/jazz/helper_generator.rb +30 -0
  17. data/lib/jazz/scaffold_generator.rb +4 -0
  18. data/templates/app_root/Rakefile +11 -0
  19. data/templates/app_root/{app → development/app}/assets/javascripts/application.js +0 -0
  20. data/templates/app_root/{app → development/app}/assets/stylesheets/application.css +0 -0
  21. data/templates/app_root/development/app/controllers/application_controller.js +11 -0
  22. data/templates/app_root/development/app/helpers/application_helper.js +7 -0
  23. data/templates/app_root/development/config/glue.js +9 -0
  24. data/templates/app_root/development/config/routes.js +5 -0
  25. data/templates/app_root/scripts/build.js +30 -0
  26. data/templates/app_root/scripts/r.js/LICENSE +58 -0
  27. data/templates/app_root/scripts/r.js/README.md +177 -0
  28. data/templates/app_root/scripts/r.js/build/build.js +26 -0
  29. data/templates/app_root/scripts/r.js/build/buildebug.sh +4 -0
  30. data/templates/app_root/scripts/r.js/build/example.build.js +296 -0
  31. data/templates/app_root/scripts/r.js/build/jslib/blank.js +4 -0
  32. data/templates/app_root/scripts/r.js/build/jslib/build.js +952 -0
  33. data/templates/app_root/scripts/r.js/build/jslib/commandLine.js +23 -0
  34. data/templates/app_root/scripts/r.js/build/jslib/commonJs.js +152 -0
  35. data/templates/app_root/scripts/r.js/build/jslib/env.js +47 -0
  36. data/templates/app_root/scripts/r.js/build/jslib/lang.js +49 -0
  37. data/templates/app_root/scripts/r.js/build/jslib/logger.js +58 -0
  38. data/templates/app_root/scripts/r.js/build/jslib/node.js +106 -0
  39. data/templates/app_root/scripts/r.js/build/jslib/node/args.js +20 -0
  40. data/templates/app_root/scripts/r.js/build/jslib/node/file.js +263 -0
  41. data/templates/app_root/scripts/r.js/build/jslib/node/load.js +17 -0
  42. data/templates/app_root/scripts/r.js/build/jslib/node/optimize.js +10 -0
  43. data/templates/app_root/scripts/r.js/build/jslib/node/print.js +16 -0
  44. data/templates/app_root/scripts/r.js/build/jslib/optimize.js +279 -0
  45. data/templates/app_root/scripts/r.js/build/jslib/opto.build.js +11 -0
  46. data/templates/app_root/scripts/r.js/build/jslib/parse.js +590 -0
  47. data/templates/app_root/scripts/r.js/build/jslib/pragma.js +251 -0
  48. data/templates/app_root/scripts/r.js/build/jslib/requirePatch.js +286 -0
  49. data/templates/app_root/scripts/r.js/build/jslib/rhino.js +22 -0
  50. data/templates/app_root/scripts/r.js/build/jslib/rhino/args.js +21 -0
  51. data/templates/app_root/scripts/r.js/build/jslib/rhino/file.js +244 -0
  52. data/templates/app_root/scripts/r.js/build/jslib/rhino/load.js +12 -0
  53. data/templates/app_root/scripts/r.js/build/jslib/rhino/optimize.js +100 -0
  54. data/templates/app_root/scripts/r.js/build/jslib/rhino/print.js +12 -0
  55. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/README.md +16 -0
  56. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/index.js +21 -0
  57. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/parse-js.js +1342 -0
  58. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/process.js +2005 -0
  59. data/templates/app_root/scripts/r.js/build/jslib/uglifyjs/squeeze-more.js +55 -0
  60. data/templates/app_root/scripts/r.js/build/jslib/x.js +243 -0
  61. data/templates/app_root/scripts/r.js/build/tests/all.js +47 -0
  62. data/templates/app_root/scripts/r.js/build/tests/allj.sh +3 -0
  63. data/templates/app_root/scripts/r.js/build/tests/alln.sh +18 -0
  64. data/templates/app_root/scripts/r.js/build/tests/anonSimple.build.js +7 -0
  65. data/templates/app_root/scripts/r.js/build/tests/buildUtils.js +19 -0
  66. data/templates/app_root/scripts/r.js/build/tests/builds.js +489 -0
  67. data/templates/app_root/scripts/r.js/build/tests/circular.build.js +18 -0
  68. data/templates/app_root/scripts/r.js/build/tests/convert.js +18 -0
  69. data/templates/app_root/scripts/r.js/build/tests/css.build.js +6 -0
  70. data/templates/app_root/scripts/r.js/build/tests/css/common/common.css +4 -0
  71. data/templates/app_root/scripts/r.js/build/tests/css/master.css +10 -0
  72. data/templates/app_root/scripts/r.js/build/tests/css/sub/sub1.css +7 -0
  73. data/templates/app_root/scripts/r.js/build/tests/cssTestCompare.css +13 -0
  74. data/templates/app_root/scripts/r.js/build/tests/end.frag +3 -0
  75. data/templates/app_root/scripts/r.js/build/tests/expected/unoExcludeShallow.js +23 -0
  76. data/templates/app_root/scripts/r.js/build/tests/exports.build.js +12 -0
  77. data/templates/app_root/scripts/r.js/build/tests/hasTestModule.build.js +10 -0
  78. data/templates/app_root/scripts/r.js/build/tests/hasTestModule.js +30 -0
  79. data/templates/app_root/scripts/r.js/build/tests/http/httpBuild.js +70 -0
  80. data/templates/app_root/scripts/r.js/build/tests/http/main.html +28 -0
  81. data/templates/app_root/scripts/r.js/build/tests/http/scripts/main.js +18 -0
  82. data/templates/app_root/scripts/r.js/build/tests/http/scripts/one.js +3 -0
  83. data/templates/app_root/scripts/r.js/build/tests/http/scripts/three.js +5 -0
  84. data/templates/app_root/scripts/r.js/build/tests/http/scripts/two.js +7 -0
  85. data/templates/app_root/scripts/r.js/build/tests/i18n.build.js +17 -0
  86. data/templates/app_root/scripts/r.js/build/tests/indexBuilder.build.js +8 -0
  87. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/a.js +17 -0
  88. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/b.js +8 -0
  89. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/build.js +6 -0
  90. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/c.js +7 -0
  91. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/d.js +5 -0
  92. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/expected.js +36 -0
  93. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/node_modules/amdefine/LICENSE +58 -0
  94. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/node_modules/amdefine/amdefine.js +188 -0
  95. data/templates/app_root/scripts/r.js/build/tests/lib/amdefine/node_modules/amdefine/package.json +21 -0
  96. data/templates/app_root/scripts/r.js/build/tests/lib/comments/bang.js +10 -0
  97. data/templates/app_root/scripts/r.js/build/tests/lib/comments/build.js +6 -0
  98. data/templates/app_root/scripts/r.js/build/tests/lib/comments/expected.js +9 -0
  99. data/templates/app_root/scripts/r.js/build/tests/lib/comments/license.js +13 -0
  100. data/templates/app_root/scripts/r.js/build/tests/lib/dotpackage/scripts/app.build.js +15 -0
  101. data/templates/app_root/scripts/r.js/build/tests/lib/dotpackage/scripts/main-expected.js +13 -0
  102. data/templates/app_root/scripts/r.js/build/tests/lib/dotpackage/scripts/main.js +7 -0
  103. data/templates/app_root/scripts/r.js/build/tests/lib/empty/build.js +13 -0
  104. data/templates/app_root/scripts/r.js/build/tests/lib/empty/expected.js +8 -0
  105. data/templates/app_root/scripts/r.js/build/tests/lib/empty/main.js +1 -0
  106. data/templates/app_root/scripts/r.js/build/tests/lib/empty/sub1.js +1 -0
  107. data/templates/app_root/scripts/r.js/build/tests/lib/empty/sub2.js +1 -0
  108. data/templates/app_root/scripts/r.js/build/tests/lib/nameInsertion/build.js +6 -0
  109. data/templates/app_root/scripts/r.js/build/tests/lib/nameInsertion/expected.js +12 -0
  110. data/templates/app_root/scripts/r.js/build/tests/lib/nameInsertion/main.js +9 -0
  111. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/build.js +8 -0
  112. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/expected.js +47 -0
  113. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/main.js +6 -0
  114. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/four.js +7 -0
  115. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/one.js +9 -0
  116. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/three.js +14 -0
  117. data/templates/app_root/scripts/r.js/build/tests/lib/namespace/modules/two.js +5 -0
  118. data/templates/app_root/scripts/r.js/build/tests/lib/nested/a.js +12 -0
  119. data/templates/app_root/scripts/r.js/build/tests/lib/nested/b.js +3 -0
  120. data/templates/app_root/scripts/r.js/build/tests/lib/nested/build.js +6 -0
  121. data/templates/app_root/scripts/r.js/build/tests/lib/nested/buildWithCE.js +7 -0
  122. data/templates/app_root/scripts/r.js/build/tests/lib/nested/c.js +3 -0
  123. data/templates/app_root/scripts/r.js/build/tests/lib/nested/d.js +3 -0
  124. data/templates/app_root/scripts/r.js/build/tests/lib/nested/e.js +3 -0
  125. data/templates/app_root/scripts/r.js/build/tests/lib/nested/expected-built.js +36 -0
  126. data/templates/app_root/scripts/r.js/build/tests/lib/nested/expected-builtWithCE.js +42 -0
  127. data/templates/app_root/scripts/r.js/build/tests/lib/nested/main.js +3 -0
  128. data/templates/app_root/scripts/r.js/build/tests/lib/nested/top.js +10 -0
  129. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/a.js +3 -0
  130. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/b.js +3 -0
  131. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/build.js +6 -0
  132. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedAll.js +9 -0
  133. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedB.js +11 -0
  134. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedC.js +11 -0
  135. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNeedD.js +11 -0
  136. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/buildNested.js +7 -0
  137. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/c.js +3 -0
  138. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/d.js +3 -0
  139. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-built.js +21 -0
  140. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedAll.js +31 -0
  141. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedB.js +24 -0
  142. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedC.js +24 -0
  143. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNeedD.js +25 -0
  144. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/expected-builtNested.js +31 -0
  145. data/templates/app_root/scripts/r.js/build/tests/lib/nestedHas/main.js +17 -0
  146. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/build.js +6 -0
  147. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/converter.js +11 -0
  148. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/main.js +6 -0
  149. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/plug.js +29 -0
  150. data/templates/app_root/scripts/r.js/build/tests/lib/plugins/util.js +7 -0
  151. data/templates/app_root/scripts/r.js/build/tests/nameOnly.build.js +10 -0
  152. data/templates/app_root/scripts/r.js/build/tests/nodeAll.js +3 -0
  153. data/templates/app_root/scripts/r.js/build/tests/nodeOptimize.js +12 -0
  154. data/templates/app_root/scripts/r.js/build/tests/nodeOptimizeNoCallback.js +10 -0
  155. data/templates/app_root/scripts/r.js/build/tests/order.build.js +16 -0
  156. data/templates/app_root/scripts/r.js/build/tests/override/override.js +36 -0
  157. data/templates/app_root/scripts/r.js/build/tests/packages.build.js +59 -0
  158. data/templates/app_root/scripts/r.js/build/tests/parse.js +103 -0
  159. data/templates/app_root/scripts/r.js/build/tests/simple.build.js +13 -0
  160. data/templates/app_root/scripts/r.js/build/tests/simpleNamespace.build.js +17 -0
  161. data/templates/app_root/scripts/r.js/build/tests/start.frag +4 -0
  162. data/templates/app_root/scripts/r.js/build/tests/text.build.js +16 -0
  163. data/templates/app_root/scripts/r.js/build/tests/textExclude.build.js +16 -0
  164. data/templates/app_root/scripts/r.js/dist.js +95 -0
  165. data/templates/app_root/scripts/r.js/dist/README.md +6 -0
  166. data/templates/app_root/scripts/r.js/dist/r-1.0.0.js +9042 -0
  167. data/templates/app_root/scripts/r.js/dist/r-edge.js +9191 -0
  168. data/templates/app_root/scripts/r.js/dist/r.js +9099 -0
  169. data/templates/app_root/scripts/r.js/lib/closure/COPYING +202 -0
  170. data/templates/app_root/scripts/r.js/lib/closure/README +292 -0
  171. data/templates/app_root/scripts/r.js/lib/closure/compiler.jar +0 -0
  172. data/templates/app_root/scripts/r.js/lib/rhino/LICENSE +4 -0
  173. data/templates/app_root/scripts/r.js/lib/rhino/js.jar +0 -0
  174. data/templates/app_root/scripts/r.js/require.js +1952 -0
  175. data/templates/app_root/scripts/r.js/tasks.txt +2 -0
  176. data/templates/app_root/scripts/r.js/tests/all.js +49 -0
  177. data/templates/app_root/scripts/r.js/tests/allNode.js +3 -0
  178. data/templates/app_root/scripts/r.js/tests/allj.sh +1 -0
  179. data/templates/app_root/scripts/r.js/tests/alln.sh +2 -0
  180. data/templates/app_root/scripts/r.js/tests/alpha.js +3 -0
  181. data/templates/app_root/scripts/r.js/tests/beta.js +6 -0
  182. data/templates/app_root/scripts/r.js/tests/doh/LICENSE +195 -0
  183. data/templates/app_root/scripts/r.js/tests/doh/README +12 -0
  184. data/templates/app_root/scripts/r.js/tests/doh/_browserRunner.js +855 -0
  185. data/templates/app_root/scripts/r.js/tests/doh/_nodeRunner.js +20 -0
  186. data/templates/app_root/scripts/r.js/tests/doh/_rhinoRunner.js +17 -0
  187. data/templates/app_root/scripts/r.js/tests/doh/_sounds/LICENSE +10 -0
  188. data/templates/app_root/scripts/r.js/tests/doh/_sounds/doh.wav +0 -0
  189. data/templates/app_root/scripts/r.js/tests/doh/_sounds/dohaaa.wav +0 -0
  190. data/templates/app_root/scripts/r.js/tests/doh/_sounds/woohoo.wav +0 -0
  191. data/templates/app_root/scripts/r.js/tests/doh/runner.html +316 -0
  192. data/templates/app_root/scripts/r.js/tests/doh/runner.js +1499 -0
  193. data/templates/app_root/scripts/r.js/tests/doh/runner.sh +3 -0
  194. data/templates/app_root/scripts/r.js/tests/doh/small_logo.png +0 -0
  195. data/templates/app_root/scripts/r.js/tests/node/canvasTest.js +39 -0
  196. data/templates/app_root/scripts/r.js/tests/node/embedded/README.md +15 -0
  197. data/templates/app_root/scripts/r.js/tests/node/embedded/coffee/foo.coffee +1 -0
  198. data/templates/app_root/scripts/r.js/tests/node/embedded/main.js +13 -0
  199. data/templates/app_root/scripts/r.js/tests/node/embedded/scripts/bar.js +13 -0
  200. data/templates/app_root/scripts/r.js/tests/node/index.js +11 -0
  201. data/templates/app_root/scripts/r.js/tests/node/tests/alpha/foo.js +6 -0
  202. data/templates/app_root/scripts/r.js/tests/node/tests/alpha/hello.html +9 -0
  203. data/templates/app_root/scripts/r.js/tests/node/tests/foo.js +3 -0
  204. data/templates/app_root/scripts/r.js/tests/node/tests/server.js +11 -0
  205. data/templates/app_root/scripts/r.js/tests/relative.js +10 -0
  206. data/templates/app_root/scripts/r.js/tests/sub/betaSub.js +3 -0
  207. data/templates/application.js +6 -5
  208. data/templates/boot.js +42 -0
  209. data/templates/helper.js +9 -0
  210. data/templates/index.html +1 -1
  211. metadata +201 -11
  212. data/dist/jazz/main.js +0 -65
  213. data/dist/mustache/mustache.js +0 -324
  214. data/templates/app_root/config/routes.js +0 -4
  215. data/templates/glue.js +0 -4
@@ -0,0 +1,20 @@
1
+
2
+ /*global doh: false, process: false */
3
+
4
+ var aps = Array.prototype.slice;
5
+
6
+ doh.debug = function () {
7
+ //Could have multiple args, join them all together.
8
+ var msg = aps.call(arguments, 0).join(' ');
9
+ console.log(msg);
10
+ };
11
+
12
+ // Override the doh._report method to make it quit with an
13
+ // appropriate exit code in case of test failures.
14
+ var oldReport = doh._report;
15
+ doh._report = function () {
16
+ oldReport.apply(doh, arguments);
17
+ if (this._failureCount > 0 || this._errorCount > 0) {
18
+ process.exit(1);
19
+ }
20
+ };
@@ -0,0 +1,17 @@
1
+ if(this["dojo"]){
2
+ dojo.provide("doh._rhinoRunner");
3
+ }
4
+
5
+ doh.debug = print;
6
+
7
+ // Override the doh._report method to make it quit with an
8
+ // appropriate exit code in case of test failures.
9
+ (function(){
10
+ var oldReport = doh._report;
11
+ doh._report = function(){
12
+ oldReport.apply(doh, arguments);
13
+ if(this._failureCount > 0 || this._errorCount > 0){
14
+ quit(1);
15
+ }
16
+ }
17
+ })();
@@ -0,0 +1,10 @@
1
+ License Disclaimer:
2
+
3
+ All contents of this directory are Copyright (c) the Dojo Foundation, with the
4
+ following exceptions:
5
+ -------------------------------------------------------------------------------
6
+
7
+ woohoo.wav, doh.wav, dohaaa.wav:
8
+ * Copyright original authors.
9
+ Copied from:
10
+ http://simpson-homer.com/homer-simpson-soundboard.html
@@ -0,0 +1,316 @@
1
+ <html>
2
+ <!--
3
+ NOTE: we are INTENTIONALLY in quirks mode. It makes it much easier to
4
+ get a "full screen" UI w/ straightforward CSS.
5
+ -->
6
+ <!--
7
+ // TODO: provide a UI for prompted tests
8
+ -->
9
+ <head>
10
+ <title>RequireJS Tests Via The Dojo Unit Test Harness, $Rev: 20149 $</title>
11
+
12
+ <script type="text/javascript">
13
+ // workaround for bug in Safari 3. See #7189
14
+ if (/3[\.0-9]+ Safari/.test(navigator.appVersion))
15
+ {
16
+ window.console = {
17
+ origConsole: window.console,
18
+ log: function(s){
19
+ this.origConsole.log(s);
20
+ },
21
+ info: function(s){
22
+ this.origConsole.info(s);
23
+ },
24
+ error: function(s){
25
+ this.origConsole.error(s);
26
+ },
27
+ warn: function(s){
28
+ this.origConsole.warn(s);
29
+ }
30
+ };
31
+ }
32
+ </script>
33
+
34
+ <script type="text/javascript">
35
+ window.dojoUrl = "../../dojo/dojo.js";
36
+ window.testUrl = "";
37
+ window.testModule = "";
38
+
39
+ // parse out our test URL and our Dojo URL from the query string
40
+ var qstr = window.location.search.substr(1);
41
+ if(qstr.length){
42
+ var qparts = qstr.split("&");
43
+ for(var x=0; x<qparts.length; x++){
44
+ var tp = qparts[x].split("=");
45
+ if(tp[0] == "dojoUrl"){
46
+ window.dojoUrl = tp[1];
47
+ }
48
+ if(tp[0] == "testUrl"){
49
+ window.testUrl = tp[1];
50
+ }
51
+ if(tp[0] == "testModule"){
52
+ window.testModule = tp[1];
53
+ }
54
+ if(tp[0] == "registerModulePath"){
55
+ var modules = tp[1].split(";");
56
+ window.registerModulePath=[];
57
+ for (var i=0; i<modules.length;i++){
58
+ window.registerModulePath.push(modules[i].split(","));
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ //document.write("<scr"+"ipt type='text/javascript' djConfig='isDebug: true' src='"+dojoUrl+"'></scr"+"ipt>");
65
+ </script>
66
+ <script type="text/javascript" src="runner.js"></script>
67
+ <script type="text/javascript" src="_browserRunner.js"></script>
68
+
69
+ <script type="text/javascript">
70
+ if(testUrl.length){
71
+ document.write("<scr"+"ipt type='text/javascript' src='"+testUrl+".js'></scr"+"ipt>");
72
+ }
73
+ </script>
74
+ <style type="text/css">
75
+ /* @import "../../dojo/resources/dojo.css"; */
76
+ /*
77
+ body {
78
+ margin: 0px;
79
+ padding: 0px;
80
+ font-size: 13px;
81
+ color: #292929;
82
+ font-family: Myriad, Lucida Grande, Bitstream Vera Sans, Arial, Helvetica, sans-serif;
83
+ *font-size: small;
84
+ *font: x-small;
85
+ }
86
+
87
+ th, td {
88
+ font-size: 13px;
89
+ color: #292929;
90
+ font-family: Myriad, Lucida Grande, Bitstream Vera Sans, Arial, Helvetica, sans-serif;
91
+ font-weight: normal;
92
+ }
93
+
94
+ * body {
95
+ line-height: 1.25em;
96
+ }
97
+
98
+ table {
99
+ border-collapse: collapse;
100
+ }
101
+ */
102
+
103
+ #testLayout {
104
+ position: relative;
105
+ left: 0px;
106
+ top: 0px;
107
+ width: 100%;
108
+ height: 100%;
109
+ border: 1px solid black;
110
+ border: 0px;
111
+ }
112
+
113
+ .tabBody {
114
+ margin: 0px;
115
+ padding: 0px;
116
+ /*
117
+ border: 1px solid black;
118
+ */
119
+ background-color: #DEDEDE;
120
+ border: 0px;
121
+ width: 100%;
122
+ height: 100%;
123
+ position: absolute;
124
+ left: 0px;
125
+ top: 0px;
126
+ overflow: auto;
127
+ }
128
+
129
+ #logBody {
130
+ padding-left: 5px;
131
+ padding-top: 5px;
132
+ font-family: Monaco, monospace;
133
+ font-size: 11px;
134
+ white-space: pre;
135
+ }
136
+
137
+ #progressOuter {
138
+ background:#e9e9e9 url("http://o.aolcdn.com/dojo/1.3/dijit/themes/tundra/images/dojoTundraGradientBg.png") repeat-x 0 0;
139
+ height: 1em;
140
+ /*the following trick is necessary to prevent IE from wrapping the last piece of progress bar into a new line*/
141
+ _margin:1px;
142
+ _padding: -1px;
143
+
144
+ /*
145
+ border-color: #e8e8e8;
146
+ */
147
+ }
148
+
149
+ #progressOuter .success, #progressOuter .failure{
150
+ float: left;
151
+ height: 1em;
152
+ }
153
+
154
+ #play, #pause {
155
+ font-family: Arial;
156
+ font-size: 1.4em;
157
+ border: 1px solid #DEDEDE;
158
+ cursor: pointer;
159
+ padding-right: 0.5em;
160
+ }
161
+
162
+ .header {
163
+ border: 1px solid #DEDEDE;
164
+ }
165
+
166
+ button.tab {
167
+ border-width: 1px 1px 0px 1px;
168
+ border-style: solid;
169
+ border-color: #DEDEDE;
170
+ margin-right: 5px;
171
+ }
172
+
173
+ #testListContainer {
174
+ /*
175
+ border: 1px solid black;
176
+ */
177
+ position: relative;
178
+ height: 99%;
179
+ width: 100%;
180
+ overflow: auto;
181
+ }
182
+
183
+ #testList {
184
+ border-collapse: collapse;
185
+ position: absolute;
186
+ left: 0px;
187
+ width: 100%;
188
+ }
189
+
190
+ #testList td {
191
+ border-bottom: 1px solid #DEDEDE;
192
+ border-right : 1px solid #DEDEDE;
193
+ padding: 3px;
194
+ }
195
+
196
+ #testListHeader th {
197
+ border-bottom: 1px solid #DEDEDE;
198
+ border-right : 1px solid #DEDEDE;
199
+ padding: 3px;
200
+ font-weight: bolder;
201
+ font-style: italic;
202
+ }
203
+
204
+ #testList tfoot {
205
+ font-weight: bold;
206
+ }
207
+
208
+ #toggleButtons {
209
+ float: left;
210
+ background-color: #DEDEDE;
211
+ }
212
+
213
+ div.testGroupName {
214
+ position: absolute;
215
+ }
216
+
217
+ .inProgress {
218
+ background-color: #85afde;
219
+ }
220
+
221
+ .success {
222
+ background-color: #7cdea7;
223
+ }
224
+
225
+ .failure {
226
+ background-color: #de827b;
227
+ }
228
+ </style>
229
+ </head>
230
+ <body>
231
+ <table id="testLayout" cellpadding="0" cellspacing="0" style="margin: 0;">
232
+ <tr valign="top" height="40">
233
+ <td colspan="2" id="logoBar">
234
+ <h3 style="margin: 5px 5px 0px 5px; float: left;">RequireJS Tests Via D.O.H.: The Dojo Objective Harness</h3>
235
+ <img src="small_logo.png" height="40" style="margin: 0px 5px 0px 5px; float: right;">
236
+ <span style="margin: 10px 5px 0px 5px; float: right;">
237
+ <input type="checkbox" id="audio" name="audio">
238
+ <label for="audio">sounds?</label>
239
+ </span>
240
+ </td>
241
+ </tr>
242
+ <tr valign="top" height="10">
243
+ <td colspan="2"><div id="progressOuter" onclick="doh._jumpToSuite(arguments[0]);"></div></td>
244
+ </tr>
245
+ <tr valign="top" height="30">
246
+ <td width="30%" class="header">
247
+ <span id="toggleButtons" onclick="doh.togglePaused();">
248
+ <button id="play">&#9658;</button>
249
+ <button id="pause" style="display: none;">&#9553;</button>
250
+ </span>
251
+ <span id="runningStatus">
252
+ <span id="pausedMsg">Stopped</span>
253
+ <span id="playingMsg" style="display: none;">Tests Running</span>
254
+ </span>
255
+ </td>
256
+ <td width="*" class="header" valign="bottom">
257
+ <button class="tab" onclick="doh.showTestPage();">Test Page</button>
258
+ <button class="tab" onclick="doh.showLogPage();">Log</button>
259
+ <button class="tab" onclick="doh.showPerfTestsPage();">Performance Tests Results</button>
260
+ </td>
261
+ </tr>
262
+ <tr valign="top" style="border: 0; padding: 0; margin: 0;">
263
+ <td height="100%" style="border: 0; padding: 0; margin: 0;">
264
+ <div id="testListContainer">
265
+ <table cellpadding="0" cellspacing="0" border="0"
266
+ width="100%" id="testList" style="margin: 0;" onclick="doh._jumpToLog(arguments[0]);">
267
+ <thead>
268
+ <tr id="testListHeader" style="border: 0; padding: 0; margin: 0;" >
269
+ <th>&nbsp;</th>
270
+ <th width="20">
271
+ <input type="checkbox" checked
272
+ onclick="doh.toggleRunAll();">
273
+ </th>
274
+ <th width="*" style="text-align: left;">test</th>
275
+ <th width="50">time</th>
276
+ </tr>
277
+ </thead>
278
+ <tbody valign="top">
279
+ <tr id="groupTemplate" style="display: none;">
280
+ <td style="font-family: Arial; width: 15px;">&#9658;</td>
281
+ <td>
282
+ <input type="checkbox" checked>
283
+ </td>
284
+ <td>group name</td>
285
+ <td>10ms</td>
286
+ </tr>
287
+ <tr id="testTemplate" style="display: none;">
288
+ <td>&nbsp;</td>
289
+ <td>&nbsp;</td>
290
+ <td style="padding-left: 20px;">test name</td>
291
+ <td>10ms</td>
292
+ </tr>
293
+ </tbody>
294
+ </table>
295
+ </div>
296
+ </td>
297
+ <td>
298
+ <div style="position: relative; width: 99%; height: 100%; top: 0px; left: 0px;">
299
+ <div class="tabBody"
300
+ style="z-index: 1;">
301
+ <pre id="logBody"></pre>
302
+ <div id="perfTestsBody" style="background-color: white;"></div>
303
+ </div>
304
+ <iframe id="testBody" class="tabBody"
305
+ style="z-index: -1;"></iframe>
306
+ <!--
307
+ src="http://redesign.dojotoolkit.org"></iframe>
308
+ -->
309
+ </div>
310
+ </td>
311
+ </tr>
312
+ </table>
313
+ <span id="hiddenAudio"></span>
314
+ </body>
315
+ </html>
316
+
@@ -0,0 +1,1499 @@
1
+ // package system gunk.
2
+ //try{
3
+ // dojo.provide("doh.runner");
4
+ //}catch(e){
5
+ if(!this["doh"]){
6
+ doh = {};
7
+ }
8
+ //}
9
+
10
+ //
11
+ // Utility Functions and Classes
12
+ //
13
+
14
+ doh.selfTest = false;
15
+
16
+ doh.global = this;
17
+
18
+ doh.hitch = function(/*Object*/thisObject, /*Function|String*/method /*, ...*/){
19
+ var args = [];
20
+ for(var x=2; x<arguments.length; x++){
21
+ args.push(arguments[x]);
22
+ }
23
+ var fcn = ((typeof method == "string") ? thisObject[method] : method) || function(){};
24
+ return function(){
25
+ var ta = args.concat([]); // make a copy
26
+ for(var x=0; x<arguments.length; x++){
27
+ ta.push(arguments[x]);
28
+ }
29
+ return fcn.apply(thisObject, ta); // Function
30
+ };
31
+ }
32
+
33
+ doh._mixin = function(/*Object*/ obj, /*Object*/ props){
34
+ // summary:
35
+ // Adds all properties and methods of props to obj. This addition is
36
+ // "prototype extension safe", so that instances of objects will not
37
+ // pass along prototype defaults.
38
+ var tobj = {};
39
+ for(var x in props){
40
+ // the "tobj" condition avoid copying properties in "props"
41
+ // inherited from Object.prototype. For example, if obj has a custom
42
+ // toString() method, don't overwrite it with the toString() method
43
+ // that props inherited from Object.protoype
44
+ if(tobj[x] === undefined || tobj[x] != props[x]){
45
+ obj[x] = props[x];
46
+ }
47
+ }
48
+ // IE doesn't recognize custom toStrings in for..in
49
+ if( this["document"]
50
+ && document.all
51
+ && (typeof props["toString"] == "function")
52
+ && (props["toString"] != obj["toString"])
53
+ && (props["toString"] != tobj["toString"])
54
+ ){
55
+ obj.toString = props.toString;
56
+ }
57
+ return obj; // Object
58
+ }
59
+
60
+ doh.mixin = function(/*Object*/obj, /*Object...*/props){
61
+ // summary: Adds all properties and methods of props to obj.
62
+ for(var i=1, l=arguments.length; i<l; i++){
63
+ doh._mixin(obj, arguments[i]);
64
+ }
65
+ return obj; // Object
66
+ }
67
+
68
+ doh.extend = function(/*Object*/ constructor, /*Object...*/ props){
69
+ // summary:
70
+ // Adds all properties and methods of props to constructor's
71
+ // prototype, making them available to all instances created with
72
+ // constructor.
73
+ for(var i=1, l=arguments.length; i<l; i++){
74
+ doh._mixin(constructor.prototype, arguments[i]);
75
+ }
76
+ return constructor; // Object
77
+ }
78
+
79
+
80
+ doh._line = "------------------------------------------------------------";
81
+
82
+ /*
83
+ doh._delegate = function(obj, props){
84
+ // boodman-crockford delegation
85
+ function TMP(){};
86
+ TMP.prototype = obj;
87
+ var tmp = new TMP();
88
+ if(props){
89
+ dojo.lang.mixin(tmp, props);
90
+ }
91
+ return tmp;
92
+ }
93
+ */
94
+
95
+ doh.debug = function(){
96
+ // summary:
97
+ // takes any number of arguments and sends them to whatever debugging
98
+ // or logging facility is available in this environment
99
+
100
+ // YOUR TEST RUNNER NEEDS TO IMPLEMENT THIS
101
+ }
102
+
103
+ doh._AssertFailure = function(msg, hint){
104
+ // idea for this as way of dis-ambiguating error types is from JUM.
105
+ // The JUM is dead! Long live the JUM!
106
+
107
+ if(!(this instanceof doh._AssertFailure)){
108
+ return new doh._AssertFailure(msg, hint);
109
+ }
110
+ if(hint){
111
+ msg = (new String(msg||""))+" with hint: \n\t\t"+(new String(hint)+"\n");
112
+ }
113
+ this.message = new String(msg||"");
114
+ return this;
115
+ }
116
+ doh._AssertFailure.prototype = new Error();
117
+ doh._AssertFailure.prototype.constructor = doh._AssertFailure;
118
+ doh._AssertFailure.prototype.name = "doh._AssertFailure";
119
+
120
+ doh.Deferred = function(canceller){
121
+ this.chain = [];
122
+ this.id = this._nextId();
123
+ this.fired = -1;
124
+ this.paused = 0;
125
+ this.results = [null, null];
126
+ this.canceller = canceller;
127
+ this.silentlyCancelled = false;
128
+ };
129
+
130
+ doh.extend(doh.Deferred, {
131
+ getTestErrback: function(cb, scope){
132
+ // summary: Replaces outer getTextCallback's in nested situations to avoid multiple callback(true)'s
133
+ var _this = this;
134
+ return function(){
135
+ try{
136
+ cb.apply(scope||doh.global||_this, arguments);
137
+ }catch(e){
138
+ _this.errback(e);
139
+ }
140
+ };
141
+ },
142
+
143
+ getTestCallback: function(cb, scope){
144
+ var _this = this;
145
+ return function(){
146
+ try{
147
+ cb.apply(scope||doh.global||_this, arguments);
148
+ }catch(e){
149
+ _this.errback(e);
150
+ return;
151
+ }
152
+ _this.callback(true);
153
+ };
154
+ },
155
+
156
+ getFunctionFromArgs: function(){
157
+ var a = arguments;
158
+ if((a[0])&&(!a[1])){
159
+ if(typeof a[0] == "function"){
160
+ return a[0];
161
+ }else if(typeof a[0] == "string"){
162
+ return doh.global[a[0]];
163
+ }
164
+ }else if((a[0])&&(a[1])){
165
+ return doh.hitch(a[0], a[1]);
166
+ }
167
+ return null;
168
+ },
169
+
170
+ makeCalled: function() {
171
+ var deferred = new doh.Deferred();
172
+ deferred.callback();
173
+ return deferred;
174
+ },
175
+
176
+ _nextId: (function(){
177
+ var n = 1;
178
+ return function(){ return n++; };
179
+ })(),
180
+
181
+ cancel: function(){
182
+ if(this.fired == -1){
183
+ if (this.canceller){
184
+ this.canceller(this);
185
+ }else{
186
+ this.silentlyCancelled = true;
187
+ }
188
+ if(this.fired == -1){
189
+ this.errback(new Error("Deferred(unfired)"));
190
+ }
191
+ }else if(this.fired == 0 &&
192
+ (this.results[0] instanceof doh.Deferred)){
193
+ this.results[0].cancel();
194
+ }
195
+ },
196
+
197
+
198
+ _pause: function(){
199
+ this.paused++;
200
+ },
201
+
202
+ _unpause: function(){
203
+ this.paused--;
204
+ if ((this.paused == 0) && (this.fired >= 0)) {
205
+ this._fire();
206
+ }
207
+ },
208
+
209
+ _continue: function(res){
210
+ this._resback(res);
211
+ this._unpause();
212
+ },
213
+
214
+ _resback: function(res){
215
+ this.fired = ((res instanceof Error) ? 1 : 0);
216
+ this.results[this.fired] = res;
217
+ this._fire();
218
+ },
219
+
220
+ _check: function(){
221
+ if(this.fired != -1){
222
+ if(!this.silentlyCancelled){
223
+ throw new Error("already called!");
224
+ }
225
+ this.silentlyCancelled = false;
226
+ return;
227
+ }
228
+ },
229
+
230
+ callback: function(res){
231
+ this._check();
232
+ this._resback(res);
233
+ },
234
+
235
+ errback: function(res){
236
+ this._check();
237
+ if(!(res instanceof Error)){
238
+ res = new Error(res);
239
+ }
240
+ this._resback(res);
241
+ },
242
+
243
+ addBoth: function(cb, cbfn){
244
+ var enclosed = this.getFunctionFromArgs(cb, cbfn);
245
+ if(arguments.length > 2){
246
+ enclosed = doh.hitch(null, enclosed, arguments, 2);
247
+ }
248
+ return this.addCallbacks(enclosed, enclosed);
249
+ },
250
+
251
+ addCallback: function(cb, cbfn){
252
+ var enclosed = this.getFunctionFromArgs(cb, cbfn);
253
+ if(arguments.length > 2){
254
+ enclosed = doh.hitch(null, enclosed, arguments, 2);
255
+ }
256
+ return this.addCallbacks(enclosed, null);
257
+ },
258
+
259
+ addErrback: function(cb, cbfn){
260
+ var enclosed = this.getFunctionFromArgs(cb, cbfn);
261
+ if(arguments.length > 2){
262
+ enclosed = doh.hitch(null, enclosed, arguments, 2);
263
+ }
264
+ return this.addCallbacks(null, enclosed);
265
+ },
266
+
267
+ addCallbacks: function(cb, eb){
268
+ this.chain.push([cb, eb]);
269
+ if(this.fired >= 0){
270
+ this._fire();
271
+ }
272
+ return this;
273
+ },
274
+
275
+ _fire: function(){
276
+ var chain = this.chain;
277
+ var fired = this.fired;
278
+ var res = this.results[fired];
279
+ var self = this;
280
+ var cb = null;
281
+ while(chain.length > 0 && this.paused == 0){
282
+ // Array
283
+ var pair = chain.shift();
284
+ var f = pair[fired];
285
+ if(f == null){
286
+ continue;
287
+ }
288
+ try {
289
+ res = f(res);
290
+ fired = ((res instanceof Error) ? 1 : 0);
291
+ if(res instanceof doh.Deferred){
292
+ cb = function(res){
293
+ self._continue(res);
294
+ };
295
+ this._pause();
296
+ }
297
+ }catch(err){
298
+ fired = 1;
299
+ res = err;
300
+ }
301
+ }
302
+ this.fired = fired;
303
+ this.results[fired] = res;
304
+ if((cb)&&(this.paused)){
305
+ res.addBoth(cb);
306
+ }
307
+ }
308
+ });
309
+
310
+ //
311
+ // State Keeping and Reporting
312
+ //
313
+
314
+ doh._testCount = 0;
315
+ doh._groupCount = 0;
316
+ doh._errorCount = 0;
317
+ doh._failureCount = 0;
318
+ doh._currentGroup = null;
319
+ doh._currentTest = null;
320
+ doh._paused = true;
321
+
322
+ doh._init = function(){
323
+ this._currentGroup = null;
324
+ this._currentTest = null;
325
+ this._errorCount = 0;
326
+ this._failureCount = 0;
327
+ this.debug(this._testCount, "tests to run in", this._groupCount, "groups");
328
+ }
329
+
330
+ // doh._urls = [];
331
+ doh._groups = {};
332
+
333
+ //
334
+ // Test Registration
335
+ //
336
+
337
+ doh.registerTestNs = function(/*String*/ group, /*Object*/ ns){
338
+ // summary:
339
+ // adds the passed namespace object to the list of objects to be
340
+ // searched for test groups. Only "public" functions (not prefixed
341
+ // with "_") will be added as tests to be run. If you'd like to use
342
+ // fixtures (setUp(), tearDown(), and runTest()), please use
343
+ // registerTest() or registerTests().
344
+ for(var x in ns){
345
+ if( (x.charAt(0) != "_") &&
346
+ (typeof ns[x] == "function") ){
347
+ this.registerTest(group, ns[x]);
348
+ }
349
+ }
350
+ }
351
+
352
+ doh._testRegistered = function(group, fixture){
353
+ // slot to be filled in
354
+ }
355
+
356
+ doh._groupStarted = function(group){
357
+ // slot to be filled in
358
+ }
359
+
360
+ doh._groupFinished = function(group, success){
361
+ // slot to be filled in
362
+ }
363
+
364
+ doh._testStarted = function(group, fixture){
365
+ // slot to be filled in
366
+ }
367
+
368
+ doh._testFinished = function(group, fixture, success){
369
+ // slot to be filled in
370
+ }
371
+
372
+ doh.registerGroup = function( /*String*/ group,
373
+ /*Array||Function||Object*/ tests,
374
+ /*Function*/ setUp,
375
+ /*Function*/ tearDown,
376
+ /*String*/ type){
377
+ // summary:
378
+ // registers an entire group of tests at once and provides a setUp and
379
+ // tearDown facility for groups. If you call this method with only
380
+ // setUp and tearDown parameters, they will replace previously
381
+ // installed setUp or tearDown functions for the group with the new
382
+ // methods.
383
+ // group:
384
+ // string name of the group
385
+ // tests:
386
+ // either a function or an object or an array of functions/objects. If
387
+ // an object, it must contain at *least* a "runTest" method, and may
388
+ // also contain "setUp" and "tearDown" methods. These will be invoked
389
+ // on either side of the "runTest" method (respectively) when the test
390
+ // is run. If an array, it must contain objects matching the above
391
+ // description or test functions.
392
+ // setUp: a function for initializing the test group
393
+ // tearDown: a function for initializing the test group
394
+ // type: The type of tests these are, such as a group of performance tests
395
+ // null/undefied are standard DOH tests, the valye 'perf' enables
396
+ // registering them as performance tests.
397
+ if(tests){
398
+ this.register(group, tests, type);
399
+ }
400
+ if(setUp){
401
+ this._groups[group].setUp = setUp;
402
+ }
403
+ if(tearDown){
404
+ this._groups[group].tearDown = tearDown;
405
+ }
406
+ }
407
+
408
+ doh._getTestObj = function(group, test, type){
409
+ var tObj = test;
410
+ if(typeof test == "string"){
411
+ if(test.substr(0, 4)=="url:"){
412
+ return this.registerUrl(group, test);
413
+ }else{
414
+ tObj = {
415
+ name: test.replace("/\s/g", "_") // FIXME: bad escapement
416
+ };
417
+ tObj.runTest = new Function("t", test);
418
+ }
419
+ }else if(typeof test == "function"){
420
+ // if we didn't get a fixture, wrap the function
421
+ tObj = { "runTest": test };
422
+ if(test["name"]){
423
+ tObj.name = test.name;
424
+ }else{
425
+ try{
426
+ var fStr = "function ";
427
+ var ts = tObj.runTest+"";
428
+ if(0 <= ts.indexOf(fStr)){
429
+ tObj.name = ts.split(fStr)[1].split("(", 1)[0];
430
+ }
431
+ // doh.debug(tObj.runTest.toSource());
432
+ }catch(e){
433
+ }
434
+ }
435
+ // FIXME: try harder to get the test name here
436
+ }
437
+
438
+ //Augment the test with some specific options to make it identifiable as a
439
+ //particular type of test so it can be executed properly.
440
+ if(type === "perf" || tObj.testType === "perf"){
441
+ tObj.testType = "perf";
442
+
443
+ //Build an object on the root DOH class to contain all the test results.
444
+ //Cache it on the test object for quick lookup later for results storage.
445
+ if(!doh.perfTestResults){
446
+ doh.perfTestResults = {};
447
+ doh.perfTestResults[group] = {};
448
+ }
449
+ if(!doh.perfTestResults[group]){
450
+ doh.perfTestResults[group] = {};
451
+ }
452
+ if(!doh.perfTestResults[group][tObj.name]){
453
+ doh.perfTestResults[group][tObj.name] = {};
454
+ }
455
+ tObj.results = doh.perfTestResults[group][tObj.name];
456
+
457
+ //If it's not set, then set the trial duration
458
+ //default to 100ms.
459
+ if(!("trialDuration" in tObj)){
460
+ tObj.trialDuration = 100;
461
+ }
462
+
463
+ //If it's not set, then set the delay between trial runs to 100ms
464
+ //default to 100ms to allow for GC and to make IE happy.
465
+ if(!("trialDelay" in tObj)){
466
+ tObj.trialDelay = 100;
467
+ }
468
+
469
+ //If it's not set, then set number of times a trial is run to 10.
470
+ if(!("trialIterations" in tObj)){
471
+ tObj.trialIterations = 10;
472
+ }
473
+ }
474
+ return tObj;
475
+ }
476
+
477
+ doh.registerTest = function(/*String*/ group, /*Function||Object*/ test, /*String*/ type){
478
+ // summary:
479
+ // add the provided test function or fixture object to the specified
480
+ // test group.
481
+ // group:
482
+ // string name of the group to add the test to
483
+ // test:
484
+ // either a function or an object. If an object, it must contain at
485
+ // *least* a "runTest" method, and may also contain "setUp" and
486
+ // "tearDown" methods. These will be invoked on either side of the
487
+ // "runTest" method (respectively) when the test is run.
488
+ // type:
489
+ // An identifier denoting the type of testing that the test performs, such
490
+ // as a performance test. If null, defaults to regular DOH test.
491
+ if(!this._groups[group]){
492
+ this._groupCount++;
493
+ this._groups[group] = [];
494
+ this._groups[group].inFlight = 0;
495
+ }
496
+ var tObj = this._getTestObj(group, test, type);
497
+ if(!tObj){ return null; }
498
+ this._groups[group].push(tObj);
499
+ this._testCount++;
500
+ this._testRegistered(group, tObj);
501
+ return tObj;
502
+ }
503
+
504
+ doh.registerTests = function(/*String*/ group, /*Array*/ testArr, /*String*/ type){
505
+ // summary:
506
+ // registers a group of tests, treating each element of testArr as
507
+ // though it were being (along with group) passed to the registerTest
508
+ // method. It also uses the type to decide how the tests should
509
+ // behave, by defining the type of tests these are, such as performance tests
510
+ for(var x=0; x<testArr.length; x++){
511
+ this.registerTest(group, testArr[x], type);
512
+ }
513
+ }
514
+
515
+ // FIXME: move implementation to _browserRunner?
516
+ doh.registerUrl = function( /*String*/ group,
517
+ /*String*/ url,
518
+ /*Integer*/ timeout,
519
+ /*String*/ type){
520
+ this.debug("ERROR:");
521
+ this.debug("\tNO registerUrl() METHOD AVAILABLE.");
522
+ // this._urls.push(url);
523
+ }
524
+
525
+ doh.registerString = function(group, str, type){
526
+ }
527
+
528
+ // FIXME: remove the doh.add alias SRTL.
529
+ doh.register = doh.add = function(groupOrNs, testOrNull, type){
530
+ // summary:
531
+ // "magical" variant of registerTests, registerTest, and
532
+ // registerTestNs. Will accept the calling arguments of any of these
533
+ // methods and will correctly guess the right one to register with.
534
+ if( (arguments.length == 1)&&
535
+ (typeof groupOrNs == "string") ){
536
+ if(groupOrNs.substr(0, 4)=="url:"){
537
+ this.registerUrl(groupOrNs, null, null, type);
538
+ }else{
539
+ this.registerTest("ungrouped", groupOrNs, type);
540
+ }
541
+ }
542
+ if(arguments.length == 1){
543
+ this.debug("invalid args passed to doh.register():", groupOrNs, ",", testOrNull);
544
+ return;
545
+ }
546
+ if(typeof testOrNull == "string"){
547
+ if(testOrNull.substr(0, 4)=="url:"){
548
+ this.registerUrl(testOrNull, null, null, type);
549
+ }else{
550
+ this.registerTest(groupOrNs, testOrNull, type);
551
+ }
552
+ // this.registerTestNs(groupOrNs, testOrNull);
553
+ return;
554
+ }
555
+ if(doh._isArray(testOrNull)){
556
+ this.registerTests(groupOrNs, testOrNull, type);
557
+ return;
558
+ }
559
+ this.registerTest(groupOrNs, testOrNull, type);
560
+ };
561
+
562
+ doh.registerDocTests = function(module){
563
+ // no-op for when Dojo isn't loaded into the page
564
+ this.debug("registerDocTests() requires dojo to be loaded into the environment. Skipping doctest set for module:", module);
565
+ };
566
+ (function(){
567
+ if(typeof dojo != "undefined"){
568
+ try{
569
+ dojo.require("dojox.testing.DocTest");
570
+ }catch(e){
571
+ // if the DocTest module isn't available (e.g., the build we're
572
+ // running from doesn't include it), stub it out and log the error
573
+ console.debug(e);
574
+
575
+ doh.registerDocTests = function(){}
576
+ return;
577
+ }
578
+ doh.registerDocTests = function(module){
579
+ // summary:
580
+ // Get all the doctests from the given module and register each of them
581
+ // as a single test case here.
582
+ //
583
+
584
+ var docTest = new dojox.testing.DocTest();
585
+ var docTests = docTest.getTests(module);
586
+ var len = docTests.length;
587
+ var tests = [];
588
+ for (var i=0; i<len; i++){
589
+ var test = docTests[i];
590
+ // Extract comment on first line and add to test name.
591
+ var comment = "";
592
+ if (test.commands.length && test.commands[0].indexOf("//")!=-1) {
593
+ var parts = test.commands[0].split("//");
594
+ comment = ", "+parts[parts.length-1]; // Get all after the last //, so we dont get trapped by http:// or alikes :-).
595
+ }
596
+ tests.push({
597
+ runTest: (function(test){
598
+ return function(t){
599
+ var r = docTest.runTest(test.commands, test.expectedResult);
600
+ t.assertTrue(r.success);
601
+ }
602
+ })(test),
603
+ name:"Line "+test.line+comment
604
+ }
605
+ );
606
+ }
607
+ this.register("DocTests: "+module, tests);
608
+ }
609
+ }
610
+ })();
611
+
612
+ //
613
+ // Assertions and In-Test Utilities
614
+ //
615
+
616
+ doh.t = doh.assertTrue = function(/*Object*/ condition, /*String?*/ hint){
617
+ // summary:
618
+ // is the passed item "truthy"?
619
+ if(arguments.length < 1){
620
+ throw new doh._AssertFailure("assertTrue failed because it was not passed at least 1 argument");
621
+ }
622
+ if(!eval(condition)){
623
+ throw new doh._AssertFailure("assertTrue('" + condition + "') failed", hint);
624
+ }
625
+ }
626
+
627
+ doh.f = doh.assertFalse = function(/*Object*/ condition, /*String?*/ hint){
628
+ // summary:
629
+ // is the passed item "falsey"?
630
+ if(arguments.length < 1){
631
+ throw new doh._AssertFailure("assertFalse failed because it was not passed at least 1 argument");
632
+ }
633
+ if(eval(condition)){
634
+ throw new doh._AssertFailure("assertFalse('" + condition + "') failed", hint);
635
+ }
636
+ }
637
+
638
+ doh.e = doh.assertError = function(/*Error object*/expectedError, /*Object*/scope, /*String*/functionName, /*Array*/args, /*String?*/ hint){
639
+ // summary:
640
+ // Test for a certain error to be thrown by the given function.
641
+ // example:
642
+ // t.assertError(dojox.data.QueryReadStore.InvalidAttributeError, store, "getValue", [item, "NOT THERE"]);
643
+ // t.assertError(dojox.data.QueryReadStore.InvalidItemError, store, "getValue", ["not an item", "NOT THERE"]);
644
+ try{
645
+ scope[functionName].apply(scope, args);
646
+ }catch (e){
647
+ if(e instanceof expectedError){
648
+ return true;
649
+ }else{
650
+ throw new doh._AssertFailure("assertError() failed:\n\texpected error\n\t\t"+expectedError+"\n\tbut got\n\t\t"+e+"\n\n", hint);
651
+ }
652
+ }
653
+ throw new doh._AssertFailure("assertError() failed:\n\texpected error\n\t\t"+expectedError+"\n\tbut no error caught\n\n", hint);
654
+ }
655
+
656
+
657
+ doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual, /*String?*/ hint){
658
+ // summary:
659
+ // are the passed expected and actual objects/values deeply
660
+ // equivalent?
661
+
662
+ // Compare undefined always with three equal signs, because undefined==null
663
+ // is true, but undefined===null is false.
664
+ if((expected === undefined)&&(actual === undefined)){
665
+ return true;
666
+ }
667
+ if(arguments.length < 2){
668
+ throw doh._AssertFailure("assertEqual failed because it was not passed 2 arguments");
669
+ }
670
+ if((expected === actual)||(expected == actual)||
671
+ ( typeof expected == "number" && typeof actual == "number" && isNaN(expected) && isNaN(actual) )){
672
+ return true;
673
+ }
674
+ if( (this._isArray(expected) && this._isArray(actual))&&
675
+ (this._arrayEq(expected, actual)) ){
676
+ return true;
677
+ }
678
+ if( ((typeof expected == "object")&&((typeof actual == "object")))&&
679
+ (this._objPropEq(expected, actual)) ){
680
+ return true;
681
+ }
682
+ throw new doh._AssertFailure("assertEqual() failed:\n\texpected\n\t\t"+expected+"\n\tbut got\n\t\t"+actual+"\n\n", hint);
683
+ }
684
+
685
+ doh.isNot = doh.assertNotEqual = function(/*Object*/ notExpected, /*Object*/ actual, /*String?*/ hint){
686
+ // summary:
687
+ // are the passed notexpected and actual objects/values deeply
688
+ // not equivalent?
689
+
690
+ // Compare undefined always with three equal signs, because undefined==null
691
+ // is true, but undefined===null is false.
692
+ if((notExpected === undefined)&&(actual === undefined)){
693
+ throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
694
+ }
695
+ if(arguments.length < 2){
696
+ throw doh._AssertFailure("assertEqual failed because it was not passed 2 arguments");
697
+ }
698
+ if((notExpected === actual)||(notExpected == actual)){
699
+ throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
700
+ }
701
+ if( (this._isArray(notExpected) && this._isArray(actual))&&
702
+ (this._arrayEq(notExpected, actual)) ){
703
+ throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
704
+ }
705
+ if( ((typeof notExpected == "object")&&((typeof actual == "object")))&&
706
+ (this._objPropEq(notExpected, actual)) ){
707
+ throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
708
+ }
709
+ return true;
710
+ }
711
+
712
+ doh._arrayEq = function(expected, actual){
713
+ if(expected.length != actual.length){ return false; }
714
+ // FIXME: we're not handling circular refs. Do we care?
715
+ for(var x=0; x<expected.length; x++){
716
+ if(!doh.assertEqual(expected[x], actual[x])){ return false; }
717
+ }
718
+ return true;
719
+ }
720
+
721
+ doh._objPropEq = function(expected, actual){
722
+ // Degenerate case: if they are both null, then their "properties" are equal.
723
+ if(expected === null && actual === null){
724
+ return true;
725
+ }
726
+ // If only one is null, they aren't equal.
727
+ if(expected === null || actual === null){
728
+ return false;
729
+ }
730
+ if(expected instanceof Date){
731
+ return actual instanceof Date && expected.getTime()==actual.getTime();
732
+ }
733
+ var x;
734
+ // Make sure ALL THE SAME properties are in both objects!
735
+ for(x in actual){ // Lets check "actual" here, expected is checked below.
736
+ if(expected[x] === undefined){
737
+ return false;
738
+ }
739
+ };
740
+
741
+ for(x in expected){
742
+ if(!doh.assertEqual(expected[x], actual[x])){
743
+ return false;
744
+ }
745
+ }
746
+ return true;
747
+ }
748
+
749
+ doh._isArray = function(it){
750
+ return (it && it instanceof Array || typeof it == "array" ||
751
+ (
752
+ !!doh.global["dojo"] &&
753
+ doh.global["dojo"]["NodeList"] !== undefined &&
754
+ it instanceof doh.global["dojo"]["NodeList"]
755
+ )
756
+ );
757
+ }
758
+
759
+ //
760
+ // Runner-Wrapper
761
+ //
762
+
763
+ doh._setupGroupForRun = function(/*String*/ groupName, /*Integer*/ idx){
764
+ var tg = this._groups[groupName];
765
+ this.debug(this._line);
766
+ this.debug("GROUP", "\""+groupName+"\"", "has", tg.length, "test"+((tg.length > 1) ? "s" : "")+" to run");
767
+ }
768
+
769
+ doh._handleFailure = function(groupName, fixture, e){
770
+ // this.debug("FAILED test:", fixture.name);
771
+ // mostly borrowed from JUM
772
+ this._groups[groupName].failures++;
773
+ var out = "";
774
+ if(e instanceof this._AssertFailure){
775
+ this._failureCount++;
776
+ if(e["fileName"]){ out += e.fileName + ':'; }
777
+ if(e["lineNumber"]){ out += e.lineNumber + ' '; }
778
+ out += e+": "+e.message;
779
+ this.debug("\t_AssertFailure:", out);
780
+ }else{
781
+ this._errorCount++;
782
+ }
783
+ this.debug(e);
784
+ if(fixture.runTest["toSource"]){
785
+ var ss = fixture.runTest.toSource();
786
+ this.debug("\tERROR IN:\n\t\t", ss);
787
+ }else{
788
+ this.debug("\tERROR IN:\n\t\t", fixture.runTest);
789
+ }
790
+
791
+ if(e.rhinoException){
792
+ e.rhinoException.printStackTrace();
793
+ }else if(e.javaException){
794
+ e.javaException.printStackTrace();
795
+ }
796
+ }
797
+
798
+ //Assume a setTimeout implementation that is synchronous, so that
799
+ //the Node and Rhino envs work similar to each other. Node defines
800
+ //a setTimeout, so testing for setTimeout is not enough, each environment
801
+ //adapter should set this value accordingly.
802
+ doh.setTimeout = function(func){
803
+ return func();
804
+ };
805
+
806
+ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
807
+ // summary:
808
+ // This function handles how to execute a 'performance' test
809
+ // which is different from a straight UT style test. These
810
+ // will often do numerous iterations of the same operation and
811
+ // gather execution statistics about it, like max, min, average,
812
+ // etc. It makes use of the already in place DOH deferred test
813
+ // handling since it is a good idea to put a pause inbetween each
814
+ // iteration to allow for GC cleanup and the like.
815
+ //
816
+ // groupName:
817
+ // The test group that contains this performance test.
818
+ // fixture:
819
+ // The performance test fixture.
820
+ var tg = this._groups[groupName];
821
+ fixture.startTime = new Date();
822
+
823
+ //Perf tests always need to act in an async manner as there is a
824
+ //number of iterations to flow through.
825
+ var def = new doh.Deferred();
826
+ tg.inFlight++;
827
+ def.groupName = groupName;
828
+ def.fixture = fixture;
829
+
830
+ def.addErrback(function(err){
831
+ doh._handleFailure(groupName, fixture, err);
832
+ });
833
+
834
+ //Set up the finalizer.
835
+ var retEnd = function(){
836
+ if(fixture["tearDown"]){ fixture.tearDown(doh); }
837
+ tg.inFlight--;
838
+ if((!tg.inFlight)&&(tg.iterated)){
839
+ doh._groupFinished(groupName, !tg.failures);
840
+ }
841
+ doh._testFinished(groupName, fixture, def.results[0]);
842
+ if(doh._paused){
843
+ doh.run();
844
+ }
845
+ };
846
+
847
+ //Since these can take who knows how long, we don't want to timeout
848
+ //unless explicitly set
849
+ var timer;
850
+ var to = fixture.timeout;
851
+ if(to > 0) {
852
+ timer = doh.setTimeout(function(){
853
+ // ret.cancel();
854
+ // retEnd();
855
+ def.errback(new Error("test timeout in "+fixture.name.toString()));
856
+ }, to);
857
+ }
858
+
859
+ //Set up the end calls to the test into the deferred we'll return.
860
+ def.addBoth(function(arg){
861
+ if(timer){
862
+ clearTimeout(timer);
863
+ }
864
+ retEnd();
865
+ });
866
+
867
+ //Okay, now set up the timing loop for the actual test.
868
+ //This is down as an async type test where there is a delay
869
+ //between each execution to allow for GC time, etc, so the GC
870
+ //has less impact on the tests.
871
+ var res = fixture.results;
872
+ res.trials = [];
873
+
874
+ //Try to figure out how many calls are needed to hit a particular threshold.
875
+ var itrDef = doh._calcTrialIterations(groupName, fixture);
876
+ itrDef.addErrback(function(err){
877
+ fixture.endTime = new Date();
878
+ def.errback(err);
879
+ });
880
+
881
+ //Blah, since tests can be deferred, the actual run has to be deferred until after
882
+ //we know how many iterations to run. This is just plain ugly.
883
+ itrDef.addCallback(function(iterations){
884
+ if(iterations){
885
+ var countdown = fixture.trialIterations;
886
+ doh.debug("TIMING TEST: [" + fixture.name +
887
+ "]\n\t\tITERATIONS PER TRIAL: " +
888
+ iterations + "\n\tTRIALS: " +
889
+ countdown);
890
+
891
+ //Figure out how many times we want to run our 'trial'.
892
+ //Where each trial consists of 'iterations' of the test.
893
+
894
+ var trialRunner = function() {
895
+ //Set up our function to execute a block of tests
896
+ var start = new Date();
897
+ var tTimer = new doh.Deferred();
898
+ var tCountdown = iterations;
899
+
900
+ var tState = {
901
+ countdown: iterations
902
+ };
903
+ var testRunner = function(state){
904
+ while(state){
905
+ try{
906
+ state.countdown--;
907
+ if(state.countdown){
908
+ var ret = fixture.runTest(doh);
909
+ if(ret instanceof doh.Deferred){
910
+ //Deferreds have to be handled async,
911
+ //otherwise we just keep looping.
912
+ var atState = {
913
+ countdown: state.countdown
914
+ };
915
+ ret.addCallback(function(){
916
+ testRunner(atState);
917
+ });
918
+ ret.addErrback(function(err) {
919
+ doh._handleFailure(groupName, fixture, err);
920
+ fixture.endTime = new Date();
921
+ def.errback(err);
922
+ });
923
+ state = null;
924
+ }
925
+ }else{
926
+ tTimer.callback(new Date());
927
+ state = null;
928
+ }
929
+ }catch(err){
930
+ fixture.endTime = new Date();
931
+ tTimer.errback(err);
932
+ }
933
+ }
934
+ };
935
+ tTimer.addCallback(function(end){
936
+ //Figure out the results and try to factor out function call costs.
937
+ var tResults = {
938
+ trial: (fixture.trialIterations - countdown),
939
+ testIterations: iterations,
940
+ executionTime: (end.getTime() - start.getTime()),
941
+ average: (end.getTime() - start.getTime())/iterations
942
+ };
943
+ res.trials.push(tResults);
944
+ doh.debug("\n\t\tTRIAL #: " +
945
+ tResults.trial + "\n\tTIME: " +
946
+ tResults.executionTime + "ms.\n\tAVG TEST TIME: " +
947
+ (tResults.executionTime/tResults.testIterations) + "ms.");
948
+
949
+ //Okay, have we run all the trials yet?
950
+ countdown--;
951
+ if(countdown){
952
+ doh.setTimeout(trialRunner, fixture.trialDelay);
953
+ }else{
954
+ //Okay, we're done, lets compute some final performance results.
955
+ var t = res.trials;
956
+
957
+
958
+
959
+ //We're done.
960
+ fixture.endTime = new Date();
961
+ def.callback(true);
962
+ }
963
+ });
964
+ tTimer.addErrback(function(err){
965
+ fixture.endTime = new Date();
966
+ def.errback(err);
967
+ });
968
+ testRunner(tState);
969
+ };
970
+ trialRunner();
971
+ }
972
+ });
973
+
974
+ //Set for a pause, returned the deferred.
975
+ if(def.fired < 0){
976
+ doh.pause();
977
+ }
978
+ return def;
979
+ };
980
+
981
+ doh._calcTrialIterations = function(/*String*/ groupName, /*Object*/ fixture){
982
+ // summary:
983
+ // This function determines the rough number of iterations to
984
+ // use to reach a particular MS threshold. This returns a deferred
985
+ // since tests can theoretically by async. Async tests aren't going to
986
+ // give great perf #s, though.
987
+ // The callback is passed the # of iterations to hit the requested
988
+ // threshold.
989
+ //
990
+ // fixture:
991
+ // The test fixture we want to calculate iterations for.
992
+ var def = new doh.Deferred();
993
+ var calibrate = function () {
994
+ var testFunc = fixture.runTest;
995
+
996
+ //Set the initial state. We have to do this as a loop instead
997
+ //of a recursive function. Otherwise, it blows the call stack
998
+ //on some browsers.
999
+ var iState = {
1000
+ start: new Date(),
1001
+ curIter: 0,
1002
+ iterations: 5
1003
+ };
1004
+ var handleIteration = function(state){
1005
+ while(state){
1006
+ if(state.curIter < state.iterations){
1007
+ try{
1008
+ var ret = testFunc(doh);
1009
+ if(ret instanceof doh.Deferred){
1010
+ var aState = {
1011
+ start: state.start,
1012
+ curIter: state.curIter + 1,
1013
+ iterations: state.iterations
1014
+ };
1015
+ ret.addCallback(function(){
1016
+ handleIteration(aState);
1017
+ });
1018
+ ret.addErrback(function(err) {
1019
+ fixture.endTime = new Date();
1020
+ def.errback(err);
1021
+ });
1022
+ state = null;
1023
+ }else{
1024
+ state.curIter++;
1025
+ }
1026
+ }catch(err){
1027
+ fixture.endTime = new Date();
1028
+ def.errback(err);
1029
+ return;
1030
+ }
1031
+ }else{
1032
+ var end = new Date();
1033
+ var totalTime = (end.getTime() - state.start.getTime());
1034
+ if(totalTime < fixture.trialDuration){
1035
+ var nState = {
1036
+ iterations: state.iterations * 2,
1037
+ curIter: 0
1038
+ }
1039
+ state = null;
1040
+ doh.setTimeout(function(){
1041
+ nState.start = new Date();
1042
+ handleIteration(nState);
1043
+ }, 50);
1044
+ }else{
1045
+ var itrs = state.iterations;
1046
+ doh.setTimeout(function(){def.callback(itrs)}, 50);
1047
+ state = null;
1048
+ }
1049
+ }
1050
+ }
1051
+ };
1052
+ handleIteration(iState);
1053
+ };
1054
+ doh.setTimeout(calibrate, 10);
1055
+ return def;
1056
+ };
1057
+
1058
+ doh._runRegFixture = function(/*String*/groupName, /*Object*/fixture){
1059
+ // summary:
1060
+ // Function to run a generic doh test. These are not
1061
+ // specialized tests, like performance groups and such.
1062
+ //
1063
+ // groupName:
1064
+ // The groupName of the test.
1065
+ // fixture:
1066
+ // The test fixture to execute.
1067
+ var tg = this._groups[groupName];
1068
+ fixture.startTime = new Date();
1069
+ var ret = fixture.runTest(this);
1070
+ fixture.endTime = new Date();
1071
+ // if we get a deferred back from the test runner, we know we're
1072
+ // gonna wait for an async result. It's up to the test code to trap
1073
+ // errors and give us an errback or callback.
1074
+ if(ret instanceof doh.Deferred){
1075
+ tg.inFlight++;
1076
+ ret.groupName = groupName;
1077
+ ret.fixture = fixture;
1078
+
1079
+ ret.addErrback(function(err){
1080
+ doh._handleFailure(groupName, fixture, err);
1081
+ });
1082
+
1083
+ var retEnd = function(){
1084
+ if(fixture["tearDown"]){ fixture.tearDown(doh); }
1085
+ tg.inFlight--;
1086
+ if((!tg.inFlight)&&(tg.iterated)){
1087
+ doh._groupFinished(groupName, !tg.failures);
1088
+ }
1089
+ doh._testFinished(groupName, fixture, ret.results[0]);
1090
+ if(doh._paused){
1091
+ doh.run();
1092
+ }
1093
+ }
1094
+
1095
+ var timer = doh.setTimeout(function(){
1096
+ // ret.cancel();
1097
+ // retEnd();
1098
+ ret.errback(new Error("test timeout in "+fixture.name.toString()));
1099
+ }, fixture["timeout"]||1000);
1100
+
1101
+ ret.addBoth(function(arg){
1102
+ clearTimeout(timer);
1103
+ retEnd();
1104
+ });
1105
+ if(ret.fired < 0){
1106
+ doh.pause();
1107
+ }
1108
+ return ret;
1109
+ }
1110
+ };
1111
+
1112
+ doh._runFixture = function(groupName, fixture){
1113
+ var tg = this._groups[groupName];
1114
+ this._testStarted(groupName, fixture);
1115
+ var threw = false;
1116
+ var err = null;
1117
+ // run it, catching exceptions and reporting them
1118
+ try{
1119
+ // let doh reference "this.group.thinger..." which can be set by
1120
+ // another test or group-level setUp function
1121
+ fixture.group = tg;
1122
+ // only execute the parts of the fixture we've got
1123
+
1124
+ if(fixture["setUp"]){ fixture.setUp(this); }
1125
+ if(fixture["runTest"]){ // should we error out of a fixture doesn't have a runTest?
1126
+ if(fixture.testType === "perf"){
1127
+ //Always async deferred, so return it.
1128
+ return doh._runPerfFixture(groupName, fixture);
1129
+ }else{
1130
+ //May or may not by async.
1131
+ var ret = doh._runRegFixture(groupName, fixture);
1132
+ if(ret){
1133
+ return ret;
1134
+ }
1135
+ }
1136
+ }
1137
+ if(fixture["tearDown"]){ fixture.tearDown(this); }
1138
+ }catch(e){
1139
+ threw = true;
1140
+ err = e;
1141
+ if(!fixture.endTime){
1142
+ fixture.endTime = new Date();
1143
+ }
1144
+ }
1145
+ var d = new doh.Deferred();
1146
+ doh.setTimeout(this.hitch(this, function(){
1147
+ if(threw){
1148
+ this._handleFailure(groupName, fixture, err);
1149
+ }
1150
+ this._testFinished(groupName, fixture, !threw);
1151
+
1152
+ if((!tg.inFlight)&&(tg.iterated)){
1153
+ doh._groupFinished(groupName, !tg.failures);
1154
+ }else if(tg.inFlight > 0){
1155
+ doh.setTimeout(this.hitch(this, function(){
1156
+ doh.runGroup(groupName); // , idx);
1157
+ }), 100);
1158
+ this._paused = true;
1159
+ }
1160
+ if(doh._paused){
1161
+ doh.run();
1162
+ }
1163
+ }), 30);
1164
+ doh.pause();
1165
+ return d;
1166
+ }
1167
+
1168
+ doh._testId = 0;
1169
+ doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){
1170
+ // summary:
1171
+ // runs the specified test group
1172
+
1173
+ // the general structure of the algorithm is to run through the group's
1174
+ // list of doh, checking before and after each of them to see if we're in
1175
+ // a paused state. This can be caused by the test returning a deferred or
1176
+ // the user hitting the pause button. In either case, we want to halt
1177
+ // execution of the test until something external to us restarts it. This
1178
+ // means we need to pickle off enough state to pick up where we left off.
1179
+
1180
+ // FIXME: need to make fixture execution async!!
1181
+
1182
+ var tg = this._groups[groupName];
1183
+ if(tg.skip === true){ return; }
1184
+ if(this._isArray(tg)){
1185
+ if(idx<=tg.length){
1186
+ if((!tg.inFlight)&&(tg.iterated == true)){
1187
+ if(tg["tearDown"]){ tg.tearDown(this); }
1188
+ doh._groupFinished(groupName, !tg.failures);
1189
+ return;
1190
+ }
1191
+ }
1192
+ if(!idx){
1193
+ tg.inFlight = 0;
1194
+ tg.iterated = false;
1195
+ tg.failures = 0;
1196
+ }
1197
+ doh._groupStarted(groupName);
1198
+ if(!idx){
1199
+ this._setupGroupForRun(groupName, idx);
1200
+ if(tg["setUp"]){ tg.setUp(this); }
1201
+ }
1202
+ for(var y=(idx||0); y<tg.length; y++){
1203
+ if(this._paused){
1204
+ this._currentTest = y;
1205
+ // this.debug("PAUSED at:", tg[y].name, this._currentGroup, this._currentTest);
1206
+ return;
1207
+ }
1208
+ doh._runFixture(groupName, tg[y]);
1209
+ if(this._paused){
1210
+ this._currentTest = y+1;
1211
+ if(this._currentTest == tg.length){
1212
+ tg.iterated = true;
1213
+ }
1214
+ // this.debug("PAUSED at:", tg[y].name, this._currentGroup, this._currentTest);
1215
+ return;
1216
+ }
1217
+ }
1218
+ tg.iterated = true;
1219
+ if(!tg.inFlight){
1220
+ if(tg["tearDown"]){ tg.tearDown(this); }
1221
+ doh._groupFinished(groupName, !tg.failures);
1222
+ }
1223
+ }
1224
+ }
1225
+
1226
+ doh._onEnd = function(){}
1227
+
1228
+ doh._report = function(){
1229
+ // summary:
1230
+ // a private method to be implemented/replaced by the "locally
1231
+ // appropriate" test runner
1232
+
1233
+ // this.debug("ERROR:");
1234
+ // this.debug("\tNO REPORTING OUTPUT AVAILABLE.");
1235
+ // this.debug("\tIMPLEMENT doh._report() IN YOUR TEST RUNNER");
1236
+
1237
+ this.debug(this._line);
1238
+ this.debug("| TEST SUMMARY:");
1239
+ this.debug(this._line);
1240
+ this.debug("\t", this._testCount, "tests in", this._groupCount, "groups");
1241
+ this.debug("\t", this._errorCount, "errors");
1242
+ this.debug("\t", this._failureCount, "failures");
1243
+ }
1244
+
1245
+ doh.togglePaused = function(){
1246
+ this[(this._paused) ? "run" : "pause"]();
1247
+ }
1248
+
1249
+ doh.pause = function(){
1250
+ // summary:
1251
+ // halt test run. Can be resumed.
1252
+ this._paused = true;
1253
+ }
1254
+
1255
+ doh.run = function(){
1256
+ // summary:
1257
+ // begins or resumes the test process.
1258
+ // this.debug("STARTING");
1259
+ this._paused = false;
1260
+ var cg = this._currentGroup;
1261
+ var ct = this._currentTest;
1262
+ var found = false;
1263
+ if(!cg){
1264
+ this._init(); // we weren't paused
1265
+ found = true;
1266
+ }
1267
+ this._currentGroup = null;
1268
+ this._currentTest = null;
1269
+
1270
+ for(var x in this._groups){
1271
+ if(
1272
+ ( (!found)&&(x == cg) )||( found )
1273
+ ){
1274
+ if(this._paused){ return; }
1275
+ this._currentGroup = x;
1276
+ if(!found){
1277
+ found = true;
1278
+ this.runGroup(x, ct);
1279
+ }else{
1280
+ this.runGroup(x);
1281
+ }
1282
+ if(this._paused){ return; }
1283
+ }
1284
+ }
1285
+ this._currentGroup = null;
1286
+ this._currentTest = null;
1287
+ this._paused = false;
1288
+ this._onEnd();
1289
+ this._report();
1290
+ }
1291
+
1292
+ //Statistics functions to handle computing performance metrics.
1293
+ //Taken from dojox.math
1294
+ // basic statistics
1295
+ doh.standardDeviation = function(/* Number[] */a){
1296
+ // summary:
1297
+ // Returns the standard deviation of the passed arguments.
1298
+ return Math.sqrt(this.variance(a)); // Number
1299
+ };
1300
+
1301
+ doh.variance = function(/* Number[] */a){
1302
+ // summary:
1303
+ // Find the variance in the passed array of numbers.
1304
+ var mean=0, squares=0;
1305
+ dojo.forEach(a, function(item){
1306
+ mean+=item;
1307
+ squares+=Math.pow(item,2);
1308
+ });
1309
+ return (squares/a.length)-Math.pow(mean/a.length, 2); // Number
1310
+ };
1311
+
1312
+ doh.mean = function(/* Number[] */a){
1313
+ // summary:
1314
+ // Returns the mean value in the passed array.
1315
+ var t=0;
1316
+ dojo.forEach(a, function(v){
1317
+ t += v;
1318
+ });
1319
+ return t / Math.max(a.length, 1); // Number
1320
+ };
1321
+
1322
+ doh.min = function(/* Number[] */a){
1323
+ // summary:
1324
+ // Returns the min value in the passed array.
1325
+ return Math.min.apply(null, a); // Number
1326
+ };
1327
+
1328
+ doh.max = function(/* Number[] */a){
1329
+ // summary:
1330
+ // Returns the max value in the passed array.
1331
+ return Math.max.apply(null, a); // Number
1332
+ },
1333
+
1334
+ doh.median= function(/* Number[] */a){
1335
+ // summary:
1336
+ // Returns the value closest to the middle from a sorted version of the passed array.
1337
+ return a.slice(0).sort()[Math.ceil(a.length/2)-1]; // Number
1338
+ },
1339
+
1340
+ doh.mode = function(/* Number[] */a){
1341
+ // summary:
1342
+ // Returns the mode from the passed array (number that appears the most often).
1343
+ // This is not the most efficient method, since it requires a double scan, but
1344
+ // is ensures accuracy.
1345
+ var o = {}, r = 0, m = Number.MIN_VALUE;
1346
+ dojo.forEach(a, function(v){
1347
+ (o[v]!==undefined)?o[v]++:o[v]=1;
1348
+ });
1349
+
1350
+ // we did the lookup map because we need the number that appears the most.
1351
+ for(var p in o){
1352
+ if(m < o[p]){
1353
+ m = o[p], r = p;
1354
+ }
1355
+ }
1356
+ return r; // Number
1357
+ };
1358
+
1359
+ doh.average = function(/* Number [] */ a){
1360
+ var i;
1361
+ var s = 0;
1362
+ for(i = 0; i < a.length; i++){
1363
+ s += a[i];
1364
+ }
1365
+ return s/a.length;
1366
+ }
1367
+
1368
+ tests = doh;
1369
+
1370
+ if (typeof skipDohSetup === "undefined") {
1371
+
1372
+ (function(){
1373
+ // scope protection
1374
+ var x;
1375
+ try{
1376
+ if(typeof dojo != "undefined"){
1377
+ dojo.platformRequire({
1378
+ browser: ["doh._browserRunner"],
1379
+ rhino: ["doh._rhinoRunner"],
1380
+ spidermonkey: ["doh._rhinoRunner"]
1381
+ });
1382
+ try{
1383
+ var _shouldRequire = dojo.isBrowser ? (dojo.global == dojo.global["parent"] || !Boolean(dojo.global.parent.doh) ) : true;
1384
+ }catch(e){
1385
+ //can't access dojo.global.parent.doh, then we need to do require
1386
+ _shouldRequire = true;
1387
+ }
1388
+ if(_shouldRequire){
1389
+ if(dojo.isBrowser){
1390
+ dojo.addOnLoad(function(){
1391
+ if (dojo.global.registerModulePath){
1392
+ dojo.forEach(dojo.global.registerModulePath, function(m){
1393
+ dojo.registerModulePath(m[0], m[1]);
1394
+ });
1395
+ }
1396
+ if(dojo.byId("testList")){
1397
+ var _tm = ( (dojo.global.testModule && dojo.global.testModule.length) ? dojo.global.testModule : "dojo.tests.module");
1398
+ dojo.forEach(_tm.split(","), dojo.require, dojo);
1399
+ doh.setTimeout(function(){
1400
+ doh.run();
1401
+ }, 500);
1402
+ }
1403
+ });
1404
+ }else{
1405
+ // dojo.require("doh._base");
1406
+ }
1407
+ }
1408
+ }else{
1409
+ if(typeof load == "function" &&
1410
+ (typeof Packages == "function" || typeof Packages == "object")){
1411
+ throw new Error();
1412
+ }else if(typeof load == "function"){
1413
+ throw new Error();
1414
+ }
1415
+
1416
+ if(this["document"]){
1417
+ /*
1418
+ // if we survived all of that, we're probably in a browser but
1419
+ // don't have Dojo handy. Load _browserRunner.js using a
1420
+ // document.write() call.
1421
+
1422
+ // find runner.js, load _browserRunner relative to it
1423
+ var scripts = document.getElementsByTagName("script"), runnerFile;
1424
+ for(x=0; x<scripts.length; x++){
1425
+ var s = scripts[x].src;
1426
+ if(s){
1427
+ if(!runnerFile && s.substr(s.length - 9) == "runner.js"){
1428
+ runnerFile = s;
1429
+ }else if(s.substr(s.length - 17) == "_browserRunner.js"){
1430
+ runnerFile = null;
1431
+ break;
1432
+ }
1433
+ }
1434
+ }
1435
+ if(runnerFile){
1436
+ document.write("<scri"+"pt src='" + runnerFile.substr(0, runnerFile.length - 9)
1437
+ + "_browserRunner.js' type='text/javascript'></scr"+"ipt>");
1438
+ }
1439
+ */
1440
+ }
1441
+ }
1442
+ }catch(e){
1443
+ print("\n"+doh._line);
1444
+ print("The Dojo Unit Test Harness, $Rev: 20389 $");
1445
+ print("Copyright (c) 2009, The Dojo Foundation, All Rights Reserved");
1446
+ print(doh._line, "\n");
1447
+
1448
+ try{
1449
+ var dojoUrl = "../../dojo/dojo.js";
1450
+ var testUrl = "";
1451
+ var testModule = "dojo.tests.module";
1452
+ var dohBase = "";
1453
+ for(x=0; x<arguments.length; x++){
1454
+ if(arguments[x].indexOf("=") > 0){
1455
+ var tp = arguments[x].split("=");
1456
+ if(tp[0] == "dohBase"){
1457
+ dohBase = tp[1];
1458
+ //Convert slashes to unix style and make sure properly
1459
+ //ended.
1460
+ dohBase = dohBase.replace(/\\/g, "/");
1461
+ if(dohBase.charAt(dohBase.length - 1) != "/"){
1462
+ dohBase += "/";
1463
+ }
1464
+ }
1465
+ if(tp[0] == "dojoUrl"){
1466
+ dojoUrl = tp[1];
1467
+ }
1468
+ if(tp[0] == "testUrl"){
1469
+ testUrl = tp[1];
1470
+ }
1471
+ if(tp[0] == "testModule"){
1472
+ testModule = tp[1];
1473
+ }
1474
+ }
1475
+ }
1476
+
1477
+ load(dohBase + "_rhinoRunner.js");
1478
+
1479
+ if(dojoUrl.length){
1480
+ if(!this["djConfig"]){
1481
+ djConfig = {};
1482
+ }
1483
+ djConfig.baseUrl = dojoUrl.split("dojo.js")[0];
1484
+ load(dojoUrl);
1485
+ }
1486
+ if(testUrl.length){
1487
+ load(testUrl);
1488
+ }
1489
+ if(testModule.length){
1490
+ dojo.forEach(testModule.split(","), dojo.require, dojo);
1491
+ }
1492
+ }catch(e){
1493
+ print("An exception occurred: " + e);
1494
+ }
1495
+
1496
+ doh.run();
1497
+ }
1498
+ }).apply(this, typeof arguments != "undefined" ? arguments : [null]);
1499
+ }