diff --git a/lib/mochaIntellijReporter.js b/lib/mochaIntellijReporter.js index e41ef54..5924b8a 100644 --- a/lib/mochaIntellijReporter.js +++ b/lib/mochaIntellijReporter.js @@ -1,7 +1,8 @@ var Tree = require('./mochaIntellijTree') , util = require('./mochaIntellijUtil') , treeUtil = require('./mochaTreeUtil') - , normalizer = require('./normalizer'); + , normalizer = require('./normalizer') + , SingleElementQueue = require('./single-element-queue'); /** * @param {Tree} tree @@ -159,8 +160,9 @@ function addStdErr(testNode, err) { * @param {Tree} tree * @param {Object} test mocha test object * @param {Object} err mocha error object + * @param {SingleElementQueue} [finishingQueue] */ -function finishTestNode(tree, test, err) { +function finishTestNode(tree, test, err, finishingQueue) { var testNode = treeUtil.getNodeForTest(test); if (testNode != null && testNode.isFinished()) { /* See https://youtrack.jetbrains.com/issue/WEB-10637 @@ -188,7 +190,12 @@ function finishTestNode(tree, test, err) { var status = test.pending ? Tree.TestOutcome.SKIPPED : Tree.TestOutcome.SUCCESS; testNode.setOutcome(status, test.duration, null, null, null, null); } - testNode.finish(false); + if (finishingQueue != null) { + finishingQueue.add(testNode); + } + else { + testNode.finish(false); + } } /** @@ -267,6 +274,10 @@ function IntellijReporter(runner) { var executeSafely = util.executeSafely; var tree; + // allows to postpone sending test finished event until 'afterEach' is done + var finishingQueue = new SingleElementQueue(function (testNode) { + testNode.finish(false); + }); runner.on('start', function () { executeSafely(function () { @@ -295,24 +306,26 @@ function IntellijReporter(runner) { runner.on('test', function (test) { executeSafely(function () { + finishingQueue.processAll(); startTest(tree, test); }); }); runner.on('pending', function (test) { executeSafely(function () { - finishTestNode(tree, test, null); + finishTestNode(tree, test, null, finishingQueue); }); }); runner.on('pass', function (test) { executeSafely(function () { - finishTestNode(tree, test, null); + finishTestNode(tree, test, null, finishingQueue); }); }); runner.on('fail', function (test, err) { executeSafely(function () { + finishingQueue.processAll(); if (isBeforeEachHook(test)) { handleBeforeEachHookFailure(tree, test, err); } @@ -321,13 +334,14 @@ function IntellijReporter(runner) { markChildrenFailed(tree, test.parent, test.title + " failed"); } else { - finishTestNode(tree, test, err); + finishTestNode(tree, test, err, finishingQueue); } }); }); runner.on('suite end', function (suite) { executeSafely(function () { + finishingQueue.processAll(); if (!suite.root) { finishSuite(suite); } @@ -336,6 +350,7 @@ function IntellijReporter(runner) { runner.on('end', function () { executeSafely(function () { + finishingQueue.processAll(); tree = null; }); }); diff --git a/lib/single-element-queue.js b/lib/single-element-queue.js new file mode 100644 index 0000000..db6b298 --- /dev/null +++ b/lib/single-element-queue.js @@ -0,0 +1,25 @@ +/** + * @constructor + * @param {Function} processor + */ +function SingleElementQueue(processor) { + this.processor = processor; + this.current = null; +} + +SingleElementQueue.prototype.add = function (element) { + if (this.current != null) { + process.stderr.write("mocha-intellij: unexpectedly unprocessed element " + element); + this.processor(this.current); + } + this.current = element; +}; + +SingleElementQueue.prototype.processAll = function () { + if (this.current != null) { + this.processor(this.current); + this.current = null; + } +}; + +module.exports = SingleElementQueue;