Skip to content

Commit

Permalink
[IMP] web: tests - restore all registries after test
Browse files Browse the repository at this point in the history
This commit ensures that all registries are registered for cleanup after
every single test.

Before this commit, this was partially the case as registries were
registered for cleanup when creating a mock environment. This means that
before that any content that was modified before that point would NOT
be cleaned up.

Part-of: #158916
  • Loading branch information
Arcasias committed Mar 28, 2024
1 parent b77e3d9 commit 9d966c8
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 29 deletions.
4 changes: 2 additions & 2 deletions addons/mail/static/tests/mail_test_helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import { browser } from "@web/core/browser/browser";
import {
getMockEnv,
makeMockEnv,
restoreRegistryFromBeforeTest,
restoreRegistry,
} from "@web/../tests/_framework/env_test_helpers";
import { cancelAllTimers } from "@odoo/hoot-mock";
import { after, before, getFixture } from "@odoo/hoot";
Expand Down Expand Up @@ -260,7 +260,7 @@ export async function start({ asTab = false } = {}) {
}
let env;
if (asTab) {
restoreRegistryFromBeforeTest(registry, { withSubRegistries: true });
restoreRegistry(registry);
const rootTarget = target;
target = document.createElement("div");
target.style.width = "100%";
Expand Down
56 changes: 29 additions & 27 deletions addons/web/static/tests/_framework/env_test_helpers.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { after, registerDebugInfo } from "@odoo/hoot";
import { after, afterEach, beforeEach, registerDebugInfo } from "@odoo/hoot";
import { startRouter } from "@web/core/browser/router";
import { createDebugContext } from "@web/core/debug/debug_context";
import { registry } from "@web/core/registry";
Expand All @@ -8,59 +8,47 @@ import { MockServer, makeMockServer } from "./mock_server/mock_server";
/**
* @typedef {import("@web/env").OdooEnv} OdooEnv
*
* @typedef {import("@web/core/registry").Registry} Registry
*
* @typedef {import("services").Services} Services
*/

//-----------------------------------------------------------------------------
// Internals
//-----------------------------------------------------------------------------

const toRestoreRegistry = new WeakMap();

export function restoreRegistryFromBeforeTest(registry, { withSubRegistries = false } = {}) {
const content = toRestoreRegistry.get(registry);
toRestoreRegistry.delete(registry);
if (content) {
registry.content = Object.fromEntries(content);
registry.elements = null;
registry.entries = null;
}
if (withSubRegistries) {
for (const subRegistry of Object.values(registry.subRegistries)) {
restoreRegistryFromBeforeTest(subRegistry);
}
}
}

/**
* TODO: remove when services do not have side effects anymore
* This forsaken block of code ensures that all are properly cleaned up after each
* test because they were populated during the starting process of some services.
*
* @param {typeof registry} registry
* @param {Registry} registry
*/
const restoreRegistryAfterTest = (registry) => {
const registerRegistryForCleanup = (registry) => {
const content = Object.entries(registry.content).map(([key, value]) => [key, value.slice()]);
toRestoreRegistry.set(registry, content);
after(() => {
restoreRegistryFromBeforeTest(registry);
});
registriesContent.set(registry, content);

for (const subRegistry of Object.values(registry.subRegistries)) {
restoreRegistryAfterTest(subRegistry);
registerRegistryForCleanup(subRegistry);
}
};

const registriesContent = new WeakMap();
/** @type {OdooEnv | null} */
let currentEnv = null;

// Registers all registries for cleanup in all tests
beforeEach(() => registerRegistryForCleanup(registry));
afterEach(() => restoreRegistry(registry));

//-----------------------------------------------------------------------------
// Exports
//-----------------------------------------------------------------------------

/**
* Empties the given registry.
*
* @param {import("@web/core/registry").Registry} registry
* @param {Registry} registry
*/
export function clearRegistry(registry) {
registry.content = {};
Expand Down Expand Up @@ -101,7 +89,6 @@ export async function makeMockEnv(partialEnv, { makeNew = false } = {}) {
Object.assign(currentEnv, partialEnv, createDebugContext(currentEnv)); // This is needed if the views are in debug mode

registerDebugInfo(currentEnv);
restoreRegistryAfterTest(registry);

startRouter();
await startServices(currentEnv);
Expand Down Expand Up @@ -141,3 +128,18 @@ export function mockService(name, serviceFactory) {
after(() => serviceRegistry.add(name, originalService, { force: true }));
}
}

/**
* @param {Registry} registry
*/
export function restoreRegistry(registry) {
if (registriesContent.has(registry)) {
clearRegistry(registry);

registry.content = Object.fromEntries(registriesContent.get(registry));
}

for (const subRegistry of Object.values(registry.subRegistries)) {
restoreRegistry(subRegistry);
}
}

0 comments on commit 9d966c8

Please sign in to comment.