| Index: test/promises-aplus/lib/mocha.js
|
| diff --git a/test/promises-aplus/lib/mocha.js b/test/promises-aplus/lib/mocha.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..24d294ef8f829889fbcdccf1a9893f92635c7aea
|
| --- /dev/null
|
| +++ b/test/promises-aplus/lib/mocha.js
|
| @@ -0,0 +1,264 @@
|
| +// Copyright 2014 the V8 project authors. All rights reserved.
|
| +// Redistribution and use in source and binary forms, with or without
|
| +// modification, are permitted provided that the following conditions are
|
| +// met:
|
| +//
|
| +// * Redistributions of source code must retain the above copyright
|
| +// notice, this list of conditions and the following disclaimer.
|
| +// * Redistributions in binary form must reproduce the above
|
| +// copyright notice, this list of conditions and the following
|
| +// disclaimer in the documentation and/or other materials provided
|
| +// with the distribution.
|
| +// * Neither the name of Google Inc. nor the names of its
|
| +// contributors may be used to endorse or promote products derived
|
| +// from this software without specific prior written permission.
|
| +//
|
| +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
| +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
| +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
| +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
| +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
| +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
| +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| +
|
| +// This file emulates Mocha test framework used in promises-aplus tests.
|
| +
|
| +var describe;
|
| +var it;
|
| +var specify;
|
| +var before;
|
| +var after;
|
| +var beforeEach;
|
| +var afterEach;
|
| +var RunAllTests;
|
| +
|
| +var assert = require('assert');
|
| +
|
| +(function() {
|
| +var TIMEOUT = 1000;
|
| +
|
| +function PostMicrotask(fn) {
|
| + var o = {};
|
| + Object.observe(o, function() {
|
| + fn();
|
| + });
|
| + // Change something to enqueue a microtask.
|
| + o.x = 'hello';
|
| +}
|
| +
|
| +var context = {
|
| + beingDescribed: undefined,
|
| + currentSuiteIndex: 0,
|
| + suites: []
|
| +};
|
| +
|
| +function Run() {
|
| + function current() {
|
| + while (context.currentSuiteIndex < context.suites.length &&
|
| + context.suites[context.currentSuiteIndex].hasRun) {
|
| + ++context.currentSuiteIndex;
|
| + }
|
| + if (context.suites.length == context.currentSuiteIndex) {
|
| + return undefined;
|
| + }
|
| + return context.suites[context.currentSuiteIndex];
|
| + }
|
| + var suite = current();
|
| + if (!suite) {
|
| + // done
|
| + print('All tests have run.');
|
| + return;
|
| + }
|
| + suite.Run();
|
| +}
|
| +
|
| +RunAllTests = function() {
|
| + context.currentSuiteIndex = 0;
|
| + var numRegularTestCases = 0;
|
| + for (var i = 0; i < context.suites.length; ++i) {
|
| + numRegularTestCases += context.suites[i].numRegularTestCases();
|
| + }
|
| + print(context.suites.length + ' suites and ' + numRegularTestCases +
|
| + ' test cases are found');
|
| + Run();
|
| +};
|
| +
|
| +function TestCase(name, before, fn, after, isRegular) {
|
| + this.name = name;
|
| + this.before = before;
|
| + this.fn = fn;
|
| + this.after = after;
|
| + this.isRegular = isRegular;
|
| + this.hasDone = false;
|
| +}
|
| +
|
| +TestCase.prototype.RunFunction = function(suite, fn, postAction) {
|
| + if (!fn) {
|
| + postAction();
|
| + return;
|
| + }
|
| + try {
|
| + if (fn.length === 0) {
|
| + // synchronous
|
| + fn();
|
| + postAction();
|
| + } else {
|
| + // asynchronous
|
| + fn(postAction);
|
| + }
|
| + } catch (e) {
|
| + suite.ReportError(this, e);
|
| + }
|
| +}
|
| +
|
| +TestCase.prototype.MarkAsDone = function() {
|
| + this.hasDone = true;
|
| + clearTimeout(this.timer);
|
| +}
|
| +
|
| +TestCase.prototype.Run = function(suite, postAction) {
|
| + print('Running ' + suite.description + '#' + this.name + ' ...');
|
| + assert.clear();
|
| +
|
| + this.timer = setTimeout(function() {
|
| + suite.ReportError(this, Error('timeout'));
|
| + }.bind(this), TIMEOUT);
|
| +
|
| + this.RunFunction(suite, this.before, function(e) {
|
| + if (this.hasDone) {
|
| + return;
|
| + }
|
| + if (e instanceof Error) {
|
| + return suite.ReportError(this, e);
|
| + }
|
| + if (assert.fails.length > 0) {
|
| + return suite.ReportError(this, assert.fails[0]);
|
| + }
|
| + this.RunFunction(suite, this.fn, function(e) {
|
| + if (this.hasDone) {
|
| + return;
|
| + }
|
| + if (e instanceof Error) {
|
| + return suite.ReportError(this, e);
|
| + }
|
| + if (assert.fails.length > 0) {
|
| + return suite.ReportError(this, assert.fails[0]);
|
| + }
|
| + this.RunFunction(suite, this.after, function(e) {
|
| + if (this.hasDone) {
|
| + return;
|
| + }
|
| + if (e instanceof Error) {
|
| + return suite.ReportError(this, e);
|
| + }
|
| + if (assert.fails.length > 0) {
|
| + return suite.ReportError(this, assert.fails[0]);
|
| + }
|
| + this.MarkAsDone();
|
| + if (this.isRegular) {
|
| + print('PASS: ' + suite.description + '#' + this.name);
|
| + }
|
| + PostMicrotask(postAction);
|
| + }.bind(this));
|
| + }.bind(this));
|
| + }.bind(this));
|
| +};
|
| +
|
| +function TestSuite(described) {
|
| + this.description = described.description;
|
| + this.cases = [];
|
| + this.currentIndex = 0;
|
| + this.hasRun = false;
|
| +
|
| + if (described.before) {
|
| + this.cases.push(new TestCase(this.description + ' :before', undefined,
|
| + described.before, undefined, false));
|
| + }
|
| + for (var i = 0; i < described.cases.length; ++i) {
|
| + this.cases.push(new TestCase(described.cases[i].description,
|
| + described.beforeEach,
|
| + described.cases[i].fn,
|
| + described.afterEach,
|
| + true));
|
| + }
|
| + if (described.after) {
|
| + this.cases.push(new TestCase(this.description + ' :after',
|
| + undefined, described.after, undefined, false));
|
| + }
|
| +}
|
| +
|
| +TestSuite.prototype.Run = function() {
|
| + this.hasRun = this.currentIndex === this.cases.length;
|
| + if (this.hasRun) {
|
| + PostMicrotask(Run);
|
| + return;
|
| + }
|
| +
|
| + // TestCase.prototype.Run cannot throw an exception.
|
| + this.cases[this.currentIndex].Run(this, function() {
|
| + ++this.currentIndex;
|
| + PostMicrotask(Run);
|
| + }.bind(this));
|
| +};
|
| +
|
| +TestSuite.prototype.numRegularTestCases = function() {
|
| + var n = 0;
|
| + for (var i = 0; i < this.cases.length; ++i) {
|
| + if (this.cases[i].isRegular) {
|
| + ++n;
|
| + }
|
| + }
|
| + return n;
|
| +}
|
| +
|
| +TestSuite.prototype.ReportError = function(testCase, e) {
|
| + if (testCase.hasDone) {
|
| + return;
|
| + }
|
| + testCase.MarkAsDone();
|
| + this.hasRun = this.currentIndex === this.cases.length;
|
| + print('FAIL: ' + this.description + '#' + testCase.name + ': ' +
|
| + e.name + ' (' + e.message + ')');
|
| + ++this.currentIndex;
|
| + PostMicrotask(Run);
|
| +};
|
| +
|
| +describe = function(description, fn) {
|
| + var parent = context.beingDescribed;
|
| + var incomplete = {
|
| + cases: [],
|
| + description: parent ? parent.description + ' ' + description : description,
|
| + parent: parent,
|
| + };
|
| + context.beingDescribed = incomplete;
|
| + fn();
|
| + context.beingDescribed = parent;
|
| +
|
| + context.suites.push(new TestSuite(incomplete));
|
| +}
|
| +
|
| +specify = it = function(description, fn) {
|
| + context.beingDescribed.cases.push({description: description, fn: fn});
|
| +}
|
| +
|
| +before = function(fn) {
|
| + context.beingDescribed.before = fn;
|
| +}
|
| +
|
| +after = function(fn) {
|
| + context.beingDescribed.after = fn;
|
| +}
|
| +
|
| +beforeEach = function(fn) {
|
| + context.beingDescribed.beforeEach = fn;
|
| +}
|
| +
|
| +afterEach = function(fn) {
|
| + context.beingDescribed.afterEach = fn;
|
| +}
|
| +
|
| +}());
|
|
|