Files
makelore/tests/unit/main-window-close.test.ts
2026-09-29 19:50:25 +08:00

95 lines
3.1 KiB
TypeScript

import { EventEmitter } from 'node:events';
import { describe, expect, it, vi } from 'vitest';
import { registerMainWindowClose } from '@electron/main/main-window-close';
class WindowStub extends EventEmitter {
fullscreen = false;
destroyed = false;
hide = vi.fn();
setFullScreen = vi.fn();
isFullScreen = () => this.fullscreen;
isDestroyed = () => this.destroyed;
close = vi.fn(() => {
const event = { defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } };
this.emit('close', event);
if (!event.defaultPrevented) {
this.destroyed = true;
this.emit('closed');
}
});
leaveFullscreen(): void {
this.fullscreen = false;
this.emit('leave-full-screen');
}
}
function setup(fullscreen = false) {
const window = new WindowStub();
window.fullscreen = fullscreen;
let quitting = false;
registerMainWindowClose(window as never, {
platform: 'darwin', isQuitting: () => quitting, hideOnClose: false,
});
return { window, quit: () => { quitting = true; window.close(); } };
}
describe('native main window close', () => {
it('really destroys a normal macOS window instead of hiding it', () => {
const { window } = setup();
window.close();
expect(window.destroyed).toBe(true);
expect(window.hide).not.toHaveBeenCalled();
expect(window.setFullScreen).not.toHaveBeenCalled();
});
it('waits for the fullscreen exit before closing, including repeated clicks', () => {
const { window } = setup(true);
const order: string[] = [];
window.prependListener('leave-full-screen', () => order.push('left fullscreen'));
window.on('closed', () => order.push('closed'));
window.close();
window.close();
expect(window.destroyed).toBe(false);
expect(window.hide).not.toHaveBeenCalled();
expect(window.setFullScreen).toHaveBeenCalledExactlyOnceWith(false);
window.leaveFullscreen();
expect(window.destroyed).toBe(true);
expect(order).toEqual(['left fullscreen', 'closed']);
});
it('does not delay a real app quit while fullscreen exit is pending', () => {
const { window, quit } = setup(true);
window.close();
quit();
expect(window.destroyed).toBe(true);
window.leaveFullscreen();
expect(window.close).toHaveBeenCalledTimes(2);
});
it('lets Cmd+Q close a fullscreen window without starting another transition', () => {
const { window, quit } = setup(true);
quit();
expect(window.destroyed).toBe(true);
expect(window.setFullScreen).not.toHaveBeenCalled();
});
it('cancels deferred closing if the window was destroyed externally', () => {
const { window } = setup(true);
window.close();
window.destroyed = true;
window.emit('closed');
window.leaveFullscreen();
expect(window.close).toHaveBeenCalledTimes(1);
});
it('preserves existing close-to-tray behavior on other platforms', () => {
const window = new WindowStub();
registerMainWindowClose(window as never, {
platform: 'win32', isQuitting: () => false, hideOnClose: true,
});
window.close();
expect(window.destroyed).toBe(false);
expect(window.hide).toHaveBeenCalledOnce();
});
});