Path: blob/main/src/vs/workbench/test/browser/window.test.ts
4778 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import assert from 'assert';6import { IRegisteredCodeWindow } from '../../../base/browser/dom.js';7import { CodeWindow, mainWindow } from '../../../base/browser/window.js';8import { DisposableStore } from '../../../base/common/lifecycle.js';9import { runWithFakedTimers } from '../../../base/test/common/timeTravelScheduler.js';10import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../base/test/common/utils.js';11import { BaseWindow } from '../../browser/window.js';12import { TestContextMenuService, TestEnvironmentService, TestHostService, TestLayoutService } from './workbenchTestServices.js';1314suite('Window', () => {1516ensureNoDisposablesAreLeakedInTestSuite();1718class TestWindow extends BaseWindow {1920constructor(window: CodeWindow, dom: { getWindowsCount: () => number; getWindows: () => Iterable<IRegisteredCodeWindow> }) {21super(window, dom, new TestHostService(), TestEnvironmentService, new TestContextMenuService(), new TestLayoutService());22}2324protected override enableWindowFocusOnElementFocus(): void { }25}2627test('multi window aware setTimeout()', async function () {28return runWithFakedTimers({ useFakeTimers: true }, async () => {29const disposables = new DisposableStore();3031let windows: IRegisteredCodeWindow[] = [];32const dom = {33getWindowsCount: () => windows.length,34getWindows: () => windows35};3637const setTimeoutCalls: number[] = [];38const clearTimeoutCalls: number[] = [];3940function createWindow(id: number, slow?: boolean) {41// eslint-disable-next-line local/code-no-any-casts42const res = {43setTimeout: function (callback: Function, delay: number, ...args: any[]): number {44setTimeoutCalls.push(id);4546return mainWindow.setTimeout(() => callback(id), slow ? delay * 2 : delay, ...args);47},48clearTimeout: function (timeoutId: number): void {49clearTimeoutCalls.push(id);5051return mainWindow.clearTimeout(timeoutId);52}53} as any;5455disposables.add(new TestWindow(res, dom));5657return res;58}5960const window1 = createWindow(1);61windows = [{ window: window1, disposables }];6263// Window Count: 16465let called = false;66await new Promise<void>((resolve, reject) => {67window1.setTimeout(() => {68if (!called) {69called = true;70resolve();71} else {72reject(new Error('timeout called twice'));73}74}, 1);75});7677assert.strictEqual(called, true);78assert.deepStrictEqual(setTimeoutCalls, [1]);79assert.deepStrictEqual(clearTimeoutCalls, []);80called = false;81setTimeoutCalls.length = 0;82clearTimeoutCalls.length = 0;8384await new Promise<void>((resolve, reject) => {85window1.setTimeout(() => {86if (!called) {87called = true;88resolve();89} else {90reject(new Error('timeout called twice'));91}92}, 0);93});9495assert.strictEqual(called, true);96assert.deepStrictEqual(setTimeoutCalls, [1]);97assert.deepStrictEqual(clearTimeoutCalls, []);98called = false;99setTimeoutCalls.length = 0;100clearTimeoutCalls.length = 0;101102// Window Count: 3103104let window2 = createWindow(2);105const window3 = createWindow(3);106windows = [107{ window: window2, disposables },108{ window: window1, disposables },109{ window: window3, disposables }110];111112await new Promise<void>((resolve, reject) => {113window1.setTimeout(() => {114if (!called) {115called = true;116resolve();117} else {118reject(new Error('timeout called twice'));119}120}, 1);121});122123assert.strictEqual(called, true);124assert.deepStrictEqual(setTimeoutCalls, [2, 1, 3]);125assert.deepStrictEqual(clearTimeoutCalls, [2, 1, 3]);126called = false;127setTimeoutCalls.length = 0;128clearTimeoutCalls.length = 0;129130// Window Count: 2 (1 fast, 1 slow)131132window2 = createWindow(2, true);133windows = [134{ window: window2, disposables },135{ window: window1, disposables },136];137138await new Promise<void>((resolve, reject) => {139window1.setTimeout((windowId: number) => {140if (!called && windowId === 1) {141called = true;142resolve();143} else if (called) {144reject(new Error('timeout called twice'));145} else {146reject(new Error('timeout called for wrong window'));147}148}, 1);149});150151assert.strictEqual(called, true);152assert.deepStrictEqual(setTimeoutCalls, [2, 1]);153assert.deepStrictEqual(clearTimeoutCalls, [2, 1]);154called = false;155setTimeoutCalls.length = 0;156clearTimeoutCalls.length = 0;157158disposables.dispose();159});160});161});162163164