blob: 982731d33843544d2f70af72a51e9bd878bbf486 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>
audioparam-exceptional-values.html
</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/resources/audit-util.js"></script>
<script src="/webaudio/resources/audit.js"></script>
</head>
<body>
<script id="layout-test-code">
let audit = Audit.createTaskRunner();
// Context to use for all of the tests. The context isn't used for any
// processing; just need one for creating a gain node, which is used for
// all the tests.
let context;
// For these values, AudioParam methods should throw a Typeerror because
// they are not finite values.
let nonFiniteValues = [Infinity, -Infinity, NaN];
audit.define('initialize', (task, should) => {
should(() => {
// Context for testing. Rendering isn't done, so any valid values can
// be used here so might as well make them small.
context = new OfflineAudioContext(1, 1, 8000);
}, 'Creating context for testing').notThrow();
task.done();
});
audit.define(
{
label: 'test value',
description: 'Test non-finite arguments for AudioParam value'
},
(task, should) => {
let gain = context.createGain();
// Default method for generating the arguments for an automation
// method for testing the value of the automation.
let defaultFuncArg = (value) => [value, 1];
// Test the value parameter
doTests(should, gain, TypeError, nonFiniteValues, [
{automationName: 'setValueAtTime', funcArg: defaultFuncArg}, {
automationName: 'linearRampToValueAtTime',
funcArg: defaultFuncArg
},
{
automationName: 'exponentialRampToValueAtTime',
funcArg: defaultFuncArg
},
{
automationName: 'setTargetAtTime',
funcArg: (value) => [value, 1, 1]
}
]);
task.done();
});
audit.define(
{
label: 'test time',
description: 'Test non-finite arguments for AudioParam time'
},
(task, should) => {
let gain = context.createGain();
// Default method for generating the arguments for an automation
// method for testing the time parameter of the automation.
let defaultFuncArg = (startTime) => [1, startTime];
// Test the time parameter
doTests(should, gain, TypeError, nonFiniteValues, [
{automationName: 'setValueAtTime', funcArg: defaultFuncArg},
{
automationName: 'linearRampToValueAtTime',
funcArg: defaultFuncArg
},
{
automationName: 'exponentialRampToValueAtTime',
funcArg: defaultFuncArg
},
// Test start time for setTarget
{
automationName: 'setTargetAtTime',
funcArg: (startTime) => [1, startTime, 1]
},
// Test time constant for setTarget
{
automationName: 'setTargetAtTime',
funcArg: (timeConstant) => [1, 1, timeConstant]
},
]);
task.done();
});
audit.define(
{
label: 'test setValueCurve',
description: 'Test non-finite arguments for setValueCurveAtTime'
},
(task, should) => {
let gain = context.createGain();
// Just an array for use by setValueCurveAtTime. The length and
// contents of the array are not important.
let curve = new Float32Array(3);
doTests(should, gain, TypeError, nonFiniteValues, [
{
automationName: 'setValueCurveAtTime',
funcArg: (startTime) => [curve, startTime, 1]
},
]);
// Non-finite values for the curve should signal an error
doTests(
should, gain, TypeError,
[[1, 2, Infinity, 3], [1, NaN, 2, 3]], [{
automationName: 'setValueCurveAtTime',
funcArg: (c) => [c, 1, 1]
}]);
task.done();
});
audit.define(
{
label: 'special cases 1',
description: 'Test exceptions for finite values'
},
(task, should) => {
let gain = context.createGain();
// Default method for generating the arguments for an automation
// method for testing the time parameter of the automation.
let defaultFuncArg = (startTime) => [1, startTime];
// Test the time parameter
let curve = new Float32Array(3);
doTests(should, gain, RangeError, [-1], [
{automationName: 'setValueAtTime', funcArg: defaultFuncArg},
{
automationName: 'linearRampToValueAtTime',
funcArg: defaultFuncArg
},
{
automationName: 'exponentialRampToValueAtTime',
funcArg: defaultFuncArg
},
{
automationName: 'setTargetAtTime',
funcArg: (startTime) => [1, startTime, 1]
},
// Test time constant
{
automationName: 'setTargetAtTime',
funcArg: (timeConstant) => [1, 1, timeConstant]
},
// startTime and duration for setValueCurve
{
automationName: 'setValueCurveAtTime',
funcArg: (startTime) => [curve, startTime, 1]
},
{
automationName: 'setValueCurveAtTime',
funcArg: (duration) => [curve, 1, duration]
},
]);
// Two final tests for setValueCurve: duration must be strictly
// positive.
should(
() => gain.gain.setValueCurveAtTime(curve, 1, 0),
'gain.gain.setValueCurveAtTime(curve, 1, 0)')
.throw(RangeError);
should(
() => gain.gain.setValueCurveAtTime(curve, 1, -1),
'gain.gain.setValueCurveAtTime(curve, 1, -1)')
.throw(RangeError);
task.done();
});
audit.define(
{
label: 'special cases 2',
description: 'Test special cases for expeonentialRamp'
},
(task, should) => {
let gain = context.createGain();
doTests(should, gain, RangeError, [0, -1e-100, 1e-100], [{
automationName: 'exponentialRampToValueAtTime',
funcArg: (value) => [value, 1]
}]);
task.done();
});
audit.run();
// Run test over the set of values in |testValues| for all of the
// automation methods in |testMethods|. The expected error type is
// |errorName|. |testMethods| is an array of dictionaries with attributes
// |automationName| giving the name of the automation method to be tested
// and |funcArg| being a function of one parameter that produces an array
// that will be used as the argument to the automation method.
function doTests(should, node, errorName, testValues, testMethods) {
testValues.forEach(value => {
testMethods.forEach(method => {
let args = method.funcArg(value);
let message = 'gain.gain.' + method.automationName + '(' +
argString(args) + ')';
should(() => node.gain[method.automationName](...args), message)
.throw(errorName);
});
});
}
// Specialized printer for automation arguments so that messages make
// sense. We assume the first element is either a number or an array. If
// it's an array, there are always three elements, and we want to print
// out the brackets for the array argument.
function argString(arg) {
if (typeof(arg[0]) === 'number') {
return arg.toString();
}
return '[' + arg[0] + '],' + arg[1] + ',' + arg[2];
}
</script>
</body>
</html>