runner 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #!/usr/bin/env node
  2. var nodeunit = require('nodeunit'),
  3. fs = require('fs'),
  4. path = require('path'),
  5. AssertionError = require('assert').AssertionError;
  6. require('console.log');
  7. var optimist = require('optimist')
  8. .usage('Run the jsdom test suite')
  9. .alias('s', 'suites')
  10. .string('s')
  11. .describe('s', 'suites that you want to run. ie: -s level1/core,1/html,html')
  12. .alias('f', 'fail-fast')
  13. .describe('f', 'stop on the first failed test')
  14. .alias('h', 'help')
  15. .describe('h', 'show the help')
  16. .alias('t', 'tests')
  17. .describe('t', 'choose the test cases to run. ie: -t jquery')
  18. .alias('d', 'debug')
  19. .describe('d', 'run in node\'s interactive debugger mode');
  20. var argv = optimist.argv;
  21. if (argv.help) {
  22. optimist.showHelp();
  23. process.exit();
  24. }
  25. var totalTests = 0;
  26. var failedTests = 0;
  27. var passedTests = 0;
  28. var modules = {};
  29. var currentModule = "";
  30. var moduleIndex = 0;
  31. var start = new Date().getTime();
  32. var fileFilter = [];
  33. var testFilter = [];
  34. Error.stackTraceLimit = 100;
  35. if (argv.suites) {
  36. fileFilter = argv.suites.replace(/\s/g, '').split(',');
  37. }
  38. if (argv.tests) {
  39. testFilter = argv.tests.replace(/\s/g, '').split(',');
  40. }
  41. var assert = require('nodeunit/lib/assert');
  42. require('nodeunit/lib/assert').equal = function equal(actual, expected, message) {
  43. if (actual != expected) {
  44. if (actual && actual.nodeType) {
  45. actual = actual.toString();
  46. }
  47. if (expected && expected.nodeType) {
  48. expected = expected.toString();
  49. }
  50. assert.fail(actual, expected, message, '==', assert.equal);
  51. }
  52. };
  53. assert.domSame = function(actual, expected, message) {
  54. if(expected != actual) {
  55. assert.equal(expected.nodeType, actual.nodeType);
  56. assert.equal(expected.nodeValue, actual.nodeValue);
  57. }
  58. };
  59. var files = [
  60. "level1/core.js",
  61. "level1/html.js",
  62. "level1/svg.js",
  63. "level2/core.js",
  64. "level2/html.js",
  65. "level2/style.js",
  66. "level2/extra.js",
  67. //"level3/core.js",
  68. //"level3/ls.js",
  69. "level3/xpath.js",
  70. "window",
  71. "sizzle/index.js",
  72. "jsdom/index.js"
  73. ];
  74. if (fileFilter.length > 0) {
  75. files = files.filter(function(val) {
  76. var ok = false;
  77. fileFilter.forEach(function(v) {
  78. if (val.indexOf(v) > -1) {
  79. ok = true;
  80. }
  81. });
  82. return ok;
  83. });
  84. }
  85. var modules = {};
  86. var modulesToRun = {};
  87. files.map(function (p) {
  88. var required = require(path.join(__dirname, p));
  89. var module = required.tests || required;
  90. var filteredModule = {};
  91. if (testFilter.length) {
  92. var moduleKeys = Object.keys(module);
  93. testFilter.forEach(function(filter) {
  94. filter = filter.toLowerCase();
  95. moduleKeys.forEach(function(moduleKey) {
  96. if (moduleKey.toLowerCase().indexOf(filter) > -1) {
  97. filteredModule[moduleKey] = module[moduleKey];
  98. }
  99. });
  100. });
  101. module = filteredModule;
  102. }
  103. if (module && Object.keys(module).length > 0) {
  104. modulesToRun[p] = module;
  105. }
  106. });
  107. nodeunit.runModules(modulesToRun, {
  108. moduleStart: function (name) {
  109. currentModule = name.replace('.js', '');
  110. console.log("running", name, currentModule);
  111. modules[currentModule] = {
  112. total : 0,
  113. fail : 0,
  114. pass : 0
  115. };
  116. moduleIndex++;
  117. },
  118. moduleDone: function (name, assertions) {
  119. },
  120. testStart: function () {
  121. modules[currentModule].total++;
  122. },
  123. testDone: function (name, assertions) {
  124. totalTests++;
  125. if (!assertions.failures()) {
  126. passedTests++;
  127. modules[currentModule].pass++;
  128. }
  129. else {
  130. failedTests++;
  131. modules[currentModule].fail++;
  132. console.log('✖ ' + currentModule + '/' + name);
  133. assertions.forEach(function (a) {
  134. if (a.failed()) {
  135. if (a.error instanceof AssertionError) {
  136. a = nodeunit.utils.betterErrors(a);
  137. if (a.message) {
  138. console.log(
  139. 'Assertion Message: ' + assertion_message(a.message) + '\n' +
  140. 'expected:', a.error.expected, 'got:', a.error.actual
  141. );
  142. }
  143. } else {
  144. if (a.error.expected || a.error.actual) {
  145. console.log('\nERROR', a.error.expected, 'vs', a.error.actual, '\n');
  146. }
  147. console.log(a.error.message, a.error.stack, (new Error()).stack);
  148. }
  149. } else {
  150. console.log(a.message);
  151. }
  152. });
  153. if (argv['fail-fast']) {
  154. process.exit();
  155. }
  156. }
  157. },
  158. done: function (assertions) {
  159. var end = new Date().getTime();
  160. var duration = end - start;
  161. var maxWidths = {
  162. name : 0,
  163. ratio : 0,
  164. percent : 4
  165. };
  166. var width = 0;
  167. var keys = Object.keys(modules);
  168. var calculateMax = function(name, value) {
  169. if (!maxWidths[name] || value.length > maxWidths[name]) {
  170. maxWidths[name] = value.length;
  171. }
  172. width = 2;
  173. Object.keys(maxWidths).forEach(function(v) {
  174. width += maxWidths[v] + 2;
  175. });
  176. }
  177. var pad = function(name, value, rightJustified) {
  178. var ret = '';
  179. var padding = '';
  180. var amount = maxWidths[name] - value.length;
  181. while(amount--) {
  182. padding += " ";
  183. }
  184. if (rightJustified) {
  185. return ' ' + padding + value + ' ';
  186. } else {
  187. return ' ' + value + padding + ' ';
  188. }
  189. }
  190. // First pass, calculate the max widths
  191. keys.forEach(function(v) {
  192. var module = modules[v];
  193. var ratio = module.pass + '/' + module.total;
  194. var percentage = Math.floor((module.pass/module.total)*100) + '%';
  195. modules[v].ratio = ratio;
  196. modules[v].percentage = percentage;
  197. calculateMax('name', v);
  198. calculateMax('ratio', ratio);
  199. calculateMax('percentage', percentage);
  200. });
  201. var caps = '';
  202. var gen = width;
  203. while(gen--) {
  204. caps += '-';
  205. }
  206. console.log('');
  207. Object.keys(modules).forEach(function(v) {
  208. var module = modules[v];
  209. process.stdout.write(pad('name', v, false));
  210. process.stdout.write(pad('ratio', module.ratio, true));
  211. process.stdout.write(pad('percentage', module.percentage, true));
  212. process.stdout.write('\n');
  213. });
  214. console.log(caps);
  215. var ratio = failedTests + '/' + totalTests;
  216. var percent = 0;
  217. if (totalTests === 0) {
  218. percent = '100%';
  219. } else {
  220. percent = Math.floor((passedTests/totalTests)*100) + '%';
  221. }
  222. console.log('TOTALS: %s failed; %s success', ratio, percent);
  223. console.log('TIME: %dms', duration);
  224. }
  225. });