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

Side by Side Diff: third_party/WebKit/LayoutTests/webaudio/resources/audit.js

Issue 2895963003: Apply layout-test-tidy to LayoutTests/webaudio (Closed)
Patch Set: Created 3 years, 7 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 /** 6 /**
7 * @fileOverview WebAudio layout test utility library. Built around W3C's 7 * @fileOverview WebAudio layout test utility library. Built around W3C's
8 * testharness.js. Includes asynchronous test task manager, 8 * testharness.js. Includes asynchronous test task manager,
9 * assertion utilities. 9 * assertion utilities.
10 * @dependency testharness.js 10 * @dependency testharness.js
11 */ 11 */
12 12
13 13
14 (function () { 14 (function() {
15 15
16 'use strict'; 16 'use strict';
17 17
18 // Selected methods from testharness.js. 18 // Selected methods from testharness.js.
19 let testharnessProperties = [ 19 let testharnessProperties = [
20 'test', 'async_test', 'promise_test', 'promise_rejects', 20 'test', 'async_test', 'promise_test', 'promise_rejects', 'generate_tests',
21 'generate_tests', 'setup', 'done', 'assert_true', 'assert_false' 21 'setup', 'done', 'assert_true', 'assert_false'
22 ]; 22 ];
23 23
24 // Check if testharness.js is properly loaded. Throw otherwise. 24 // Check if testharness.js is properly loaded. Throw otherwise.
25 for (let name in testharnessProperties) { 25 for (let name in testharnessProperties) {
26 if (!self.hasOwnProperty(testharnessProperties[name])) 26 if (!self.hasOwnProperty(testharnessProperties[name]))
27 throw new Error('Cannot proceed. testharness.js is not loaded.'); 27 throw new Error('Cannot proceed. testharness.js is not loaded.');
28 } 28 }
29 })(); 29 })();
30 30
31 31
32 window.Audit = (function () { 32 window.Audit = (function() {
33 33
34 'use strict'; 34 'use strict';
35 35
36 // NOTE: Moving this method (or any other code above) will change the location 36 // NOTE: Moving this method (or any other code above) will change the location
37 // of 'CONSOLE ERROR...' message in the expected text files. 37 // of 'CONSOLE ERROR...' message in the expected text files.
38 function _logError (message) { 38 function _logError(message) {
39 console.error('[audit.js] ' + message); 39 console.error('[audit.js] ' + message);
40 } 40 }
41 41
42 function _logPassed (message) { 42 function _logPassed(message) {
43 test(function (arg) { 43 test(function(arg) {
44 assert_true(true); 44 assert_true(true);
45 }, message); 45 }, message);
46 } 46 }
47 47
48 function _logFailed (message, detail) { 48 function _logFailed(message, detail) {
49 test(function () { 49 test(function() {
50 assert_true(false, detail); 50 assert_true(false, detail);
51 }, message); 51 }, message);
52 } 52 }
53 53
54 function _throwException (message) { 54 function _throwException(message) {
55 throw new Error(message); 55 throw new Error(message);
56 } 56 }
57 57
58 // TODO(hongchan): remove this hack after confirming all the tests are 58 // TODO(hongchan): remove this hack after confirming all the tests are
59 // finished correctly. (crbug.com/708817) 59 // finished correctly. (crbug.com/708817)
60 const _testharnessDone = window.done; 60 const _testharnessDone = window.done;
61 window.done = () => { 61 window.done = () => {
62 _throwException('Do NOT call done() method from the test code.'); 62 _throwException('Do NOT call done() method from the test code.');
63 }; 63 };
64 64
65 // Generate a descriptive string from a target value in various types. 65 // Generate a descriptive string from a target value in various types.
66 function _generateDescription (target, options) { 66 function _generateDescription(target, options) {
67 let targetString; 67 let targetString;
68 68
69 switch (typeof target) { 69 switch (typeof target) {
70 case 'object': 70 case 'object':
71 // Handle Arrays. 71 // Handle Arrays.
72 if (target instanceof Array || target instanceof Float32Array || 72 if (target instanceof Array || target instanceof Float32Array ||
73 target instanceof Float64Array || target instanceof Uint8Array) { 73 target instanceof Float64Array || target instanceof Uint8Array) {
74 let arrayElements = target.length < options.numberOfArrayElements 74 let arrayElements = target.length < options.numberOfArrayElements ?
75 ? String(target) 75 String(target) :
76 : String(target.slice(0, options.numberOfArrayElements)) + '...'; 76 String(target.slice(0, options.numberOfArrayElements)) + '...';
77 targetString = '[' + arrayElements + ']'; 77 targetString = '[' + arrayElements + ']';
78 } else { 78 } else {
79 targetString = '' + String(targetString).split(/[\s\]]/)[1]; 79 targetString = '' + String(targetString).split(/[\s\]]/)[1];
80 } 80 }
81 break; 81 break;
82 default: 82 default:
83 targetString = String(target); 83 targetString = String(target);
84 break; 84 break;
85 } 85 }
86 86
87 return targetString; 87 return targetString;
88 } 88 }
89 89
90 // Return a string suitable for printing one failed element in 90 // Return a string suitable for printing one failed element in
91 // |beCloseToArray|. 91 // |beCloseToArray|.
92 function _formatFailureEntry(index, actual, expected, abserr, threshold) { 92 function _formatFailureEntry(index, actual, expected, abserr, threshold) {
93 return '\t[' + index + ']\t' 93 return '\t[' + index + ']\t' + actual.toExponential(16) + '\t' +
94 + actual.toExponential(16) + '\t' 94 expected.toExponential(16) + '\t' + abserr.toExponential(16) + '\t' +
95 + expected.toExponential(16) + '\t' 95 (abserr / Math.abs(expected)).toExponential(16) + '\t' +
96 + abserr.toExponential(16) + '\t' 96 threshold.toExponential(16);
97 + (abserr / Math.abs(expected)).toExponential(16) + '\t'
98 + threshold.toExponential(16);
99 } 97 }
100 98
101 // Compute the error threshold criterion for |beCloseToArray| 99 // Compute the error threshold criterion for |beCloseToArray|
102 function _closeToThreshold(abserr, relerr, expected) { 100 function _closeToThreshold(abserr, relerr, expected) {
103 return Math.max(abserr, relerr * Math.abs(expected)); 101 return Math.max(abserr, relerr * Math.abs(expected));
104 } 102 }
105 103
106 /** 104 /**
107 * @class Should 105 * @class Should
108 * @description Assertion subtask for the Audit task. 106 * @description Assertion subtask for the Audit task.
109 * @param {Task} parentTask Associated Task object. 107 * @param {Task} parentTask Associated Task object.
110 * @param {Any} actual Target value to be tested. 108 * @param {Any} actual Target value to be tested.
111 * @param {String} actualDescription String description of the test target. 109 * @param {String} actualDescription String description of the test target.
112 */ 110 */
113 class Should { 111 class Should {
114 112 constructor(parentTask, actual, actualDescription) {
115 constructor (parentTask, actual, actualDescription) {
116 this._task = parentTask; 113 this._task = parentTask;
117 114
118 this._actual = actual; 115 this._actual = actual;
119 this._actualDescription = (actualDescription || null); 116 this._actualDescription = (actualDescription || null);
120 this._expected = null; 117 this._expected = null;
121 this._expectedDescription = null; 118 this._expectedDescription = null;
122 119
123 this._detail = ''; 120 this._detail = '';
124 this._printActualForFailure = true; 121 this._printActualForFailure = true;
125 122
126 this._result = null; 123 this._result = null;
127 124
128 /** 125 /**
129 * @param {Number} numberOfErrors Number of errors to be printed. 126 * @param {Number} numberOfErrors Number of errors to be printed.
130 * @param {Number} numberOfArrayElements Number of array elements to be 127 * @param {Number} numberOfArrayElements Number of array elements to be
131 * printed in the test log. 128 * printed in the test log.
132 * @param {Boolean} verbose Verbose output from the assertion. 129 * @param {Boolean} verbose Verbose output from the assertion.
133 */ 130 */
134 this._options = { 131 this._options = {
135 numberOfErrors: 4, 132 numberOfErrors: 4,
136 numberOfArrayElements: 16, 133 numberOfArrayElements: 16,
137 verbose: false 134 verbose: false
138 }; 135 };
139 } 136 }
140 137
141 _processArguments (args) { 138 _processArguments(args) {
142 if (args.length === 0) 139 if (args.length === 0)
143 return; 140 return;
144 141
145 if (args.length > 0) 142 if (args.length > 0)
146 this._expected = args[0]; 143 this._expected = args[0];
147 144
148 if (typeof args[1] === 'string') { 145 if (typeof args[1] === 'string') {
149 // case 1: (expected, description, options) 146 // case 1: (expected, description, options)
150 this._expectedDescription = args[1]; 147 this._expectedDescription = args[1];
151 Object.assign(this._options, args[2]); 148 Object.assign(this._options, args[2]);
152 } else if (typeof args[1] === 'object') { 149 } else if (typeof args[1] === 'object') {
153 // case 2: (expected, options) 150 // case 2: (expected, options)
154 Object.assign(this._options, args[1]); 151 Object.assign(this._options, args[1]);
155 } 152 }
156 } 153 }
157 154
158 _buildResultText () { 155 _buildResultText() {
159 if (this._result === null) 156 if (this._result === null)
160 _throwException('Illegal invocation: the assertion is not finished.'); 157 _throwException('Illegal invocation: the assertion is not finished.');
161 158
162 let actualString = _generateDescription(this._actual, this._options); 159 let actualString = _generateDescription(this._actual, this._options);
163 160
164 // Use generated text when the description is not provided. 161 // Use generated text when the description is not provided.
165 if (!this._actualDescription) 162 if (!this._actualDescription)
166 this._actualDescription = actualString; 163 this._actualDescription = actualString;
167 164
168 if (!this._expectedDescription) { 165 if (!this._expectedDescription) {
169 this._expectedDescription = 166 this._expectedDescription =
170 _generateDescription(this._expected, this._options); 167 _generateDescription(this._expected, this._options);
171 } 168 }
172 169
173 // For the assertion with a single operand. 170 // For the assertion with a single operand.
174 this._detail = this._detail.replace( 171 this._detail =
175 /\$\{actual\}/g, this._actualDescription); 172 this._detail.replace(/\$\{actual\}/g, this._actualDescription);
176 173
177 // If there is a second operand (i.e. expected value), we have to build 174 // If there is a second operand (i.e. expected value), we have to build
178 // the string for it as well. 175 // the string for it as well.
179 if (this._expected !== null) { 176 if (this._expected !== null) {
180 this._detail = this._detail.replace( 177 this._detail =
181 /\$\{expected\}/g, this._expectedDescription); 178 this._detail.replace(/\$\{expected\}/g, this._expectedDescription);
182 } 179 }
183 180
184 // If there is any property in |_options|, replace the property name 181 // If there is any property in |_options|, replace the property name
185 // with the value. 182 // with the value.
186 for (let name in this._options) { 183 for (let name in this._options) {
187 if (name === 'numberOfErrors' 184 if (name === 'numberOfErrors' || name === 'numberOfArrayElements' ||
188 || name === 'numberOfArrayElements' 185 name === 'verbose') {
189 || name === 'verbose') {
190 continue; 186 continue;
191 } 187 }
192 188
193 // The RegExp key string contains special character. Take care of it. 189 // The RegExp key string contains special character. Take care of it.
194 let re = '\$\{' + name + '\}'; 190 let re = '\$\{' + name + '\}';
195 re = re.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); 191 re = re.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1');
196 this._detail = this._detail.replace(new RegExp(re, 'g'), 192 this._detail = this._detail.replace(
197 _generateDescription(this._options[name])); 193 new RegExp(re, 'g'), _generateDescription(this._options[name]));
198 } 194 }
199 195
200 // If the test failed, add the actual value at the end. 196 // If the test failed, add the actual value at the end.
201 if (this._result === false && this._printActualForFailure === true) { 197 if (this._result === false && this._printActualForFailure === true) {
202 this._detail += ' Got ' + actualString + '.'; 198 this._detail += ' Got ' + actualString + '.';
203 } 199 }
204 } 200 }
205 201
206 _finalize () { 202 _finalize() {
207 if (this._result) { 203 if (this._result) {
208 _logPassed(' ' + this._detail); 204 _logPassed(' ' + this._detail);
209 } else { 205 } else {
210 _logFailed('X ' + this._detail); 206 _logFailed('X ' + this._detail);
211 } 207 }
212 208
213 // This assertion is finished, so update the parent task accordingly. 209 // This assertion is finished, so update the parent task accordingly.
214 this._task.update(this); 210 this._task.update(this);
215 211
216 // TODO(hongchan): configurable 'detail' message. 212 // TODO(hongchan): configurable 'detail' message.
217 } 213 }
218 214
219 _assert (condition, passDetail, failDetail) { 215 _assert(condition, passDetail, failDetail) {
220 this._result = Boolean(condition); 216 this._result = Boolean(condition);
221 this._detail = this._result ? passDetail : failDetail; 217 this._detail = this._result ? passDetail : failDetail;
222 this._buildResultText(); 218 this._buildResultText();
223 this._finalize(); 219 this._finalize();
224 220
225 return this._result; 221 return this._result;
226 } 222 }
227 223
228 get result () { 224 get result() {
229 return this._result; 225 return this._result;
230 } 226 }
231 227
232 get detail () { 228 get detail() {
233 return this._detail; 229 return this._detail;
234 } 230 }
235 231
236 /** 232 /**
237 * should() assertions. 233 * should() assertions.
238 * 234 *
239 * @example All the assertions can have 1, 2 or 3 arguments: 235 * @example All the assertions can have 1, 2 or 3 arguments:
240 * should().doAssert(expected); 236 * should().doAssert(expected);
241 * should().doAssert(expected, options); 237 * should().doAssert(expected, options);
242 * should().doAssert(expected, expectedDescription, options); 238 * should().doAssert(expected, expectedDescription, options);
(...skipping 11 matching lines...) Expand all
254 */ 250 */
255 251
256 /** 252 /**
257 * Check if |actual| exists. 253 * Check if |actual| exists.
258 * 254 *
259 * @example 255 * @example
260 * should({}, 'An empty object').exist(); 256 * should({}, 'An empty object').exist();
261 * @result 257 * @result
262 * "PASS An empty object does exist." 258 * "PASS An empty object does exist."
263 */ 259 */
264 exist () { 260 exist() {
265 return this._assert( 261 return this._assert(
266 this._actual !== null && this._actual !== undefined, 262 this._actual !== null && this._actual !== undefined,
267 '${actual} does exist.', 263 '${actual} does exist.', '${actual} does not exist.');
268 '${actual} does not exist.');
269 } 264 }
270 265
271 /** 266 /**
272 * Check if |actual| operation wrapped in a function throws an exception 267 * Check if |actual| operation wrapped in a function throws an exception
273 * with a expected error type correctly. |expected| is optional. 268 * with a expected error type correctly. |expected| is optional.
274 * 269 *
275 * @example 270 * @example
276 * should(() => { let a = b; }, 'A bad code').throw(); 271 * should(() => { let a = b; }, 'A bad code').throw();
277 * should(() => { let c = d; }, 'Assigning d to c.') 272 * should(() => { let c = d; }, 'Assigning d to c.')
278 * .throw('ReferenceError'); 273 * .throw('ReferenceError');
279 * should(() => { let e = f; }, 'Assigning e to f.') 274 * should(() => { let e = f; }, 'Assigning e to f.')
280 * .throw('ReferenceError', { omitErrorMessage: true }); 275 * .throw('ReferenceError', { omitErrorMessage: true });
281 * 276 *
282 * @result 277 * @result
283 * "PASS A bad code threw an exception of ReferenceError: b is not 278 * "PASS A bad code threw an exception of ReferenceError: b is not
284 * defined." 279 * defined."
285 * "PASS Assigning d to c threw ReferenceError: d is not defined." 280 * "PASS Assigning d to c threw ReferenceError: d is not defined."
286 * "PASS Assigning e to f threw ReferenceError: [error message 281 * "PASS Assigning e to f threw ReferenceError: [error message
287 * omitted]." 282 * omitted]."
288 */ 283 */
289 throw () { 284 throw() {
290 this._processArguments(arguments); 285 this._processArguments(arguments);
291 this._printActualForFailure = false; 286 this._printActualForFailure = false;
292 287
293 let didThrowCorrectly = false; 288 let didThrowCorrectly = false;
294 let passDetail, failDetail; 289 let passDetail, failDetail;
295 290
296 try { 291 try {
297 // This should throw. 292 // This should throw.
298 this._actual(); 293 this._actual();
299 // Catch did not happen, so the test is failed. 294 // Catch did not happen, so the test is failed.
300 failDetail = '${actual} did not throw an exception.'; 295 failDetail = '${actual} did not throw an exception.';
301 } catch (error) { 296 } catch (error) {
302 let errorMessage = this._options.omitErrorMessage 297 let errorMessage = this._options.omitErrorMessage ?
303 ? ': [error message omitted]' 298 ': [error message omitted]' :
304 : ': "' + error.message + '"'; 299 ': "' + error.message + '"';
305 if (this._expected === null || this._expected === undefined) { 300 if (this._expected === null || this._expected === undefined) {
306 // The expected error type was not given. 301 // The expected error type was not given.
307 didThrowCorrectly = true; 302 didThrowCorrectly = true;
308 passDetail = '${actual} threw ' + error.name + errorMessage + '.'; 303 passDetail = '${actual} threw ' + error.name + errorMessage + '.';
309 } else if (error.name === this._expected) { 304 } else if (error.name === this._expected) {
310 // The expected error type match the actual one. 305 // The expected error type match the actual one.
311 didThrowCorrectly = true; 306 didThrowCorrectly = true;
312 passDetail = '${actual} threw ${expected}' + errorMessage + '.'; 307 passDetail = '${actual} threw ${expected}' + errorMessage + '.';
313 } else { 308 } else {
314 didThrowCorrectly = false; 309 didThrowCorrectly = false;
315 failDetail = '${actual} threw "' + error.name 310 failDetail =
316 + '" instead of ${expected}.'; 311 '${actual} threw "' + error.name + '" instead of ${expected}.';
317 } 312 }
318 } 313 }
319 314
320 return this._assert(didThrowCorrectly, passDetail, failDetail); 315 return this._assert(didThrowCorrectly, passDetail, failDetail);
321 } 316 }
322 317
323 /** 318 /**
324 * Check if |actual| operation wrapped in a function does not throws an 319 * Check if |actual| operation wrapped in a function does not throws an
325 * exception correctly. 320 * exception correctly.
326 * 321 *
327 * @example 322 * @example
328 * should(() => { let foo = 'bar'; }, 'let foo = "bar"').notThrow(); 323 * should(() => { let foo = 'bar'; }, 'let foo = "bar"').notThrow();
329 * 324 *
330 * @result 325 * @result
331 * "PASS let foo = "bar" did not throw an exception." 326 * "PASS let foo = "bar" did not throw an exception."
332 */ 327 */
333 notThrow () { 328 notThrow() {
334 this._printActualForFailure = false; 329 this._printActualForFailure = false;
335 330
336 let didThrowCorrectly = false; 331 let didThrowCorrectly = false;
337 let passDetail, failDetail; 332 let passDetail, failDetail;
338 333
339 try { 334 try {
340 this._actual(); 335 this._actual();
341 passDetail = '${actual} did not throw an exception.'; 336 passDetail = '${actual} did not throw an exception.';
342 } catch (error) { 337 } catch (error) {
343 didThrowCorrectly = true; 338 didThrowCorrectly = true;
344 failDetail = '${actual} incorrectly threw ' + error.name + ': "' 339 failDetail = '${actual} incorrectly threw ' + error.name + ': "' +
345 + error.message + '".'; 340 error.message + '".';
346 } 341 }
347 342
348 return this._assert(!didThrowCorrectly, passDetail, failDetail); 343 return this._assert(!didThrowCorrectly, passDetail, failDetail);
349 } 344 }
350 345
351 /** 346 /**
352 * Check if |actual| promise is resolved correctly. Note that the returned 347 * Check if |actual| promise is resolved correctly. Note that the returned
353 * result from promise object will be passed to the following then() 348 * result from promise object will be passed to the following then()
354 * function. 349 * function.
355 * 350 *
356 * @example 351 * @example
357 * should('My promise', promise).beResolve().then((result) => { 352 * should('My promise', promise).beResolve().then((result) => {
358 * console.log(result); 353 * console.log(result);
359 * }); 354 * });
360 * 355 *
361 * @result 356 * @result
362 * "PASS My promise resolved correctly." 357 * "PASS My promise resolved correctly."
363 * "FAIL X My promise rejected *INCORRECTLY* with _ERROR_." 358 * "FAIL X My promise rejected *INCORRECTLY* with _ERROR_."
364 */ 359 */
365 beResolved () { 360 beResolved() {
366 return this._actual.then(function (result) { 361 return this._actual.then(
367 this._assert(true, '${actual} resolved correctly.', null); 362 function(result) {
368 return result; 363 this._assert(true, '${actual} resolved correctly.', null);
369 }.bind(this), function (error) { 364 return result;
370 this._assert(false, null, 365 }.bind(this),
371 '${actual} rejected incorrectly with ' + error + '.'); 366 function(error) {
372 }.bind(this)); 367 this._assert(
368 false, null,
369 '${actual} rejected incorrectly with ' + error + '.');
370 }.bind(this));
373 } 371 }
374 372
375 /** 373 /**
376 * Check if |actual| promise is rejected correctly. 374 * Check if |actual| promise is rejected correctly.
377 * 375 *
378 * @example 376 * @example
379 * should('My promise', promise).beRejected().then(nextStuff); 377 * should('My promise', promise).beRejected().then(nextStuff);
380 * 378 *
381 * @result 379 * @result
382 * "PASS My promise rejected correctly (with _ERROR_)." 380 * "PASS My promise rejected correctly (with _ERROR_)."
383 * "FAIL X My promise resolved *INCORRECTLY*." 381 * "FAIL X My promise resolved *INCORRECTLY*."
384 */ 382 */
385 beRejected () { 383 beRejected() {
386 return this._actual.then(function () { 384 return this._actual.then(
387 this._assert(false, null, '${actual} resolved incorrectly.'); 385 function() {
388 }.bind(this), function (error) { 386 this._assert(false, null, '${actual} resolved incorrectly.');
389 this._assert(true, 387 }.bind(this),
390 '${actual} rejected correctly with ' + error + '.', null); 388 function(error) {
391 }.bind(this)); 389 this._assert(
390 true, '${actual} rejected correctly with ' + error + '.', null);
391 }.bind(this));
392 } 392 }
393 393
394 /** 394 /**
395 * Check if |actual| promise is rejected correctly. 395 * Check if |actual| promise is rejected correctly.
396 * 396 *
397 * @example 397 * @example
398 * should(promise, 'My promise').beRejectedWith('_ERROR_').then(); 398 * should(promise, 'My promise').beRejectedWith('_ERROR_').then();
399 * 399 *
400 * @result 400 * @result
401 * "PASS My promise rejected correctly with _ERROR_." 401 * "PASS My promise rejected correctly with _ERROR_."
402 * "FAIL X My promise rejected correctly but got _ACTUAL_ERROR instead of 402 * "FAIL X My promise rejected correctly but got _ACTUAL_ERROR instead of
403 * _EXPECTED_ERROR_." 403 * _EXPECTED_ERROR_."
404 * "FAIL X My promise resolved incorrectly." 404 * "FAIL X My promise resolved incorrectly."
405 */ 405 */
406 beRejectedWith() { 406 beRejectedWith() {
407 this._processArguments(arguments); 407 this._processArguments(arguments);
408 408
409 return this._actual.then( 409 return this._actual.then(
410 function() { 410 function() {
411 this._assert(false, null, '${actual} resolved incorrectly.'); 411 this._assert(false, null, '${actual} resolved incorrectly.');
412 }.bind(this), 412 }.bind(this),
413 function(error) { 413 function(error) {
414 if (this._expected !== error.name) { 414 if (this._expected !== error.name) {
415 this._assert( 415 this._assert(
416 false, null, '${actual} rejected correctly but got ' + 416 false, null,
417 error.name + ' instead of ' + this._expected + '.'); 417 '${actual} rejected correctly but got ' + error.name +
418 ' instead of ' + this._expected + '.');
418 } else { 419 } else {
419 this._assert( 420 this._assert(
420 true, 421 true,
421 '${actual} rejected correctly with ' + this._expected + '.', 422 '${actual} rejected correctly with ' + this._expected + '.',
422 null); 423 null);
423 } 424 }
424 }.bind(this)); 425 }.bind(this));
425 } 426 }
426 427
427 /** 428 /**
428 * Check if |actual| is a boolean true. 429 * Check if |actual| is a boolean true.
429 * 430 *
430 * @example 431 * @example
431 * should(3 < 5, '3 < 5').beTrue(); 432 * should(3 < 5, '3 < 5').beTrue();
432 * 433 *
433 * @result 434 * @result
434 * "PASS 3 < 5 is true." 435 * "PASS 3 < 5 is true."
435 */ 436 */
436 beTrue () { 437 beTrue() {
437 return this._assert( 438 return this._assert(
438 this._actual === true, 439 this._actual === true, '${actual} is true.',
439 '${actual} is true.',
440 '${actual} is not true.'); 440 '${actual} is not true.');
441 } 441 }
442 442
443 /** 443 /**
444 * Check if |actual| is a boolean false. 444 * Check if |actual| is a boolean false.
445 * 445 *
446 * @example 446 * @example
447 * should(3 > 5, '3 > 5').beFalse(); 447 * should(3 > 5, '3 > 5').beFalse();
448 * 448 *
449 * @result 449 * @result
450 * "PASS 3 > 5 is false." 450 * "PASS 3 > 5 is false."
451 */ 451 */
452 beFalse () { 452 beFalse() {
453 return this._assert( 453 return this._assert(
454 this._actual === false, 454 this._actual === false, '${actual} is false.',
455 '${actual} is false.',
456 '${actual} is not false.'); 455 '${actual} is not false.');
457 } 456 }
458 457
459 /** 458 /**
460 * Check if |actual| is strictly equal to |expected|. (no type coercion) 459 * Check if |actual| is strictly equal to |expected|. (no type coercion)
461 * 460 *
462 * @example 461 * @example
463 * should(1).beEqualTo(1); 462 * should(1).beEqualTo(1);
464 * 463 *
465 * @result 464 * @result
466 * "PASS 1 is equal to 1." 465 * "PASS 1 is equal to 1."
467 */ 466 */
468 beEqualTo () { 467 beEqualTo() {
469 this._processArguments(arguments); 468 this._processArguments(arguments);
470 return this._assert( 469 return this._assert(
471 this._actual === this._expected, 470 this._actual === this._expected, '${actual} is equal to ${expected}.',
472 '${actual} is equal to ${expected}.',
473 '${actual} is not equal to ${expected}.'); 471 '${actual} is not equal to ${expected}.');
474 } 472 }
475 473
476 /** 474 /**
477 * Check if |actual| is not equal to |expected|. 475 * Check if |actual| is not equal to |expected|.
478 * 476 *
479 * @example 477 * @example
480 * should(1).notBeEqualTo(2); 478 * should(1).notBeEqualTo(2);
481 * 479 *
482 * @result 480 * @result
483 * "PASS 1 is not equal to 2." 481 * "PASS 1 is not equal to 2."
484 */ 482 */
485 notBeEqualTo () { 483 notBeEqualTo() {
486 this._processArguments(arguments); 484 this._processArguments(arguments);
487 return this._assert( 485 return this._assert(
488 this._actual !== this._expected, 486 this._actual !== this._expected,
489 '${actual} is not equal to ${expected}.', 487 '${actual} is not equal to ${expected}.',
490 '${actual} should not be equal to ${expected}.'); 488 '${actual} should not be equal to ${expected}.');
491 } 489 }
492 490
493 /** 491 /**
494 * Check if |actual| is greater than |expected|. 492 * Check if |actual| is greater than |expected|.
495 * 493 *
496 * @example 494 * @example
497 * should(2).beGreaterThanOrEqualTo(2); 495 * should(2).beGreaterThanOrEqualTo(2);
498 * 496 *
499 * @result 497 * @result
500 * "PASS 2 is greater than or equal to 2." 498 * "PASS 2 is greater than or equal to 2."
501 */ 499 */
502 beGreaterThan () { 500 beGreaterThan() {
503 this._processArguments(arguments); 501 this._processArguments(arguments);
504 return this._assert( 502 return this._assert(
505 this._actual > this._expected, 503 this._actual > this._expected,
506 '${actual} is greater than ${expected}.', 504 '${actual} is greater than ${expected}.',
507 '${actual} is not greater than ${expected}.' 505 '${actual} is not greater than ${expected}.');
508 );
509 } 506 }
510 507
511 /** 508 /**
512 * Check if |actual| is greater than or equal to |expected|. 509 * Check if |actual| is greater than or equal to |expected|.
513 * 510 *
514 * @example 511 * @example
515 * should(2).beGreaterThan(1); 512 * should(2).beGreaterThan(1);
516 * 513 *
517 * @result 514 * @result
518 * "PASS 2 is greater than 1." 515 * "PASS 2 is greater than 1."
519 */ 516 */
520 beGreaterThanOrEqualTo () { 517 beGreaterThanOrEqualTo() {
521 this._processArguments(arguments); 518 this._processArguments(arguments);
522 return this._assert( 519 return this._assert(
523 this._actual >= this._expected, 520 this._actual >= this._expected,
524 '${actual} is greater than or equal to ${expected}.', 521 '${actual} is greater than or equal to ${expected}.',
525 '${actual} is not greater than or equal to ${expected}.' 522 '${actual} is not greater than or equal to ${expected}.');
526 );
527 } 523 }
528 524
529 /** 525 /**
530 * Check if |actual| is less than |expected|. 526 * Check if |actual| is less than |expected|.
531 * 527 *
532 * @example 528 * @example
533 * should(1).beLessThan(2); 529 * should(1).beLessThan(2);
534 * 530 *
535 * @result 531 * @result
536 * "PASS 1 is less than 2." 532 * "PASS 1 is less than 2."
537 */ 533 */
538 beLessThan () { 534 beLessThan() {
539 this._processArguments(arguments); 535 this._processArguments(arguments);
540 return this._assert( 536 return this._assert(
541 this._actual < this._expected, 537 this._actual < this._expected, '${actual} is less than ${expected}.',
542 '${actual} is less than ${expected}.', 538 '${actual} is not less than ${expected}.');
543 '${actual} is not less than ${expected}.'
544 );
545 } 539 }
546 540
547 /** 541 /**
548 * Check if |actual| is less than or equal to |expected|. 542 * Check if |actual| is less than or equal to |expected|.
549 * 543 *
550 * @example 544 * @example
551 * should(1).beLessThanOrEqualTo(1); 545 * should(1).beLessThanOrEqualTo(1);
552 * 546 *
553 * @result 547 * @result
554 * "PASS 1 is less than or equal to 1." 548 * "PASS 1 is less than or equal to 1."
555 */ 549 */
556 beLessThanOrEqualTo () { 550 beLessThanOrEqualTo() {
557 this._processArguments(arguments); 551 this._processArguments(arguments);
558 return this._assert( 552 return this._assert(
559 this._actual <= this._expected, 553 this._actual <= this._expected,
560 '${actual} is less than or equal to ${expected}.', 554 '${actual} is less than or equal to ${expected}.',
561 '${actual} is not less than or equal to ${expected}.' 555 '${actual} is not less than or equal to ${expected}.');
562 );
563 } 556 }
564 557
565 /** 558 /**
566 * Check if |actual| array is filled with a constant |expected| value. 559 * Check if |actual| array is filled with a constant |expected| value.
567 * 560 *
568 * @example 561 * @example
569 * should([1, 1, 1]).beConstantValueOf(1); 562 * should([1, 1, 1]).beConstantValueOf(1);
570 * 563 *
571 * @result 564 * @result
572 * "PASS [1,1,1] contains only the constant 1." 565 * "PASS [1,1,1] contains only the constant 1."
573 */ 566 */
574 beConstantValueOf () { 567 beConstantValueOf() {
575 this._processArguments(arguments); 568 this._processArguments(arguments);
576 this._printActualForFailure = false; 569 this._printActualForFailure = false;
577 570
578 let passed = true; 571 let passed = true;
579 let passDetail, failDetail; 572 let passDetail, failDetail;
580 let errors = {}; 573 let errors = {};
581 574
582 let actual = this._actual; 575 let actual = this._actual;
583 let expected = this._expected; 576 let expected = this._expected;
584 for (let index = 0; index < actual.length; ++index) { 577 for (let index = 0; index < actual.length; ++index) {
585 if (actual[index] !== expected) 578 if (actual[index] !== expected)
586 errors[index] = actual[index]; 579 errors[index] = actual[index];
587 } 580 }
588 581
589 let numberOfErrors = Object.keys(errors).length; 582 let numberOfErrors = Object.keys(errors).length;
590 passed = numberOfErrors === 0; 583 passed = numberOfErrors === 0;
591 584
592 if (passed) { 585 if (passed) {
593 passDetail = '${actual} contains only the constant ${expected}.'; 586 passDetail = '${actual} contains only the constant ${expected}.';
594 } else { 587 } else {
595 let counter = 0; 588 let counter = 0;
596 failDetail = 'Expected ${expected} for all values but found ' 589 failDetail = 'Expected ${expected} for all values but found ' +
597 + numberOfErrors + ' unexpected values: '; 590 numberOfErrors + ' unexpected values: ';
598 failDetail += '\n\tIndex\tActual'; 591 failDetail += '\n\tIndex\tActual';
599 for (let errorIndex in errors) { 592 for (let errorIndex in errors) {
600 failDetail += '\n\t[' + errorIndex + ']' 593 failDetail += '\n\t[' + errorIndex + ']' +
601 + '\t' + errors[errorIndex]; 594 '\t' + errors[errorIndex];
602 if (++counter >= this._options.numberOfErrors) { 595 if (++counter >= this._options.numberOfErrors) {
603 failDetail += '\n\t...and ' + (numberOfErrors - counter) 596 failDetail +=
604 + ' more errors.'; 597 '\n\t...and ' + (numberOfErrors - counter) + ' more errors.';
605 break; 598 break;
606 } 599 }
607 } 600 }
608 } 601 }
609 602
610 return this._assert(passed, passDetail, failDetail); 603 return this._assert(passed, passDetail, failDetail);
611 } 604 }
612 605
613 /** 606 /**
614 * Check if |actual| array is not filled with a constant |expected| value. 607 * Check if |actual| array is not filled with a constant |expected| value.
615 * 608 *
616 * @example 609 * @example
617 * should([1, 0, 1]).notBeConstantValueOf(1); 610 * should([1, 0, 1]).notBeConstantValueOf(1);
618 * should([0, 0, 0]).notBeConstantValueOf(0); 611 * should([0, 0, 0]).notBeConstantValueOf(0);
619 * 612 *
620 * @result 613 * @result
621 * "PASS [1,0,1] is not constantly 1 (contains 1 different value)." 614 * "PASS [1,0,1] is not constantly 1 (contains 1 different value)."
622 * "FAIL X [0,0,0] should have contain at least one value different 615 * "FAIL X [0,0,0] should have contain at least one value different
623 * from 0." 616 * from 0."
624 */ 617 */
625 notBeConstantValueOf () { 618 notBeConstantValueOf() {
626 this._processArguments(arguments); 619 this._processArguments(arguments);
627 this._printActualForFailure = false; 620 this._printActualForFailure = false;
628 621
629 let passed = true; 622 let passed = true;
630 let passDetail; 623 let passDetail;
631 let failDetail; 624 let failDetail;
632 let differences = {}; 625 let differences = {};
633 626
634 let actual = this._actual; 627 let actual = this._actual;
635 let expected = this._expected; 628 let expected = this._expected;
(...skipping 19 matching lines...) Expand all
655 648
656 /** 649 /**
657 * Check if |actual| array is identical to |expected| array element-wise. 650 * Check if |actual| array is identical to |expected| array element-wise.
658 * 651 *
659 * @example 652 * @example
660 * should([1, 2, 3]).beEqualToArray([1, 2, 3]); 653 * should([1, 2, 3]).beEqualToArray([1, 2, 3]);
661 * 654 *
662 * @result 655 * @result
663 * "[1,2,3] is identical to the array [1,2,3]." 656 * "[1,2,3] is identical to the array [1,2,3]."
664 */ 657 */
665 beEqualToArray () { 658 beEqualToArray() {
666 this._processArguments(arguments); 659 this._processArguments(arguments);
667 this._printActualForFailure = false; 660 this._printActualForFailure = false;
668 661
669 let passed = true; 662 let passed = true;
670 let passDetail, failDetail; 663 let passDetail, failDetail;
671 let errorIndices = []; 664 let errorIndices = [];
672 665
673 if (this._actual.length !== this._expected.length) { 666 if (this._actual.length !== this._expected.length) {
674 passed = false; 667 passed = false;
675 failDetail = 'The array length does not match.'; 668 failDetail = 'The array length does not match.';
676 return this._assert(passed, passDetail, failDetail); 669 return this._assert(passed, passDetail, failDetail);
677 } 670 }
678 671
679 let actual = this._actual; 672 let actual = this._actual;
680 let expected = this._expected; 673 let expected = this._expected;
681 for (let index = 0; index < actual.length; ++index) { 674 for (let index = 0; index < actual.length; ++index) {
682 if (actual[index] !== expected[index]) 675 if (actual[index] !== expected[index])
683 errorIndices.push(index); 676 errorIndices.push(index);
684 } 677 }
685 678
686 passed = errorIndices.length === 0; 679 passed = errorIndices.length === 0;
687 680
688 if (passed) { 681 if (passed) {
689 passDetail = '${actual} is identical to the array ${expected}.'; 682 passDetail = '${actual} is identical to the array ${expected}.';
690 } else { 683 } else {
691 let counter = 0; 684 let counter = 0;
692 failDetail = '${actual} expected to be equal to the array ${expected} ' 685 failDetail =
693 + 'but differs in ' + errorIndices.length + ' places:' 686 '${actual} expected to be equal to the array ${expected} ' +
694 + '\n\tIndex\tActual\t\t\tExpected'; 687 'but differs in ' + errorIndices.length + ' places:' +
688 '\n\tIndex\tActual\t\t\tExpected';
695 for (let index of errorIndices) { 689 for (let index of errorIndices) {
696 failDetail += '\n\t[' + index + ']' 690 failDetail += '\n\t[' + index + ']' +
697 + '\t' + this._actual[index].toExponential(16) 691 '\t' + this._actual[index].toExponential(16) + '\t' +
698 + '\t' + this._expected[index].toExponential(16); 692 this._expected[index].toExponential(16);
699 if (++counter >= this._options.numberOfErrors) { 693 if (++counter >= this._options.numberOfErrors) {
700 failDetail += '\n\t...and ' + (errorIndices.length - counter) 694 failDetail += '\n\t...and ' + (errorIndices.length - counter) +
701 + ' more errors.'; 695 ' more errors.';
702 break; 696 break;
703 } 697 }
704 } 698 }
705 } 699 }
706 700
707 return this._assert(passed, passDetail, failDetail); 701 return this._assert(passed, passDetail, failDetail);
708 } 702 }
709 703
710 /** 704 /**
711 * Check if |actual| array contains only the values in |expected| in the 705 * Check if |actual| array contains only the values in |expected| in the
712 * order of values in |expected|. 706 * order of values in |expected|.
713 * 707 *
714 * @example 708 * @example
715 * Should([1, 1, 3, 3, 2], 'My random array').containValues([1, 3, 2]); 709 * Should([1, 1, 3, 3, 2], 'My random array').containValues([1, 3, 2]);
716 * 710 *
717 * @result 711 * @result
718 * "PASS [1,1,3,3,2] contains all the expected values in the correct 712 * "PASS [1,1,3,3,2] contains all the expected values in the correct
719 * order: [1,3,2]. 713 * order: [1,3,2].
720 */ 714 */
721 containValues () { 715 containValues() {
722 this._processArguments(arguments); 716 this._processArguments(arguments);
723 this._printActualForFailure = false; 717 this._printActualForFailure = false;
724 718
725 let passed = true; 719 let passed = true;
726 let indexedActual = []; 720 let indexedActual = [];
727 let firstErrorIndex = null; 721 let firstErrorIndex = null;
728 722
729 // Collect the unique value sequence from the actual. 723 // Collect the unique value sequence from the actual.
730 for (let i = 0, prev = null; i < this._actual.length; i++) { 724 for (let i = 0, prev = null; i < this._actual.length; i++) {
731 if (this._actual[i] !== prev) { 725 if (this._actual[i] !== prev) {
732 indexedActual.push({ 726 indexedActual.push({index: i, value: this._actual[i]});
733 index: i,
734 value: this._actual[i]
735 });
736 prev = this._actual[i]; 727 prev = this._actual[i];
737 } 728 }
738 } 729 }
739 730
740 // Compare against the expected sequence. 731 // Compare against the expected sequence.
741 for (let j = 0; j < this._expected.length; j++) { 732 for (let j = 0; j < this._expected.length; j++) {
742 if (this._expected[j] !== indexedActual[j].value) { 733 if (this._expected[j] !== indexedActual[j].value) {
743 firstErrorIndex = indexedActual[j].index; 734 firstErrorIndex = indexedActual[j].index;
744 passed = false; 735 passed = false;
745 break; 736 break;
746 } 737 }
747 } 738 }
748 739
749 return this._assert( 740 return this._assert(
750 passed, 741 passed,
751 '${actual} contains all the expected values in the correct order: ' 742 '${actual} contains all the expected values in the correct order: ' +
752 + '${expected}.', 743 '${expected}.',
753 '${actual} expected to have the value sequence of ${expected} but ' 744 '${actual} expected to have the value sequence of ${expected} but ' +
754 + 'got ' + this._actual[firstErrorIndex] + ' at index ' 745 'got ' + this._actual[firstErrorIndex] + ' at index ' +
755 + firstErrorIndex + '.'); 746 firstErrorIndex + '.');
756 } 747 }
757 748
758 /** 749 /**
759 * Check if |actual| array does not have any glitches. Note that |threshold| 750 * Check if |actual| array does not have any glitches. Note that |threshold|
760 * is not optional and is to define the desired threshold value. 751 * is not optional and is to define the desired threshold value.
761 * 752 *
762 * @example 753 * @example
763 * should([0.5, 0.5, 0.55, 0.5, 0.45, 0.5]).notGlitch(0.06); 754 * should([0.5, 0.5, 0.55, 0.5, 0.45, 0.5]).notGlitch(0.06);
764 * 755 *
765 * @result 756 * @result
766 * "PASS [0.5,0.5,0.55,0.5,0.45,0.5] has no glitch above the threshold 757 * "PASS [0.5,0.5,0.55,0.5,0.45,0.5] has no glitch above the threshold
767 * of 0.06." 758 * of 0.06."
768 * 759 *
769 */ 760 */
770 notGlitch () { 761 notGlitch() {
771 this._processArguments(arguments); 762 this._processArguments(arguments);
772 this._printActualForFailure = false; 763 this._printActualForFailure = false;
773 764
774 let passed = true; 765 let passed = true;
775 let passDetail, failDetail; 766 let passDetail, failDetail;
776 767
777 let actual = this._actual; 768 let actual = this._actual;
778 let expected = this._expected; 769 let expected = this._expected;
779 for (let index = 0; index < actual.length; ++index) { 770 for (let index = 0; index < actual.length; ++index) {
780 let diff = Math.abs(actual[index - 1] - actual[index]); 771 let diff = Math.abs(actual[index - 1] - actual[index]);
781 if (diff >= expected) { 772 if (diff >= expected) {
782 passed = false; 773 passed = false;
783 failDetail = '${actual} has a glitch at index ' + index + ' of size ' 774 failDetail = '${actual} has a glitch at index ' + index +
784 + diff + '.'; 775 ' of size ' + diff + '.';
785 } 776 }
786 } 777 }
787 778
788 passDetail = 779 passDetail =
789 '${actual} has no glitch above the threshold of ${expected}.'; 780 '${actual} has no glitch above the threshold of ${expected}.';
790 781
791 return this._assert(passed, passDetail, failDetail); 782 return this._assert(passed, passDetail, failDetail);
792 } 783 }
793 784
794 /** 785 /**
795 * Check if |actual| is close to |expected| using the given relative error 786 * Check if |actual| is close to |expected| using the given relative error
796 * |threshold|. 787 * |threshold|.
797 * 788 *
798 * @example 789 * @example
799 * should(2.3).beCloseTo(2, { threshold: 0.3 }); 790 * should(2.3).beCloseTo(2, { threshold: 0.3 });
800 * 791 *
801 * @result 792 * @result
802 * "PASS 2.3 is 2 within an error of 0.3." 793 * "PASS 2.3 is 2 within an error of 0.3."
803 * @param {Object} options Options for assertion. 794 * @param {Object} options Options for assertion.
804 * @param {Number} options.threshold Threshold value for the comparison. 795 * @param {Number} options.threshold Threshold value for the comparison.
805 */ 796 */
806 beCloseTo () { 797 beCloseTo() {
807 this._processArguments(arguments); 798 this._processArguments(arguments);
808 799
809 // The threshold is relative except when |expected| is zero, in which case 800 // The threshold is relative except when |expected| is zero, in which case
810 // it is absolute. 801 // it is absolute.
811 let absExpected = this._expected ? Math.abs(this._expected) : 1; 802 let absExpected = this._expected ? Math.abs(this._expected) : 1;
812 let error = Math.abs(this._actual - this._expected) / absExpected; 803 let error = Math.abs(this._actual - this._expected) / absExpected;
813 804
814 // debugger; 805 // debugger;
815 806
816 return this._assert( 807 return this._assert(
817 error <= this._options.threshold, 808 error <= this._options.threshold,
818 '${actual} is ${expected} within an error of ${threshold}.', 809 '${actual} is ${expected} within an error of ${threshold}.',
819 '${actual} is not close to ${expected} within a relative error of ' + 810 '${actual} is not close to ${expected} within a relative error of ' +
820 '${threshold} (RelErr=' + error + ').'); 811 '${threshold} (RelErr=' + error + ').');
821 } 812 }
822 813
823 /** 814 /**
824 * Check if |target| array is close to |expected| array element-wise within 815 * Check if |target| array is close to |expected| array element-wise within
825 * a certain error bound given by the |options|. 816 * a certain error bound given by the |options|.
826 * 817 *
827 * The error criterion is: 818 * The error criterion is:
828 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected)) 819 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected))
829 * 820 *
830 * If nothing is given for |options|, then absErr = relErr = 0. If 821 * If nothing is given for |options|, then absErr = relErr = 0. If
831 * absErr = 0, then the error criterion is a relative error. A non-zero 822 * absErr = 0, then the error criterion is a relative error. A non-zero
832 * absErr value produces a mix intended to handle the case where the 823 * absErr value produces a mix intended to handle the case where the
833 * expected value is 0, allowing the target value to differ by absErr from 824 * expected value is 0, allowing the target value to differ by absErr from
834 * the expected. 825 * the expected.
835 * 826 *
836 * @param {Number} options.absoluteThreshold Absolute threshold. 827 * @param {Number} options.absoluteThreshold Absolute threshold.
837 * @param {Number} options.relativeThreshold Relative threshold. 828 * @param {Number} options.relativeThreshold Relative threshold.
838 */ 829 */
839 beCloseToArray () { 830 beCloseToArray() {
840 this._processArguments(arguments); 831 this._processArguments(arguments);
841 this._printActualForFailure = false; 832 this._printActualForFailure = false;
842 833
843 let passed = true; 834 let passed = true;
844 let passDetail, failDetail; 835 let passDetail, failDetail;
845 836
846 // Parsing options. 837 // Parsing options.
847 let absErrorThreshold = (this._options.absoluteThreshold || 0); 838 let absErrorThreshold = (this._options.absoluteThreshold || 0);
848 let relErrorThreshold = (this._options.relativeThreshold || 0); 839 let relErrorThreshold = (this._options.relativeThreshold || 0);
849 840
(...skipping 10 matching lines...) Expand all
860 let maxRelError = -Infinity, maxRelErrorIndex = -1; 851 let maxRelError = -Infinity, maxRelErrorIndex = -1;
861 852
862 let actual = this._actual; 853 let actual = this._actual;
863 let expected = this._expected; 854 let expected = this._expected;
864 855
865 for (let index = 0; index < expected.length; ++index) { 856 for (let index = 0; index < expected.length; ++index) {
866 let diff = Math.abs(actual[index] - expected[index]); 857 let diff = Math.abs(actual[index] - expected[index]);
867 let absExpected = Math.abs(expected[index]); 858 let absExpected = Math.abs(expected[index]);
868 let relError = diff / absExpected; 859 let relError = diff / absExpected;
869 860
870 if (diff > Math.max(absErrorThreshold, 861 if (diff >
871 relErrorThreshold * absExpected)) { 862 Math.max(absErrorThreshold, relErrorThreshold * absExpected)) {
872
873 if (diff > maxAbsError) { 863 if (diff > maxAbsError) {
874 maxAbsErrorIndex = index; 864 maxAbsErrorIndex = index;
875 maxAbsError = diff; 865 maxAbsError = diff;
876 } 866 }
877 867
878 if (!isNaN(relError) && relError > maxRelError) { 868 if (!isNaN(relError) && relError > maxRelError) {
879 maxRelErrorIndex = index; 869 maxRelErrorIndex = index;
880 maxRelError = relError; 870 maxRelError = relError;
881 } 871 }
882 872
883 errors[index] = diff; 873 errors[index] = diff;
884 } 874 }
885 } 875 }
886 876
887 let numberOfErrors = Object.keys(errors).length; 877 let numberOfErrors = Object.keys(errors).length;
888 let maxAllowedErrorDetail = JSON.stringify({ 878 let maxAllowedErrorDetail = JSON.stringify({
889 absoluteThreshold: absErrorThreshold, 879 absoluteThreshold: absErrorThreshold,
890 relativeThreshold: relErrorThreshold 880 relativeThreshold: relErrorThreshold
891 }); 881 });
892 882
893 if (numberOfErrors === 0) { 883 if (numberOfErrors === 0) {
894 // The assertion was successful. 884 // The assertion was successful.
895 passDetail = '${actual} equals ${expected} with an element-wise ' 885 passDetail = '${actual} equals ${expected} with an element-wise ' +
896 + 'tolerance of ' + maxAllowedErrorDetail + '.'; 886 'tolerance of ' + maxAllowedErrorDetail + '.';
897 } else { 887 } else {
898 // Failed. Prepare the detailed failure log. 888 // Failed. Prepare the detailed failure log.
899 passed = false; 889 passed = false;
900 failDetail = '${actual} does not equal ${expected} with an ' 890 failDetail = '${actual} does not equal ${expected} with an ' +
901 + 'element-wise tolerance of ' + maxAllowedErrorDetail + '.\n'; 891 'element-wise tolerance of ' + maxAllowedErrorDetail + '.\n';
902 892
903 // Print out actual, expected, absolute error, and relative error. 893 // Print out actual, expected, absolute error, and relative error.
904 let counter = 0; 894 let counter = 0;
905 failDetail += '\tIndex\tActual\t\t\tExpected\t\tAbsError' 895 failDetail += '\tIndex\tActual\t\t\tExpected\t\tAbsError' +
906 + '\t\tRelError\t\tTest threshold'; 896 '\t\tRelError\t\tTest threshold';
907 let printedIndices = []; 897 let printedIndices = [];
908 for (let index in errors) { 898 for (let index in errors) {
909 failDetail += '\n' + _formatFailureEntry( 899 failDetail +=
910 index, actual[index], 900 '\n' +
911 expected[index], errors[index], 901 _formatFailureEntry(
912 _closeToThreshold( 902 index, actual[index], expected[index], errors[index],
913 absErrorThreshold, relErrorThreshold, 903 _closeToThreshold(
914 expected[index])); 904 absErrorThreshold, relErrorThreshold, expected[index]));
915 905
916 printedIndices.push(index); 906 printedIndices.push(index);
917 if (++counter > this._options.numberOfErrors) { 907 if (++counter > this._options.numberOfErrors) {
918 failDetail += 908 failDetail +=
919 '\n\t...and ' + (numberOfErrors - counter) + ' more errors.'; 909 '\n\t...and ' + (numberOfErrors - counter) + ' more errors.';
920 break; 910 break;
921 } 911 }
922 } 912 }
923 913
924 // Finalize the error log: print out the location of both the maxAbs 914 // Finalize the error log: print out the location of both the maxAbs
925 // error and the maxRel error so we can adjust thresholds appropriately 915 // error and the maxRel error so we can adjust thresholds appropriately
926 // in the test. 916 // in the test.
927 failDetail += '\n' 917 failDetail += '\n' +
928 + '\tMax AbsError of ' + maxAbsError.toExponential(16) 918 '\tMax AbsError of ' + maxAbsError.toExponential(16) +
929 + ' at index of ' + maxAbsErrorIndex + '.\n'; 919 ' at index of ' + maxAbsErrorIndex + '.\n';
930 if (printedIndices.find(element => { 920 if (printedIndices.find(element => {
931 return element == maxAbsErrorIndex; 921 return element == maxAbsErrorIndex;
932 }) === undefined) { 922 }) === undefined) {
933 // Print an entry for this index if we haven't already. 923 // Print an entry for this index if we haven't already.
934 failDetail += 924 failDetail +=
935 _formatFailureEntry( 925 _formatFailureEntry(
936 maxAbsErrorIndex, actual[maxAbsErrorIndex], 926 maxAbsErrorIndex, actual[maxAbsErrorIndex],
937 expected[maxAbsErrorIndex], errors[maxAbsErrorIndex], 927 expected[maxAbsErrorIndex], errors[maxAbsErrorIndex],
938 _closeToThreshold( 928 _closeToThreshold(
939 absErrorThreshold, relErrorThreshold, 929 absErrorThreshold, relErrorThreshold,
(...skipping 26 matching lines...) Expand all
966 * 956 *
967 * TODO(hongchan): remove this method when the transition from the old Audit 957 * TODO(hongchan): remove this method when the transition from the old Audit
968 * to the new Audit is completed. 958 * to the new Audit is completed.
969 * @example 959 * @example
970 * should(true, 'The message is').message('truthful!', 'false!'); 960 * should(true, 'The message is').message('truthful!', 'false!');
971 * 961 *
972 * @result 962 * @result
973 * "PASS The message is truthful!" 963 * "PASS The message is truthful!"
974 */ 964 */
975 message(passDetail, failDetail) { 965 message(passDetail, failDetail) {
976 return this._assert(this._actual, 966 return this._assert(
977 '${actual} ' + passDetail, 967 this._actual, '${actual} ' + passDetail, '${actual} ' + failDetail);
978 '${actual} ' + failDetail);
979 } 968 }
980 969
981 /** 970 /**
982 * Check if |expected| property is truly owned by |actual| object. 971 * Check if |expected| property is truly owned by |actual| object.
983 * 972 *
984 * @example 973 * @example
985 * should(BaseAudioContext.prototype, 974 * should(BaseAudioContext.prototype,
986 * 'BaseAudioContext.prototype').haveOwnProperty('createGain'); 975 * 'BaseAudioContext.prototype').haveOwnProperty('createGain');
987 * 976 *
988 * @result 977 * @result
989 * "PASS BaseAudioContext.prototype has an own property of 978 * "PASS BaseAudioContext.prototype has an own property of
990 * 'createGain'." 979 * 'createGain'."
991 */ 980 */
992 haveOwnProperty () { 981 haveOwnProperty() {
993 this._processArguments(arguments); 982 this._processArguments(arguments);
994 983
995 return this._assert( 984 return this._assert(
996 this._actual.hasOwnProperty(this._expected), 985 this._actual.hasOwnProperty(this._expected),
997 '${actual} has an own property of "${expected}".', 986 '${actual} has an own property of "${expected}".',
998 '${actual} does not own the property of "${expected}".'); 987 '${actual} does not own the property of "${expected}".');
999 } 988 }
1000 989
1001 990
1002 /** 991 /**
1003 * Check if |expected| property is not owned by |actual| object. 992 * Check if |expected| property is not owned by |actual| object.
1004 * 993 *
1005 * @example 994 * @example
1006 * should(BaseAudioContext.prototype, 995 * should(BaseAudioContext.prototype,
1007 * 'BaseAudioContext.prototype') 996 * 'BaseAudioContext.prototype')
1008 * .notHaveOwnProperty('startRendering'); 997 * .notHaveOwnProperty('startRendering');
1009 * 998 *
1010 * @result 999 * @result
1011 * "PASS BaseAudioContext.prototype does not have an own property of 1000 * "PASS BaseAudioContext.prototype does not have an own property of
1012 * 'startRendering'." 1001 * 'startRendering'."
1013 */ 1002 */
1014 notHaveOwnProperty () { 1003 notHaveOwnProperty() {
1015 this._processArguments(arguments); 1004 this._processArguments(arguments);
1016 1005
1017 return this._assert( 1006 return this._assert(
1018 !this._actual.hasOwnProperty(this._expected), 1007 !this._actual.hasOwnProperty(this._expected),
1019 '${actual} does not have an own property of "${expected}".', 1008 '${actual} does not have an own property of "${expected}".',
1020 '${actual} has an own the property of "${expected}".') 1009 '${actual} has an own the property of "${expected}".')
1021 } 1010 }
1022 1011
1023 1012
1024 /** 1013 /**
1025 * Check if an object is inherited from a class. This looks up the entire 1014 * Check if an object is inherited from a class. This looks up the entire
1026 * prototype chain of a given object and tries to find a match. 1015 * prototype chain of a given object and tries to find a match.
1027 * 1016 *
1028 * @example 1017 * @example
1029 * should(sourceNode, 'A buffer source node') 1018 * should(sourceNode, 'A buffer source node')
1030 * .inheritFrom('AudioScheduledSourceNode'); 1019 * .inheritFrom('AudioScheduledSourceNode');
1031 * 1020 *
1032 * @result 1021 * @result
1033 * "PASS A buffer source node inherits from 'AudioScheduledSourceNode'." 1022 * "PASS A buffer source node inherits from 'AudioScheduledSourceNode'."
1034 */ 1023 */
1035 inheritFrom () { 1024 inheritFrom() {
1036 this._processArguments(arguments); 1025 this._processArguments(arguments);
1037 1026
1038 let prototypes = []; 1027 let prototypes = [];
1039 let currentPrototype = Object.getPrototypeOf(this._actual); 1028 let currentPrototype = Object.getPrototypeOf(this._actual);
1040 while (currentPrototype) { 1029 while (currentPrototype) {
1041 prototypes.push(currentPrototype.constructor.name); 1030 prototypes.push(currentPrototype.constructor.name);
1042 currentPrototype = Object.getPrototypeOf(currentPrototype); 1031 currentPrototype = Object.getPrototypeOf(currentPrototype);
1043 } 1032 }
1044 1033
1045 return this._assert( 1034 return this._assert(
1046 prototypes.includes(this._expected), 1035 prototypes.includes(this._expected),
1047 '${actual} inherits from "${expected}".', 1036 '${actual} inherits from "${expected}".',
1048 '${actual} does not inherit from "${expected}".'); 1037 '${actual} does not inherit from "${expected}".');
1049 } 1038 }
1050 } 1039 }
1051 1040
1052 1041
1053 // Task Class state enum. 1042 // Task Class state enum.
1054 const TaskState = { 1043 const TaskState = {PENDING: 0, STARTED: 1, FINISHED: 2};
1055 PENDING: 0,
1056 STARTED: 1,
1057 FINISHED: 2
1058 };
1059 1044
1060 1045
1061 /** 1046 /**
1062 * @class Task 1047 * @class Task
1063 * @description WebAudio testing task. Managed by TaskRunner. 1048 * @description WebAudio testing task. Managed by TaskRunner.
1064 */ 1049 */
1065 class Task { 1050 class Task {
1066
1067 /** 1051 /**
1068 * Task constructor. 1052 * Task constructor.
1069 * @param {Object} taskRunner Reference of associated task runner. 1053 * @param {Object} taskRunner Reference of associated task runner.
1070 * @param {String||Object} taskLabel Task label if a string is given. This 1054 * @param {String||Object} taskLabel Task label if a string is given. This
1071 * parameter can be a dictionary with the 1055 * parameter can be a dictionary with the
1072 * following fields. 1056 * following fields.
1073 * @param {String} taskLabel.label Task label. 1057 * @param {String} taskLabel.label Task label.
1074 * @param {String} taskLabel.description Description of task. 1058 * @param {String} taskLabel.description Description of task.
1075 * @param {Function} taskFunction Task function to be performed. 1059 * @param {Function} taskFunction Task function to be performed.
1076 * @return {Object} Task object. 1060 * @return {Object} Task object.
1077 */ 1061 */
1078 constructor (taskRunner, taskLabel, taskFunction) { 1062 constructor(taskRunner, taskLabel, taskFunction) {
1079 this._taskRunner = taskRunner; 1063 this._taskRunner = taskRunner;
1080 this._taskFunction = taskFunction; 1064 this._taskFunction = taskFunction;
1081 1065
1082 if (typeof taskLabel === 'string') { 1066 if (typeof taskLabel === 'string') {
1083 this._label = taskLabel; 1067 this._label = taskLabel;
1084 this._description = null; 1068 this._description = null;
1085 } else if (typeof taskLabel === 'object') { 1069 } else if (typeof taskLabel === 'object') {
1086 if (typeof taskLabel.label !== 'string') { 1070 if (typeof taskLabel.label !== 'string') {
1087 _throwException('Task.constructor:: task label must be string.'); 1071 _throwException('Task.constructor:: task label must be string.');
1088 } 1072 }
1089 this._label = taskLabel.label; 1073 this._label = taskLabel.label;
1090 this._description = (typeof taskLabel.description === 'string') 1074 this._description = (typeof taskLabel.description === 'string') ?
1091 ? taskLabel.description : null; 1075 taskLabel.description :
1076 null;
1092 } else { 1077 } else {
1093 _throwException('Task.constructor:: task label must be a string or ' + 1078 _throwException(
1094 'a dictionary.'); 1079 'Task.constructor:: task label must be a string or ' +
1080 'a dictionary.');
1095 } 1081 }
1096 1082
1097 this._state = TaskState.PENDING; 1083 this._state = TaskState.PENDING;
1098 this._result = true; 1084 this._result = true;
1099 1085
1100 this._totalAssertions = 0; 1086 this._totalAssertions = 0;
1101 this._failedAssertions = 0; 1087 this._failedAssertions = 0;
1102 } 1088 }
1103 1089
1104 get label () { 1090 get label() {
1105 return this._label; 1091 return this._label;
1106 } 1092 }
1107 1093
1108 get state () { 1094 get state() {
1109 return this._state; 1095 return this._state;
1110 } 1096 }
1111 1097
1112 get result () { 1098 get result() {
1113 return this._result; 1099 return this._result;
1114 } 1100 }
1115 1101
1116 // Start the assertion chain. 1102 // Start the assertion chain.
1117 should (actual, actualDescription) { 1103 should(actual, actualDescription) {
1118 // If no argument is given, we cannot proceed. Halt. 1104 // If no argument is given, we cannot proceed. Halt.
1119 if (arguments.length === 0) 1105 if (arguments.length === 0)
1120 _throwException('Task.should:: requires at least 1 argument.'); 1106 _throwException('Task.should:: requires at least 1 argument.');
1121 1107
1122 return new Should(this, actual, actualDescription); 1108 return new Should(this, actual, actualDescription);
1123 } 1109 }
1124 1110
1125 // Run this task. |this| task will be passed into the user-supplied test 1111 // Run this task. |this| task will be passed into the user-supplied test
1126 // task function. 1112 // task function.
1127 run () { 1113 run() {
1128 this._state = TaskState.STARTED; 1114 this._state = TaskState.STARTED;
1129 1115
1130 // Print out the task entry with label and description. 1116 // Print out the task entry with label and description.
1131 _logPassed('> [' + this._label + '] ' 1117 _logPassed(
1132 + (this._description ? this._description : '')); 1118 '> [' + this._label + '] ' +
1119 (this._description ? this._description : ''));
1133 1120
1134 this._taskFunction( 1121 this._taskFunction(this, this.should.bind(this));
1135 this,
1136 this.should.bind(this));
1137 } 1122 }
1138 1123
1139 // Update the task success based on the individual assertion/test inside. 1124 // Update the task success based on the individual assertion/test inside.
1140 update (subTask) { 1125 update(subTask) {
1141 // After one of tests fails within a task, the result is irreversible. 1126 // After one of tests fails within a task, the result is irreversible.
1142 if (subTask.result === false) { 1127 if (subTask.result === false) {
1143 this._result = false; 1128 this._result = false;
1144 this._failedAssertions++; 1129 this._failedAssertions++;
1145 } 1130 }
1146 1131
1147 this._totalAssertions++; 1132 this._totalAssertions++;
1148 } 1133 }
1149 1134
1150 // Finish the current task and start the next one if available. 1135 // Finish the current task and start the next one if available.
1151 done () { 1136 done() {
1152 this._state = TaskState.FINISHED; 1137 this._state = TaskState.FINISHED;
1153 1138
1154 let message = '< [' + this._label + '] '; 1139 let message = '< [' + this._label + '] ';
1155 1140
1156 if (this._result) { 1141 if (this._result) {
1157 message += 'All assertions passed. (total ' + this._totalAssertions 1142 message += 'All assertions passed. (total ' + this._totalAssertions +
1158 + ' assertions)'; 1143 ' assertions)';
1159 _logPassed(message); 1144 _logPassed(message);
1160 } else { 1145 } else {
1161 message += this._failedAssertions + ' out of ' + this._totalAssertions 1146 message += this._failedAssertions + ' out of ' + this._totalAssertions +
1162 + ' assertions were failed.' 1147 ' assertions were failed.'
1163 _logFailed(message); 1148 _logFailed(message);
1164 } 1149 }
1165 1150
1166 this._taskRunner._runNextTask(); 1151 this._taskRunner._runNextTask();
1167 } 1152 }
1168 1153
1169 isPassed () { 1154 isPassed() {
1170 return this._state === TaskState.FINISHED && this._result; 1155 return this._state === TaskState.FINISHED && this._result;
1171 } 1156 }
1172 1157
1173 toString () { 1158 toString() {
1174 return '"' + this._label + '": ' + this._description; 1159 return '"' + this._label + '": ' + this._description;
1175 } 1160 }
1176
1177 } 1161 }
1178 1162
1179 1163
1180 /** 1164 /**
1181 * @class TaskRunner 1165 * @class TaskRunner
1182 * @description WebAudio testing task runner. Manages tasks. 1166 * @description WebAudio testing task runner. Manages tasks.
1183 */ 1167 */
1184 class TaskRunner { 1168 class TaskRunner {
1185 1169 constructor() {
1186 constructor () {
1187 this._tasks = {}; 1170 this._tasks = {};
1188 this._taskSequence = []; 1171 this._taskSequence = [];
1189 this._currentTaskIndex = -1; 1172 this._currentTaskIndex = -1;
1190 1173
1191 // Configure testharness.js for the async operation. 1174 // Configure testharness.js for the async operation.
1192 setup (new Function (), { 1175 setup(new Function(), {explicit_done: true});
1193 explicit_done: true
1194 });
1195 } 1176 }
1196 1177
1197 _runNextTask () { 1178 _runNextTask() {
1198 if (this._currentTaskIndex < this._taskSequence.length) { 1179 if (this._currentTaskIndex < this._taskSequence.length) {
1199 this._tasks[this._taskSequence[this._currentTaskIndex++]].run(); 1180 this._tasks[this._taskSequence[this._currentTaskIndex++]].run();
1200 } else { 1181 } else {
1201 this._finish(); 1182 this._finish();
1202 } 1183 }
1203 } 1184 }
1204 1185
1205 _finish () { 1186 _finish() {
1206 let numberOfFailures = 0; 1187 let numberOfFailures = 0;
1207 for (let taskIndex in this._taskSequence) { 1188 for (let taskIndex in this._taskSequence) {
1208 let task = this._tasks[this._taskSequence[taskIndex]]; 1189 let task = this._tasks[this._taskSequence[taskIndex]];
1209 numberOfFailures += task.result ? 0 : 1; 1190 numberOfFailures += task.result ? 0 : 1;
1210 } 1191 }
1211 1192
1212 let prefix = '# AUDIT TASK RUNNER FINISHED: '; 1193 let prefix = '# AUDIT TASK RUNNER FINISHED: ';
1213 if (numberOfFailures > 0) { 1194 if (numberOfFailures > 0) {
1214 _logFailed(prefix + numberOfFailures + ' out of ' 1195 _logFailed(
1215 + this._taskSequence.length + ' tasks were failed.'); 1196 prefix + numberOfFailures + ' out of ' + this._taskSequence.length +
1197 ' tasks were failed.');
1216 } else { 1198 } else {
1217 _logPassed(prefix + this._taskSequence.length 1199 _logPassed(
1218 + ' tasks ran successfully.'); 1200 prefix + this._taskSequence.length + ' tasks ran successfully.');
1219 } 1201 }
1220 1202
1221 // From testharness.js, report back to the test infrastructure that 1203 // From testharness.js, report back to the test infrastructure that
1222 // the task runner completed all the tasks. 1204 // the task runner completed all the tasks.
1223 _testharnessDone(); 1205 _testharnessDone();
1224 } 1206 }
1225 1207
1226 // |taskLabel| can be either a string or a dictionary. See Task constructor 1208 // |taskLabel| can be either a string or a dictionary. See Task constructor
1227 // for the detail. 1209 // for the detail.
1228 define (taskLabel, taskFunction) { 1210 define(taskLabel, taskFunction) {
1229 let task = new Task(this, taskLabel, taskFunction); 1211 let task = new Task(this, taskLabel, taskFunction);
1230 if (this._tasks.hasOwnProperty(task.label)) { 1212 if (this._tasks.hasOwnProperty(task.label)) {
1231 _throwException('Audit.define:: Duplicate task definition.'); 1213 _throwException('Audit.define:: Duplicate task definition.');
1232 return; 1214 return;
1233 } 1215 }
1234 this._tasks[task.label] = task; 1216 this._tasks[task.label] = task;
1235 this._taskSequence.push(task.label); 1217 this._taskSequence.push(task.label);
1236 } 1218 }
1237 1219
1238 // Start running all the tasks scheduled. Multiple task names can be passed 1220 // Start running all the tasks scheduled. Multiple task names can be passed
1239 // to execute them sequentially. Zero argument will perform all defined 1221 // to execute them sequentially. Zero argument will perform all defined
1240 // tasks in the order of definition. 1222 // tasks in the order of definition.
1241 run () { 1223 run() {
1242 // Display the beginning of the test suite. 1224 // Display the beginning of the test suite.
1243 _logPassed('# AUDIT TASK RUNNER STARTED.'); 1225 _logPassed('# AUDIT TASK RUNNER STARTED.');
1244 1226
1245 // If the argument is specified, override the default task sequence with 1227 // If the argument is specified, override the default task sequence with
1246 // the specified one. 1228 // the specified one.
1247 if (arguments.length > 0) { 1229 if (arguments.length > 0) {
1248 this._taskSequence = []; 1230 this._taskSequence = [];
1249 for (let i = 0; i < arguments.length; i++) { 1231 for (let i = 0; i < arguments.length; i++) {
1250 let taskLabel = arguments[i]; 1232 let taskLabel = arguments[i];
1251 if (!this._tasks.hasOwnProperty(taskLabel)) { 1233 if (!this._tasks.hasOwnProperty(taskLabel)) {
1252 _throwException('Audit.run:: undefined task.'); 1234 _throwException('Audit.run:: undefined task.');
1253 } else if (this._taskSequence.includes(taskLabel)) { 1235 } else if (this._taskSequence.includes(taskLabel)) {
1254 _throwException('Audit.run:: duplicate task request.'); 1236 _throwException('Audit.run:: duplicate task request.');
1255 } else { 1237 } else {
1256 this._taskSequence.push(taskLabel); 1238 this._taskSequence.push(taskLabel);
1257 } 1239 }
1258 } 1240 }
1259 } 1241 }
1260 1242
1261 if (this._taskSequence.length === 0) { 1243 if (this._taskSequence.length === 0) {
1262 _throwException('Audit.run:: no task to run.'); 1244 _throwException('Audit.run:: no task to run.');
1263 return; 1245 return;
1264 } 1246 }
1265 1247
1266 // Start the first task. 1248 // Start the first task.
1267 this._currentTaskIndex = 0; 1249 this._currentTaskIndex = 0;
1268 this._runNextTask(); 1250 this._runNextTask();
1269 } 1251 }
1270
1271 } 1252 }
1272 1253
1273 /** 1254 /**
1274 * Load file from a given URL and pass ArrayBuffer to the following promise. 1255 * Load file from a given URL and pass ArrayBuffer to the following promise.
1275 * @param {String} fileUrl file URL. 1256 * @param {String} fileUrl file URL.
1276 * @return {Promise} 1257 * @return {Promise}
1277 * 1258 *
1278 * @example 1259 * @example
1279 * Audit.loadFileFromUrl('resources/my-sound.ogg').then((response) => { 1260 * Audit.loadFileFromUrl('resources/my-sound.ogg').then((response) => {
1280 * audioContext.decodeAudioData(response).then((audioBuffer) => { 1261 * audioContext.decodeAudioData(response).then((audioBuffer) => {
1281 * // Do something with AudioBuffer. 1262 * // Do something with AudioBuffer.
1282 * }); 1263 * });
1283 * }); 1264 * });
1284 */ 1265 */
1285 function loadFileFromUrl (fileUrl) { 1266 function loadFileFromUrl(fileUrl) {
1286 return new Promise((resolve, reject) => { 1267 return new Promise((resolve, reject) => {
1287 let xhr = new XMLHttpRequest(); 1268 let xhr = new XMLHttpRequest();
1288 xhr.open('GET', fileUrl, true); 1269 xhr.open('GET', fileUrl, true);
1289 xhr.responseType = 'arraybuffer'; 1270 xhr.responseType = 'arraybuffer';
1290 1271
1291 xhr.onload = () => { 1272 xhr.onload = () => {
1292 // |status = 0| is a workaround for the run-webkit-test server. We are 1273 // |status = 0| is a workaround for the run-webkit-test server. We are
1293 // speculating the server quits the transaction prematurely without 1274 // speculating the server quits the transaction prematurely without
1294 // completing the request. 1275 // completing the request.
1295 if (xhr.status === 200 || xhr.status === 0) { 1276 if (xhr.status === 200 || xhr.status === 0) {
1296 resolve(xhr.response); 1277 resolve(xhr.response);
1297 } else { 1278 } else {
1298 let errorMessage = 'loadFile: Request failed when loading ' + 1279 let errorMessage = 'loadFile: Request failed when loading ' +
1299 fileUrl + '. ' + xhr.statusText + '. (status = ' + 1280 fileUrl + '. ' + xhr.statusText + '. (status = ' + xhr.status +
1300 xhr.status + ')'; 1281 ')';
1301 if (reject) { 1282 if (reject) {
1302 reject(errorMessage); 1283 reject(errorMessage);
1303 } else { 1284 } else {
1304 new Error(errorMessage); 1285 new Error(errorMessage);
1305 } 1286 }
1306 } 1287 }
1307 }; 1288 };
1308 1289
1309 xhr.onerror = (event) => { 1290 xhr.onerror = (event) => {
1310 let errorMessage = 1291 let errorMessage =
(...skipping 23 matching lines...) Expand all
1334 return { 1315 return {
1335 1316
1336 /** 1317 /**
1337 * Creates an instance of Audit task runner. 1318 * Creates an instance of Audit task runner.
1338 * @param {Object} options Options for task runner. 1319 * @param {Object} options Options for task runner.
1339 * @param {Boolean} options.requireResultFile True if the test suite 1320 * @param {Boolean} options.requireResultFile True if the test suite
1340 * requires explicit text 1321 * requires explicit text
1341 * comparison with the expected 1322 * comparison with the expected
1342 * result file. 1323 * result file.
1343 */ 1324 */
1344 createTaskRunner: function (options) { 1325 createTaskRunner: function(options) {
1345 if (options && options.requireResultFile == true) { 1326 if (options && options.requireResultFile == true) {
1346 _logError('this test requires the explicit comparison with the ' 1327 _logError(
1347 + 'expected result when it runs with run-webkit-tests.'); 1328 'this test requires the explicit comparison with the ' +
1329 'expected result when it runs with run-webkit-tests.');
1348 } 1330 }
1349 1331
1350 return new TaskRunner(); 1332 return new TaskRunner();
1351 }, 1333 },
1352 1334
1353 /** 1335 /**
1354 * Load file from a given URL and pass ArrayBuffer to the following promise. 1336 * Load file from a given URL and pass ArrayBuffer to the following promise.
1355 * See |loadFileFromUrl| method for the detail. 1337 * See |loadFileFromUrl| method for the detail.
1356 */ 1338 */
1357 loadFileFromUrl: loadFileFromUrl 1339 loadFileFromUrl: loadFileFromUrl
1358 1340
1359 }; 1341 };
1360 1342
1361 })(); 1343 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698