Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Unified Diff: test/promises-aplus/lib/mocha.js

Issue 196733002: Add Promises/A+ Compliance Test Suite. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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;
+}
+
+}());

Powered by Google App Engine
This is Rietveld 408576698