Skip to content

Commit 05aa209

Browse files
committed
test: stabilize coverage shard native checks
1 parent 2847734 commit 05aa209

7 files changed

Lines changed: 62 additions & 13 deletions

File tree

electron/DesktopLyricManager.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ import type { SongPlatform } from '@shared/types/schemas'
55
import { DEFAULT_APP_CONFIG, type AppConfig } from '@shared/contracts/config'
66
import { RECEIVE_CHANNELS, type ReceiveChannel } from '@shared/protocol/channels'
77

8+
import { getElectronModule } from './utils/electronModule'
89
import { MAIN_DIST, RENDERER_DIST } from './utils/paths'
910

10-
const getElectron = (): typeof import('electron') =>
11-
require('electron') as typeof import('electron')
12-
1311
type ElectronStoreInstance = {
1412
get(key: string): unknown
1513
set(key: string, value: unknown): void
@@ -219,7 +217,7 @@ export class DesktopLyricManager {
219217
this.isWindowReady = false
220218
this.isRendererReady = false
221219

222-
const { BrowserWindow, screen } = getElectron()
220+
const { BrowserWindow, screen } = getElectronModule()
223221
const primaryDisplay = screen.getPrimaryDisplay()
224222
const { width, height } = primaryDisplay.workAreaSize
225223
const x = this.lastPosition ? this.lastPosition.x : Math.floor((width - 800) / 2)

electron/WindowManager.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@ import type {
55
Rectangle,
66
WebContents as WebContentsType
77
} from 'electron'
8-
import { BrowserWindow, nativeImage } from 'electron'
98
import path from 'node:path'
109

1110
import { downloadManager } from './DownloadManager'
1211
import logger from './logger'
1312
import { getWindowsShellIdentity, type WindowsShellIdentity } from './main/app'
1413
import { RECEIVE_CHANNELS } from '@shared/protocol/channels'
14+
import { getElectronModule } from './utils/electronModule'
1515
import { MAIN_DIST, RENDERER_DIST, VITE_PUBLIC } from './utils/paths'
1616
const StoreModule = require('electron-store') as {
1717
default?: new (options?: { projectName: string }) => {
@@ -92,6 +92,7 @@ export class WindowManager {
9292
}
9393

9494
createWindow(): void {
95+
const { BrowserWindow } = getElectronModule()
9596
const startedAt = Date.now()
9697
const width = this.lastSize ? this.lastSize.width : 1200
9798
const height = this.lastSize ? this.lastSize.height : 800
@@ -507,6 +508,7 @@ export class WindowManager {
507508
return
508509
}
509510

511+
const { nativeImage } = getElectronModule()
510512
const iconsPath = process.env.VITE_PUBLIC || path.join(__dirname, '../public')
511513
const buttons = [
512514
{

electron/utils/electronModule.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
type ElectronModule = typeof import('electron')
2+
3+
type ElectronTestGlobal = typeof globalThis & {
4+
__LUO_ELECTRON_TEST_MOCK__?: Partial<ElectronModule>
5+
}
6+
7+
export function getElectronModule(): ElectronModule {
8+
const testMock =
9+
process.env.VITEST === 'true'
10+
? (globalThis as ElectronTestGlobal).__LUO_ELECTRON_TEST_MOCK__
11+
: undefined
12+
13+
if (testMock) {
14+
return testMock as ElectronModule
15+
}
16+
17+
return require('electron') as ElectronModule
18+
}

scripts/test-audio-output-remote-refresh.cjs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ const freshUrlEnv = "LUO_AUDIO_OUTPUT_REMOTE_FRESH_URL";
1717
const freshHeadersEnv = "LUO_AUDIO_OUTPUT_REMOTE_FRESH_HEADERS";
1818
const nativePlaybackEnv = "LUO_AUDIO_OUTPUT_REMOTE_NATIVE_PLAYBACK";
1919
const nativePlaybackModeEnv = "LUO_AUDIO_OUTPUT_REMOTE_NATIVE_MODE";
20+
const nativePlaybackSkipHelperEnv =
21+
"LUO_AUDIO_OUTPUT_REMOTE_NATIVE_SKIP_HELPER";
2022
const nativePlaybackStates = new Set(["starting", "playing", "ended"]);
2123
const projectRoot = path.resolve(__dirname, "..");
2224
const protocolVersion = 2;
@@ -493,8 +495,6 @@ async function verifyNativePlaybackFromFreshAudio(scenario, options = {}) {
493495
};
494496
}
495497

496-
const helperInfo = prepareAudioOutputHelper({ projectRoot });
497-
498498
const cacheDir = fs.mkdtempSync(path.join(os.tmpdir(), "luo-remote-native-"));
499499
const extension = extensionForContentType(
500500
wholeFresh.contentType,
@@ -503,6 +503,26 @@ async function verifyNativePlaybackFromFreshAudio(scenario, options = {}) {
503503
const cachePath = path.join(cacheDir, `fresh-audio${extension}`);
504504
fs.writeFileSync(cachePath, wholeFresh.bytes);
505505

506+
const nativeMode = normalizeNativePlaybackMode(
507+
process.env[nativePlaybackModeEnv],
508+
);
509+
510+
if (parseBooleanEnv(nativePlaybackSkipHelperEnv, false)) {
511+
return {
512+
attempted: true,
513+
started: false,
514+
cachePath,
515+
extension,
516+
bytesReceived: wholeFresh.bytesReceived,
517+
bodySha256: wholeFresh.bodySha256,
518+
contentType: wholeFresh.contentType,
519+
requestedMode: nativeMode,
520+
reason: `Native helper startup skipped by ${nativePlaybackSkipHelperEnv}.`,
521+
};
522+
}
523+
524+
const helperInfo = prepareAudioOutputHelper({ projectRoot });
525+
506526
const helper = spawn(helperInfo.helperPath, [], {
507527
cwd: projectRoot,
508528
env: process.env,
@@ -511,9 +531,6 @@ async function verifyNativePlaybackFromFreshAudio(scenario, options = {}) {
511531
});
512532
const events = attachHelperEventParser(helper);
513533
const deviceId = process.env.LUO_AUDIO_OUTPUT_TEST_DEVICE_ID || "";
514-
const nativeMode = normalizeNativePlaybackMode(
515-
process.env[nativePlaybackModeEnv],
516-
);
517534
const timeoutMs = parseIntegerEnv(
518535
"LUO_AUDIO_OUTPUT_REMOTE_NATIVE_TIMEOUT_MS",
519536
15_000,

tests/electron/DesktopLyricManager.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { beforeEach, describe, expect, it, vi } from 'vitest'
1+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
22

33
import { RECEIVE_CHANNELS } from '@shared/protocol/channels'
44

@@ -78,6 +78,9 @@ function setInternals(manager: DesktopLyricManager, patch: Partial<ManagerIntern
7878
}
7979

8080
type DesktopLyricManager = import('../../electron/DesktopLyricManager').DesktopLyricManager
81+
type ElectronTestGlobal = typeof globalThis & {
82+
__LUO_ELECTRON_TEST_MOCK__?: ReturnType<typeof createElectronMock>
83+
}
8184

8285
function createMockWindow(
8386
overrides: { isVisible?: boolean } = {}
@@ -94,7 +97,7 @@ function createMockWindow(
9497
describe('DesktopLyricManager', () => {
9598
beforeEach(() => {
9699
vi.resetModules()
97-
vi.doMock('electron', createElectronMock)
100+
;(globalThis as ElectronTestGlobal).__LUO_ELECTRON_TEST_MOCK__ = createElectronMock()
98101
vi.clearAllMocks()
99102
browserWindowInstances.length = 0
100103
storeData.clear()
@@ -103,6 +106,10 @@ describe('DesktopLyricManager', () => {
103106
delete process.env.LUO_DESKTOP_LYRIC_DEBUG
104107
})
105108

109+
afterEach(() => {
110+
delete (globalThis as ElectronTestGlobal).__LUO_ELECTRON_TEST_MOCK__
111+
})
112+
106113
it('replays the last cached lyric when an existing ready window is shown', async () => {
107114
const { DesktopLyricManager } = await import('../../electron/DesktopLyricManager')
108115
const manager = new DesktopLyricManager()

tests/electron/windowManager.test.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,17 @@ vi.mock('../../electron/utils/paths', () => ({
128128
VITE_PUBLIC: '/public'
129129
}))
130130

131+
type ElectronTestGlobal = typeof globalThis & {
132+
__LUO_ELECTRON_TEST_MOCK__?: ReturnType<typeof createElectronMock>
133+
}
134+
131135
describe('electron/WindowManager', () => {
132136
const platformDescriptor = Object.getOwnPropertyDescriptor(process, 'platform')
133137

134138
beforeEach(() => {
135139
vi.useFakeTimers()
136140
vi.resetModules()
137-
vi.doMock('electron', createElectronMock)
141+
;(globalThis as ElectronTestGlobal).__LUO_ELECTRON_TEST_MOCK__ = createElectronMock()
138142
vi.clearAllMocks()
139143
browserWindowInstances.length = 0
140144
delete process.env.VITE_DEV_SERVER_URL
@@ -146,6 +150,7 @@ describe('electron/WindowManager', () => {
146150

147151
afterEach(() => {
148152
vi.useRealTimers()
153+
delete (globalThis as ElectronTestGlobal).__LUO_ELECTRON_TEST_MOCK__
149154
delete process.env.VITE_DEV_SERVER_URL
150155
if (platformDescriptor) {
151156
Object.defineProperty(process, 'platform', platformDescriptor)

tests/scripts/audioOutputRemoteRefreshScript.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ describe('audio output remote refresh script', () => {
7878
LUO_AUDIO_OUTPUT_REMOTE_FRESH_HEADERS: '',
7979
LUO_AUDIO_OUTPUT_REMOTE_REFRESH_REPORT: reportPath,
8080
LUO_AUDIO_OUTPUT_REMOTE_NATIVE_PLAYBACK: '1',
81+
LUO_AUDIO_OUTPUT_REMOTE_NATIVE_SKIP_HELPER: '1',
8182
LUO_AUDIO_OUTPUT_REMOTE_NATIVE_TIMEOUT_MS: '5000'
8283
},
8384
timeout: 60_000
@@ -182,6 +183,7 @@ describe('audio output remote refresh script', () => {
182183
expect(script).toContain('resolveReportPathFromEnv')
183184
expect(script).toContain('LUO_AUDIO_OUTPUT_REMOTE_NATIVE_PLAYBACK')
184185
expect(script).toContain('LUO_AUDIO_OUTPUT_REMOTE_NATIVE_MODE')
186+
expect(script).toContain('LUO_AUDIO_OUTPUT_REMOTE_NATIVE_SKIP_HELPER')
185187
expect(script).toContain('requestedMode: nativeMode')
186188
expect(script).toContain('mode: nativeMode')
187189
expect(script).toContain('writeReportIfRequested')

0 commit comments

Comments
 (0)