MOBILE-4069 test: Add unit tests to CoreComponentsRegistry singleton

main
Dani Palou 2022-05-10 16:49:42 +02:00
parent c0488d1399
commit a3d2444f2d
2 changed files with 117 additions and 0 deletions

View File

@ -0,0 +1,104 @@
// (C) Copyright 2015 Moodle Pty Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { wait } from '@/testing/utils';
import { CoreComponentsRegistry } from '@singletons/components-registry';
const cssClassName = 'core-components-registry-test';
const createAndRegisterInstance = () => {
const element = document.createElement('div');
element.classList.add(cssClassName);
const instance = new ComponentsRegistryTestClass();
CoreComponentsRegistry.register(element, instance);
return { element, instance };
};
describe('CoreComponentsRegistry singleton', () => {
let element: HTMLElement;
let testClassInstance: ComponentsRegistryTestClass;
beforeEach(() => {
const result = createAndRegisterInstance();
element = result.element;
testClassInstance = result.instance;
});
it('resolves stored instances', () => {
expect(CoreComponentsRegistry.resolve(element)).toEqual(testClassInstance);
expect(CoreComponentsRegistry.resolve(element, ComponentsRegistryTestClass)).toEqual(testClassInstance);
expect(CoreComponentsRegistry.resolve(element, CoreComponentsRegistry)).toEqual(null);
expect(CoreComponentsRegistry.resolve(document.createElement('div'))).toEqual(null);
});
it('requires stored instances', () => {
expect(CoreComponentsRegistry.require(element)).toEqual(testClassInstance);
expect(CoreComponentsRegistry.require(element, ComponentsRegistryTestClass)).toEqual(testClassInstance);
expect(() => CoreComponentsRegistry.require(element, CoreComponentsRegistry)).toThrow();
expect(() => CoreComponentsRegistry.require(document.createElement('div'))).toThrow();
});
it('waits for component ready', async () => {
expect(testClassInstance.isReady).toBe(false);
await CoreComponentsRegistry.waitComponentReady(element);
expect(testClassInstance.isReady).toBe(true);
});
it('waits for components ready: just one', async () => {
expect(testClassInstance.isReady).toBe(false);
await CoreComponentsRegistry.waitComponentsReady(element, `.${cssClassName}`);
expect(testClassInstance.isReady).toBe(true);
});
it('waits for components ready: multiple', async () => {
const secondResult = createAndRegisterInstance();
const thirdResult = createAndRegisterInstance();
thirdResult.element.classList.remove(cssClassName); // Remove the class so the element and instance aren't treated.
const parent = document.createElement('div');
parent.appendChild(element);
parent.appendChild(secondResult.element);
parent.appendChild(thirdResult.element);
expect(testClassInstance.isReady).toBe(false);
expect(secondResult.instance.isReady).toBe(false);
expect(thirdResult.instance.isReady).toBe(false);
await CoreComponentsRegistry.waitComponentsReady(parent, `.${cssClassName}`);
expect(testClassInstance.isReady).toBe(true);
expect(secondResult.instance.isReady).toBe(true);
expect(thirdResult.instance.isReady).toBe(false);
});
});
class ComponentsRegistryTestClass {
randomId = Math.random();
isReady = false;
async ready(): Promise<void> {
await wait(50);
this.isReady = true;
}
}

View File

@ -256,3 +256,16 @@ export async function renderWrapperComponent<T>(
export function agnosticPath(unixPath: string): string { export function agnosticPath(unixPath: string): string {
return unixPath.replace(/\//g, sep); return unixPath.replace(/\//g, sep);
} }
/**
* Waits a certain time.
*
* @param time Number of milliseconds.
*/
export function wait(time: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, time);
});
}