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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 // This file emulates Mocha test framework used in promises-aplus tests.
29
30 var describe;
31 var it;
32 var specify;
33 var before;
34 var after;
35 var beforeEach;
36 var afterEach;
37 var RunAllTests;
38
39 var assert = require('assert');
40
41 (function() {
42 var TIMEOUT = 1000;
43
44 function PostMicrotask(fn) {
45 var o = {};
46 Object.observe(o, function() {
47 fn();
48 });
49 // Change something to enqueue a microtask.
50 o.x = 'hello';
51 }
52
53 var context = {
54 beingDescribed: undefined,
55 currentSuiteIndex: 0,
56 suites: []
57 };
58
59 function Run() {
60 function current() {
61 while (context.currentSuiteIndex < context.suites.length &&
62 context.suites[context.currentSuiteIndex].hasRun) {
63 ++context.currentSuiteIndex;
64 }
65 if (context.suites.length == context.currentSuiteIndex) {
66 return undefined;
67 }
68 return context.suites[context.currentSuiteIndex];
69 }
70 var suite = current();
71 if (!suite) {
72 // done
73 print('All tests have run.');
74 return;
75 }
76 suite.Run();
77 }
78
79 RunAllTests = function() {
80 context.currentSuiteIndex = 0;
81 var numRegularTestCases = 0;
82 for (var i = 0; i < context.suites.length; ++i) {
83 numRegularTestCases += context.suites[i].numRegularTestCases();
84 }
85 print(context.suites.length + ' suites and ' + numRegularTestCases +
86 ' test cases are found');
87 Run();
88 };
89
90 function TestCase(name, before, fn, after, isRegular) {
91 this.name = name;
92 this.before = before;
93 this.fn = fn;
94 this.after = after;
95 this.isRegular = isRegular;
96 this.hasDone = false;
97 }
98
99 TestCase.prototype.RunFunction = function(suite, fn, postAction) {
100 if (!fn) {
101 postAction();
102 return;
103 }
104 try {
105 if (fn.length === 0) {
106 // synchronous
107 fn();
108 postAction();
109 } else {
110 // asynchronous
111 fn(postAction);
112 }
113 } catch (e) {
114 suite.ReportError(this, e);
115 }
116 }
117
118 TestCase.prototype.MarkAsDone = function() {
119 this.hasDone = true;
120 clearTimeout(this.timer);
121 }
122
123 TestCase.prototype.Run = function(suite, postAction) {
124 print('Running ' + suite.description + '#' + this.name + ' ...');
125 assert.clear();
126
127 this.timer = setTimeout(function() {
128 suite.ReportError(this, Error('timeout'));
129 }.bind(this), TIMEOUT);
130
131 this.RunFunction(suite, this.before, function(e) {
132 if (this.hasDone) {
133 return;
134 }
135 if (e instanceof Error) {
136 return suite.ReportError(this, e);
137 }
138 if (assert.fails.length > 0) {
139 return suite.ReportError(this, assert.fails[0]);
140 }
141 this.RunFunction(suite, this.fn, function(e) {
142 if (this.hasDone) {
143 return;
144 }
145 if (e instanceof Error) {
146 return suite.ReportError(this, e);
147 }
148 if (assert.fails.length > 0) {
149 return suite.ReportError(this, assert.fails[0]);
150 }
151 this.RunFunction(suite, this.after, function(e) {
152 if (this.hasDone) {
153 return;
154 }
155 if (e instanceof Error) {
156 return suite.ReportError(this, e);
157 }
158 if (assert.fails.length > 0) {
159 return suite.ReportError(this, assert.fails[0]);
160 }
161 this.MarkAsDone();
162 if (this.isRegular) {
163 print('PASS: ' + suite.description + '#' + this.name);
164 }
165 PostMicrotask(postAction);
166 }.bind(this));
167 }.bind(this));
168 }.bind(this));
169 };
170
171 function TestSuite(described) {
172 this.description = described.description;
173 this.cases = [];
174 this.currentIndex = 0;
175 this.hasRun = false;
176
177 if (described.before) {
178 this.cases.push(new TestCase(this.description + ' :before', undefined,
179 described.before, undefined, false));
180 }
181 for (var i = 0; i < described.cases.length; ++i) {
182 this.cases.push(new TestCase(described.cases[i].description,
183 described.beforeEach,
184 described.cases[i].fn,
185 described.afterEach,
186 true));
187 }
188 if (described.after) {
189 this.cases.push(new TestCase(this.description + ' :after',
190 undefined, described.after, undefined, false));
191 }
192 }
193
194 TestSuite.prototype.Run = function() {
195 this.hasRun = this.currentIndex === this.cases.length;
196 if (this.hasRun) {
197 PostMicrotask(Run);
198 return;
199 }
200
201 // TestCase.prototype.Run cannot throw an exception.
202 this.cases[this.currentIndex].Run(this, function() {
203 ++this.currentIndex;
204 PostMicrotask(Run);
205 }.bind(this));
206 };
207
208 TestSuite.prototype.numRegularTestCases = function() {
209 var n = 0;
210 for (var i = 0; i < this.cases.length; ++i) {
211 if (this.cases[i].isRegular) {
212 ++n;
213 }
214 }
215 return n;
216 }
217
218 TestSuite.prototype.ReportError = function(testCase, e) {
219 if (testCase.hasDone) {
220 return;
221 }
222 testCase.MarkAsDone();
223 this.hasRun = this.currentIndex === this.cases.length;
224 print('FAIL: ' + this.description + '#' + testCase.name + ': ' +
225 e.name + ' (' + e.message + ')');
226 ++this.currentIndex;
227 PostMicrotask(Run);
228 };
229
230 describe = function(description, fn) {
231 var parent = context.beingDescribed;
232 var incomplete = {
233 cases: [],
234 description: parent ? parent.description + ' ' + description : description,
235 parent: parent,
236 };
237 context.beingDescribed = incomplete;
238 fn();
239 context.beingDescribed = parent;
240
241 context.suites.push(new TestSuite(incomplete));
242 }
243
244 specify = it = function(description, fn) {
245 context.beingDescribed.cases.push({description: description, fn: fn});
246 }
247
248 before = function(fn) {
249 context.beingDescribed.before = fn;
250 }
251
252 after = function(fn) {
253 context.beingDescribed.after = fn;
254 }
255
256 beforeEach = function(fn) {
257 context.beingDescribed.beforeEach = fn;
258 }
259
260 afterEach = function(fn) {
261 context.beingDescribed.afterEach = fn;
262 }
263
264 }());
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698