Update web-platform-tests to revision 4f397167b4ed552a02201c92d363cfaecfe2c7f0

This commit is contained in:
WPT Sync Bot 2018-04-26 21:09:36 -04:00 committed by Anthony Ramine
parent 73b5bf201f
commit 84b40513c3
182 changed files with 4779 additions and 1937 deletions

View file

@ -0,0 +1,251 @@
// Test that constructor for the node with name |nodeName| handles the
// various possible values for channelCount, channelCountMode, and
// channelInterpretation.
// The |should| parameter is the test function from new |Audit|.
function testAudioNodeOptions(should, context, nodeName, expectedNodeOptions) {
if (expectedNodeOptions === undefined)
expectedNodeOptions = {};
let node;
// Test that we can set channelCount and that errors are thrown for
// invalid values
let testChannelCount = 17;
if (expectedNodeOptions.channelCount) {
testChannelCount = expectedNodeOptions.channelCount.value;
}
should(
() => {
node = new window[nodeName](
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
channelCount: testChannelCount
}));
},
'new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '}}')
.notThrow();
should(node.channelCount, 'node.channelCount').beEqualTo(testChannelCount);
if (expectedNodeOptions.channelCount &&
expectedNodeOptions.channelCount.isFixed) {
// The channel count is fixed. Verify that we throw an error if
// we try to change it. Arbitrarily set the count to be one more
// than the expected value.
testChannelCount = expectedNodeOptions.channelCount.value + 1;
should(
() => {
node = new window[nodeName](
context,
Object.assign(
{}, expectedNodeOptions.additionalOptions,
{channelCount: testChannelCount}));
},
'new ' + nodeName + '(c, {channelCount: ' + testChannelCount + '}}')
.throw(expectedNodeOptions.channelCount.errorType || 'TypeError');
} else {
// The channel count is not fixed. Try to set the count to invalid
// values and make sure an error is thrown.
let errorType = 'NotSupportedError';
[0, 99].forEach(testValue => {
should(() => {
node = new window[nodeName](
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
channelCount: testValue
}));
}, `new ${nodeName}(c, {channelCount: ${testValue}})`).throw(errorType);
});
}
// Test channelCountMode
let testChannelCountMode = 'max';
if (expectedNodeOptions.channelCountMode) {
testChannelCountMode = expectedNodeOptions.channelCountMode.value;
}
should(
() => {
node = new window[nodeName](
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
channelCountMode: testChannelCountMode
}));
},
'new ' + nodeName + '(c, {channelCountMode: "' + testChannelCountMode +
'"}')
.notThrow();
should(node.channelCountMode, 'node.channelCountMode')
.beEqualTo(testChannelCountMode);
if (expectedNodeOptions.channelCountMode &&
expectedNodeOptions.channelCountMode.isFixed) {
// Channel count mode is fixed. Test setting to something else throws.
['max', 'clamped-max', 'explicit'].forEach(testValue => {
if (testValue !== expectedNodeOptions.channelCountMode.value) {
should(
() => {
node = new window[nodeName](
context,
Object.assign(
{}, expectedNodeOptions.additionalOptions,
{channelCountMode: testValue}));
},
`new ${nodeName}(c, {channelCountMode: "${testValue}"})`)
.throw(expectedNodeOptions.channelCountMode.errorType);
}
});
} else {
// Mode is not fixed. Verify that we can set the mode to all valid
// values, and that we throw for invalid values.
let testValues = ['max', 'clamped-max', 'explicit'];
testValues.forEach(testValue => {
should(() => {
node = new window[nodeName](
context, Object.assign({}, expectedNodeOptions.additionalOptions, {
channelCountMode: testValue
}));
}, `new ${nodeName}(c, {channelCountMode: "${testValue}"})`).notThrow();
should(
node.channelCountMode, 'node.channelCountMode after valid setter')
.beEqualTo(testValue);
});
should(
() => {
node = new window[nodeName](
context,
Object.assign(
{}, expectedNodeOptions.additionalOptions,
{channelCountMode: 'foobar'}));
},
'new ' + nodeName + '(c, {channelCountMode: "foobar"}')
.throw('TypeError');
should(node.channelCountMode, 'node.channelCountMode after invalid setter')
.beEqualTo(testValues[testValues.length - 1]);
}
// Test channelInterpretation
if (expectedNodeOptions.channelInterpretation &&
expectedNodeOptions.channelInterpretation.isFixed) {
// The channel interpretation is fixed. Verify that we throw an
// error if we try to change it.
['speakers', 'discrete'].forEach(testValue => {
if (testValue !== expectedNodeOptions.channelInterpretation.value) {
should(
() => {
node = new window[nodeName](
context,
Object.assign(
{}, expectedNodeOptions.additionOptions,
{channelInterpretation: testValue}));
},
`new ${nodeName}(c, {channelInterpretation: "${testValue}"})`)
.throw(expectedNodeOptions.channelInterpretation.errorType);
}
});
} else {
// Channel interpretation is not fixed. Verify that we can set it
// to all possible values.
should(
() => {
node = new window[nodeName](
context,
Object.assign(
{}, expectedNodeOptions.additionalOptions,
{channelInterpretation: 'speakers'}));
},
'new ' + nodeName + '(c, {channelInterpretation: "speakers"})')
.notThrow();
should(node.channelInterpretation, 'node.channelInterpretation')
.beEqualTo('speakers');
should(
() => {
node = new window[nodeName](
context,
Object.assign(
{}, expectedNodeOptions.additionalOptions,
{channelInterpretation: 'discrete'}));
},
'new ' + nodeName + '(c, {channelInterpretation: "discrete"})')
.notThrow();
should(node.channelInterpretation, 'node.channelInterpretation')
.beEqualTo('discrete');
should(
() => {
node = new window[nodeName](
context,
Object.assign(
{}, expectedNodeOptions.additionalOptions,
{channelInterpretation: 'foobar'}));
},
'new ' + nodeName + '(c, {channelInterpretation: "foobar"})')
.throw('TypeError');
should(
node.channelInterpretation,
'node.channelInterpretation after invalid setter')
.beEqualTo('discrete');
}
}
function initializeContext(should) {
let c;
should(() => {
c = new OfflineAudioContext(1, 1, 48000);
}, 'context = new OfflineAudioContext(...)').notThrow();
return c;
}
function testInvalidConstructor(should, name, context) {
should(() => {
new window[name]();
}, 'new ' + name + '()').throw('TypeError');
should(() => {
new window[name](1);
}, 'new ' + name + '(1)').throw('TypeError');
should(() => {
new window[name](context, 42);
}, 'new ' + name + '(context, 42)').throw('TypeError');
}
function testDefaultConstructor(should, name, context, options) {
let node;
let message = options.prefix + ' = new ' + name + '(context';
if (options.constructorOptions)
message += ', ' + JSON.stringify(options.constructorOptions);
message += ')'
should(() => {
node = new window[name](context, options.constructorOptions);
}, message).notThrow();
should(node instanceof window[name], options.prefix + ' instanceof ' + name)
.beEqualTo(true);
should(node.numberOfInputs, options.prefix + '.numberOfInputs')
.beEqualTo(options.numberOfInputs);
should(node.numberOfOutputs, options.prefix + '.numberOfOutputs')
.beEqualTo(options.numberOfOutputs);
should(node.channelCount, options.prefix + '.channelCount')
.beEqualTo(options.channelCount);
should(node.channelCountMode, options.prefix + '.channelCountMode')
.beEqualTo(options.channelCountMode);
should(node.channelInterpretation, options.prefix + '.channelInterpretation')
.beEqualTo(options.channelInterpretation);
return node;
}
function testDefaultAttributes(should, node, prefix, items) {
items.forEach((item) => {
let attr = node[item.name];
if (attr instanceof AudioParam) {
should(attr.value, prefix + '.' + item.name + '.value')
.beEqualTo(item.value);
} else {
should(attr, prefix + '.' + item.name).beEqualTo(item.value);
}
});
}

View file

@ -0,0 +1,183 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: AnalyserNode
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'AnalyserNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'AnalyserNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 1,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [
{name: 'fftSize', value: 2048},
{name: 'frequencyBinCount', value: 1024},
{name: 'minDecibels', value: -100}, {name: 'maxDecibels', value: -30},
{name: 'smoothingTimeConstant', value: 0.8}
]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'AnalyserNode');
task.done();
});
audit.define('constructor with options', (task, should) => {
let options = {
fftSize: 32,
maxDecibels: 1,
minDecibels: -13,
// Choose a value that can be represented the same as a float and as a
// double.
smoothingTimeConstant: 0.125
};
let node;
should(
() => {
node = new AnalyserNode(context, options);
},
'node1 = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node instanceof AnalyserNode, 'node1 instanceof AnalyserNode')
.beEqualTo(true);
should(node.fftSize, 'node1.fftSize').beEqualTo(options.fftSize);
should(node.maxDecibels, 'node1.maxDecibels')
.beEqualTo(options.maxDecibels);
should(node.minDecibels, 'node1.minDecibels')
.beEqualTo(options.minDecibels);
should(node.smoothingTimeConstant, 'node1.smoothingTimeConstant')
.beEqualTo(options.smoothingTimeConstant);
task.done();
});
audit.define('construct invalid options', (task, should) => {
let node;
should(
() => {
node = new AnalyserNode(context, {fftSize: 33});
},
'node = new AnalyserNode(c, { fftSize: 33 })')
.throw('IndexSizeError');
should(
() => {
node = new AnalyserNode(context, {maxDecibels: -500});
},
'node = new AnalyserNode(c, { maxDecibels: -500 })')
.throw('IndexSizeError');
should(
() => {
node = new AnalyserNode(context, {minDecibels: -10});
},
'node = new AnalyserNode(c, { minDecibels: -10 })')
.throw('IndexSizeError');
should(
() => {
node = new AnalyserNode(context, {smoothingTimeConstant: 2});
},
'node = new AnalyserNode(c, { smoothingTimeConstant: 2 })')
.throw('IndexSizeError');
should(function() {
node = new AnalyserNode(context, {frequencyBinCount: 33});
}, 'node = new AnalyserNode(c, { frequencyBinCount: 33 })').notThrow();
should(node.frequencyBinCount, 'node.frequencyBinCount')
.beEqualTo(1024);
task.done();
});
audit.define('setting min/max', (task, should) => {
let node;
// Recall the default values of minDecibels and maxDecibels are -100,
// and -30, respectively. Setting both values in the constructor should
// not signal an error in any of the following cases.
let options = {minDecibels: -10, maxDecibels: 20};
should(
() => {
node = new AnalyserNode(context, options);
},
'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
options = {maxDecibels: 20, minDecibels: -10};
should(
() => {
node = new AnalyserNode(context, options);
},
'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
options = {minDecibels: -200, maxDecibels: -150};
should(
() => {
node = new AnalyserNode(context, options);
},
'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
options = {maxDecibels: -150, minDecibels: -200};
should(
() => {
node = new AnalyserNode(context, options);
},
'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
// But these should signal because minDecibel > maxDecibel
options = {maxDecibels: -150, minDecibels: -10};
should(
() => {
node = new AnalyserNode(context, options);
},
'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
.throw('IndexSizeError');
options = {minDecibels: -10, maxDecibels: -150};
should(
() => {
node = new AnalyserNode(context, options);
},
'node = new AnalyserNode(c, ' + JSON.stringify(options) + ')')
.throw('IndexSizeError');
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: AudioBufferSource
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'AudioBufferSourceNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node =
testDefaultConstructor(should, 'AudioBufferSourceNode', context, {
prefix: prefix,
numberOfInputs: 0,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [
{name: 'buffer', value: null},
{name: 'detune', value: 0},
{name: 'loop', value: false},
{name: 'loopEnd', value: 0.0},
{name: 'loopStart', value: 0.0},
{name: 'playbackRate', value: 1.0},
]);
task.done();
});
audit.define('nullable buffer', (task, should) => {
let node;
let options = {buffer: null};
should(
() => {
node = new AudioBufferSourceNode(context, options);
},
'node1 = new AudioBufferSourceNode(c, ' + JSON.stringify(options))
.notThrow();
should(node.buffer, 'node1.buffer').beEqualTo(null);
task.done();
});
audit.define('constructor options', (task, should) => {
let node;
let buffer = context.createBuffer(2, 1000, context.sampleRate);
let options = {
buffer: buffer,
detune: .5,
loop: true,
loopEnd: (buffer.length / 2) / context.sampleRate,
loopStart: 5 / context.sampleRate,
playbackRate: .75
};
let message = 'node = new AudioBufferSourceNode(c, ' +
JSON.stringify(options) + ')';
should(() => {
node = new AudioBufferSourceNode(context, options);
}, message).notThrow();
// Use the factory method to create an equivalent node and compare the
// results from the constructor against this node.
let factoryNode = context.createBufferSource();
factoryNode.buffer = options.buffer;
factoryNode.detune.value = options.detune;
factoryNode.loop = options.loop;
factoryNode.loopEnd = options.loopEnd;
factoryNode.loopStart = options.loopStart;
factoryNode.playbackRate.value = options.playbackRate;
should(node.buffer === buffer, 'node2.buffer === buffer')
.beEqualTo(true);
should(node.detune.value, 'node2.detune.value')
.beEqualTo(factoryNode.detune.value);
should(node.loop, 'node2.loop').beEqualTo(factoryNode.loop);
should(node.loopEnd, 'node2.loopEnd').beEqualTo(factoryNode.loopEnd);
should(node.loopStart, 'node2.loopStart')
.beEqualTo(factoryNode.loopStart);
should(node.playbackRate.value, 'node2.playbackRate.value')
.beEqualTo(factoryNode.playbackRate.value);
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,86 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: BiquadFilter
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'BiquadFilterNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'BiquadFilterNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [
{name: 'type', value: 'lowpass'}, {name: 'Q', value: 1},
{name: 'detune', value: 0}, {name: 'frequency', value: 350},
{name: 'gain', value: 0.0}
]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'BiquadFilterNode');
task.done();
});
audit.define('construct with options', (task, should) => {
let node;
let options = {
type: 'highpass',
frequency: 512,
detune: 1,
Q: 5,
gain: 3,
};
should(
() => {
node = new BiquadFilterNode(context, options);
},
'node = new BiquadFilterNode(..., ' + JSON.stringify(options) + ')')
.notThrow();
// Test that attributes are set according to the option values.
should(node.type, 'node.type').beEqualTo(options.type);
should(node.frequency.value, 'node.frequency.value')
.beEqualTo(options.frequency);
should(node.detune.value, 'node.detuen.value')
.beEqualTo(options.detune);
should(node.Q.value, 'node.Q.value').beEqualTo(options.Q);
should(node.gain.value, 'node.gain.value').beEqualTo(options.gain);
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,109 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: ChannelMerger
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'ChannelMergerNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node =
testDefaultConstructor(should, 'ChannelMergerNode', context, {
prefix: prefix,
numberOfInputs: 6,
numberOfOutputs: 1,
channelCount: 1,
channelCountMode: 'explicit',
channelInterpretation: 'speakers'
});
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'ChannelMergerNode', {
channelCount:
{value: 1, isFixed: true, errorType: 'InvalidStateError'},
channelCountMode: {
value: 'explicit',
isFixed: true,
errorType: 'InvalidStateError'
}
});
task.done();
});
audit.define('constructor options', (task, should) => {
let node;
let options = {
numberOfInputs: 3,
numberOfOutputs: 9,
channelInterpretation: 'discrete'
};
should(
() => {
node = new ChannelMergerNode(context, options);
},
'node1 = new ChannelMergerNode(context, ' +
JSON.stringify(options) + ')')
.notThrow();
should(node.numberOfInputs, 'node1.numberOfInputs')
.beEqualTo(options.numberOfInputs);
should(node.numberOfOutputs, 'node1.numberOfOutputs').beEqualTo(1);
should(node.channelInterpretation, 'node1.channelInterpretation')
.beEqualTo(options.channelInterpretation);
options = {numberOfInputs: 99};
should(
() => {
node = new ChannelMergerNode(context, options);
},
'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')')
.throw('IndexSizeError');
options = {channelCount: 3};
should(
() => {
node = new ChannelMergerNode(context, options);
},
'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')')
.throw('InvalidStateError');
options = {channelCountMode: 'max'};
should(
() => {
node = new ChannelMergerNode(context, options);
},
'new ChannelMergerNode(c, ' + JSON.stringify(options) + ')')
.throw('InvalidStateError');
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,111 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: ChannelSplitter
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'ChannelSplitterNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
testDefaultConstructor(should, 'ChannelSplitterNode', context, {
prefix: 'node0',
numberOfInputs: 1,
numberOfOutputs: 6,
channelCount: 6,
channelCountMode: 'explicit',
channelInterpretation: 'discrete'
});
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'ChannelSplitterNode', {
channelCount:
{value: 6, isFixed: true, errorType: 'InvalidStateError'},
channelCountMode: {
value: 'explicit',
isFixed: true,
},
channelInterpretation: {
value: 'discrete',
isFixed: true,
errorType: 'InvalidStateError'
},
});
task.done();
});
audit.define('constructor options', (task, should) => {
let node;
let options = {
numberOfInputs: 3,
numberOfOutputs: 9,
channelInterpretation: 'discrete'
};
should(
() => {
node = new ChannelSplitterNode(context, options);
},
'node1 = new ChannelSplitterNode(context, ' +
JSON.stringify(options) + ')')
.notThrow();
should(node.numberOfInputs, 'node1.numberOfInputs').beEqualTo(1);
should(node.numberOfOutputs, 'node1.numberOfOutputs')
.beEqualTo(options.numberOfOutputs);
should(node.channelInterpretation, 'node1.channelInterpretation')
.beEqualTo(options.channelInterpretation);
options = {numberOfOutputs: 99};
should(
() => {
node = new ChannelSplitterNode(context, options);
},
'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')')
.throw('IndexSizeError');
options = {channelCount: 3};
should(
() => {
node = new ChannelSplitterNode(context, options);
},
'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')')
.throw('InvalidStateError');
options = {channelCountMode: 'max'};
should(
() => {
node = new ChannelSplitterNode(context, options);
},
'new ChannelSplitterNode(c, ' + JSON.stringify(options) + ')')
.throw('InvalidStateError');
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,50 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: ConstantSource
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'ConstantSourceNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node =
testDefaultConstructor(should, 'ConstantSourceNode', context, {
prefix: prefix,
numberOfInputs: 0,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(
should, node, prefix, [{name: 'offset', value: 1}]);
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,125 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: Convolver
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'ConvolverNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'ConvolverNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'clamped-max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(
should, node, prefix,
[{name: 'normalize', value: true}, {name: 'buffer', value: null}]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'ConvolverNode', {
channelCount:
{value: 2, isFixed: true, errorType: 'NotSupportedError'},
channelCountMode: {
value: 'clamped-max',
isFixed: true,
errorType: 'NotSupportedError'
},
});
task.done();
});
audit.define('nullable buffer', (task, should) => {
let node;
let options = {buffer: null};
should(
() => {
node = new ConvolverNode(context, options);
},
'node1 = new ConvolverNode(c, ' + JSON.stringify(options))
.notThrow();
should(node.buffer, 'node1.buffer').beEqualTo(null);
task.done();
});
audit.define('construct with options', (task, should) => {
let buf = context.createBuffer(1, 1, context.sampleRate);
let options = {buffer: buf, disableNormalization: false};
let message =
'node = new ConvolverNode(c, ' + JSON.stringify(options) + ')';
let node;
should(() => {
node = new ConvolverNode(context, options);
}, message).notThrow();
should(node instanceof ConvolverNode, 'node1 instanceOf ConvolverNode')
.beEqualTo(true);
should(node.buffer === options.buffer, 'node1.buffer === <buf>')
.beEqualTo(true);
should(node.normalize, 'node1.normalize')
.beEqualTo(!options.disableNormalization);
options.buffer = null;
options.disableNormalization = true;
message =
'node2 = new ConvolverNode(, ' + JSON.stringify(options) + ')';
should(() => {
node = new ConvolverNode(context, options);
}, message).notThrow();
should(node.buffer, 'node2.buffer').beEqualTo(null);
should(node.normalize, 'node2.normalize')
.beEqualTo(!options.disableNormalization);
options.disableNormalization = false;
message = 'node3 = new ConvolverNode(context, ' +
JSON.stringify(options) + ')';
should(() => {
node = new ConvolverNode(context, options);
}, message).notThrow();
should(node.buffer, 'node3.buffer').beEqualTo(null);
should(node.normalize, 'node3.normalize')
.beEqualTo(!options.disableNormalization);
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: Delay
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'DelayNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'DelayNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(
should, node, prefix, [{name: 'delayTime', value: 0}]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'DelayNode');
task.done();
});
audit.define('constructor options', (task, should) => {
let node;
let options = {
delayTime: 0.5,
maxDelayTime: 1.5,
};
should(
() => {
node = new DelayNode(context, options);
},
'node1 = new DelayNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.delayTime.value, 'node1.delayTime.value')
.beEqualTo(options.delayTime);
should(node.delayTime.maxValue, 'node1.delayTime.maxValue')
.beEqualTo(options.maxDelayTime);
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,196 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: DynamicsCompressor
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'DynamicsCompressorNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node =
testDefaultConstructor(should, 'DynamicsCompressorNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'clamped-max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [
{name: 'threshold', value: -24}, {name: 'knee', value: 30},
{name: 'ratio', value: 12}, {name: 'reduction', value: 0},
{name: 'attack', value: Math.fround(0.003)},
{name: 'release', value: 0.25}
]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
// Can't use testAudioNodeOptions because the constraints for this node
// are not supported there.
// Array of test options to be run. Each entry is a dictionary where
// |testAttribute| is the name of the attribute to be tested,
// |testValue| is the value to be used, and |expectedErrorType| is the
// error type if the test is expected to throw an error.
// |expectedErrorType| should be set only if the test does throw.
let testOptions = [
// Test channel count
{
testAttribute: 'channelCount',
testValue: 1,
},
{
testAttribute: 'channelCount',
testValue: 2,
},
{
testAttribute: 'channelCount',
testValue: 0,
expectedErrorType: 'NotSupportedError'
},
{
testAttribute: 'channelCount',
testValue: 3,
expectedErrorType: 'NotSupportedError'
},
{
testAttribute: 'channelCount',
testValue: 99,
expectedErrorType: 'NotSupportedError'
},
// Test channel count mode
{
testAttribute: 'channelCountMode',
testValue: 'clamped-max',
},
{
testAttribute: 'channelCountMode',
testValue: 'explicit',
},
{
testAttribute: 'channelCountMode',
testValue: 'max',
expectedErrorType: 'NotSupportedError'
},
{
testAttribute: 'channelCountMode',
testValue: 'foobar',
expectedErrorType: 'TypeError'
},
// Test channel interpretation
{
testAttribute: 'channelInterpretation',
testValue: 'speakers',
},
{
testAttribute: 'channelInterpretation',
testValue: 'discrete',
},
{
testAttribute: 'channelInterpretation',
testValue: 'foobar',
expectedErrorType: 'TypeError'
}
];
testOptions.forEach((option) => {
let nodeOptions = {};
nodeOptions[option.testAttribute] = option.testValue;
testNode(should, context, {
nodeOptions: nodeOptions,
testAttribute: option.testAttribute,
expectedValue: option.testValue,
expectedErrorType: option.expectedErrorType
});
});
task.done();
});
audit.define('constructor with options', (task, should) => {
let node;
let options =
{threshold: -33, knee: 15, ratio: 7, attack: 0.625, release: 0.125};
should(
() => {
node = new DynamicsCompressorNode(context, options);
},
'node1 = new DynamicsCompressorNode(c, ' + JSON.stringify(options) +
')')
.notThrow();
should(
node instanceof DynamicsCompressorNode,
'node1 instanceof DynamicsCompressorNode')
.beEqualTo(true);
should(node.threshold.value, 'node1.threshold.value')
.beEqualTo(options.threshold);
should(node.knee.value, 'node1.knee.value').beEqualTo(options.knee);
should(node.ratio.value, 'node1.ratio.value').beEqualTo(options.ratio);
should(node.attack.value, 'node1.attack.value')
.beEqualTo(options.attack);
should(node.release.value, 'node1.release.value')
.beEqualTo(options.release);
should(node.channelCount, 'node1.channelCount').beEqualTo(2);
should(node.channelCountMode, 'node1.channelCountMode')
.beEqualTo('clamped-max');
should(node.channelInterpretation, 'node1.channelInterpretation')
.beEqualTo('speakers');
task.done();
});
audit.run();
// Test possible options for DynamicsCompressor constructor.
function testNode(should, context, options) {
// Node to be tested
let node;
let createNodeFunction = () => {
return () => node =
new DynamicsCompressorNode(context, options.nodeOptions);
};
let message = 'new DynamicsCompressorNode(c, ' +
JSON.stringify(options.nodeOptions) + ')';
if (options.expectedErrorType) {
should(createNodeFunction(), message)
.throw(options.expectedErrorType);
} else {
should(createNodeFunction(), message).notThrow();
should(node[options.testAttribute], 'node.' + options.testAttribute)
.beEqualTo(options.expectedValue);
}
}
</script>
</body>
</html>

View file

@ -0,0 +1,79 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: Gain
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'GainNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'GainNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [{name: 'gain', value: 1}]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'GainNode');
task.done();
});
audit.define('constructor with options', (task, should) => {
let node;
let options = {
gain: -2,
};
should(
() => {
node = new GainNode(context, options);
},
'node1 = new GainNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node instanceof GainNode, 'node1 instanceof GainNode')
.beEqualTo(true);
should(node.gain.value, 'node1.gain.value').beEqualTo(options.gain);
should(node.channelCount, 'node1.channelCount').beEqualTo(2);
should(node.channelCountMode, 'node1.channelCountMode')
.beEqualTo('max');
should(node.channelInterpretation, 'node1.channelInterpretation')
.beEqualTo('speakers');
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,126 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: IIRFilter
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'IIRFilterNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'IIRFilterNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers',
constructorOptions: {feedforward: [1], feedback: [1, -.9]}
});
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(
should, context, 'IIRFilterNode',
{additionalOptions: {feedforward: [1, 1], feedback: [1, .5]}});
task.done();
});
audit.define('constructor options', (task, should) => {
let node;
let options = {feedback: [1, .5]};
should(
() => {
node = new IIRFilterNode(context, options);
},
'node = new IIRFilterNode(, ' + JSON.stringify(options) + ')')
.throw('TypeError');
options = {feedforward: [1, 0.5]};
should(
() => {
node = new IIRFilterNode(context, options);
},
'node = new IIRFilterNode(c, ' + JSON.stringify(options) + ')')
.throw('TypeError');
task.done();
});
// Test functionality of constructor. This is needed because we have no
// way of determining if the filter coefficients were were actually set
// appropriately.
// TODO(rtoy): This functionality test should be moved out to a separate
// file.
audit.define('functionality', (task, should) => {
let options = {feedback: [1, .5], feedforward: [1, 1]};
// Create two-channel offline context; sample rate and length are fairly
// arbitrary. Channel 0 contains the test output and channel 1 contains
// the expected output.
let sampleRate = 48000;
let renderLength = 0.125;
let testContext =
new OfflineAudioContext(2, renderLength * sampleRate, sampleRate);
// The test node uses the constructor. The reference node creates the
// same filter but uses the old factory method.
let testNode = new IIRFilterNode(testContext, options);
let refNode = testContext.createIIRFilter(
Float32Array.from(options.feedforward),
Float32Array.from(options.feedback));
let source = testContext.createOscillator();
source.connect(testNode);
source.connect(refNode);
let merger = testContext.createChannelMerger(
testContext.destination.channelCount);
testNode.connect(merger, 0, 0);
refNode.connect(merger, 0, 1);
merger.connect(testContext.destination);
source.start();
testContext.startRendering()
.then(function(resultBuffer) {
let actual = resultBuffer.getChannelData(0);
let expected = resultBuffer.getChannelData(1);
// The output from the two channels should be exactly equal
// because exactly the same IIR filter should have been created.
should(actual, 'Output of filter using new IIRFilter(...)')
.beEqualToArray(expected);
})
.then(() => task.done());
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,203 @@
<!doctype html>
<html>
<head>
<title>Test Constructor: OfflineAudioContext</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/webaudio/resources/audit.js"></script>
<script src="/webaudio/resources/audit-util.js"></script>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script>
let audit = Audit.createTaskRunner();
// Just a simple test of the 3-arg constructor; This should be
// well-covered by other layout tests that use the 3-arg constructor.
audit.define(
{label: 'basic', description: 'Old-style constructor'},
(task, should) => {
let context;
// First and only arg should be a dictionary.
should(() => {
new OfflineAudioContext(3);
}, 'new OfflineAudioContext(3)').throw('TypeError');
// Constructor needs 1 or 3 args, so 2 should throw.
should(() => {
new OfflineAudioContext(3, 42);
}, 'new OfflineAudioContext(3, 42)').throw('TypeError');
// Valid constructor
should(() => {
context = new OfflineAudioContext(3, 42, 12345);
}, 'context = new OfflineAudioContext(3, 42, 12345)').notThrow();
// Verify that the context was constructed correctly.
should(context.length, 'context.length').beEqualTo(42);
should(context.sampleRate, 'context.sampleRate').beEqualTo(12345);
should(
context.destination.channelCount,
'context.destination.channelCount')
.beEqualTo(3);
should(
context.destination.channelCountMode,
'context.destination.channelCountMode')
.beEqualTo('explicit');
should(
context.destination.channelInterpretation,
'context.destination.channelInterpretation')
.beEqualTo('speakers');
task.done();
});
// Test constructor throws an error if the required members of the
// dictionary are not given.
audit.define(
{label: 'options-1', description: 'Required options'},
(task, should) => {
let context2;
// No args should throw
should(() => {
new OfflineAudioContext();
}, 'new OfflineAudioContext()').throw('TypeError');
// Empty OfflineAudioContextOptions should throw
should(() => {
new OfflineAudioContext({});
}, 'new OfflineAudioContext({})').throw('TypeError');
let options = {length: 42};
// sampleRate is required.
should(
() => {
new OfflineAudioContext(options);
},
'new OfflineAudioContext(' + JSON.stringify(options) + ')')
.throw('TypeError');
options = {sampleRate: 12345};
// length is required.
should(
() => {
new OfflineAudioContext(options);
},
'new OfflineAudioContext(' + JSON.stringify(options) + ')')
.throw('TypeError');
// Valid constructor. Verify that the resulting context has the
// correct values.
options = {length: 42, sampleRate: 12345};
should(
() => {
context2 = new OfflineAudioContext(options);
},
'c2 = new OfflineAudioContext(' + JSON.stringify(options) + ')')
.notThrow();
should(
context2.destination.channelCount,
'c2.destination.channelCount')
.beEqualTo(1);
should(context2.length, 'c2.length').beEqualTo(options.length);
should(context2.sampleRate, 'c2.sampleRate')
.beEqualTo(options.sampleRate);
should(
context2.destination.channelCountMode,
'c2.destination.channelCountMode')
.beEqualTo('explicit');
should(
context2.destination.channelInterpretation,
'c2.destination.channelInterpretation')
.beEqualTo('speakers');
task.done();
});
// Constructor should throw errors for invalid values specified by
// OfflineAudioContextOptions.
audit.define(
{label: 'options-2', description: 'Invalid options'},
(task, should) => {
let options = {length: 42, sampleRate: 8000, numberOfChannels: 33};
// channelCount too large.
should(
() => {
new OfflineAudioContext(options);
},
'new OfflineAudioContext(' + JSON.stringify(options) + ')')
.throw('NotSupportedError');
// length cannot be 0
options = {length: 0, sampleRate: 8000};
should(
() => {
new OfflineAudioContext(options);
},
'new OfflineAudioContext(' + JSON.stringify(options) + ')')
.throw('NotSupportedError');
// sampleRate outside valid range
options = {length: 1, sampleRate: 1};
should(
() => {
new OfflineAudioContext(options);
},
'new OfflineAudioContext(' + JSON.stringify(options) + ')')
.throw('NotSupportedError');
task.done();
});
audit.define(
{label: 'options-3', description: 'Valid options'},
(task, should) => {
let context;
let options = {
length: 1,
sampleRate: 8000,
};
// Verify context with valid constructor has the correct values.
should(
() => {
context = new OfflineAudioContext(options);
},
'c = new OfflineAudioContext' + JSON.stringify(options) + ')')
.notThrow();
should(context.length, 'c.length').beEqualTo(options.length);
should(context.sampleRate, 'c.sampleRate')
.beEqualTo(options.sampleRate);
should(
context.destination.channelCount, 'c.destination.channelCount')
.beEqualTo(1);
should(
context.destination.channelCountMode,
'c.destination.channelCountMode')
.beEqualTo('explicit');
should(
context.destination.channelInterpretation,
'c.destination.channelCountMode')
.beEqualTo('speakers');
options.numberOfChannels = 7;
should(
() => {
context = new OfflineAudioContext(options);
},
'c = new OfflineAudioContext' + JSON.stringify(options) + ')')
.notThrow();
should(
context.destination.channelCount, 'c.destination.channelCount')
.beEqualTo(options.numberOfChannels);
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,106 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: Oscillator
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'OscillatorNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'OscillatorNode', context, {
prefix: prefix,
numberOfInputs: 0,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(
should, node, prefix,
[{name: 'type', value: 'sine'}, {name: 'frequency', value: 440}]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'OscillatorNode');
task.done();
});
audit.define('constructor options', (task, should) => {
let node;
let options = {type: 'sawtooth', detune: 7, frequency: 918};
should(
() => {
node = new OscillatorNode(context, options);
},
'node1 = new OscillatorNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.type, 'node1.type').beEqualTo(options.type);
should(node.detune.value, 'node1.detune.value')
.beEqualTo(options.detune);
should(node.frequency.value, 'node1.frequency.value')
.beEqualTo(options.frequency);
should(node.channelCount, 'node1.channelCount').beEqualTo(2);
should(node.channelCountMode, 'node1.channelCountMode')
.beEqualTo('max');
should(node.channelInterpretation, 'node1.channelInterpretation')
.beEqualTo('speakers');
// Test that type and periodicWave options work as described.
options = {
type: 'sine',
periodicWave: new PeriodicWave(context, {real: [1, 1]})
};
should(() => {
node = new OscillatorNode(context, options);
}, 'new OscillatorNode(c, ' + JSON.stringify(options) + ')').notThrow();
options = {type: 'custom'};
should(
() => {
node = new OscillatorNode(context, options);
},
'new OscillatorNode(c, ' + JSON.stringify(options) + ')')
.throw('InvalidStateError');
options = {
type: 'custom',
periodicWave: new PeriodicWave(context, {real: [1, 1]})
};
should(() => {
node = new OscillatorNode(context, options);
}, 'new OscillatorNode(, ' + JSON.stringify(options) + ')').notThrow();
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,274 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: Panner
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'PannerNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'PannerNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'clamped-max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [
{name: 'panningModel', value: 'equalpower'},
{name: 'positionX', value: 0}, {name: 'positionY', value: 0},
{name: 'positionZ', value: 0}, {name: 'orientationX', value: 1},
{name: 'orientationY', value: 0}, {name: 'orientationZ', value: 0},
{name: 'distanceModel', value: 'inverse'},
{name: 'refDistance', value: 1}, {name: 'maxDistance', value: 10000},
{name: 'rolloffFactor', value: 1},
{name: 'coneInnerAngle', value: 360},
{name: 'coneOuterAngle', value: 360},
{name: 'coneOuterGain', value: 0}
]);
// Test the listener too, while we're at it.
let listenerAttributes = [
{name: 'positionX', value: 0},
{name: 'positionY', value: 0},
{name: 'positionZ', value: 0},
{name: 'forwardX', value: 0},
{name: 'forwardY', value: 0},
{name: 'forwardZ', value: -1},
{name: 'upX', value: 0},
{name: 'upY', value: 1},
{name: 'upZ', value: 0},
];
listenerAttributes.forEach((item) => {
should(
context.listener[item.name].value,
'context.listener.' + item.name + '.value')
.beEqualTo(item.value);
});
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
// Can't use testAudioNodeOptions because the constraints for this node
// are not supported there.
let node;
let success = true;
// Test that we can set the channel count to 1 or 2.
let options = {channelCount: 1};
should(
() => {
node = new PannerNode(context, options);
},
'node1 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.channelCount, 'node1.channelCount')
.beEqualTo(options.channelCount);
options = {channelCount: 2};
should(
() => {
node = new PannerNode(context, options);
},
'node2 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.channelCount, 'node2.channelCount')
.beEqualTo(options.channelCount);
// Test that other channel counts throw an error
options = {channelCount: 0};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw('NotSupportedError');
options = {channelCount: 3};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw('NotSupportedError');
options = {channelCount: 99};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw('NotSupportedError');
// Test channelCountMode. A mode of "max" is illegal, but others are
// ok.
options = {channelCountMode: 'clamped-max'};
should(
() => {
node = new PannerNode(context, options);
},
'node3 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.channelCountMode, 'node3.channelCountMode')
.beEqualTo(options.channelCountMode);
options = {channelCountMode: 'explicit'};
should(
() => {
node = new PannerNode(context, options);
},
'node4 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.channelCountMode, 'node4.channelCountMode')
.beEqualTo(options.channelCountMode);
options = {channelCountMode: 'max'};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw('NotSupportedError');
options = {channelCountMode: 'foobar'};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, " + JSON.stringify(options) + ")')
.throw('TypeError');
// Test channelInterpretation.
options = {channelInterpretation: 'speakers'};
should(
() => {
node = new PannerNode(context, options);
},
'node5 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.channelInterpretation, 'node5.channelInterpretation')
.beEqualTo(options.channelInterpretation);
options = {channelInterpretation: 'discrete'};
should(
() => {
node = new PannerNode(context, options);
},
'node6 = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node.channelInterpretation, 'node6.channelInterpretation')
.beEqualTo(options.channelInterpretation);
options = {channelInterpretation: 'foobar'};
should(
() => {
node = new PannerNode(context, options);
},
'new PannerNode(c, ' + JSON.stringify(options) + ')')
.throw('TypeError');
task.done();
});
audit.define('constructor with options', (task, should) => {
let node;
let success = true;
let options = {
panningModel: 'HRTF',
// We use full double float values here to verify also that the actual
// AudioParam value is properly rounded to a float. The actual value
// is immaterial as long as x != Math.fround(x).
positionX: Math.SQRT2,
positionY: 2 * Math.SQRT2,
positionZ: 3 * Math.SQRT2,
orientationX: -Math.SQRT2,
orientationY: -2 * Math.SQRT2,
orientationZ: -3 * Math.SQRT2,
distanceModel: 'linear',
// We use full double float values here to verify also that the actual
// attribute is a double float. The actual value is immaterial as
// long as x != Math.fround(x).
refDistance: Math.PI,
maxDistance: 2 * Math.PI,
rolloffFactor: 3 * Math.PI,
coneInnerAngle: 4 * Math.PI,
coneOuterAngle: 5 * Math.PI,
coneOuterGain: 6 * Math.PI
};
should(
() => {
node = new PannerNode(context, options);
},
'node = new PannerNode(c, ' + JSON.stringify(options) + ')')
.notThrow();
should(node instanceof PannerNode, 'node instanceof PannerNode')
.beEqualTo(true);
should(node.panningModel, 'node.panningModel')
.beEqualTo(options.panningModel);
should(node.positionX.value, 'node.positionX.value')
.beEqualTo(Math.fround(options.positionX));
should(node.positionY.value, 'node.positionY.value')
.beEqualTo(Math.fround(options.positionY));
should(node.positionZ.value, 'node.positionZ.value')
.beEqualTo(Math.fround(options.positionZ));
should(node.orientationX.value, 'node.orientationX.value')
.beEqualTo(Math.fround(options.orientationX));
should(node.orientationY.value, 'node.orientationY.value')
.beEqualTo(Math.fround(options.orientationY));
should(node.orientationZ.value, 'node.orientationZ.value')
.beEqualTo(Math.fround(options.orientationZ));
should(node.distanceModel, 'node.distanceModel')
.beEqualTo(options.distanceModel);
should(node.refDistance, 'node.refDistance')
.beEqualTo(options.refDistance);
should(node.maxDistance, 'node.maxDistance')
.beEqualTo(options.maxDistance);
should(node.rolloffFactor, 'node.rolloffFactor')
.beEqualTo(options.rolloffFactor);
should(node.coneInnerAngle, 'node.coneInnerAngle')
.beEqualTo(options.coneInnerAngle);
should(node.coneOuterAngle, 'node.coneOuterAngle')
.beEqualTo(options.coneOuterAngle);
should(node.coneOuterGain, 'node.coneOuterGain')
.beEqualTo(options.coneOuterGain);
should(node.channelCount, 'node.channelCount').beEqualTo(2);
should(node.channelCountMode, 'node.channelCountMode')
.beEqualTo('clamped-max');
should(node.channelInterpretation, 'node.channelInterpretation')
.beEqualTo('speakers');
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,125 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: StereoPanner
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('invalid constructor', (task, should) => {
testInvalidConstructor(should, 'StereoPannerNode', context);
task.done();
});
audit.define('default constructor', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'StereoPannerNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'clamped-max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [{name: 'pan', value: 0}]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
// Can't use testAudioNodeOptions because the constraints for this node
// are not supported there.
let node;
// An array of tests.
[{
// Test that we can set the channel count to 1 or 2 and that other
// channel counts throw an error.
attribute: 'channelCount',
tests: [
{value: 1}, {value: 2}, {value: 0, error: 'NotSupportedError'},
{value: 3, error: 'NotSupportedError'},
{value: 99, error: 'NotSupportedError'}
]
},
{
// Test channelCountMode. A mode of "max" is illegal, but others are
// ok. But also throw an error of unknown values.
attribute: 'channelCountMode',
tests: [
{value: 'clamped-max'}, {value: 'explicit'},
{value: 'max', error: 'NotSupportedError'},
{value: 'foobar', error: 'TypeError'}
]
},
{
// Test channelInterpretation can be set for valid values and an
// error is thrown for others.
attribute: 'channelInterpretation',
tests: [
{value: 'speakers'}, {value: 'discrete'},
{value: 'foobar', error: 'TypeError'}
]
}].forEach(entry => {
entry.tests.forEach(testItem => {
let options = {};
options[entry.attribute] = testItem.value;
let method = testItem.error ? 'throw' : 'notThrow';
should(
() => {
node = new StereoPannerNode(context, options);
},
`new StereoPannerNode(c, ${JSON.stringify(options)})`)[method](
testItem.error);
if (!testItem.error)
should(node[entry.attribute], `node.${entry.attribute}`)
.beEqualTo(options[entry.attribute]);
});
});
task.done();
});
audit.define('constructor with options', (task, should) => {
let node;
let options = {
pan: 0.75,
};
should(
() => {
node = new StereoPannerNode(context, options);
},
'node1 = new StereoPannerNode(, ' + JSON.stringify(options) + ')')
.notThrow();
should(
node instanceof StereoPannerNode,
'node1 instanceof StereoPannerNode')
.beEqualTo(true);
should(node.pan.value, 'node1.pan.value').beEqualTo(options.pan);
task.done();
});
audit.run();
</script>
</body>
</html>

View file

@ -0,0 +1,72 @@
<!DOCTYPE html>
<html>
<head>
<title>
Test Constructor: WaveShaper
</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>
<script src="/webaudio/resources/audionodeoptions.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let audit = Audit.createTaskRunner();
audit.define('initialize', (task, should) => {
context = initializeContext(should);
task.done();
});
audit.define('incorrect construction', (task, should) => {
testInvalidConstructor(should, 'WaveShaperNode', context);
task.done();
});
audit.define('valid default construction', (task, should) => {
let prefix = 'node0';
let node = testDefaultConstructor(should, 'WaveShaperNode', context, {
prefix: prefix,
numberOfInputs: 1,
numberOfOutputs: 1,
channelCount: 2,
channelCountMode: 'max',
channelInterpretation: 'speakers'
});
testDefaultAttributes(should, node, prefix, [
{name: 'curve', value: null}, {name: 'oversample', value: 'none'}
]);
task.done();
});
audit.define('test AudioNodeOptions', (task, should) => {
testAudioNodeOptions(should, context, 'WaveShaperNode');
task.done();
});
audit.define('valid non-default', (task, should) => {
// Construct an WaveShaperNode with options
let options = {curve: Float32Array.from([1, 2, 3]), oversample: '4x'};
let node;
let message =
'node1 = new WaveShaperNode(, ' + JSON.stringify(options) + ')';
should(() => {
node = new WaveShaperNode(context, options);
}, message).notThrow();
should(node.curve, 'node1.curve').beEqualToArray(options.curve);
should(node.oversample, 'node1.oversample')
.beEqualTo(options.oversample);
task.done();
});
audit.run();
</script>
</body>
</html>