index.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. var fs = require('fs'),
  2. path = require('path');
  3. function JasmineRunner(options, callback){
  4. var doServer = options.serve,
  5. port = options.port || 8081,
  6. refreshInterval = options.refreshInterval || 2000,
  7. runners = options.runners || null,
  8. that = this;
  9. this.isRunningTests = false;
  10. this.isTestRunQueued = false;
  11. this.reporter = this._setupReporter(function(){
  12. callback();
  13. }); // async
  14. if(doServer){
  15. this.server = that._setupServer({
  16. port: port,
  17. reporter: this.reporter,
  18. refreshInterval: refreshInterval
  19. });
  20. };
  21. if(runners){
  22. this.tests = this._setupRunners({
  23. runners: runners,
  24. jasmineReporter: this.reporter.getJasmineReporter(),
  25. });
  26. } else {
  27. console.error("I don't have any tests to run!");
  28. process.exit(1);
  29. }
  30. };
  31. JasmineRunner.prototype._setupReporter = function(callback){
  32. console.debug("Setting up reporter");
  33. var reporter = require('./reporter-agregator.js').create({
  34. onDone: function(){
  35. console.debug("Reporter created.");
  36. callback();
  37. }
  38. });
  39. return reporter;
  40. };
  41. JasmineRunner.prototype._setupServer = function(options){
  42. console.debug("Setting up server");
  43. var that = this,
  44. server = require('./server.js');
  45. server.start(options.port, function(){
  46. callback(server);
  47. });
  48. options.reporter.onUpdate(function(report){
  49. server.updateHtml(report.html);
  50. server.updateJson(report.simple);
  51. console.debug("Tests will run again in " + (options.refreshInterval/1000) + " seconds.");
  52. setTimeout(function(){
  53. that.runTests();
  54. }, options.refreshInterval);
  55. });
  56. return server;
  57. };
  58. JasmineRunner.prototype._setupRunners = function(options,callback){
  59. console.debug("Setting up tests.");
  60. var tests = [];
  61. var runners = options.runners || [],
  62. jasmineReporter = options.jasmineReporter;
  63. for(var k in runners){
  64. var runner = runners[k];
  65. console.debug('Creating test based on ' + runner);
  66. var test = require('./runner-from-html.js').create({
  67. runner: runner,
  68. jasmineReporter: jasmineReporter
  69. });
  70. tests.push(test);
  71. }
  72. console.debug("Finished creating tests ( based on " +tests.length + " runner/s).");
  73. return tests;
  74. };
  75. JasmineRunner.prototype.runTests = function(callback){
  76. var that = this;
  77. // We have to maintain synchronisity, otherwise things
  78. // get hectic.
  79. if(this.isRunningTests) {
  80. // DANGER: if more than one call to runTests is made when
  81. // tests are running, only the last callback will ever be
  82. // triggered.
  83. this.isTestRunQueued = true;
  84. this.queuedCallback = callback;
  85. console.debug("Cannot run tests concurrently. Queued another run.");
  86. return;
  87. };
  88. var whenAllTestsHaveRun = function(){
  89. console.debug("Finished running tests.");
  90. if(callback) callback(that.reporter.getReport());
  91. that.reporter.reset();
  92. that.isRunningTests = false;
  93. if(that.isTestRunQueued){
  94. that.isTestRunQueued = false;
  95. that.runTests(that.queuedCallback);
  96. that.queuedCallback = false;
  97. }
  98. };
  99. console.debug("Running tests.");
  100. this.isRunningTests = true;
  101. var queue = [],
  102. tests = this.tests;
  103. for(var i = 0; i < tests.length; i++) queue.push(tests[i]);
  104. // !! Is recursive
  105. var runNextTest = function(){
  106. if(queue.length == 0){
  107. whenAllTestsHaveRun();
  108. return;
  109. }
  110. var test = queue.pop();
  111. console.debug("Running " + test.name);
  112. test.run(function(){
  113. console.debug("Finished running " + test.name);
  114. runNextTest();
  115. });
  116. };
  117. runNextTest();
  118. };
  119. exports.run = function(options, callback){
  120. var onDone = options.onDone || function(){},
  121. debug = options.debug;
  122. console.debug = debug ? function(msg){ console.log(msg); } : function(msg){};
  123. process.on('uncaughtException', function(err){
  124. if(debug){
  125. console.debug("An uncaught error occured!");
  126. console.error(err.message + "\n",err.stack);
  127. } else {
  128. console.error("An error occurred while running the tests. Use the --debug switch to find out more.")
  129. exit(1);
  130. }
  131. });
  132. var runner = new JasmineRunner(options, function(){
  133. runner.runTests(onDone);
  134. callback( runner );
  135. });
  136. };