| OLD | NEW |
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title> | 4 <title> |
| 5 audioparam-exceptional-values.html | 5 audioparam-exceptional-values.html |
| 6 </title> | 6 </title> |
| 7 <script src="../../resources/testharness.js"></script> | 7 <script src="../../resources/testharness.js"></script> |
| 8 <script src="../../resources/testharnessreport.js"></script> | 8 <script src="../../resources/testharnessreport.js"></script> |
| 9 <script src="../resources/audit-util.js"></script> | 9 <script src="../resources/audit-util.js"></script> |
| 10 <script src="../resources/audit.js"></script> | 10 <script src="../resources/audit.js"></script> |
| 11 </head> | 11 </head> |
| 12 <body> | 12 <body> |
| 13 <script id="layout-test-code"> | 13 <script id="layout-test-code"> |
| 14 let audit = Audit.createTaskRunner(); | 14 let audit = Audit.createTaskRunner(); |
| 15 | 15 |
| 16 // For these values, AudioParam methods should throw an error because they | 16 // Context to use for all of the tests. The context isn't used for any |
| 17 // are invalid; only | 17 // processing; just need one for creating a gain node, which is used for |
| 18 // finite values are allowed. | 18 // all the tests. |
| 19 let targetValues = [Infinity, -Infinity, NaN]; | 19 let context; |
| 20 | 20 |
| 21 // For these time values, AudioParam methods should throw an error because | 21 // For these values, AudioParam methods should throw a Typeerror because |
| 22 // they are | 22 // they are not finite values. |
| 23 // invalid. Only finite non-negative values are allowed for any time or | 23 let nonFiniteValues = [Infinity, -Infinity, NaN]; |
| 24 // time-like parameter. | 24 |
| 25 let timeValues = [-1, Infinity, -Infinity, NaN]; | 25 audit.define('initialize', (task, should) => { |
| 26 | 26 should(() => { |
| 27 // For these duration values, AudioParam methods should throw an error | 27 // Context for testing. Rendering isn't done, so any valid values can |
| 28 // because they are | 28 // be used here so might as well make them small. |
| 29 // invalid. Only finite values are allowed for any duration parameter. | 29 context = new OfflineAudioContext(1, 1, 8000); |
| 30 let durationValues = [-1, Infinity, -Infinity, NaN, 0]; | 30 }, 'Creating context for testing').notThrow(); |
| 31 | 31 |
| 32 // For these timeConstant values for setTargetAtTime an error must be | 32 task.done(); |
| 33 // thrown because they are | 33 }); |
| 34 // invalid. | 34 |
| 35 let timeConstantValues = [-1, Infinity, -Infinity, NaN]; | 35 audit.define( |
| 36 | 36 { |
| 37 // Just an array for use by setValueCurveAtTime. The length and contents | 37 label: 'test value', |
| 38 // of the array are not | 38 description: 'Test non-finite arguments for AudioParam value' |
| 39 // important. | 39 }, |
| 40 let curve = new Float32Array(10); | 40 (task, should) => { |
| 41 | 41 let gain = context.createGain(); |
| 42 audit.define( | 42 |
| 43 { | 43 // Default method for generating the arguments for an automation |
| 44 label: 'test', | 44 // method for testing the value of the automation. |
| 45 description: | 45 let defaultFuncArg = (value) => [value, 1]; |
| 46 'Test exceptional arguments for AudioParam timeline events' | |
| 47 }, | |
| 48 function(task, should) { | |
| 49 let context = new AudioContext(); | |
| 50 let gain = context.createGain(); | |
| 51 | 46 |
| 52 // Test the value parameter | 47 // Test the value parameter |
| 53 for (value of targetValues) { | 48 doTests(should, gain, 'TypeError', nonFiniteValues, [ |
| 54 let testMethods = [ | 49 {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, { |
| 55 {name: 'setValueAtTime', arg: [value, 1]}, | 50 automationName: 'linearRampToValueAtTime', |
| 56 {name: 'linearRampToValueAtTime', arg: [value, 1]}, | 51 funcArg: defaultFuncArg |
| 57 {name: 'exponentialRampToValueAtTime', arg: [value, 1]}, | 52 }, |
| 58 {name: 'setTargetAtTime', arg: [value, 1, 1]} | 53 { |
| 59 ]; | 54 automationName: 'exponentialRampToValueAtTime', |
| 60 | 55 funcArg: defaultFuncArg |
| 61 for (method of testMethods) { | 56 }, |
| 62 let message = | 57 { |
| 63 'gain.gain.' + method.name + '(' + method.arg + ')'; | 58 automationName: 'setTargetAtTime', |
| 64 should( | 59 funcArg: (value) => [value, 1, 1] |
| 65 () => gain.gain[method.name].apply(gain.gain, method.arg), | |
| 66 message) | |
| 67 .throw(); | |
| 68 } | 60 } |
| 69 } | 61 ]); |
| 62 task.done(); |
| 63 }); |
| 64 |
| 65 audit.define( |
| 66 { |
| 67 label: 'test time', |
| 68 description: 'Test non-finite arguments for AudioParam time' |
| 69 }, |
| 70 (task, should) => { |
| 71 let gain = context.createGain(); |
| 72 |
| 73 // Default method for generating the arguments for an automation |
| 74 // method for testing the time parameter of the automation. |
| 75 let defaultFuncArg = (startTime) => [1, startTime]; |
| 70 | 76 |
| 71 // Test the time parameter | 77 // Test the time parameter |
| 72 for (startTime of timeValues) { | 78 doTests(should, gain, 'TypeError', nonFiniteValues, [ |
| 73 let testMethods = [ | 79 {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, |
| 74 {name: 'setValueAtTime', arg: [1, startTime]}, | 80 { |
| 75 {name: 'linearRampToValueAtTime', arg: [1, startTime]}, | 81 automationName: 'linearRampToValueAtTime', |
| 76 {name: 'exponentialRampToValueAtTime', arg: [1, startTime]}, | 82 funcArg: defaultFuncArg |
| 77 {name: 'setTargetAtTime', arg: [1, startTime, 1]} | 83 }, |
| 78 ]; | 84 { |
| 79 | 85 automationName: 'exponentialRampToValueAtTime', |
| 80 for (method of testMethods) { | 86 funcArg: defaultFuncArg |
| 81 let message = | 87 }, |
| 82 'gain.gain.' + method.name + '(' + method.arg + ')'; | 88 // Test start time for setTarget |
| 83 should( | 89 { |
| 84 () => gain.gain[method.name].apply(gain.gain, method.arg), | 90 automationName: 'setTargetAtTime', |
| 85 message) | 91 funcArg: (startTime) => [1, startTime, 1] |
| 86 .throw(); | 92 }, |
| 87 } | 93 // Test time constant for setTarget |
| 88 } | 94 { |
| 89 | 95 automationName: 'setTargetAtTime', |
| 90 // Test time constant | 96 funcArg: (timeConstant) => [1, 1, timeConstant] |
| 91 for (value of timeConstantValues) { | 97 }, |
| 92 should( | 98 ]); |
| 93 () => gain.gain.setTargetAtTime(1, 1, value), | 99 |
| 94 'gain.gain.setTargetAtTime(1, 1, ' + value + ')') | 100 task.done(); |
| 95 .throw(); | 101 }); |
| 96 } | 102 |
| 97 | 103 audit.define( |
| 98 // Test startTime and duration for setValueCurveAtTime | 104 { |
| 99 for (startTime of timeValues) { | 105 label: 'test setValueCurve', |
| 100 should( | 106 description: 'Test non-finite arguments for setValueCurveAtTime' |
| 101 () => gain.gain.setValueCurveAtTime(curve, startTime, 1), | 107 }, |
| 102 'gain.gain.setValueCurveAtTime(curve, ' + startTime + ', 1)') | 108 (task, should) => { |
| 103 .throw(); | 109 let gain = context.createGain(); |
| 104 } | 110 |
| 105 for (duration of durationValues) { | 111 // Just an array for use by setValueCurveAtTime. The length and |
| 106 should( | 112 // contents of the array are not important. |
| 107 () => gain.gain.setValueCurveAtTime(curve, 1, duration), | 113 let curve = new Float32Array(3); |
| 108 'gain.gain.setValueCurveAtTime(curve, 1, ' + duration + ')') | 114 |
| 109 .throw(); | 115 doTests(should, gain, 'TypeError', nonFiniteValues, [ |
| 110 } | 116 { |
| 111 // Non-finite curve values should signal an error. | 117 automationName: 'setValueCurveAtTime', |
| 112 for (curve of [[1, 2, Infinity, 3], [1, NaN, 2, 3]]) { | 118 funcArg: (startTime) => [curve, startTime, 1] |
| 113 should( | 119 }, |
| 114 () => gain.gain.setValueCurveAtTime(curve, 1, 1), | 120 ]); |
| 115 'gain.gain.setValueCurveAtTime([' + curve + '], 1, 1)') | 121 |
| 116 .throw(); | 122 // Non-finite values for the curve should signal an error |
| 117 } | 123 doTests( |
| 124 should, gain, 'TypeError', |
| 125 [[1, 2, Infinity, 3], [1, NaN, 2, 3]], [{ |
| 126 automationName: 'setValueCurveAtTime', |
| 127 funcArg: (c) => [c, 1, 1] |
| 128 }]); |
| 129 |
| 130 task.done(); |
| 131 }); |
| 132 |
| 133 audit.define( |
| 134 { |
| 135 label: 'special cases 1', |
| 136 description: 'Test exceptions for finite values' |
| 137 }, |
| 138 (task, should) => { |
| 139 let gain = context.createGain(); |
| 140 |
| 141 // Default method for generating the arguments for an automation |
| 142 // method for testing the time parameter of the automation. |
| 143 let defaultFuncArg = (startTime) => [1, startTime]; |
| 144 |
| 145 // Test the time parameter |
| 146 let curve = new Float32Array(3); |
| 147 doTests(should, gain, 'RangeError', [-1], [ |
| 148 {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, |
| 149 { |
| 150 automationName: 'linearRampToValueAtTime', |
| 151 funcArg: defaultFuncArg |
| 152 }, |
| 153 { |
| 154 automationName: 'exponentialRampToValueAtTime', |
| 155 funcArg: defaultFuncArg |
| 156 }, |
| 157 { |
| 158 automationName: 'setTargetAtTime', |
| 159 funcArg: (startTime) => [1, startTime, 1] |
| 160 }, |
| 161 // Test time constant |
| 162 { |
| 163 automationName: 'setTargetAtTime', |
| 164 funcArg: (timeConstant) => [1, 1, timeConstant] |
| 165 }, |
| 166 // startTime and duration for setValueCurve |
| 167 { |
| 168 automationName: 'setValueCurveAtTime', |
| 169 funcArg: (startTime) => [curve, startTime, 1] |
| 170 }, |
| 171 { |
| 172 automationName: 'setValueCurveAtTime', |
| 173 funcArg: (duration) => [curve, 1, duration] |
| 174 }, |
| 175 ]); |
| 176 |
| 177 // One final test for setValueCurve: duration can't be 0. |
| 178 should( |
| 179 () => gain.gain.setValueCurveAtTime(curve, 1, 0), |
| 180 'gain.gain.setValueCurveAtTime(curve, 1, 0)') |
| 181 .throw('RangeError'); |
| 182 |
| 183 task.done(); |
| 184 }); |
| 185 |
| 186 audit.define( |
| 187 { |
| 188 label: 'special cases 2', |
| 189 description: 'Test special cases for expeonentialRamp' |
| 190 }, |
| 191 (task, should) => { |
| 192 let gain = context.createGain(); |
| 193 |
| 194 doTests(should, gain, 'RangeError', [0, -1e-100, 1e-100], [{ |
| 195 automationName: 'exponentialRampToValueAtTime', |
| 196 funcArg: (value) => [value, 1] |
| 197 }]); |
| 198 |
| 118 task.done(); | 199 task.done(); |
| 119 }); | 200 }); |
| 120 | 201 |
| 121 audit.run(); | 202 audit.run(); |
| 203 |
| 204 // Run test over the set of values in |testValues| for all of the |
| 205 // automation methods in |testMethods|. The expected error type is |
| 206 // |errorName|. |testMethods| is an array of dictionaries with attributes |
| 207 // |automationName| giving the name of the automation method to be tested |
| 208 // and |funcArg| being a function of one parameter that produces an array |
| 209 // that will be used as the argument to the automation method. |
| 210 function doTests(should, node, errorName, testValues, testMethods) { |
| 211 testValues.forEach(value => { |
| 212 testMethods.forEach(method => { |
| 213 let args = method.funcArg(value); |
| 214 let message = 'gain.gain.' + method.automationName + '(' + |
| 215 argString(args) + ')'; |
| 216 should(() => node.gain[method.automationName](...args), message) |
| 217 .throw(errorName); |
| 218 }); |
| 219 }); |
| 220 } |
| 221 |
| 222 // Specialized printer for automation arguments so that messages make |
| 223 // sense. We assume the first element is either a number or an array. If |
| 224 // it's an array, there are always three elements, and we want to print |
| 225 // out the brackets for the array argument. |
| 226 function argString(arg) { |
| 227 if (typeof(arg[0]) === 'number') { |
| 228 return arg.toString(); |
| 229 } |
| 230 |
| 231 return '[' + arg[0] + '],' + arg[1] + ',' + arg[2]; |
| 232 } |
| 122 </script> | 233 </script> |
| 123 </body> | 234 </body> |
| 124 </html> | 235 </html> |
| OLD | NEW |