Chromium Code Reviews| 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 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 class Should { | 91 class Should { |
| 92 | 92 |
| 93 constructor (parentTask, actual, actualDescription) { | 93 constructor (parentTask, actual, actualDescription) { |
| 94 this._task = parentTask; | 94 this._task = parentTask; |
| 95 | 95 |
| 96 this._actual = actual; | 96 this._actual = actual; |
| 97 this._actualDescription = (actualDescription || null); | 97 this._actualDescription = (actualDescription || null); |
| 98 this._expected = null; | 98 this._expected = null; |
| 99 this._expectedDescription = null; | 99 this._expectedDescription = null; |
| 100 | 100 |
| 101 this._result = true; | |
| 102 this._detail = ''; | 101 this._detail = ''; |
| 102 this._hasArrayLog = false; | |
| 103 | |
| 104 this._result = null; | |
| 103 | 105 |
| 104 /** | 106 /** |
| 105 * @param {Number} numberOfErrors Number of errors to be printed. | 107 * @param {Number} numberOfErrors Number of errors to be printed. |
| 106 * @param {Number} numberOfArrayElements Number of array elements to be | 108 * @param {Number} numberOfArrayElements Number of array elements to be |
| 107 * printed in the test log. | 109 * printed in the test log. |
| 108 * @param {Boolean} verbose Verbose output from the assertion. | 110 * @param {Boolean} verbose Verbose output from the assertion. |
| 109 */ | 111 */ |
| 110 this._options = { | 112 this._options = { |
| 111 numberOfErrors: 4, | 113 numberOfErrors: 4, |
| 112 numberOfArrayElements: 16, | 114 numberOfArrayElements: 16, |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 125 // case 1: (expected, description, options) | 127 // case 1: (expected, description, options) |
| 126 this._expectedDescription = args[1]; | 128 this._expectedDescription = args[1]; |
| 127 Object.assign(this._options, args[2]); | 129 Object.assign(this._options, args[2]); |
| 128 } else if (typeof args[1] === 'object') { | 130 } else if (typeof args[1] === 'object') { |
| 129 // case 2: (expected, options) | 131 // case 2: (expected, options) |
| 130 Object.assign(this._options, args[1]); | 132 Object.assign(this._options, args[1]); |
| 131 } | 133 } |
| 132 } | 134 } |
| 133 | 135 |
| 134 _buildResultText () { | 136 _buildResultText () { |
| 135 if (!this._actualDescription) { | 137 if (this._result === null) |
| 136 this._actualDescription = | 138 _throwException('Illegal invocation: the assertion is not finished.'); |
|
Raymond Toy
2016/12/21 18:58:12
What does "not finished" really mean here?
hongchan
2016/12/21 21:30:02
Building result text must be done after the assert
Raymond Toy
2016/12/21 21:57:37
So this is really an error in Audit? Not somethin
| |
| 137 _generateDescription(this._actual, this._options); | 139 |
| 138 } | 140 let actualString = _generateDescription(this._actual, this._options); |
|
Raymond Toy
2016/12/21 18:58:12
Would actualResult be a better name?
hongchan
2016/12/21 21:30:02
This is a stringified result. So I would like to k
Raymond Toy
2016/12/21 21:57:37
I find "String" not really relevant since it's the
hongchan
2016/12/21 22:43:55
Acknowledged.
| |
| 141 | |
| 142 // Use generated text when the description is not provided. | |
| 143 if (!this._actualDescription) | |
| 144 this._actualDescription = actualString; | |
| 139 | 145 |
| 140 if (!this._expectedDescription) { | 146 if (!this._expectedDescription) { |
| 141 this._expectedDescription = | 147 this._expectedDescription = |
| 142 _generateDescription(this._expected, this._options); | 148 _generateDescription(this._expected, this._options); |
| 143 } | 149 } |
| 144 | 150 |
| 145 // For the assertion with a single operand. | 151 // For the assertion with a single operand. |
| 146 this._detail = this._detail.replace( | 152 this._detail = this._detail.replace( |
| 147 /\$\{actual\}/g, this._actualDescription); | 153 /\$\{actual\}/g, this._actualDescription); |
| 148 | 154 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 161 || name === 'verbose') { | 167 || name === 'verbose') { |
| 162 continue; | 168 continue; |
| 163 } | 169 } |
| 164 | 170 |
| 165 // The RegExp key string contains special character. Take care of it. | 171 // The RegExp key string contains special character. Take care of it. |
| 166 let re = '\$\{' + name + '\}'; | 172 let re = '\$\{' + name + '\}'; |
| 167 re = re.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); | 173 re = re.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); |
| 168 this._detail = this._detail.replace(new RegExp(re, 'g'), | 174 this._detail = this._detail.replace(new RegExp(re, 'g'), |
| 169 _generateDescription(this._options[name])); | 175 _generateDescription(this._options[name])); |
| 170 } | 176 } |
| 177 | |
| 178 // If the test is failed, add the actual value at the end. | |
|
Raymond Toy
2016/12/21 18:58:12
s/test is/test/
hongchan
2016/12/21 21:30:02
Done.
| |
| 179 if (this._result === false && this._hasArrayLog === false) { | |
| 180 this._detail += ' Got ' + actualString + '.'; | |
| 181 } | |
| 171 } | 182 } |
| 172 | 183 |
| 173 _finalize () { | 184 _finalize () { |
| 174 if (this._result) { | 185 if (this._result) { |
| 175 _logPassed(' ' + this._detail); | 186 _logPassed(' ' + this._detail); |
| 176 } else { | 187 } else { |
| 177 _logFailed('X ' + this._detail); | 188 _logFailed('X ' + this._detail); |
| 178 } | 189 } |
| 179 | 190 |
| 180 // This assertion is finished, so update the parent task accordingly. | 191 // This assertion is finished, so update the parent task accordingly. |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 480 * Check if |actual| array is filled with a constant |expected| value. | 491 * Check if |actual| array is filled with a constant |expected| value. |
| 481 * | 492 * |
| 482 * @example | 493 * @example |
| 483 * should([1, 1, 1]).beConstantValueOf(1); | 494 * should([1, 1, 1]).beConstantValueOf(1); |
| 484 * | 495 * |
| 485 * @result | 496 * @result |
| 486 * "PASS [1,1,1] contains only the constant 1." | 497 * "PASS [1,1,1] contains only the constant 1." |
| 487 */ | 498 */ |
| 488 beConstantValueOf () { | 499 beConstantValueOf () { |
| 489 this._processArguments(arguments); | 500 this._processArguments(arguments); |
| 501 this._hasArrayLog = true; | |
| 490 | 502 |
| 491 let passed = true; | 503 let passed = true; |
| 492 let passDetail, failDetail; | 504 let passDetail, failDetail; |
| 493 let errors = {}; | 505 let errors = {}; |
| 494 | 506 |
| 495 for (let index in this._actual) { | 507 for (let index in this._actual) { |
| 496 if (this._actual[index] !== this._expected) | 508 if (this._actual[index] !== this._expected) |
| 497 errors[index] = this._actual[index]; | 509 errors[index] = this._actual[index]; |
| 498 } | 510 } |
| 499 | 511 |
| 500 let numberOfErrors = Object.keys(errors).length; | 512 let numberOfErrors = Object.keys(errors).length; |
| 501 passed = numberOfErrors === 0; | 513 passed = numberOfErrors === 0; |
| 502 | 514 |
| 503 if (passed) { | 515 if (passed) { |
| 504 passDetail = '${actual} contains only the constant ${expected}.'; | 516 passDetail = '${actual} contains only the constant ${expected}.'; |
| 505 } else { | 517 } else { |
| 506 let counter = 0; | 518 let counter = 0; |
| 507 failDetail = 'Expected ${expected} for all values but found ' | 519 failDetail = 'Expected ${expected} for all values but found ' |
| 508 + numberOfErrors + ' unexpected values. : '; | 520 + numberOfErrors + ' unexpected values: '; |
| 509 failDetail += '\n\tIndex\tActual'; | 521 failDetail += '\n\tIndex\tActual'; |
| 510 for (let errorIndex in errors) { | 522 for (let errorIndex in errors) { |
| 511 failDetail += '\n\t[' + errorIndex + ']' | 523 failDetail += '\n\t[' + errorIndex + ']' |
| 512 + '\t' + errors[errorIndex]; | 524 + '\t' + errors[errorIndex]; |
| 513 if (++counter >= this._options.numberOfErrors) { | 525 if (++counter >= this._options.numberOfErrors) { |
| 514 failDetail += '\n\t...and ' + (numberOfErrors - counter) | 526 failDetail += '\n\t...and ' + (numberOfErrors - counter) |
| 515 + ' more errors.'; | 527 + ' more errors.'; |
| 516 break; | 528 break; |
| 517 } | 529 } |
| 518 } | 530 } |
| 519 } | 531 } |
| 520 | 532 |
| 521 return this._assert(passed, passDetail, failDetail); | 533 return this._assert(passed, passDetail, failDetail); |
| 522 } | 534 } |
| 523 | 535 |
| 524 /** | 536 /** |
| 525 * Check if |actual| array is identical to |expected| array element-wise. | 537 * Check if |actual| array is identical to |expected| array element-wise. |
| 526 * | 538 * |
| 527 * @example | 539 * @example |
| 528 * should([1, 2, 3]).beEqualToArray([1, 2, 3]); | 540 * should([1, 2, 3]).beEqualToArray([1, 2, 3]); |
| 529 * | 541 * |
| 530 * @result | 542 * @result |
| 531 * "[1,2,3] is identical to the array [1,2,3]." | 543 * "[1,2,3] is identical to the array [1,2,3]." |
| 532 */ | 544 */ |
| 533 beEqualToArray () { | 545 beEqualToArray () { |
| 534 this._processArguments(arguments); | 546 this._processArguments(arguments); |
| 547 this._hasArrayLog = true; | |
| 535 | 548 |
| 536 let passed = true; | 549 let passed = true; |
| 537 let passDetail, failDetail; | 550 let passDetail, failDetail; |
| 538 let errorIndices = []; | 551 let errorIndices = []; |
| 539 | 552 |
| 540 if (this._actual.length !== this._expected.length) { | 553 if (this._actual.length !== this._expected.length) { |
| 541 passed = false; | 554 passed = false; |
| 542 failDetail = 'The array length does not match.'; | 555 failDetail = 'The array length does not match.'; |
| 543 return this._assert(passed, passDetail, failDetail); | 556 return this._assert(passed, passDetail, failDetail); |
| 544 } | 557 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 578 * | 591 * |
| 579 * @example | 592 * @example |
| 580 * Should([1, 1, 3, 3, 2], 'My random array').containValues([1, 3, 2]); | 593 * Should([1, 1, 3, 3, 2], 'My random array').containValues([1, 3, 2]); |
| 581 * | 594 * |
| 582 * @result | 595 * @result |
| 583 * "PASS [1,1,3,3,2] contains all the expected values in the correct | 596 * "PASS [1,1,3,3,2] contains all the expected values in the correct |
| 584 * order: [1,3,2]. | 597 * order: [1,3,2]. |
| 585 */ | 598 */ |
| 586 containValues () { | 599 containValues () { |
| 587 this._processArguments(arguments); | 600 this._processArguments(arguments); |
| 601 this._hasArrayLog = true; | |
| 588 | 602 |
| 589 let passed = true; | 603 let passed = true; |
| 590 let indexedActual = []; | 604 let indexedActual = []; |
| 591 let firstErrorIndex = null; | 605 let firstErrorIndex = null; |
| 592 | 606 |
| 593 // Collect the unique value sequence from the actual. | 607 // Collect the unique value sequence from the actual. |
| 594 for (let i = 0, prev = null; i < this._actual.length; i++) { | 608 for (let i = 0, prev = null; i < this._actual.length; i++) { |
| 595 if (this._actual[i] !== prev) { | 609 if (this._actual[i] !== prev) { |
| 596 indexedActual.push({ | 610 indexedActual.push({ |
| 597 index: i, | 611 index: i, |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 626 * @example | 640 * @example |
| 627 * should([0.5, 0.5, 0.55, 0.5, 0.45, 0.5]).notGlitch(0.06); | 641 * should([0.5, 0.5, 0.55, 0.5, 0.45, 0.5]).notGlitch(0.06); |
| 628 * | 642 * |
| 629 * @result | 643 * @result |
| 630 * "PASS [0.5,0.5,0.55,0.5,0.45,0.5] has no glitch above the threshold | 644 * "PASS [0.5,0.5,0.55,0.5,0.45,0.5] has no glitch above the threshold |
| 631 * of 0.06." | 645 * of 0.06." |
| 632 * | 646 * |
| 633 */ | 647 */ |
| 634 notGlitch () { | 648 notGlitch () { |
| 635 this._processArguments(arguments); | 649 this._processArguments(arguments); |
| 650 this._hasArrayLog = true; | |
| 636 | 651 |
| 637 let passed = true; | 652 let passed = true; |
| 638 let passDetail, failDetail; | 653 let passDetail, failDetail; |
| 639 | 654 |
| 640 for (let index in this._actual) { | 655 for (let index in this._actual) { |
| 641 let diff = Math.abs(this._actual[index - 1] - this._actual[index]); | 656 let diff = Math.abs(this._actual[index - 1] - this._actual[index]); |
| 642 if (diff >= this._expected) { | 657 if (diff >= this._expected) { |
| 643 passed = false; | 658 passed = false; |
| 644 failDetail = '${actual} has a glitch at index ' + index + ' of size ' | 659 failDetail = '${actual} has a glitch at index ' + index + ' of size ' |
| 645 + diff + '.'; | 660 + diff + '.'; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 669 | 684 |
| 670 // The threshold is relative except when |expected| is zero, in which case | 685 // The threshold is relative except when |expected| is zero, in which case |
| 671 // it is absolute. | 686 // it is absolute. |
| 672 let absExpected = this._expected ? Math.abs(this._expected) : 1; | 687 let absExpected = this._expected ? Math.abs(this._expected) : 1; |
| 673 let error = Math.abs(this._actual - this._expected) / absExpected; | 688 let error = Math.abs(this._actual - this._expected) / absExpected; |
| 674 | 689 |
| 675 return this._assert( | 690 return this._assert( |
| 676 error <= this._options.threshold, | 691 error <= this._options.threshold, |
| 677 '${actual} is ${expected} within an error of ${threshold}.', | 692 '${actual} is ${expected} within an error of ${threshold}.', |
| 678 '${actual} is not close to ${expected} within an error of ' + | 693 '${actual} is not close to ${expected} within an error of ' + |
| 679 '${threshold}'); | 694 '${threshold}.'); |
| 680 } | 695 } |
| 681 | 696 |
| 682 /** | 697 /** |
| 683 * Check if |target| array is close to |expected| array element-wise within | 698 * Check if |target| array is close to |expected| array element-wise within |
| 684 * a certain error bound given by the |options|. | 699 * a certain error bound given by the |options|. |
| 685 * | 700 * |
| 686 * The error criterion is: | 701 * The error criterion is: |
| 687 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected)) | 702 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected)) |
| 688 * | 703 * |
| 689 * If nothing is given for |options|, then absErr = relErr = 0. If | 704 * If nothing is given for |options|, then absErr = relErr = 0. If |
| 690 * absErr = 0, then the error criterion is a relative error. A non-zero | 705 * absErr = 0, then the error criterion is a relative error. A non-zero |
| 691 * absErr value produces a mix intended to handle the case where the | 706 * absErr value produces a mix intended to handle the case where the |
| 692 * expected value is 0, allowing the target value to differ by absErr from | 707 * expected value is 0, allowing the target value to differ by absErr from |
| 693 * the expected. | 708 * the expected. |
| 694 * | 709 * |
| 695 * @param {Number} options.absoluteThreshold Absolute threshold. | 710 * @param {Number} options.absoluteThreshold Absolute threshold. |
| 696 * @param {Number} options.relativeThreshold Relative threshold. | 711 * @param {Number} options.relativeThreshold Relative threshold. |
| 697 */ | 712 */ |
| 698 beCloseToArray () { | 713 beCloseToArray () { |
| 699 this._processArguments(arguments); | 714 this._processArguments(arguments); |
| 715 this._hasArrayLog = true; | |
| 700 | 716 |
| 701 let passed = true; | 717 let passed = true; |
| 702 let passDetail, failDetail; | 718 let passDetail, failDetail; |
| 703 | 719 |
| 704 // Parsing options. | 720 // Parsing options. |
| 705 let absErrorThreshold = (this._options.absoluteThreshold || 0); | 721 let absErrorThreshold = (this._options.absoluteThreshold || 0); |
| 706 let relErrorThreshold = (this._options.relativeThreshold || 0); | 722 let relErrorThreshold = (this._options.relativeThreshold || 0); |
| 707 | 723 |
| 708 // A collection of all of the values that satisfy the error criterion. | 724 // A collection of all of the values that satisfy the error criterion. |
| 709 // This holds the absolute difference between the target element and the | 725 // This holds the absolute difference between the target element and the |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1005 _logError('this test requires the explicit comparison with the ' | 1021 _logError('this test requires the explicit comparison with the ' |
| 1006 + 'expected result when it runs with run-webkit-tests.'); | 1022 + 'expected result when it runs with run-webkit-tests.'); |
| 1007 } | 1023 } |
| 1008 | 1024 |
| 1009 return new TaskRunner(); | 1025 return new TaskRunner(); |
| 1010 } | 1026 } |
| 1011 | 1027 |
| 1012 }; | 1028 }; |
| 1013 | 1029 |
| 1014 })(); | 1030 })(); |
| OLD | NEW |