author | Raymond Toy <rtoy@chromium.org> |
Tue, 01 May 2018 14:58:46 +0000 | |
changeset 416541 | ff155e599e248b7e4834e7a2ff2d6f29423baca9 |
parent 416540 | b6a3b6789d460b704ddb6fb31897aaf9b0164319 |
child 416542 | ec73f6441af6f652a2c1e64f50c0b9d4b8e509cf |
push id | 102808 |
push user | james@hoppipolla.co.uk |
push date | Wed, 02 May 2018 07:14:45 +0000 |
treeherder | mozilla-inbound@37b3d10ba167 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | testonly |
bugs | 1456980, 10643, 745778, 1028713, 554032 |
milestone | 61.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -297219,16 +297219,21 @@ {} ] ], "webaudio/refresh_idl.rb": [ [ {} ] ], + "webaudio/resources/audionodeoptions.js": [ + [ + {} + ] + ], "webaudio/resources/audioparam-testing.js": [ [ {} ] ], "webaudio/resources/audit-util.js": [ [ {} @@ -369140,16 +369145,22 @@ ] ], "webaudio/idlharness.https.html": [ [ "/webaudio/idlharness.https.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html": [ [ @@ -369176,16 +369187,22 @@ ] ], "webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html": [ [ "/webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-audionode-interface/audionode-channel-rules.html": [ [ @@ -369488,16 +369505,22 @@ ] ], "webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html": [ [ "/webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-basic.html": [ [ @@ -369518,22 +369541,34 @@ ] ], "webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-input.html": [ [ "/webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-input.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html": [ [ @@ -369542,16 +369577,22 @@ ] ], "webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html": [ [ "/webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-convolvernode-interface/convolution-mono-mono.html": [ [ @@ -369590,16 +369631,28 @@ ] ], "webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html": [ [ "/webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-delaynode-interface/delaynode-max-nondefault-delay.html": [ [ @@ -369632,22 +369685,34 @@ ] ], "webaudio/the-audio-api/the-delaynode-interface/no-dezippering.html": [ [ "/webaudio/the-audio-api/the-delaynode-interface/no-dezippering.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-gainnode-interface/gain.html": [ [ @@ -369662,16 +369727,22 @@ ] ], "webaudio/the-audio-api/the-gainnode-interface/test-gainnode.html": [ [ "/webaudio/the-audio-api/the-gainnode-interface/test-gainnode.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-getFrequencyResponse.html": [ [ @@ -369692,22 +369763,40 @@ ] ], "webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html": [ [ "/webaudio/the-audio-api/the-mediaelementaudiosourcenode-interface/mediaElementAudioSourceToScriptProcessorTest.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html": [ [ @@ -369770,16 +369859,22 @@ ] ], "webaudio/the-audio-api/the-pannernode-interface/test-pannernode-automation.html": [ [ "/webaudio/the-audio-api/the-pannernode-interface/test-pannernode-automation.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-stereopanner-interface/stereopannernode-basic.html": [ [ @@ -369788,16 +369883,22 @@ ] ], "webaudio/the-audio-api/the-stereopanner-interface/stereopannernode-panning.html": [ [ "/webaudio/the-audio-api/the-stereopanner-interface/stereopannernode-panning.html", {} ] ], + "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", {} ] ], "webaudio/the-audio-api/the-waveshapernode-interface/waveshaper-copy-curve.html": [ [ @@ -608969,16 +609070,20 @@ "webaudio/js/helpers.js": [ "3cb468605c1fa8e5005bc8552b15f7a37ee9b935", "support" ], "webaudio/refresh_idl.rb": [ "9ef52c13448d19b241b40a5c81f4a0480c05c5de", "support" ], + "webaudio/resources/audionodeoptions.js": [ + "d7712311bddd23e171e7e1f024aec0a565b08a13", + "support" + ], "webaudio/resources/audioparam-testing.js": [ "2855fbee30e629ea397166911b9bcdec74bd4fdf", "support" ], "webaudio/resources/audit-util.js": [ "4405458b8f8bdc621c95c1d9ec1c1ad4e6002f1e", "support" ], @@ -609033,16 +609138,20 @@ "webaudio/resources/stereopanner-testing.js": [ "dc02b4fad40f381d924db447a3d955e4455fd561", "support" ], "webaudio/the-audio-api/the-analysernode-interface/.gitkeep": [ "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" ], "webaudio/the-audio-api/the-analysernode-interface/test-analyser-minimum.html": [ "26282412113f6298a90a2cac963a2b0de03ef43d", "testharness" ], @@ -609065,16 +609174,20 @@ "webaudio/the-audio-api/the-audiobuffer-interface/idl-test.html": [ "0ef05c242d8f987d521c0e9ce474d0f9a46bee28", "testharness" ], "webaudio/the-audio-api/the-audiobuffersourcenode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], + "webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html": [ + "ce84d25460435564021a13dc9e26384bc30e9d96", + "testharness" + ], "webaudio/the-audio-api/the-audiocontext-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], "webaudio/the-audio-api/the-audiodestinationnode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], @@ -609345,16 +609458,20 @@ "webaudio/the-audio-api/the-biquadfilternode-interface/biquad-tail.html": [ "e15e696492076d522c1052ae890b37f52e7bd27b", "testharness" ], "webaudio/the-audio-api/the-biquadfilternode-interface/biquadfilternode-basic.html": [ "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" ], "webaudio/the-audio-api/the-channelmergernode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], @@ -609369,36 +609486,48 @@ "webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-input-non-default.html": [ "89c8356eeed96c06eca2c904c22047dd02da4f3b", "testharness" ], "webaudio/the-audio-api/the-channelmergernode-interface/audiochannelmerger-input.html": [ "250c35e36dda600c30554024cbd500a37180292a", "testharness" ], + "webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html": [ + "72bfba4cbca1b4d3e7692ef236afb905f852fadd", + "testharness" + ], "webaudio/the-audio-api/the-channelsplitternode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], "webaudio/the-audio-api/the-channelsplitternode-interface/audiochannelsplitter.html": [ "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" ], "webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-onended.html": [ "10f6b84a4c8de1a8b689cc443f2526b0455a4d27", "testharness" ], "webaudio/the-audio-api/the-constantsourcenode-interface/constant-source-output.html": [ "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" ], "webaudio/the-audio-api/the-convolvernode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], @@ -609425,20 +609554,28 @@ "webaudio/the-audio-api/the-convolvernode-interface/convolver-response-4-chan.html": [ "8fac11e0ecfa8bfb9b49d68d0792793f44e94ad4", "testharness" ], "webaudio/the-audio-api/the-convolvernode-interface/convolver-setBuffer-null.html": [ "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" ], "webaudio/the-audio-api/the-delaynode-interface/delaynode-max-nondefault-delay.html": [ "8c1a46ae95f921d78a59473c6f1f5d12315f07e8", "testharness" ], @@ -609461,24 +609598,32 @@ "webaudio/the-audio-api/the-delaynode-interface/no-dezippering.html": [ "96b405fd00ee657194de348ea46b263ba43f98a4", "testharness" ], "webaudio/the-audio-api/the-dynamicscompressornode-interface/.gitkeep": [ "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" ], "webaudio/the-audio-api/the-gainnode-interface/.gitkeep": [ "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" ], "webaudio/the-audio-api/the-gainnode-interface/gain-expected.wav": [ "823f7ae1a5f5eb0c630e7d1881c50a1f710f9350", "support" ], @@ -609489,16 +609634,20 @@ "webaudio/the-audio-api/the-gainnode-interface/no-dezippering.html": [ "2205ec8f56472bd45e102cf57f10b4532b18a554", "testharness" ], "webaudio/the-audio-api/the-gainnode-interface/test-gainnode.html": [ "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" ], "webaudio/the-audio-api/the-iirfilternode-interface/iirfilter-getFrequencyResponse.html": [ "1f1cc3004a65acf09667d3a21150f9ce052f71fb", "testharness" ], @@ -609525,28 +609674,40 @@ "webaudio/the-audio-api/the-mediastreamaudiosourcenode-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], "webaudio/the-audio-api/the-offlineaudiocontext-interface/.gitkeep": [ "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" ], "webaudio/the-audio-api/the-oscillatornode-interface/.gitkeep": [ "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" ], "webaudio/the-audio-api/the-pannernode-interface/distance-inverse.html": [ "400d2a373de3e4255279930fca2ec559aed19688", "testharness" ], @@ -609593,32 +609754,40 @@ "webaudio/the-audio-api/the-periodicwave-interface/.gitkeep": [ "da39a3ee5e6b4b0d3255bfef95601890afd80709", "support" ], "webaudio/the-audio-api/the-scriptprocessornode-interface/.gitkeep": [ "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" ], "webaudio/the-audio-api/the-stereopanner-interface/stereopannernode-basic.html": [ "5654219a5816d603260c33b4d72030e89e8c63d9", "testharness" ], "webaudio/the-audio-api/the-stereopanner-interface/stereopannernode-panning.html": [ "4f49a7d5726c922676d350613679c9c441ff6c65", "testharness" ], "webaudio/the-audio-api/the-waveshapernode-interface/.gitkeep": [ "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" ], "webaudio/the-audio-api/the-waveshapernode-interface/waveshaper-copy-curve.html": [ "28cc01fdd27a3ff88f2e886bc625d4dfd15db742", "testharness" ],
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/resources/audionodeoptions.js @@ -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); + } + }); +}
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-analysernode-interface/ctor-analyser.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-audiobuffersourcenode-interface/ctor-audiobuffersource.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-biquadfilternode-interface/ctor-biquadfilter.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-channelmergernode-interface/ctor-channelmerger.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-channelsplitternode-interface/ctor-channelsplitter.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-constantsourcenode-interface/ctor-constantsource.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-convolvernode-interface/ctor-convolver.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-delaynode-interface/ctor-delay.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-dynamicscompressornode-interface/ctor-dynamicscompressor.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-gainnode-interface/ctor-gain.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-iirfilternode-interface/ctor-iirfilter.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-offlineaudiocontext-interface/ctor-offlineaudiocontext.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-oscillatornode-interface/ctor-oscillator.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-pannernode-interface/ctor-panner.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-stereopanner-interface/ctor-stereopanner.html @@ -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>
new file mode 100644 --- /dev/null +++ b/testing/web-platform/tests/webaudio/the-audio-api/the-waveshapernode-interface/ctor-waveshaper.html @@ -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>