Skip to content

Commit

Permalink
feat: [#1670] Adds property isRegistered to GlobalRegistrator (#1674)
Browse files Browse the repository at this point in the history
  • Loading branch information
capricorn86 authored Jan 8, 2025
1 parent a68a9cc commit 02820d9
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 10 deletions.
29 changes: 19 additions & 10 deletions packages/global-registrator/src/GlobalRegistrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,16 @@ const IGNORE_LIST = ['constructor', 'undefined', 'NaN', 'global', 'globalThis'];
*
*/
export default class GlobalRegistrator {
private static registered: { [key: string | symbol]: PropertyDescriptor } | null = null;
static #registered: { [key: string | symbol]: PropertyDescriptor } | null = null;

/**
* Returns the registered state.
*
* @returns Registered state.
*/
public static get isRegistered(): boolean {
return this.#registered !== null;
}

/**
* Registers Happy DOM globally.
Expand All @@ -24,13 +33,13 @@ export default class GlobalRegistrator {
url?: string;
settings?: IOptionalBrowserSettings;
}): void {
if (this.registered !== null) {
if (this.#registered !== null) {
throw new Error('Failed to register. Happy DOM has already been globally registered.');
}

const window = new GlobalWindow({ ...options, console: globalThis.console });

this.registered = {};
this.#registered = {};

// Define properties on the global object
const propertyDescriptors = Object.getOwnPropertyDescriptors(window);
Expand All @@ -44,7 +53,7 @@ export default class GlobalRegistrator {
globalPropertyDescriptor?.value === undefined ||
globalPropertyDescriptor?.value !== windowPropertyDescriptor.value
) {
this.registered[key] = globalPropertyDescriptor || null;
this.#registered[key] = globalPropertyDescriptor || null;

// If the property is the window object, replace it with the global object
if (windowPropertyDescriptor.value === window) {
Expand All @@ -65,7 +74,7 @@ export default class GlobalRegistrator {

for (const key of propertySymbols) {
const propertyDescriptor = Object.getOwnPropertyDescriptor(window, key);
this.registered[key] = null;
this.#registered[key] = null;

// If the property is the window object, replace it with the global object
if (propertyDescriptor.value === window) {
Expand All @@ -87,23 +96,23 @@ export default class GlobalRegistrator {
* Closes the window and unregisters Happy DOM from being global.
*/
public static async unregister(): Promise<void> {
if (this.registered === null) {
if (this.#registered === null) {
throw new Error(
'Failed to unregister. Happy DOM has not previously been globally registered.'
);
}

const happyDOM = globalThis.happyDOM;

for (const key of Object.keys(this.registered)) {
if (this.registered[key] !== null) {
Object.defineProperty(globalThis, key, this.registered[key]);
for (const key of Object.keys(this.#registered)) {
if (this.#registered[key] !== null) {
Object.defineProperty(globalThis, key, this.#registered[key]);
} else {
delete globalThis[key];
}
}

this.registered = null;
this.#registered = null;

if (happyDOM) {
await happyDOM.close();
Expand Down
19 changes: 19 additions & 0 deletions packages/global-registrator/test/react/React.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,25 @@ async function main(): Promise<void> {
}

testWindowOptions();

/**
* Test is registered property.
*/
function testIsRegisteredProperty(): void {
GlobalRegistrator.register();

if (!GlobalRegistrator.isRegistered) {
throw Error('The "isRegistered" property is incorrect.');
}

GlobalRegistrator.unregister();

if (GlobalRegistrator.isRegistered) {
throw Error('The "isRegistered" property is incorrect.');
}
}

testIsRegisteredProperty();
}

main();

0 comments on commit 02820d9

Please sign in to comment.