UNPKG

@lightningjs/renderer

Version:
154 lines (128 loc) 4.42 kB
/* * If not stated otherwise in this file or this component's LICENSE file the * following copyright and licenses apply: * * Copyright 2023 Comcast Cable Communications Management, LLC. * * 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. */ // @vitest-environment happy-dom import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { RendererMain } from './Renderer.js'; import type { Platform } from '../core/platforms/Platform.js'; import type { Inspector } from './Inspector.js'; import type { CanvasRenderer } from '../core/renderers/canvas/CanvasRenderer.js'; import type { WebGlRenderer } from '../core/renderers/webgl/WebGlRenderer.js'; // Mock isProductionEnvironment so the Inspector gets initialized vi.mock('../utils.js', async (importOriginal) => { const actual = (await importOriginal()) as typeof import('../utils.js'); return { ...actual, isProductionEnvironment: false, }; }); // Mock Stage to avoid real WebGL/Canvas renderer setup vi.mock('../core/Stage.js', () => { const mockStage = { root: { id: 1, children: [], props: {}, on: vi.fn(), off: vi.fn(), emit: vi.fn(), }, destroy: vi.fn(), on: vi.fn(), off: vi.fn(), emit: vi.fn(), txManager: { destroy: vi.fn() }, }; return { Stage: vi.fn(() => mockStage), }; }); /** * Minimal platform mock: returns a real <canvas> element so the Renderer * can set its width/height and append it to the target. */ function makeMockPlatform() { const canvas = document.createElement('canvas'); return vi.fn().mockReturnValue({ canvas, settings: {}, glw: null }); } /** Convenience: construct RendererMain with the minimum required settings. */ function makeRenderer( target: HTMLElement, extra: Partial<{ inspector: typeof Inspector | false; }> = {}, ) { const MockPlatform = makeMockPlatform(); return new RendererMain( { appWidth: 1920, appHeight: 1080, inspector: extra.inspector ?? false, platform: MockPlatform as unknown as typeof Platform, renderEngine: {} as unknown as | typeof CanvasRenderer | typeof WebGlRenderer, }, target, ); } describe('RendererMain.close()', () => { let target: HTMLDivElement; beforeEach(() => { target = document.createElement('div'); document.body.appendChild(target); vi.clearAllMocks(); }); afterEach(() => { target.remove(); }); it('should call inspector.destroy() when close() is called', () => { const inspectorDestroy = vi.fn(); const MockInspector = vi.fn(() => ({ destroy: inspectorDestroy })); const renderer = makeRenderer(target, { inspector: MockInspector as unknown as typeof Inspector, }); renderer.close(); expect(inspectorDestroy).toHaveBeenCalledOnce(); }); it('should call stage.destroy() when close() is called', async () => { const { Stage } = await import('../core/Stage.js'); const renderer = makeRenderer(target); const mockStageInstance = vi.mocked(Stage).mock.results[0]?.value as { destroy: ReturnType<typeof vi.fn>; }; renderer.close(); expect(mockStageInstance?.destroy).toHaveBeenCalledOnce(); }); it('should remove the canvas from the DOM when close() is called', () => { const renderer = makeRenderer(target); const canvas = renderer.canvas; expect(target.contains(canvas)).toBe(true); renderer.close(); expect(document.contains(canvas)).toBe(false); }); it('should not throw when close() is called a second time', () => { const MockInspector = vi.fn(() => ({ destroy: vi.fn() })); const renderer = makeRenderer(target, { inspector: MockInspector as unknown as typeof Inspector, }); renderer.close(); // inspector is set to null after close(); the ?. guard must handle it expect(() => renderer.close()).not.toThrow(); }); });