@@ -5,10 +5,12 @@ import {
55 beforeEach ,
66 afterEach ,
77 vi ,
8- beforeAll
8+ beforeAll ,
9+ MockInstance
910} from 'vitest'
1011import Docker , { ContainerInfo } from 'dockerode'
1112import * as compose from '../src'
13+ import childProcess from 'child_process'
1214import * as path from 'path'
1315import { readFile } from 'fs'
1416import { mapPsOutput , mapImListOutput } from '../src'
@@ -1202,3 +1204,68 @@ describe('when upAll is called', () => {
12021204 } )
12031205 } )
12041206} )
1207+
1208+ describe ( 'executable path resolution' , ( ) : void => {
1209+ let spawnSpy : MockInstance < typeof childProcess . spawn >
1210+
1211+ beforeEach ( ( ) : void => {
1212+ const mockProc = {
1213+ on : vi . fn ( ) ,
1214+ stdout : { on : vi . fn ( ) , pipe : vi . fn ( ) } ,
1215+ stderr : { on : vi . fn ( ) , pipe : vi . fn ( ) } ,
1216+ stdin : { write : vi . fn ( ) , end : vi . fn ( ) }
1217+ }
1218+
1219+ mockProc . on . mockImplementation ( ( event , cb ) => {
1220+ if ( event === 'exit' ) {
1221+ setTimeout ( ( ) => cb ( 0 ) , 0 )
1222+ }
1223+ } )
1224+
1225+ spawnSpy = vi
1226+ . spyOn ( childProcess , 'spawn' )
1227+ . mockReturnValue ( ( mockProc as unknown ) as childProcess . ChildProcess )
1228+ } )
1229+
1230+ afterEach ( ( ) : void => {
1231+ spawnSpy . mockRestore ( )
1232+ } )
1233+
1234+ // spawn is always called with a third argument ({ cwd, env }) so we use
1235+ // expect.objectContaining({}) to match it without being brittle about its contents.
1236+ it ( 'uses custom executablePath in standalone mode without appending compose' , async ( ) : Promise < void > => {
1237+ await compose . execCompose ( 'up' , [ ] , {
1238+ executable : {
1239+ standalone : true ,
1240+ executablePath : '/custom/path/docker-compose'
1241+ }
1242+ } )
1243+ expect ( spawnSpy ) . toHaveBeenCalledWith (
1244+ '/custom/path/docker-compose' ,
1245+ [ 'up' ] ,
1246+ expect . objectContaining ( { } )
1247+ )
1248+ } )
1249+
1250+ it ( 'defaults to docker-compose in standalone mode when no executablePath is provided' , async ( ) : Promise < void > => {
1251+ await compose . execCompose ( 'up' , [ ] , {
1252+ executable : { standalone : true }
1253+ } )
1254+ expect ( spawnSpy ) . toHaveBeenCalledWith (
1255+ 'docker-compose' ,
1256+ [ 'up' ] ,
1257+ expect . objectContaining ( { } )
1258+ )
1259+ } )
1260+
1261+ it ( 'appends compose subcommand when not in standalone mode' , async ( ) : Promise < void > => {
1262+ await compose . execCompose ( 'up' , [ ] , {
1263+ executable : { executablePath : '/custom/docker' }
1264+ } )
1265+ expect ( spawnSpy ) . toHaveBeenCalledWith (
1266+ '/custom/docker' ,
1267+ [ 'compose' , 'up' ] ,
1268+ expect . objectContaining ( { } )
1269+ )
1270+ } )
1271+ } )
0 commit comments