blob: 91b6449613056d4be6a0dd87da9160e65d56aeda [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>
Test AudioContext.close()
</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<script src="../resources/audit-util.js"></script>
<script src="../resources/audit.js"></script>
</head>
<body>
<script id="layout-test-code">
let context;
let destination;
let offline;
let osc;
let gain;
let offlinePromise;
let wave = new Float32Array(5);
let audit = Audit.createTaskRunner();
// Task: test online context (1).
audit.define(
{
label: 'test-online-context-1',
description: 'Test online context 1'
},
function(task, should) {
// Create a context and verify that the various states are correct
// and that close() exists.
should(
() => context = new AudioContext(),
'context0 = new AudioContext()')
.notThrow();
should(context.state, 'context0.state').beEqualTo('running');
// Create gain and oscillator for testing later.
should(
() => osc = context.createOscillator(),
'osc = context.createOscillator()')
.notThrow();
should(
() => gain = context.createGain(),
'gain = context0.createGain()')
.notThrow();
destination = context.destination;
should(
() => gain.connect(context.destination),
'gain.connect(context0.destination)')
.notThrow();
// Close the context. When the promise is resolved, continue the
// next test task.
let promise = context.close().then(() => {
should(
() => gain.disconnect(destination),
'gain.disconnect(destination) after close')
.notThrow();
});
should(promise, 'context0.close()')
.beResolved()
.then(task.done.bind(this));
});
// Task: test online context (2).
audit.define(
{
label: 'test-online-context-2',
description: 'Test closed online context 2'
},
function(task, should) {
// Context is closed, so verify that we cannot create any more
// nodes, nor connect any.
should(() => context.createAnalyser(), 'context.createAnalyser()')
.notThrow();
should(
() => context.createConstantSource(),
'context.createConstantSource()')
.notThrow();
should(
() => context.createBiquadFilter(),
'context.createBiquadFilter()')
.notThrow();
// createBuffer is an exception because it's not really tied in any
// way to an audio context. And it's useful to be able to create a
// buffer inside the oncomplete event of an offline context to use
// for testing purposes.
should(
() => context.createBuffer(1, 1, 48000),
'context.createBuffer(1, 1, 48000)')
.notThrow();
should(
() => context.createBufferSource(),
'context.createBufferSource()')
.notThrow();
should(
() => context.createChannelMerger(),
'context.createChannelMerger()')
.notThrow();
should(
() => context.createChannelSplitter(),
'context.createChannelSplitter()')
.notThrow();
should(() => context.createConvolver(), 'context.createConvolver()')
.notThrow();
should(() => context.createDelay(), 'context.createDelay()')
.notThrow();
should(
() => context.createDynamicsCompressor(),
'context.createDynamicsCompressor()')
.notThrow();
should(() => context.createGain(), 'context.createGain()')
.notThrow();
should(
() => context.createIIRFilter([1], [1, .9]),
'context.createIIRFilter()')
.notThrow();
should(
() => context.createOscillator(), 'context.createOscillator()')
.notThrow();
should(() => context.createPanner(), 'context.createPanner()')
.notThrow();
should(
() => context.createPeriodicWave(wave, wave),
'context.createPeriodicWave(wave, wave)')
.notThrow();
should(
() => context.createScriptProcessor(),
'context.createScriptProcessor()')
.notThrow();
should(
() => context.createStereoPanner(),
'context.createStereoPanner()')
.notThrow();
should(
() => context.createWaveShaper(), 'context.createWaveShaper()')
.notThrow();
should(() => osc.connect(gain), 'osc.connect(gain)').notThrow();
should(() => gain.disconnect(), 'gain.disconnect()').notThrow();
// Can't resume a context that is closed (released).
should(context.resume(), 'context.resume()')
.beRejected()
.then(task.done.bind(task));
});
// Task: test online context (3).
audit.define(
{
label: 'test-online-context-3',
description: 'Close an online context again'
},
function(task, should) {
// Try closing the context again. The promise should be rejected.
should(context.close(), 'context.close() again')
.beRejected()
.then(() => {
// Finally, run GC. The context should be gone, but this seems
// difficult to verify.
if (window.gc)
gc();
should(context.destination, 'context.destination')
.notBeEqualTo(null);
})
.then(task.done.bind(task));
});
// Task: test online context (4).
audit.define(
{
label: 'test-online-context-4',
description: 'Test closed online context 4'
},
function(task, should) {
// Create a context and verify that its sampleRate and baseLatency
// return valid values whether it's open or closed.
should(
() => context = new AudioContext(),
'context1 = new AudioContext()')
.notThrow();
should(context.sampleRate, 'context1.sampleRate')
.beGreaterThan('0');
should(context.sampleRate, 'context1.baseLatency')
.beGreaterThan('0');
should(context.close(), 'context1.close()')
.beResolved()
.then(() => {
should(context.sampleRate, 'After close, context1.sampleRate')
.beGreaterThan('0');
should(
context.sampleRate, 'After close, context1.baseLatency')
.beGreaterThan('0');
})
.then(task.done.bind(task));
});
// Task: test offline context (1).
audit.define(
{
label: 'test-offline-context-1',
description: 'Test offline context'
},
function(task, should) {
// For an offline context, verify that close is not defined.
should(
() => offline = new OfflineAudioContext(1, 1000, 48000),
'offline = new OfflineAudioContext(1, 1000, 48000)')
.notThrow();
should(offline.state, 'offline.state').beEqualTo('suspended');
should(offline.close, 'offline.close').beEqualTo(undefined);
task.done();
});
audit.run();
</script>
</body>
</html>