зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1644647 test AudioContext state updates with suspend() shortly after construction r=padenot
Differential Revision: https://phabricator.services.mozilla.com/D79057
This commit is contained in:
Родитель
083e8d5a3e
Коммит
96bbd9e7ae
|
@ -0,0 +1,72 @@
|
|||
<!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>
|
Загрузка…
Ссылка в новой задаче