OLD | NEW |
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 * @seealso webaudio/unit-tests/audit.html for actual examples. | |
12 */ | 11 */ |
13 | 12 |
14 | 13 |
15 (function () { | 14 (function () { |
16 | 15 |
17 'use strict'; | 16 'use strict'; |
18 | 17 |
19 // Selected properties from testharness.js | 18 // Selected properties from testharness.js |
20 let testharnessProperties = [ | 19 let testharnessProperties = [ |
21 'test', 'async_test', 'promise_test', 'promise_rejects', | 20 'test', 'async_test', 'promise_test', 'promise_rejects', |
22 'generate_tests', 'setup', 'done', 'assert_true', 'assert_false' | 21 'generate_tests', 'setup', 'done', 'assert_true', 'assert_false' |
23 ]; | 22 ]; |
24 | 23 |
25 // Check if testharness.js is properly loaded. Throw otherwise. | 24 // Check if testharness.js is properly loaded. Throw otherwise. |
26 for (let name in testharnessProperties) { | 25 for (let name in testharnessProperties) { |
27 if (!self.hasOwnProperty(testharnessProperties[name])) { | 26 if (!self.hasOwnProperty(testharnessProperties[name])) |
28 throw new Error('Cannot proceed. testharness.js is not loaded.'); | 27 throw new Error('Cannot proceed. testharness.js is not loaded.'); |
29 break; | |
30 } | |
31 } | 28 } |
32 })(); | 29 })(); |
33 | 30 |
34 | 31 |
35 /** | |
36 * @class Audit | |
37 * @description A WebAudio layout test task manager. | |
38 * @example | |
39 * let audit = Audit.createTaskRunner(); | |
40 * audit.define('first-task', function (task, should) { | |
41 * task.describe('the first task'); | |
42 * should(someValue).beEqualTo(someValue); | |
43 * task.done(); | |
44 * }); | |
45 * audit.run(); | |
46 */ | |
47 window.Audit = (function () { | 32 window.Audit = (function () { |
48 | 33 |
49 'use strict'; | 34 'use strict'; |
50 | 35 |
| 36 // NOTE: Moving this method (or any other code above) will change the location |
| 37 // of 'CONSOLE ERROR...' message in the expected text files. |
| 38 function _logError (message) { |
| 39 console.error('[audit.js] ' + message); |
| 40 } |
| 41 |
51 function _logPassed (message) { | 42 function _logPassed (message) { |
52 test(function (arg) { | 43 test(function (arg) { |
53 assert_true(true); | 44 assert_true(true); |
54 }, message); | 45 }, message); |
55 } | 46 } |
56 | 47 |
57 function _logFailed (message, detail) { | 48 function _logFailed (message, detail) { |
58 test(function () { | 49 test(function () { |
59 assert_true(false, detail); | 50 assert_true(false, detail); |
60 }, message); | 51 }, message); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 * | 223 * |
233 * @example | 224 * @example |
234 * should({}, 'An empty object').exist(); | 225 * should({}, 'An empty object').exist(); |
235 * @result | 226 * @result |
236 * "PASS An empty object does exist." | 227 * "PASS An empty object does exist." |
237 */ | 228 */ |
238 exist () { | 229 exist () { |
239 return this._assert( | 230 return this._assert( |
240 this._actual !== null && this._actual !== undefined, | 231 this._actual !== null && this._actual !== undefined, |
241 '${actual} does exist.', | 232 '${actual} does exist.', |
242 '${actual} does *NOT* exist.'); | 233 '${actual} does not exist.'); |
243 } | 234 } |
244 | 235 |
245 /** | 236 /** |
246 * Check if |actual| operation wrapped in a function throws an exception | 237 * Check if |actual| operation wrapped in a function throws an exception |
247 * with a expected error type correctly. |expected| is optional. | 238 * with a expected error type correctly. |expected| is optional. |
248 * | 239 * |
249 * @example | 240 * @example |
250 * should(() => { let a = b; }, 'A bad code').throw(); | 241 * should(() => { let a = b; }, 'A bad code').throw(); |
251 * should(() => { let c = d; }, 'Assigning d to c.') | 242 * should(() => { let c = d; }, 'Assigning d to c.') |
252 * .throw('ReferenceError'); | 243 * .throw('ReferenceError'); |
253 * | 244 * |
254 * @result | 245 * @result |
255 * "PASS A bad code threw an exception of ReferenceError." | 246 * "PASS A bad code threw an exception of ReferenceError." |
256 * "PASS Assigning d to c threw ReferenceError." | 247 * "PASS Assigning d to c threw ReferenceError." |
257 */ | 248 */ |
258 throw () { | 249 throw () { |
259 this._processArguments(arguments); | 250 this._processArguments(arguments); |
260 | 251 |
261 let didThrowCorrectly = false; | 252 let didThrowCorrectly = false; |
262 let passDetail, failDetail; | 253 let passDetail, failDetail; |
263 | 254 |
264 try { | 255 try { |
265 // This should throw. | 256 // This should throw. |
266 this._actual(); | 257 this._actual(); |
267 // Catch did not happen, so the test is failed. | 258 // Catch did not happen, so the test is failed. |
268 failDetail = '${actual} did *NOT* throw an exception.'; | 259 failDetail = '${actual} did not throw an exception.'; |
269 } catch (error) { | 260 } catch (error) { |
270 if (this._expected === undefined) { | 261 if (this._expected === undefined) { |
271 didThrowCorrectly = true; | 262 didThrowCorrectly = true; |
272 passDetail = '${actual} threw an exception of ' + error.name + '.'; | 263 passDetail = '${actual} threw an exception of ' + error.name + '.'; |
273 } else if (error.name === this._expected) { | 264 } else if (error.name === this._expected) { |
274 didThrowCorrectly = true; | 265 didThrowCorrectly = true; |
275 passDetail = '${actual} threw ${expected} : "' + error.message + '".'; | 266 passDetail = '${actual} threw ${expected} : "' + error.message + '".'; |
276 } else { | 267 } else { |
277 didThrowCorrectly = false; | 268 didThrowCorrectly = false; |
278 failDetail = '${actual} threw "' + error.name | 269 failDetail = '${actual} threw "' + error.name |
(...skipping 16 matching lines...) Expand all Loading... |
295 */ | 286 */ |
296 notThrow () { | 287 notThrow () { |
297 let didThrowCorrectly = false; | 288 let didThrowCorrectly = false; |
298 let passDetail, failDetail; | 289 let passDetail, failDetail; |
299 | 290 |
300 try { | 291 try { |
301 this._actual(); | 292 this._actual(); |
302 passDetail = '${actual} did not throw an exception.'; | 293 passDetail = '${actual} did not throw an exception.'; |
303 } catch (error) { | 294 } catch (error) { |
304 didThrowCorrectly = true; | 295 didThrowCorrectly = true; |
305 failDetail = '${actual} threw ' + error.name + ': ' | 296 failDetail = '${actual} incorrectly threw ' + error.name + ': "' |
306 + error.message + '.'; | 297 + error.message + '".'; |
307 } | 298 } |
308 | 299 |
309 return this._assert(!didThrowCorrectly, passDetail, failDetail); | 300 return this._assert(!didThrowCorrectly, passDetail, failDetail); |
310 } | 301 } |
311 | 302 |
312 /** | 303 /** |
313 * Check if |actual| promise is resolved correctly. | 304 * Check if |actual| promise is resolved correctly. |
314 * | 305 * |
315 * @example | 306 * @example |
316 * should('My promise', promise).beResolve().then(nextStuff); | 307 * should('My promise', promise).beResolve().then(nextStuff); |
317 * | 308 * |
318 * @result | 309 * @result |
319 * "PASS My promise resolved correctly." | 310 * "PASS My promise resolved correctly." |
320 * "FAIL X My promise rejected *INCORRECTLY* with _ERROR_." | 311 * "FAIL X My promise rejected *INCORRECTLY* with _ERROR_." |
321 */ | 312 */ |
322 beResolved () { | 313 beResolved () { |
323 return this._actual.then(function () { | 314 return this._actual.then(function () { |
324 this._assert(true, '${actual} resolved correctly.', null); | 315 this._assert(true, '${actual} resolved correctly.', null); |
325 }.bind(this), function (error) { | 316 }.bind(this), function (error) { |
326 this._assert(false, null, | 317 this._assert(false, null, |
327 '${actual} rejected *INCORRECTLY* with ' + error + '.'); | 318 '${actual} rejected incorrectly with ' + error + '.'); |
328 }.bind(this)); | 319 }.bind(this)); |
329 } | 320 } |
330 | 321 |
331 /** | 322 /** |
332 * Check if |actual| promise is rejected correctly. | 323 * Check if |actual| promise is rejected correctly. |
333 * | 324 * |
334 * @example | 325 * @example |
335 * should('My promise', promise).beRejected().then(nextStuff); | 326 * should('My promise', promise).beRejected().then(nextStuff); |
336 * | 327 * |
337 * @result | 328 * @result |
338 * "PASS My promise rejected correctly (with _ERROR_)." | 329 * "PASS My promise rejected correctly (with _ERROR_)." |
339 * "FAIL X My promise resolved *INCORRECTLY*." | 330 * "FAIL X My promise resolved *INCORRECTLY*." |
340 */ | 331 */ |
341 beRejected () { | 332 beRejected () { |
342 return this._actual.then(function () { | 333 return this._actual.then(function () { |
343 this._assert(false, null, '${actual} resolved *INCORRECTLY*.'); | 334 this._assert(false, null, '${actual} resolved incorrectly.'); |
344 }.bind(this), function (error) { | 335 }.bind(this), function (error) { |
345 this._assert(true, | 336 this._assert(true, |
346 '${actual} rejected correctly with ' + error + '.', null); | 337 '${actual} rejected correctly with ' + error + '.', null); |
347 }.bind(this)); | 338 }.bind(this)); |
348 } | 339 } |
349 | 340 |
350 /** | 341 /** |
351 * Check if |actual| is a boolean true. | 342 * Check if |actual| is a boolean true. |
352 * | 343 * |
353 * @example | 344 * @example |
354 * should(3 < 5, '3 < 5').beTrue(); | 345 * should(3 < 5, '3 < 5').beTrue(); |
355 * | 346 * |
356 * @result | 347 * @result |
357 * "PASS 3 < 5 is true." | 348 * "PASS 3 < 5 is true." |
358 */ | 349 */ |
359 beTrue () { | 350 beTrue () { |
360 return this._assert( | 351 return this._assert( |
361 this._actual === true, | 352 this._actual === true, |
362 '${actual} is true.', | 353 '${actual} is true.', |
363 '${actual} is *NOT* true.'); | 354 '${actual} is not true.'); |
364 } | 355 } |
365 | 356 |
366 /** | 357 /** |
367 * Check if |actual| is a boolean false. | 358 * Check if |actual| is a boolean false. |
368 * | 359 * |
369 * @example | 360 * @example |
370 * should(3 > 5, '3 > 5').beFalse(); | 361 * should(3 > 5, '3 > 5').beFalse(); |
371 * | 362 * |
372 * @result | 363 * @result |
373 * "PASS 3 > 5 is false." | 364 * "PASS 3 > 5 is false." |
374 */ | 365 */ |
375 beFalse () { | 366 beFalse () { |
376 return this._assert( | 367 return this._assert( |
377 this._actual === false, | 368 this._actual === false, |
378 '${actual} is false.', | 369 '${actual} is false.', |
379 '${actual} is *NOT* false.'); | 370 '${actual} is not false.'); |
380 } | 371 } |
381 | 372 |
382 /** | 373 /** |
383 * Check if |actual| is strictly equal to |expected|. (no type coercion) | 374 * Check if |actual| is strictly equal to |expected|. (no type coercion) |
384 * | 375 * |
385 * @example | 376 * @example |
386 * should(1).beEqualTo(1); | 377 * should(1).beEqualTo(1); |
387 * | 378 * |
388 * @result | 379 * @result |
389 * "PASS 1 is equal to 1." | 380 * "PASS 1 is equal to 1." |
390 */ | 381 */ |
391 beEqualTo () { | 382 beEqualTo () { |
392 this._processArguments(arguments); | 383 this._processArguments(arguments); |
393 return this._assert( | 384 return this._assert( |
394 this._actual === this._expected, | 385 this._actual === this._expected, |
395 '${actual} is equal to ${expected}.', | 386 '${actual} is equal to ${expected}.', |
396 '${actual} is *NOT* equal to ${expected}.'); | 387 '${actual} is not equal to ${expected}.'); |
397 } | 388 } |
398 | 389 |
399 /** | 390 /** |
400 * Check if |actual| is not equal to |expected|. | 391 * Check if |actual| is not equal to |expected|. |
401 * | 392 * |
402 * @example | 393 * @example |
403 * should(1).notBeEqualTo(2); | 394 * should(1).notBeEqualTo(2); |
404 * | 395 * |
405 * @result | 396 * @result |
406 * "PASS 1 is *NOT* equal to 2." | 397 * "PASS 1 is not equal to 2." |
407 */ | 398 */ |
408 notBeEqualTo () { | 399 notBeEqualTo () { |
409 this._processArguments(arguments); | 400 this._processArguments(arguments); |
410 return this._assert( | 401 return this._assert( |
411 this._actual !== this._expected, | 402 this._actual !== this._expected, |
412 '${actual} is not equal to ${expected}.', | 403 '${actual} is not equal to ${expected}.', |
413 '${actual} should *NOT* be equal to ${expected}.'); | 404 '${actual} should not be equal to ${expected}.'); |
414 } | 405 } |
415 | 406 |
416 /** | 407 /** |
417 * Check if |actual| is greater than |expected|. | 408 * Check if |actual| is greater than |expected|. |
418 * | 409 * |
419 * @example | 410 * @example |
420 * should(2).beGreaterThanOrEqualTo(2); | 411 * should(2).beGreaterThanOrEqualTo(2); |
421 * | 412 * |
422 * @result | 413 * @result |
423 * "PASS 2 is greater than or equal to 2." | 414 * "PASS 2 is greater than or equal to 2." |
424 */ | 415 */ |
425 beGreaterThan () { | 416 beGreaterThan () { |
426 this._processArguments(arguments); | 417 this._processArguments(arguments); |
427 return this._assert( | 418 return this._assert( |
428 this._actual > this._expected, | 419 this._actual > this._expected, |
429 '${actual} is greater than ${expected}.', | 420 '${actual} is greater than ${expected}.', |
430 '${actual} is *NOT* greater than ${expected}.' | 421 '${actual} is not greater than ${expected}.' |
431 ); | 422 ); |
432 } | 423 } |
433 | 424 |
434 /** | 425 /** |
435 * Check if |actual| is greater than or equal to |expected|. | 426 * Check if |actual| is greater than or equal to |expected|. |
436 * | 427 * |
437 * @example | 428 * @example |
438 * should(2).beGreaterThan(1); | 429 * should(2).beGreaterThan(1); |
439 * | 430 * |
440 * @result | 431 * @result |
441 * "PASS 2 is greater than 1." | 432 * "PASS 2 is greater than 1." |
442 */ | 433 */ |
443 beGreaterThanOrEqualTo () { | 434 beGreaterThanOrEqualTo () { |
444 this._processArguments(arguments); | 435 this._processArguments(arguments); |
445 return this._assert( | 436 return this._assert( |
446 this._actual >= this._expected, | 437 this._actual >= this._expected, |
447 '${actual} is greater than or equal to ${expected}.', | 438 '${actual} is greater than or equal to ${expected}.', |
448 '${actual} is *NOT* greater than or equal to ${expected}.' | 439 '${actual} is not greater than or equal to ${expected}.' |
449 ); | 440 ); |
450 } | 441 } |
451 | 442 |
452 /** | 443 /** |
453 * Check if |actual| is less than |expected|. | 444 * Check if |actual| is less than |expected|. |
454 * | 445 * |
455 * @example | 446 * @example |
456 * should(1).beLessThan(2); | 447 * should(1).beLessThan(2); |
457 * | 448 * |
458 * @result | 449 * @result |
459 * "PASS 1 is less than 2." | 450 * "PASS 1 is less than 2." |
460 */ | 451 */ |
461 beLessThan () { | 452 beLessThan () { |
462 this._processArguments(arguments); | 453 this._processArguments(arguments); |
463 return this._assert( | 454 return this._assert( |
464 this._actual < this._expected, | 455 this._actual < this._expected, |
465 '${actual} is less than ${expected}.', | 456 '${actual} is less than ${expected}.', |
466 '${actual} is *NOT* less than ${expected}.' | 457 '${actual} is not less than ${expected}.' |
467 ); | 458 ); |
468 } | 459 } |
469 | 460 |
470 /** | 461 /** |
471 * Check if |actual| is less than or equal to |expected|. | 462 * Check if |actual| is less than or equal to |expected|. |
472 * | 463 * |
473 * @example | 464 * @example |
474 * should(1).beLessThanOrEqualTo(1); | 465 * should(1).beLessThanOrEqualTo(1); |
475 * | 466 * |
476 * @result | 467 * @result |
477 * "PASS 1 is less than or equal to 1." | 468 * "PASS 1 is less than or equal to 1." |
478 */ | 469 */ |
479 beLessThanOrEqualTo () { | 470 beLessThanOrEqualTo () { |
480 this._processArguments(arguments); | 471 this._processArguments(arguments); |
481 return this._assert( | 472 return this._assert( |
482 this._actual <= this._expected, | 473 this._actual <= this._expected, |
483 '${actual} is less than or equal to ${expected}.', | 474 '${actual} is less than or equal to ${expected}.', |
484 '${actual} is *NOT* less than or equal to ${expected}.' | 475 '${actual} is not less than or equal to ${expected}.' |
485 ); | 476 ); |
486 } | 477 } |
487 | 478 |
488 /** | 479 /** |
489 * Check if |actual| array is filled with a constant |expected| value. | 480 * Check if |actual| array is filled with a constant |expected| value. |
490 * | 481 * |
491 * @example | 482 * @example |
492 * should([1, 1, 1]).beConstantValueOf(1); | 483 * should([1, 1, 1]).beConstantValueOf(1); |
493 * | 484 * |
494 * @result | 485 * @result |
(...skipping 11 matching lines...) Expand all Loading... |
506 errors[index] = this._actual[index]; | 497 errors[index] = this._actual[index]; |
507 } | 498 } |
508 | 499 |
509 let numberOfErrors = Object.keys(errors).length; | 500 let numberOfErrors = Object.keys(errors).length; |
510 passed = numberOfErrors === 0; | 501 passed = numberOfErrors === 0; |
511 | 502 |
512 if (passed) { | 503 if (passed) { |
513 passDetail = '${actual} contains only the constant ${expected}.'; | 504 passDetail = '${actual} contains only the constant ${expected}.'; |
514 } else { | 505 } else { |
515 let counter = 0; | 506 let counter = 0; |
516 failDetail = '${actual} contains ' + numberOfErrors | 507 failDetail = 'Expected ${expected} for all values but found ' |
517 + ' values that are *NOT* equal to ${expected}: '; | 508 + numberOfErrors + ' unexpected values. : '; |
518 failDetail += '\n\tIndex\tActual'; | 509 failDetail += '\n\tIndex\tActual'; |
519 for (let errorIndex in errors) { | 510 for (let errorIndex in errors) { |
520 failDetail += '\n\t[' + errorIndex + ']' | 511 failDetail += '\n\t[' + errorIndex + ']' |
521 + '\t' + errors[errorIndex]; | 512 + '\t' + errors[errorIndex]; |
522 if (++counter >= this._options.numberOfErrors) { | 513 if (++counter >= this._options.numberOfErrors) { |
523 failDetail += '\n\t...and ' + (numberOfErrors - counter) | 514 failDetail += '\n\t...and ' + (numberOfErrors - counter) |
524 + ' more errors.'; | 515 + ' more errors.'; |
525 break; | 516 break; |
526 } | 517 } |
527 } | 518 } |
(...skipping 13 matching lines...) Expand all Loading... |
541 */ | 532 */ |
542 beEqualToArray () { | 533 beEqualToArray () { |
543 this._processArguments(arguments); | 534 this._processArguments(arguments); |
544 | 535 |
545 let passed = true; | 536 let passed = true; |
546 let passDetail, failDetail; | 537 let passDetail, failDetail; |
547 let errorIndices = []; | 538 let errorIndices = []; |
548 | 539 |
549 if (this._actual.length !== this._expected.length) { | 540 if (this._actual.length !== this._expected.length) { |
550 passed = false; | 541 passed = false; |
551 failDetail = 'The array length does *NOT* match.'; | 542 failDetail = 'The array length does not match.'; |
552 return this._assert(passed, passDetail, failDetail); | 543 return this._assert(passed, passDetail, failDetail); |
553 } | 544 } |
554 | 545 |
555 for (let index in this._actual) { | 546 for (let index in this._actual) { |
556 if (this._actual[index] !== this._expected[index]) | 547 if (this._actual[index] !== this._expected[index]) |
557 errorIndices.push(index); | 548 errorIndices.push(index); |
558 } | 549 } |
559 | 550 |
560 passed = errorIndices.length === 0; | 551 passed = errorIndices.length === 0; |
561 | 552 |
562 if (passed) { | 553 if (passed) { |
563 passDetail = '${actual} is identical to the array ${expected}.'; | 554 passDetail = '${actual} is identical to the array ${expected}.'; |
564 } else { | 555 } else { |
565 let counter = 0; | 556 let counter = 0; |
566 failDetail = '${actual} contains ' + errorIndices.length | 557 failDetail = '${actual} expected to be equal to the array ${expected} ' |
567 + ' values that are *NOT* equal to ${expected}: '; | 558 + 'but differs in ' + errorIndices.length + ' places:' |
568 failDetail += '\n\tIndex\tActual\t\t\tExpected'; | 559 + '\n\tIndex\tActual\t\t\tExpected'; |
569 for (let index of errorIndices) { | 560 for (let index of errorIndices) { |
570 failDetail += '\n\t[' + index + ']' | 561 failDetail += '\n\t[' + index + ']' |
571 + '\t' + this._actual[index].toExponential(16) | 562 + '\t' + this._actual[index].toExponential(16) |
572 + '\t' + this._expected[index].toExponential(16); | 563 + '\t' + this._expected[index].toExponential(16); |
573 if (++counter >= this._options.numberOfErrors) { | 564 if (++counter >= this._options.numberOfErrors) { |
574 failDetail += '\n\t...and ' + (numberOfErrors - counter) | 565 failDetail += '\n\t...and ' + (numberOfErrors - counter) |
575 + ' more errors.'; | 566 + ' more errors.'; |
576 break; | 567 break; |
577 } | 568 } |
578 } | 569 } |
(...skipping 10 matching lines...) Expand all Loading... |
589 * Should([1, 1, 3, 3, 2], 'My random array').containValues([1, 3, 2]); | 580 * Should([1, 1, 3, 3, 2], 'My random array').containValues([1, 3, 2]); |
590 * | 581 * |
591 * @result | 582 * @result |
592 * "PASS [1,1,3,3,2] contains all the expected values in the correct | 583 * "PASS [1,1,3,3,2] contains all the expected values in the correct |
593 * order: [1,3,2]. | 584 * order: [1,3,2]. |
594 */ | 585 */ |
595 containValues () { | 586 containValues () { |
596 this._processArguments(arguments); | 587 this._processArguments(arguments); |
597 | 588 |
598 let passed = true; | 589 let passed = true; |
599 let indexActual = 0, indexExpected = 0; | 590 let indexedActual = []; |
| 591 let firstErrorIndex = null; |
600 | 592 |
601 while (indexActual < this._actual.length | 593 // Collect the unique value sequence from the actual. |
602 && indexExpected < this._expected.length) { | 594 for (let i = 0, prev = null; i < this._actual.length; i++) { |
603 if (this._actual[indexActual] === this._expected[indexExpected]) { | 595 if (this._actual[i] !== prev) { |
604 indexActual++; | 596 indexedActual.push({ |
605 } else { | 597 index: i, |
606 indexExpected++; | 598 value: this._actual[i] |
| 599 }); |
| 600 prev = this._actual[i]; |
607 } | 601 } |
608 } | 602 } |
609 | 603 |
610 passed = !(indexActual < this._actual.length - 1 | 604 // Compare against the expected sequence. |
611 || indexExpected < this._expected.length - 1); | 605 for (let j = 0; j < this._expected.length; j++) { |
| 606 if (this._expected[j] !== indexedActual[j].value) { |
| 607 firstErrorIndex = indexedActual[j].index; |
| 608 passed = false; |
| 609 break; |
| 610 } |
| 611 } |
612 | 612 |
613 return this._assert( | 613 return this._assert( |
614 passed, | 614 passed, |
615 '${actual} contains all the expected values in the correct order: ' | 615 '${actual} contains all the expected values in the correct order: ' |
616 + '${expected}.', | 616 + '${expected}.', |
617 '${actual} contains an unexpected value of ' | 617 '${actual} expected to have the value sequence of ${expected} but ' |
618 + this._actual[indexActual] + ' at index ' + indexActual + '.'); | 618 + 'got ' + this._actual[firstErrorIndex] + ' at index ' |
| 619 + firstErrorIndex + '.'); |
619 } | 620 } |
620 | 621 |
621 /** | 622 /** |
622 * Check if |actual| array does not have any glitches. Note that |threshold| | 623 * Check if |actual| array does not have any glitches. Note that |threshold| |
623 * is not optional and is to define the desired threshold value. | 624 * is not optional and is to define the desired threshold value. |
624 * | 625 * |
625 * @example | 626 * @example |
626 * should([0.5, 0.5, 0.55, 0.5, 0.45, 0.5]).notGlitch(0.06); | 627 * should([0.5, 0.5, 0.55, 0.5, 0.45, 0.5]).notGlitch(0.06); |
627 * | 628 * |
628 * @result | 629 * @result |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
665 */ | 666 */ |
666 beCloseTo () { | 667 beCloseTo () { |
667 this._processArguments(arguments); | 668 this._processArguments(arguments); |
668 | 669 |
669 // The threshold is relative except when |expected| is zero, in which case | 670 // The threshold is relative except when |expected| is zero, in which case |
670 // it is absolute. | 671 // it is absolute. |
671 let absExpected = this._expected ? Math.abs(this._expected) : 1; | 672 let absExpected = this._expected ? Math.abs(this._expected) : 1; |
672 let error = Math.abs(this._actual - this._expected) / absExpected; | 673 let error = Math.abs(this._actual - this._expected) / absExpected; |
673 | 674 |
674 return this._assert( | 675 return this._assert( |
675 error <= this._options.threshold, | 676 error <= this._options.threshold, |
676 '${actual} is ${expected} within an error of ${threshold}.', | 677 '${actual} is ${expected} within an error of ${threshold}.', |
677 '${actual} is not ${expected} within an error of ${threshold}: ' + | 678 '${actual} is not close to ${expected} within an error of ' + |
678 '${actual} with error of ${threshold}.'); | 679 '${threshold}'); |
679 } | 680 } |
680 | 681 |
681 /** | 682 /** |
682 * Check if |target| array is close to |expected| array element-wise within | 683 * Check if |target| array is close to |expected| array element-wise within |
683 * a certain error bound given by the |options|. | 684 * a certain error bound given by the |options|. |
684 * | 685 * |
685 * The error criterion is: | 686 * The error criterion is: |
686 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected)) | 687 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected)) |
687 * | 688 * |
688 * If nothing is given for |options|, then absErr = relErr = 0. If | 689 * If nothing is given for |options|, then absErr = relErr = 0. If |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 } | 971 } |
971 | 972 |
972 // Start the first task. | 973 // Start the first task. |
973 this._currentTaskIndex = 0; | 974 this._currentTaskIndex = 0; |
974 this._runNextTask(); | 975 this._runNextTask(); |
975 } | 976 } |
976 | 977 |
977 } | 978 } |
978 | 979 |
979 | 980 |
| 981 /** |
| 982 * @class Audit |
| 983 * @description A WebAudio layout test task manager. |
| 984 * @example |
| 985 * let audit = Audit.createTaskRunner(); |
| 986 * audit.define('first-task', function (task, should) { |
| 987 * task.describe('the first task'); |
| 988 * should(someValue).beEqualTo(someValue); |
| 989 * task.done(); |
| 990 * }); |
| 991 * audit.run(); |
| 992 */ |
980 return { | 993 return { |
981 | 994 |
982 /** | 995 /** |
983 * Creates an instance of Audit task runner. | 996 * Creates an instance of Audit task runner. |
| 997 * @param {Object} options Options for task runner. |
| 998 * @param {Boolean} options.requireResultFile True if the test suite |
| 999 * requires explicit text |
| 1000 * comparison with the expected |
| 1001 * result file. |
984 */ | 1002 */ |
985 createTaskRunner: function () { | 1003 createTaskRunner: function (options) { |
| 1004 if (options && options.requireResultFile == true) { |
| 1005 _logError('this test requires the explicit comparison with the ' |
| 1006 + 'expected result when it runs with run-webkit-tests.'); |
| 1007 } |
| 1008 |
986 return new TaskRunner(); | 1009 return new TaskRunner(); |
987 } | 1010 } |
988 | 1011 |
989 }; | 1012 }; |
990 | 1013 |
991 })(); | 1014 })(); |
OLD | NEW |