1616 * SPDX-License-Identifier: Apache-2.0
1717 ***********************************************************************/
1818import type { App as ElectronApp } from 'electron' ;
19- import { afterEach , beforeEach , expect , test , vi } from 'vitest' ;
19+ import { afterEach , beforeEach , describe , expect , test , vi } from 'vitest' ;
2020
2121import { SecurityRestrictions } from '/@/security-restrictions.js' ;
22- import { isWindows } from '/@/util.js' ;
22+ import { isLinux , isMac , isWindows } from '/@/util.js' ;
2323
2424import { Main } from './main.js' ;
2525
@@ -34,6 +34,7 @@ const ELECTRON_APP_MOCK: ElectronApp = {
3434 requestSingleInstanceLock : vi . fn ( ) ,
3535 setAppUserModelId : vi . fn ( ) ,
3636 quit : vi . fn ( ) ,
37+ on : vi . fn ( ) ,
3738} as unknown as ElectronApp ;
3839
3940let PROCESS_EXIT_ORIGINAL : typeof process . exit ;
@@ -87,3 +88,64 @@ test('on windows setAppUserModelId should be called', async () => {
8788
8889 expect ( ELECTRON_APP_MOCK . setAppUserModelId ) . toHaveBeenCalledWith ( ELECTRON_APP_MOCK . name ) ;
8990} ) ;
91+
92+ // Utility type definition for {@link ElectronApp.on } and {@link WebContents.on }
93+ type Listener = ( ...args : unknown [ ] ) => void ;
94+
95+ /**
96+ * Utility function to get listener register in {@link ELECTRON_APP_MOCK.on}
97+ * @remarks cannot found any way to properly infer type based on event value (see https://github.com/microsoft/TypeScript/issues/53439)
98+ * @param event
99+ */
100+ function findElectronAppListener ( event : string ) : Listener | undefined {
101+ expect ( ELECTRON_APP_MOCK . on ) . toHaveBeenCalledWith ( event , expect . any ( Function ) ) ;
102+ return vi . mocked ( ELECTRON_APP_MOCK . on ) . mock . calls . find ( ( [ mEvent ] ) => mEvent === event ) ?. [ 1 ] ;
103+ }
104+
105+ /**
106+ * Based on {@link findElectronAppListener}, throw an error if the result is undefined
107+ * @param event
108+ */
109+ function getElectronAppListener ( event : string ) : Listener {
110+ const listener = findElectronAppListener ( event ) ;
111+ if ( ! listener ) throw new Error ( `cannot found listener for event ${ event } ` ) ;
112+ return listener ;
113+ }
114+
115+ describe ( 'ElectronApp#on window-all-closed' , ( ) => {
116+ let code : Main ;
117+ beforeEach ( ( ) => {
118+ code = new Main ( ELECTRON_APP_MOCK ) ;
119+ code . main ( [ ] ) ;
120+ } ) ;
121+
122+ test ( 'listener should be registered on init' , ( ) => {
123+ expect ( ELECTRON_APP_MOCK . on ) . toHaveBeenCalledWith ( 'window-all-closed' , expect . any ( Function ) ) ;
124+ } ) ;
125+
126+ test ( 'listener should be a valid function' , ( ) => {
127+ const listener = findElectronAppListener ( 'window-all-closed' ) ;
128+ expect ( listener ) . toBeDefined ( ) ;
129+ expect ( listener ) . toBeInstanceOf ( Function ) ;
130+ } ) ;
131+
132+ test ( 'listener should not call ElectronApp#quit on mac' , ( ) => {
133+ vi . mocked ( isMac ) . mockReturnValue ( true ) ;
134+
135+ const listener = getElectronAppListener ( 'window-all-closed' ) ;
136+ listener ( ) ;
137+
138+ expect ( ELECTRON_APP_MOCK . quit ) . not . toHaveBeenCalled ( ) ;
139+ } ) ;
140+
141+ test . each ( [ 'windows' , 'linux' ] ) ( 'listener should not call ElectronApp#quit on %s' , platform => {
142+ vi . mocked ( isMac ) . mockReturnValue ( false ) ;
143+ vi . mocked ( isWindows ) . mockReturnValue ( platform === 'windows' ) ;
144+ vi . mocked ( isLinux ) . mockReturnValue ( platform === 'linux' ) ;
145+
146+ const listener = getElectronAppListener ( 'window-all-closed' ) ;
147+ listener ( ) ;
148+
149+ expect ( ELECTRON_APP_MOCK . quit ) . toHaveBeenCalledOnce ( ) ;
150+ } ) ;
151+ } ) ;
0 commit comments