72 lines
2.7 KiB
HTML
72 lines
2.7 KiB
HTML
<!doctype html>
|
|
<title>Test AudioContext state updates with suspend() shortly after
|
|
construction</title>
|
|
<script src=/resources/testharness.js></script>
|
|
<script src=/resources/testharnessreport.js></script>
|
|
<script>
|
|
// A separate async_test is used for tracking state change counts so that it
|
|
// can report excess changes after the promise_test for the iteration has
|
|
// completed.
|
|
const changeCountingTest = async_test('State change counting');
|
|
|
|
const doTest = async (testCount) => {
|
|
const ctx = new AudioContext();
|
|
// Explicitly resume to get a promise to indicate whether the context
|
|
// successfully started running.
|
|
const resume = ctx.resume();
|
|
const suspend = ctx.suspend();
|
|
let stateChangesDone = new Promise((resolve) => {
|
|
ctx.onstatechange = () => {
|
|
++ctx.stateChangeCount;
|
|
changeCountingTest.step(() => {
|
|
assert_less_than_equal(ctx.stateChangeCount,
|
|
ctx.expectedStateChangeCount,
|
|
`ctx ${testCount} state change count.`);
|
|
assert_equals(ctx.state, ctx.expectedState, `ctx ${testCount} state`);
|
|
});
|
|
if (ctx.stateChangeCount == ctx.totalStateChangeCount) {
|
|
resolve();
|
|
}
|
|
};
|
|
});
|
|
ctx.stateChangeCount = 0;
|
|
ctx.expectedStateChangeCount = 1;
|
|
ctx.expectedState = 'running';
|
|
ctx.totalStateChangeCount = 2;
|
|
let resumeState = 'pending';
|
|
resume.then(() => {
|
|
resumeState = 'fulfilled';
|
|
assert_equals(ctx.state, 'running', 'state on resume fulfilled.');
|
|
}).catch(() => {
|
|
// The resume() promise may be rejected if "Attempt to acquire system
|
|
// resources" fails. The spec does not discuss the possibility of a
|
|
// subsequent suspend causing such a failure, but accept this as a
|
|
// reasonable behavior.
|
|
resumeState = 'rejected';
|
|
assert_equals(ctx.state, 'suspended', 'state on resume rejected.');
|
|
assert_equals(ctx.stateChangeCount, 0);
|
|
ctx.expectedStateChangeCount = 0;
|
|
stateChangesDone = Promise.resolve();
|
|
});
|
|
suspend.then(() => {
|
|
assert_not_equals(resumeState, 'pending',
|
|
'resume promise should settle before suspend promise.')
|
|
if (resumeState == 'fulfilled') {
|
|
++ctx.expectedStateChangeCount;
|
|
}
|
|
ctx.expectedState = 'suspended';
|
|
assert_equals(ctx.state, 'suspended', 'state on suspend fulfilled.');
|
|
});
|
|
await resume;
|
|
await suspend;
|
|
await stateChangesDone;
|
|
};
|
|
|
|
// Repeat the test because Gecko uses different code when there is more than
|
|
// one AudioContext. The third run provides time to check that no further
|
|
// state changes from the second run are pending.
|
|
for (const testCount of [1, 2, 3]) {
|
|
promise_test(() => { return doTest(testCount); }, `Iteration ${testCount}`);
|
|
}
|
|
promise_test(async () => changeCountingTest.done(), 'Stop waiting');
|
|
</script>
|