child.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. var path = require('path');
  2. var fs = require('fs');
  3. var nodeunit = require('nodeunit');
  4. var filepaths = fs.readdirSync('test').map(function(filename) {
  5. return path.join('test', filename);
  6. });
  7. var unfinished = {};
  8. var currentModule;
  9. function sendMessage(message) {
  10. process.stdout.write(JSON.stringify(message) + '\n');
  11. }
  12. // If an exception is thrown, let the parent process know and exit.
  13. process.on('uncaughtException', function (e) {
  14. sendMessage({error: [e.name, e.message, e.stack]});
  15. process.exit();
  16. });
  17. // If Nodeunit explodes because a test was missing test.done(), handle it.
  18. var unfinished = {};
  19. process.on('exit', function (e) {
  20. var len = Object.keys(unfinished).length
  21. if (len > 0) {
  22. sendMessage({exit: ['UNFINISHED']});
  23. // process.reallyExit(len);
  24. } else {
  25. sendMessage({exit: ['finished']});
  26. }
  27. // process.exit();
  28. });
  29. nodeunit.reporters.test = {
  30. run: function(files, options, callback) {
  31. // Nodeunit needs absolute paths.
  32. var paths = files.map(function (filepath) {
  33. return path.resolve(filepath);
  34. });
  35. nodeunit.runFiles(paths, {
  36. // No idea.
  37. testspec: undefined,
  38. // Executed when the first test in a file is run. If no tests exist in
  39. // the file, this doesn't execute.
  40. moduleStart: function(name) {
  41. // Keep track of this so that moduleDone output can be suppressed in
  42. // cases where a test file contains no tests.
  43. currentModule = name;
  44. // Send back to the parent process.
  45. sendMessage({moduleStart: [name.toString()]});
  46. },
  47. // Executed after a file is done being processed. This executes whether
  48. // tests exist in the file or not.
  49. moduleDone: function(name) {
  50. // Abort if no tests actually ran.
  51. if (name !== currentModule) { return; }
  52. // Send back to the parent process.
  53. sendMessage({moduleDone: [name.toString()]});
  54. },
  55. // Executed before each test is run.
  56. testStart: function(name) {
  57. // Keep track of the current test, in case test.done() was omitted
  58. // and Nodeunit explodes.
  59. unfinished[name] = name;
  60. // Send back to the parent process.
  61. sendMessage({testStart: [name.toString()]});
  62. },
  63. // Executed after each test and all its assertions are run.
  64. testDone: function(name, assertions) {
  65. delete unfinished[name];
  66. // Send back to the parent process.
  67. sendMessage({testDone: [
  68. name.toString(),
  69. assertions.failures(),
  70. assertions.map(function(assertion) {
  71. var e = assertion.error;
  72. if (e) {
  73. assertion.error = {
  74. name: e.name,
  75. message: e.message,
  76. stack: e.stack
  77. };
  78. }
  79. return assertion;
  80. })
  81. ]});
  82. },
  83. // Executed when everything is all done.
  84. done: function (assertions) {
  85. // Send back to the parent process.
  86. sendMessage({done: [
  87. assertions.failures(),
  88. assertions.duration,
  89. assertions
  90. ]});
  91. }
  92. });
  93. }
  94. }
  95. nodeunit.reporters.test.run(filepaths, {});