1- import { test } from 'vitest' ;
1+ import { beforeEach , test , vi } from 'vitest' ;
22import assert from 'node:assert/strict' ;
3- import { promises as fs } from 'node:fs' ;
3+ import { appendFileSync , promises as fs , writeFileSync } from 'node:fs' ;
44import os from 'node:os' ;
55import path from 'node:path' ;
6+ vi . mock ( '../../../utils/exec.ts' , async ( importOriginal ) => {
7+ const actual = await importOriginal < typeof import ( '../../../utils/exec.ts' ) > ( ) ;
8+ return { ...actual , runCmdDetached : vi . fn ( actual . runCmdDetached ) } ;
9+ } ) ;
10+
11+ const execActual =
12+ await vi . importActual < typeof import ( '../../../utils/exec.ts' ) > ( '../../../utils/exec.ts' ) ;
13+
614import { AppError } from '../../../utils/errors.ts' ;
15+ import { runCmdDetached } from '../../../utils/exec.ts' ;
716import {
817 ensureAndroidEmulatorBooted ,
918 listAndroidDevices ,
@@ -15,6 +24,8 @@ import {
1524 resolveAndroidEmulatorAvdName ,
1625} from '../devices.ts' ;
1726
27+ const mockRunCmdDetached = vi . mocked ( runCmdDetached ) ;
28+
1829const MOCK_ANDROID_ADB_SCRIPT = [
1930 '#!/bin/sh' ,
2031 'if [ "$1" = "devices" ] && [ "$2" = "-l" ]; then' ,
@@ -86,11 +97,27 @@ const MOCK_ANDROID_EMULATOR_SCRIPT = [
8697 '' ,
8798] ;
8899
100+ beforeEach ( ( ) => {
101+ mockRunCmdDetached . mockReset ( ) ;
102+ mockRunCmdDetached . mockImplementation ( execActual . runCmdDetached ) ;
103+ } ) ;
104+
89105async function writeExecutable ( filePath : string , lines : readonly string [ ] ) : Promise < void > {
90106 await fs . writeFile ( filePath , lines . join ( '\n' ) , 'utf8' ) ;
91107 await fs . chmod ( filePath , 0o755 ) ;
92108}
93109
110+ function mockDetachedEmulatorLaunch ( emulatorLogPath : string , emulatorBootedPath : string ) : void {
111+ mockRunCmdDetached . mockImplementation ( ( cmd , args , options ) => {
112+ if ( cmd === 'emulator' && args [ 0 ] === '-avd' ) {
113+ appendFileSync ( emulatorLogPath , `${ args . join ( ' ' ) } \n` , 'utf8' ) ;
114+ writeFileSync ( emulatorBootedPath , 'ready' , 'utf8' ) ;
115+ return 1234 ;
116+ }
117+ return execActual . runCmdDetached ( cmd , args , options ) ;
118+ } ) ;
119+ }
120+
94121async function withEnv (
95122 overrides : Record < string , string | undefined > ,
96123 run : ( ) => Promise < void > ,
@@ -161,6 +188,7 @@ async function withMockedAndroidTools(
161188 await writeExecutable ( emulatorPath , MOCK_ANDROID_EMULATOR_SCRIPT ) ;
162189
163190 try {
191+ mockDetachedEmulatorLaunch ( emulatorLogPath , emulatorBootedPath ) ;
164192 await withEnv (
165193 {
166194 PATH : `${ tmpDir } ${ path . delimiter } ${ process . env . PATH ?? '' } ` ,
@@ -201,6 +229,7 @@ async function withMockedAndroidSdkRoot(
201229 await writeExecutable ( emulatorPath , MOCK_ANDROID_EMULATOR_SCRIPT ) ;
202230
203231 try {
232+ mockDetachedEmulatorLaunch ( emulatorLogPath , emulatorBootedPath ) ;
204233 await withEnv (
205234 {
206235 PATH : process . env . PATH ?? '' ,
0 commit comments