Bug 1456980 [wpt PR 10643] - Move WebAudio node constructor tests to WPT, a=testonly

Automatic update from web-platform-testsMove WebAudio node constructor tests to WPT

Move the constructor tests.  Manually verified that Firefox either
passes the tests or fails because of bugs in Firefox.

Bug: 745778
Change-Id: Iee14d9c7531dc0094bac86daede5d62299c5fb93
Reviewed-on: https://chromium-review.googlesource.com/1028713
Reviewed-by: Hongchan Choi <hongchan@chromium.org>
Commit-Queue: Raymond Toy <rtoy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#554032}

--

wpt-commits: 5fa96e1b9cb116519bcb0e6bd1a5b1f532130009
wpt-pr: 10643
This commit is contained in:
Raymond Toy 2018-05-01 14:58:46 +00:00 committed by James Graham
parent 0f8c10b2b3
commit 211833629f
18 changed files with 2457 additions and 0 deletions

View File

@ -297224,6 +297224,11 @@
{}
]
],
"webaudio/resources/audionodeoptions.js": [
[
{}
]
],
"webaudio/resources/audioparam-testing.js": [
[
{}
@ -369145,6 +369150,12 @@
{}
]
],
"webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html": [
[
"/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html",
{}
]
],
"webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html": [
[
"/webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html",
@ -369181,6 +369192,12 @@
{}
]
],
"webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html": [
[
"/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html",
{}
]
],
"webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html": [
[
"/webaudio/the-audio-api/the-audiodestinationnode-interface/idl-test.html",
@ -369493,6 +369510,12 @@
{}
]
],
"webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html": [
[
"/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html",
{}
]
],
"webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html": [
[
"/webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html",
@ -369523,12 +369546,24 @@
{}
]
],
"webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html": [
[
"/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html",
{}
]
],
"webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html": [
[
"/webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html",
{}
]
],
"webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html": [
[
"/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html",
{}
]
],
"webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html": [
[
"/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html",
@ -369547,6 +369582,12 @@
{}
]
],
"webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html": [
[
"/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html",
{}
]
],
"webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html": [
[
"/webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html",
@ -369595,6 +369636,18 @@
{}
]
],
"webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html": [
[
"/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html",
{}
]
],
"webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html": [
[
"/webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html",
{}
]
],
"webaudio/the-audio-api/the-delaynode-interface/delaynode-max-default-delay.html": [
[
"/webaudio/the-audio-api/the-delaynode-interface/delaynode-max-default-delay.html",
@ -369637,12 +369690,24 @@
{}
]
],
"webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html": [
[
"/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html",
{}
]
],
"webaudio/the-audio-api/the-dynamicscompressornode-interface/dynamicscompressor-basic.html": [
[
"/webaudio/the-audio-api/the-dynamicscompressornode-interface/dynamicscompressor-basic.html",
{}
]
],
"webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html": [
[
"/webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html",
{}
]
],
"webaudio/the-audio-api/the-gainnode-interface/gain-basic.html": [
[
"/webaudio/the-audio-api/the-gainnode-interface/gain-basic.html",
@ -369667,6 +369732,12 @@
{}
]
],
"webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html": [
[
"/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html",
{}
]
],
"webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html": [
[
"/webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html",
@ -369697,12 +369768,30 @@
{}
]
],
"webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html": [
[
"/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html",
{}
]
],
"webaudio/the-audio-api/the-offlineaudiocontext-interface/current-time-block-size.html": [
[
"/webaudio/the-audio-api/the-offlineaudiocontext-interface/current-time-block-size.html",
{}
]
],
"webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html": [
[
"/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html",
{}
]
],
"webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html": [
[
"/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html",
{}
]
],
"webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html": [
[
"/webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html",
@ -369775,6 +369864,12 @@
{}
]
],
"webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html": [
[
"/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html",
{}
]
],
"webaudio/the-audio-api/the-stereopanner-interface/no-dezippering.html": [
[
"/webaudio/the-audio-api/the-stereopanner-interface/no-dezippering.html",
@ -369793,6 +369888,12 @@
{}
]
],
"webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html": [
[
"/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html",
{}
]
],
"webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html": [
[
"/webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html",
@ -608974,6 +609075,10 @@
"9ef52c13448d19b241b40a5c81f4a0480c05c5de",
"support"
],
"webaudio/resources/audionodeoptions.js": [
"d7712311bddd23e171e7e1f024aec0a565b08a13",
"support"
],
"webaudio/resources/audioparam-testing.js": [
"2855fbee30e629ea397166911b9bcdec74bd4fdf",
"support"
@ -609038,6 +609143,10 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html": [
"7e35ac29f00d39c84230535212c0b9ea081951d3",
"testharness"
],
"webaudio/the-audio-api/the-analysernode-interface/test-analyser-gain.html": [
"e2320e33ef1df0155d5fcf536550e0e398b15407",
"testharness"
@ -609070,6 +609179,10 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html": [
"ce84d25460435564021a13dc9e26384bc30e9d96",
"testharness"
],
"webaudio/the-audio-api/the-audiocontext-interface/.gitkeep": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
@ -609350,6 +609463,10 @@
"f24a473f695c2d10788ba7d50728259a08ed53c8",
"testharness"
],
"webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html": [
"475916d4aba810c017c385d98d51d353ad0fc561",
"testharness"
],
"webaudio/the-audio-api/the-biquadfilternode-interface/no-dezippering.html": [
"348376a643b765700342e9620e1346d432a28131",
"testharness"
@ -609374,6 +609491,10 @@
"250c35e36dda600c30554024cbd500a37180292a",
"testharness"
],
"webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html": [
"72bfba4cbca1b4d3e7692ef236afb905f852fadd",
"testharness"
],
"webaudio/the-audio-api/the-channelsplitternode-interface/.gitkeep": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
@ -609382,6 +609503,10 @@
"80cfd321970b37df7995d6e0d262a2c008e6e10c",
"testharness"
],
"webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html": [
"743fd6af6f67958f67f4a63cef432515518edf41",
"testharness"
],
"webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-basic.html": [
"d60c7c7c6d9236f773199a213bef6b1103e02e2e",
"testharness"
@ -609394,6 +609519,10 @@
"ce90b4d7ca5840abdc830d734df26028958fadd7",
"testharness"
],
"webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html": [
"1fa8892c98ce5f979a08294a838b3b91ce11a3a3",
"testharness"
],
"webaudio/the-audio-api/the-constantsourcenode-interface/test-constantsourcenode.html": [
"711b3f183d847e437a4c332f33054cc5a648fd22",
"testharness"
@ -609430,10 +609559,18 @@
"f32f5acdf031b1a2b32bc37324b105d1df7c5fdb",
"testharness"
],
"webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html": [
"70f49ae8525bd998d3b51bada7a296ba4cef03e5",
"testharness"
],
"webaudio/the-audio-api/the-delaynode-interface/.gitkeep": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html": [
"473c5e05ab6ee4930de9e3a3ec47075af7e9650d",
"testharness"
],
"webaudio/the-audio-api/the-delaynode-interface/delaynode-max-default-delay.html": [
"c732635549f5eab61f8bdce05b27f0f3e8a3f6c2",
"testharness"
@ -609466,6 +609603,10 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html": [
"6338104e8199673ff7de6f41d310b79a2ee51f04",
"testharness"
],
"webaudio/the-audio-api/the-dynamicscompressornode-interface/dynamicscompressor-basic.html": [
"6ceaf50b8cacdfa246bc997f2c8e46aefd789659",
"testharness"
@ -609474,6 +609615,10 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html": [
"3c77f0ac735a224fa6d905f62585beba39643393",
"testharness"
],
"webaudio/the-audio-api/the-gainnode-interface/gain-basic.html": [
"70165c60c482d6507670af965756f639e7b3ba78",
"testharness"
@ -609494,6 +609639,10 @@
"bf2de43e568c79b96fd5b0602e26346c483162a5",
"testharness"
],
"webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html": [
"3627d5b4a447a62de6c6a6f10556fa9f9dec1700",
"testharness"
],
"webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-basic.html": [
"176168861bc667b2b05312dbae48f76f7f90d791",
"testharness"
@ -609530,6 +609679,10 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html": [
"4264798e9e64d30c72f9f0577a9648efa2d0a50a",
"testharness"
],
"webaudio/the-audio-api/the-offlineaudiocontext-interface/current-time-block-size.html": [
"d0b1fefa6c0f75c0666cd5b7e8305099e9925d62",
"testharness"
@ -609538,10 +609691,18 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html": [
"53df9d36a96c61a6ce9215cbc2830783e26c91be",
"testharness"
],
"webaudio/the-audio-api/the-pannernode-interface/.gitkeep": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html": [
"2b59d21a54b2216c1171a6ba2c7809291955a8af",
"testharness"
],
"webaudio/the-audio-api/the-pannernode-interface/distance-exponential.html": [
"c1c94753ebcd1930e326d73c085e6c3197967cd5",
"testharness"
@ -609598,6 +609759,10 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html": [
"1908ffc477d8c16b81ab371f5b9dbca46cc16a83",
"testharness"
],
"webaudio/the-audio-api/the-stereopanner-interface/no-dezippering.html": [
"b3525a2c459125281196201216417c39030e79a8",
"testharness"
@ -609614,6 +609779,10 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html": [
"80b585554acf22f357264e3a024d2159fd184f13",
"testharness"
],
"webaudio/the-audio-api/the-waveshapernode-interface/curve-tests.html": [
"f88431616d6a8084a3434c1606e3543178d019fb",
"testharness"

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>