diff options
Diffstat (limited to 'testing/web-platform/tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html')
-rw-r--r-- | testing/web-platform/tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html | 468 |
1 files changed, 468 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html b/testing/web-platform/tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html new file mode 100644 index 0000000000..c434aa8c6a --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html @@ -0,0 +1,468 @@ +<!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(DOMException, 'NotSupportedError'); + should( + () => { + node = new PannerNode(context); + node.channelCount = options.channelCount; + }, + `node.channelCount = ${options.channelCount}`) + .throw(DOMException, "NotSupportedError"); + should(node.channelCount, + `node.channelCount after setting to ${options.channelCount}`) + .beEqualTo(2); + + options = {channelCount: 3}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(DOMException, 'NotSupportedError'); + should( + () => { + node = new PannerNode(context); + node.channelCount = options.channelCount; + }, + `node.channelCount = ${options.channelCount}`) + .throw(DOMException, "NotSupportedError"); + should(node.channelCount, + `node.channelCount after setting to ${options.channelCount}`) + .beEqualTo(2); + + options = {channelCount: 99}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(DOMException, 'NotSupportedError'); + should( + () => { + node = new PannerNode(context); + node.channelCount = options.channelCount; + }, + `node.channelCount = ${options.channelCount}`) + .throw(DOMException, "NotSupportedError"); + should(node.channelCount, + `node.channelCount after setting to ${options.channelCount}`) + .beEqualTo(2); + + // 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(DOMException, 'NotSupportedError'); + should( + () => { + node = new PannerNode(context); + node.channelCountMode = options.channelCountMode; + }, + `node.channelCountMode = ${options.channelCountMode}`) + .throw(DOMException, "NotSupportedError"); + should(node.channelCountMode, + `node.channelCountMode after setting to ${options.channelCountMode}`) + .beEqualTo("clamped-max"); + + options = {channelCountMode: 'foobar'}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, " + JSON.stringify(options) + ")') + .throw(TypeError); + should( + () => { + node = new PannerNode(context); + node.channelCountMode = options.channelCountMode; + }, + `node.channelCountMode = ${options.channelCountMode}`) + .notThrow(); // Invalid assignment to enum-valued attrs does not throw. + should(node.channelCountMode, + `node.channelCountMode after setting to ${options.channelCountMode}`) + .beEqualTo("clamped-max"); + + // 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); + + // Test maxDistance + options = {maxDistance: -1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(RangeError); + should( + () => { + node = new PannerNode(context); + node.maxDistance = options.maxDistance; + }, + `node.maxDistance = ${options.maxDistance}`) + .throw(RangeError); + should(node.maxDistance, + `node.maxDistance after setting to ${options.maxDistance}`) + .beEqualTo(10000); + + options = {maxDistance: 100}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node7 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.maxDistance, 'node7.maxDistance') + .beEqualTo(options.maxDistance); + + // Test rolloffFactor + options = {rolloffFactor: -1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(RangeError); + should( + () => { + node = new PannerNode(context); + node.rolloffFactor = options.rolloffFactor; + }, + `node.rolloffFactor = ${options.rolloffFactor}`) + .throw(RangeError); + should(node.rolloffFactor, + `node.rolloffFactor after setting to ${options.rolloffFactor}`) + .beEqualTo(1); + + options = {rolloffFactor: 0}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node8 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.rolloffFactor, 'node8.rolloffFactor') + .beEqualTo(options.rolloffFactor); + + options = {rolloffFactor: 0.5}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node8 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.rolloffFactor, 'node8.rolloffFactor') + .beEqualTo(options.rolloffFactor); + + options = {rolloffFactor: 100}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node8 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.rolloffFactor, 'node8.rolloffFactor') + .beEqualTo(options.rolloffFactor); + + // Test coneOuterGain + options = {coneOuterGain: -1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(DOMException, 'InvalidStateError'); + should( + () => { + node = new PannerNode(context); + node.coneOuterGain = options.coneOuterGain; + }, + `node.coneOuterGain = ${options.coneOuterGain}`) + .throw(DOMException, 'InvalidStateError'); + should(node.coneOuterGain, + `node.coneOuterGain after setting to ${options.coneOuterGain}`) + .beEqualTo(0); + + options = {coneOuterGain: 1.1}; + should( + () => { + node = new PannerNode(context, options); + }, + 'new PannerNode(c, ' + JSON.stringify(options) + ')') + .throw(DOMException, 'InvalidStateError'); + should( + () => { + node = new PannerNode(context); + node.coneOuterGain = options.coneOuterGain; + }, + `node.coneOuterGain = ${options.coneOuterGain}`) + .throw(DOMException, 'InvalidStateError'); + should(node.coneOuterGain, + `node.coneOuterGain after setting to ${options.coneOuterGain}`) + .beEqualTo(0); + + options = {coneOuterGain: 0.0}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node9 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.coneOuterGain, 'node9.coneOuterGain') + .beEqualTo(options.coneOuterGain); + options = {coneOuterGain: 0.5}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node9 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.coneOuterGain, 'node9.coneOuterGain') + .beEqualTo(options.coneOuterGain); + + options = {coneOuterGain: 1.0}; + should( + () => { + node = new PannerNode(context, options); + }, + 'node9 = new PannerNode(c, ' + JSON.stringify(options) + ')') + .notThrow(); + should(node.coneOuterGain, 'node9.coneOuterGain') + .beEqualTo(options.coneOuterGain); + + 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: 0.1 * 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> |