audioparam-exceptional-values.html (8596B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title> 5 audioparam-exceptional-values.html 6 </title> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="/webaudio/resources/audit-util.js"></script> 10 <script src="/webaudio/resources/audit.js"></script> 11 </head> 12 <body> 13 <script id="layout-test-code"> 14 let audit = Audit.createTaskRunner(); 15 16 // Context to use for all of the tests. The context isn't used for any 17 // processing; just need one for creating a gain node, which is used for 18 // all the tests. 19 let context; 20 21 // For these values, AudioParam methods should throw a Typeerror because 22 // they are not finite values. 23 let nonFiniteValues = [Infinity, -Infinity, NaN]; 24 25 audit.define('initialize', (task, should) => { 26 should(() => { 27 // Context for testing. Rendering isn't done, so any valid values can 28 // be used here so might as well make them small. 29 context = new OfflineAudioContext(1, 1, 8000); 30 }, 'Creating context for testing').notThrow(); 31 32 task.done(); 33 }); 34 35 audit.define( 36 { 37 label: 'test value', 38 description: 'Test non-finite arguments for AudioParam value' 39 }, 40 (task, should) => { 41 let gain = context.createGain(); 42 43 // Default method for generating the arguments for an automation 44 // method for testing the value of the automation. 45 let defaultFuncArg = (value) => [value, 1]; 46 47 // Test the value parameter 48 doTests(should, gain, TypeError, nonFiniteValues, [ 49 {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, { 50 automationName: 'linearRampToValueAtTime', 51 funcArg: defaultFuncArg 52 }, 53 { 54 automationName: 'exponentialRampToValueAtTime', 55 funcArg: defaultFuncArg 56 }, 57 { 58 automationName: 'setTargetAtTime', 59 funcArg: (value) => [value, 1, 1] 60 } 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]; 76 77 // Test the time parameter 78 doTests(should, gain, TypeError, nonFiniteValues, [ 79 {automationName: 'setValueAtTime', funcArg: defaultFuncArg}, 80 { 81 automationName: 'linearRampToValueAtTime', 82 funcArg: defaultFuncArg 83 }, 84 { 85 automationName: 'exponentialRampToValueAtTime', 86 funcArg: defaultFuncArg 87 }, 88 // Test start time for setTarget 89 { 90 automationName: 'setTargetAtTime', 91 funcArg: (startTime) => [1, startTime, 1] 92 }, 93 // Test time constant for setTarget 94 { 95 automationName: 'setTargetAtTime', 96 funcArg: (timeConstant) => [1, 1, timeConstant] 97 }, 98 ]); 99 100 task.done(); 101 }); 102 103 audit.define( 104 { 105 label: 'test setValueCurve', 106 description: 'Test non-finite arguments for setValueCurveAtTime' 107 }, 108 (task, should) => { 109 let gain = context.createGain(); 110 111 // Just an array for use by setValueCurveAtTime. The length and 112 // contents of the array are not important. 113 let curve = new Float32Array(3); 114 115 doTests(should, gain, TypeError, nonFiniteValues, [ 116 { 117 automationName: 'setValueCurveAtTime', 118 funcArg: (startTime) => [curve, startTime, 1] 119 }, 120 ]); 121 122 // Non-finite values for the curve should signal an error 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 // Two final tests for setValueCurve: duration must be strictly 178 // positive. 179 should( 180 () => gain.gain.setValueCurveAtTime(curve, 1, 0), 181 'gain.gain.setValueCurveAtTime(curve, 1, 0)') 182 .throw(RangeError); 183 should( 184 () => gain.gain.setValueCurveAtTime(curve, 1, -1), 185 'gain.gain.setValueCurveAtTime(curve, 1, -1)') 186 .throw(RangeError); 187 188 task.done(); 189 }); 190 191 audit.define( 192 { 193 label: 'special cases 2', 194 description: 'Test special cases for expeonentialRamp' 195 }, 196 (task, should) => { 197 let gain = context.createGain(); 198 199 doTests(should, gain, RangeError, [0, -1e-100, 1e-100], [{ 200 automationName: 'exponentialRampToValueAtTime', 201 funcArg: (value) => [value, 1] 202 }]); 203 204 task.done(); 205 }); 206 207 audit.run(); 208 209 // Run test over the set of values in |testValues| for all of the 210 // automation methods in |testMethods|. The expected error type is 211 // |errorName|. |testMethods| is an array of dictionaries with attributes 212 // |automationName| giving the name of the automation method to be tested 213 // and |funcArg| being a function of one parameter that produces an array 214 // that will be used as the argument to the automation method. 215 function doTests(should, node, errorName, testValues, testMethods) { 216 testValues.forEach(value => { 217 testMethods.forEach(method => { 218 let args = method.funcArg(value); 219 let message = 'gain.gain.' + method.automationName + '(' + 220 argString(args) + ')'; 221 should(() => node.gain[method.automationName](...args), message) 222 .throw(errorName); 223 }); 224 }); 225 } 226 227 // Specialized printer for automation arguments so that messages make 228 // sense. We assume the first element is either a number or an array. If 229 // it's an array, there are always three elements, and we want to print 230 // out the brackets for the array argument. 231 function argString(arg) { 232 if (typeof(arg[0]) === 'number') { 233 return arg.toString(); 234 } 235 236 return '[' + arg[0] + '],' + arg[1] + ',' + arg[2]; 237 } 238 </script> 239 </body> 240 </html>