| 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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 145 this._actualDescription = | 145 this._actualDescription = |
| 146 _generateDescription(this._actual, this._options); | 146 _generateDescription(this._actual, this._options); |
| 147 } | 147 } |
| 148 | 148 |
| 149 if (!this._expectedDescription) { | 149 if (!this._expectedDescription) { |
| 150 this._expectedDescription = | 150 this._expectedDescription = |
| 151 _generateDescription(this._expected, this._options); | 151 _generateDescription(this._expected, this._options); |
| 152 } | 152 } |
| 153 | 153 |
| 154 // For the assertion with a single operand. | 154 // For the assertion with a single operand. |
| 155 this._detail = this._detail.replace('${actual}', this._actualDescription); | 155 this._detail = this._detail.replace( |
| 156 /\$\{actual\}/g, this._actualDescription); |
| 156 | 157 |
| 157 // If there is a second operand (i.e. expected value), we have to build | 158 // If there is a second operand (i.e. expected value), we have to build |
| 158 // the string for it as well. | 159 // the string for it as well. |
| 159 if (this._expected) { | 160 if (this._expected !== null) { |
| 160 this._detail = this._detail.replace( | 161 this._detail = this._detail.replace( |
| 161 '${expected}', this._expectedDescription); | 162 /\$\{expected\}/g, this._expectedDescription); |
| 162 } | 163 } |
| 163 | 164 |
| 164 // If there is any property in |_options|, replace the property name | 165 // If there is any property in |_options|, replace the property name |
| 165 // with the value. | 166 // with the value. |
| 166 for (let name in this._options) { | 167 for (let name in this._options) { |
| 167 this._detail = this._detail.replace( | 168 if (name === 'numberOfErrors' |
| 168 '${' + name + '}', | 169 || name === 'numberOfArrayElements' |
| 170 || name === 'verbose') { |
| 171 continue; |
| 172 } |
| 173 |
| 174 // The RegExp key string contains special character. Take care of it. |
| 175 let re = '\$\{' + name + '\}'; |
| 176 re = re.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, '\\$1'); |
| 177 this._detail = this._detail.replace(new RegExp(re, 'g'), |
| 169 _generateDescription(this._options[name])); | 178 _generateDescription(this._options[name])); |
| 170 } | 179 } |
| 171 } | 180 } |
| 172 | 181 |
| 173 _finalize () { | 182 _finalize () { |
| 174 if (this._result) { | 183 if (this._result) { |
| 175 _logPassed(' ' + this._detail); | 184 _logPassed(' ' + this._detail); |
| 176 } else { | 185 } else { |
| 177 _logFailed('X ' + this._detail); | 186 _logFailed('X ' + this._detail); |
| 178 } | 187 } |
| (...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 640 '${actual} has no glitch above the threshold of ${expected}.'; | 649 '${actual} has no glitch above the threshold of ${expected}.'; |
| 641 | 650 |
| 642 return this._assert(passed, passDetail, failDetail); | 651 return this._assert(passed, passDetail, failDetail); |
| 643 } | 652 } |
| 644 | 653 |
| 645 /** | 654 /** |
| 646 * Check if |actual| is close to |expected| using the given relative error | 655 * Check if |actual| is close to |expected| using the given relative error |
| 647 * |threshold|. | 656 * |threshold|. |
| 648 * | 657 * |
| 649 * @example | 658 * @example |
| 650 * should(2.3).beCloseTo(2, 0.3); | 659 * should(2.3).beCloseTo(2, { threshold: 0.3 }); |
| 651 * | 660 * |
| 652 * @result | 661 * @result |
| 653 * "PASS 2.3 is 2 within an error of 0.3." | 662 * "PASS 2.3 is 2 within an error of 0.3." |
| 654 * | 663 * @param {Object} options Options for assertion. |
| 655 * @param {Number} options.threshold Threshold value for the comparison. | 664 * @param {Number} options.threshold Threshold value for the comparison. |
| 656 */ | 665 */ |
| 657 beCloseTo () { | 666 beCloseTo () { |
| 658 this._processArguments(arguments); | 667 this._processArguments(arguments); |
| 659 | 668 |
| 669 // The threshold is relative except when |expected| is zero, in which case |
| 670 // it is absolute. |
| 660 let absExpected = this._expected ? Math.abs(this._expected) : 1; | 671 let absExpected = this._expected ? Math.abs(this._expected) : 1; |
| 661 let error = Math.abs(this._actual - this._expected) / absExpected; | 672 let error = Math.abs(this._actual - this._expected) / absExpected; |
| 662 | 673 |
| 663 return this._assert( | 674 return this._assert( |
| 664 error < this._options.threshold, | 675 error <= this._options.threshold, |
| 665 '${actual} is ${expected} within an error of ${threshold}', | 676 '${actual} is ${expected} within an error of ${threshold}.', |
| 666 '${actual} is not ${expected} within a error of ${threshold}: ' + | 677 '${actual} is not ${expected} within an error of ${threshold}: ' + |
| 667 '${actual} with error of ${threshold}.'); | 678 '${actual} with error of ${threshold}.'); |
| 668 } | 679 } |
| 669 | 680 |
| 670 /** | 681 /** |
| 671 * Check if |target| array is close to |expected| array element-wise within | 682 * Check if |target| array is close to |expected| array element-wise within |
| 672 * a certain error bound given by the |options|. | 683 * a certain error bound given by the |options|. |
| 673 * | 684 * |
| 674 * The error criterion is: | 685 * The error criterion is: |
| 675 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected)) | 686 * abs(actual[k] - expected[k]) < max(absErr, relErr * abs(expected)) |
| 676 * | 687 * |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 934 // to execute them sequentially. Zero argument will perform all defined | 945 // to execute them sequentially. Zero argument will perform all defined |
| 935 // tasks in the order of definition. | 946 // tasks in the order of definition. |
| 936 run () { | 947 run () { |
| 937 // Display the beginning of the test suite. | 948 // Display the beginning of the test suite. |
| 938 _logPassed('# AUDIT TASK RUNNER STARTED.'); | 949 _logPassed('# AUDIT TASK RUNNER STARTED.'); |
| 939 | 950 |
| 940 // If the argument is specified, override the default task sequence with | 951 // If the argument is specified, override the default task sequence with |
| 941 // the specified one. | 952 // the specified one. |
| 942 if (arguments.length > 0) { | 953 if (arguments.length > 0) { |
| 943 this._taskSequence = []; | 954 this._taskSequence = []; |
| 944 for (let i = 0; arguments.length; i++) { | 955 for (let i = 0; i < arguments.length; i++) { |
| 945 let taskLabel = arguments[i]; | 956 let taskLabel = arguments[i]; |
| 946 if (!this._tasks.hasOwnProperty(taskLabel)) { | 957 if (!this._tasks.hasOwnProperty(taskLabel)) { |
| 947 _throwException('Audit.run:: undefined task.'); | 958 _throwException('Audit.run:: undefined task.'); |
| 948 } else if (this._taskSequence.includes(taskLabel)) { | 959 } else if (this._taskSequence.includes(taskLabel)) { |
| 949 _throwException('Audit.run:: duplicate task request.'); | 960 _throwException('Audit.run:: duplicate task request.'); |
| 950 } else { | 961 } else { |
| 951 this._taskSequence.push[taskLabel]; | 962 this._taskSequence.push(taskLabel); |
| 952 } | 963 } |
| 953 } | 964 } |
| 954 } | 965 } |
| 955 | 966 |
| 956 if (this._taskSequence.length === 0) { | 967 if (this._taskSequence.length === 0) { |
| 957 _throwException('Audit.run:: no task to run.'); | 968 _throwException('Audit.run:: no task to run.'); |
| 958 return; | 969 return; |
| 959 } | 970 } |
| 960 | 971 |
| 961 // Start the first task. | 972 // Start the first task. |
| 962 this._currentTaskIndex = 0; | 973 this._currentTaskIndex = 0; |
| 963 this._runNextTask(); | 974 this._runNextTask(); |
| 964 } | 975 } |
| 965 | 976 |
| 966 } | 977 } |
| 967 | 978 |
| 968 | 979 |
| 969 return { | 980 return { |
| 970 | 981 |
| 971 /** | 982 /** |
| 972 * Creates an instance of Audit task runner. | 983 * Creates an instance of Audit task runner. |
| 973 */ | 984 */ |
| 974 createTaskRunner: function () { | 985 createTaskRunner: function () { |
| 975 return new TaskRunner(); | 986 return new TaskRunner(); |
| 976 } | 987 } |
| 977 | 988 |
| 978 }; | 989 }; |
| 979 | 990 |
| 980 })(); | 991 })(); |
| OLD | NEW |