setup.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. import fs from 'node:fs'
  2. import path from 'node:path'
  3. import { fileURLToPath } from 'node:url'
  4. import { vi } from 'vitest'
  5. const testDir = path.dirname(fileURLToPath(import.meta.url))
  6. const tmpDir = path.join(testDir, 'tmp')
  7. const testTmpDir = path.join(tmpDir, 'electron')
  8. const testHomeDir = path.join(tmpDir, 'home')
  9. fs.rmSync(tmpDir, { force: true, recursive: true })
  10. fs.mkdirSync(testHomeDir, { recursive: true })
  11. process.env.HOME = testHomeDir
  12. process.env.USERPROFILE = testHomeDir
  13. ;(globalThis as typeof globalThis & { data_dir?: string }).data_dir = path.join(testHomeDir, '.SwitchHosts')
  14. class BrowserWindowMock {
  15. static fromWebContents() {
  16. return new BrowserWindowMock()
  17. }
  18. private bounds = { x: 0, y: 0, width: 300, height: 600 }
  19. private focused = false
  20. private visible = false
  21. webContents = {
  22. closeDevTools() {},
  23. openDevTools() {},
  24. once() {},
  25. session: {
  26. setPermissionRequestHandler() {},
  27. webRequest: {
  28. onBeforeSendHeaders() {},
  29. onHeadersReceived() {},
  30. },
  31. },
  32. toggleDevTools() {},
  33. }
  34. constructor(options?: { width?: number; height?: number }) {
  35. if (options?.width) this.bounds.width = options.width
  36. if (options?.height) this.bounds.height = options.height
  37. }
  38. focus() {
  39. this.focused = true
  40. }
  41. getBounds() {
  42. return this.bounds
  43. }
  44. hide() {
  45. this.focused = false
  46. this.visible = false
  47. }
  48. isFocused() {
  49. return this.focused
  50. }
  51. isVisible() {
  52. return this.visible
  53. }
  54. loadURL() {
  55. return Promise.resolve()
  56. }
  57. on() {
  58. return this
  59. }
  60. setPosition(x: number, y: number) {
  61. this.bounds.x = x
  62. this.bounds.y = y
  63. }
  64. setVisibleOnAllWorkspaces() {}
  65. show() {
  66. this.focused = true
  67. this.visible = true
  68. }
  69. }
  70. const electronMock = {
  71. app: {
  72. getPath(name: string) {
  73. if (name === 'userData') {
  74. fs.mkdirSync(testTmpDir, { recursive: true })
  75. return testTmpDir
  76. }
  77. return testTmpDir
  78. },
  79. quit() {},
  80. whenReady() {
  81. return new Promise(() => {})
  82. },
  83. dock: {
  84. hide() {},
  85. show() {
  86. return Promise.resolve()
  87. },
  88. },
  89. },
  90. BrowserWindow: BrowserWindowMock,
  91. Menu: {
  92. buildFromTemplate() {
  93. return {}
  94. },
  95. },
  96. MenuItem: class MenuItem {},
  97. Tray: class Tray {
  98. setToolTip() {}
  99. setContextMenu() {}
  100. on() {}
  101. popUpContextMenu() {}
  102. getBounds() {
  103. return { x: 0, y: 0, width: 20, height: 20 }
  104. }
  105. },
  106. screen: {
  107. getCursorScreenPoint() {
  108. return { x: 0, y: 0 }
  109. },
  110. getDisplayNearestPoint() {
  111. return {
  112. bounds: { x: 0, y: 0, width: 1200, height: 800 },
  113. workAreaSize: { width: 1200, height: 800 },
  114. }
  115. },
  116. },
  117. shell: {
  118. openExternal() {
  119. return Promise.resolve()
  120. },
  121. showItemInFolder() {
  122. return Promise.resolve()
  123. },
  124. },
  125. dialog: {
  126. showOpenDialog() {
  127. return Promise.resolve({ canceled: true, filePaths: [] })
  128. },
  129. showSaveDialog() {
  130. return Promise.resolve({ canceled: true, filePath: undefined })
  131. },
  132. },
  133. ipcMain: {
  134. emit() {},
  135. on() {},
  136. handle() {},
  137. removeHandler() {},
  138. removeAllListeners() {},
  139. },
  140. ipcRenderer: {
  141. invoke() {
  142. return Promise.resolve(undefined)
  143. },
  144. on() {},
  145. send() {},
  146. removeAllListeners() {},
  147. },
  148. contextBridge: {
  149. exposeInMainWorld() {},
  150. },
  151. nativeTheme: {
  152. shouldUseDarkColors: false,
  153. },
  154. }
  155. vi.mock('electron', () => electronMock)