From 9e1bdd7912058bae73e61f3d78cbc06145982bf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Thu, 5 May 2022 11:56:39 +0000 Subject: [PATCH] [IMP] web: improve test helpers to mock timeouts Part-of: odoo/odoo#88994 --- .../core/effects/effect_service_tests.js | 2 +- .../web/static/tests/core/transition_test.js | 4 +-- .../static/tests/core/utils/timing_tests.js | 4 +-- addons/web/static/tests/helpers/utils.js | 31 ++++++++++++++----- .../webclient/loading_indicator_tests.js | 2 +- .../static/tests/webclient/navbar_tests.js | 2 +- 6 files changed, 31 insertions(+), 14 deletions(-) diff --git a/addons/web/static/tests/core/effects/effect_service_tests.js b/addons/web/static/tests/core/effects/effect_service_tests.js index ed95e09b875..6e71fe24881 100644 --- a/addons/web/static/tests/core/effects/effect_service_tests.js +++ b/addons/web/static/tests/core/effects/effect_service_tests.js @@ -49,7 +49,7 @@ QUnit.module("Effect Service", (hooks) => { message: markup("
Congrats!
"), }; - execRegisteredTimeouts = mockTimeout(); + execRegisteredTimeouts = mockTimeout().execRegisteredTimeouts; patchWithCleanup(session, { show_effect: true }); // enable effects serviceRegistry.add("user", userService); diff --git a/addons/web/static/tests/core/transition_test.js b/addons/web/static/tests/core/transition_test.js index 32b2211b0e3..ee9897368ce 100644 --- a/addons/web/static/tests/core/transition_test.js +++ b/addons/web/static/tests/core/transition_test.js @@ -20,7 +20,7 @@ QUnit.test("useTransition hook", async (assert) => { } } Parent.template = xml`
`; - const execRegisteredTimeouts = mockTimeout(); + const { execRegisteredTimeouts } = mockTimeout(); const target = getFixture(); const parent = await mount(Parent, target); @@ -58,7 +58,7 @@ QUnit.test("Transition HOC", async (assert) => { `; Parent.components = { Transition }; - const execRegisteredTimeouts = mockTimeout(); + const { execRegisteredTimeouts } = mockTimeout(); const target = getFixture(); const parent = await mount(Parent, target); diff --git a/addons/web/static/tests/core/utils/timing_tests.js b/addons/web/static/tests/core/utils/timing_tests.js index f95435a65ca..87a1746062c 100644 --- a/addons/web/static/tests/core/utils/timing_tests.js +++ b/addons/web/static/tests/core/utils/timing_tests.js @@ -69,7 +69,7 @@ QUnit.module("utils", () => { }); QUnit.test("debounce with immediate", async function (assert) { - const execRegisteredTimeouts = mockTimeout(); + const { execRegisteredTimeouts } = mockTimeout(); const myFunc = () => { assert.step("myFunc"); return 42; @@ -100,7 +100,7 @@ QUnit.module("utils", () => { QUnit.test("debounced call can be cancelled", async function (assert) { assert.expect(3); - const execRegisteredTimeouts = mockTimeout(); + const { execRegisteredTimeouts } = mockTimeout(); const myFunc = () => { assert.step("myFunc"); }; diff --git a/addons/web/static/tests/helpers/utils.js b/addons/web/static/tests/helpers/utils.js index d5ad5e034d9..60c04085940 100644 --- a/addons/web/static/tests/helpers/utils.js +++ b/addons/web/static/tests/helpers/utils.js @@ -360,21 +360,38 @@ for (const propName of Object.keys(window.console)) { export function mockTimeout() { const timeouts = new Map(); + let currentTime = 0; let id = 1; patchWithCleanup(browser, { - setTimeout(fn) { - timeouts.set(id, fn); + setTimeout(fn, delay = 0) { + timeouts.set(id, { fn, scheduledFor: delay + currentTime, id }); return id++; }, clearTimeout(id) { timeouts.delete(id); }, }); - return function execRegisteredTimeouts() { - for (const fn of timeouts.values()) { - fn(); - } - timeouts.clear(); + return { + execRegisteredTimeouts() { + for (const { fn } of timeouts.values()) { + fn(); + } + timeouts.clear(); + }, + async advanceTime(duration) { + // wait here so all microtasktick scheduled in this frame can be + // executed and possibly register their own timeout + await nextTick(); + currentTime += duration; + for (const { fn, scheduledFor, id } of timeouts.values()) { + if (scheduledFor <= currentTime) { + fn(); + timeouts.delete(id); + } + } + // wait here to make sure owl can update the UI + await nextTick(); + }, }; } diff --git a/addons/web/static/tests/webclient/loading_indicator_tests.js b/addons/web/static/tests/webclient/loading_indicator_tests.js index 55c34aa3165..a1c9ba20ee9 100644 --- a/addons/web/static/tests/webclient/loading_indicator_tests.js +++ b/addons/web/static/tests/webclient/loading_indicator_tests.js @@ -151,7 +151,7 @@ QUnit.test("loading indicator blocks UI", async (assert) => { QUnit.test("loading indicator doesn't unblock ui if it didn't block it", async (assert) => { const env = await makeTestEnv({ ...baseConfig }); - const execRegisteredTimeouts = mockTimeout(); + const { execRegisteredTimeouts } = mockTimeout(); const ui = env.services.ui; ui.bus.on("BLOCK", null, () => { assert.step("block"); diff --git a/addons/web/static/tests/webclient/navbar_tests.js b/addons/web/static/tests/webclient/navbar_tests.js index db98b380a8c..3a1cdf38f28 100644 --- a/addons/web/static/tests/webclient/navbar_tests.js +++ b/addons/web/static/tests/webclient/navbar_tests.js @@ -427,7 +427,7 @@ QUnit.test("'more' menu sections properly updated on app change", async (assert) QUnit.test("Do not execute adapt when navbar is destroyed", async (assert) => { assert.expect(5); - const execRegisteredTimeouts = mockTimeout(); + const { execRegisteredTimeouts } = mockTimeout(); class MyNavbar extends NavBar { async adapt() { assert.step("adapt NavBar");