@@ -2,6 +2,10 @@ import { describe, expect, it } from "bun:test";
22import * as os from "os" ;
33import * as path from "path" ;
44import { LocalRuntime } from "./LocalRuntime" ;
5+ import * as fs from "fs" ;
6+ import * as fsPromises from "fs/promises" ;
7+ import { execFileSync } from "child_process" ;
8+ import type { InitLogger } from "./Runtime" ;
59
610describe ( "LocalRuntime constructor" , ( ) => {
711 it ( "should expand tilde in srcBaseDir" , ( ) => {
@@ -65,3 +69,88 @@ describe("LocalRuntime.resolvePath", () => {
6569 expect ( path . isAbsolute ( resolved ) ) . toBe ( true ) ;
6670 } ) ;
6771} ) ;
72+
73+ const GIT_ENV = {
74+ ...process . env ,
75+ GIT_AUTHOR_NAME : "Test User" ,
76+ GIT_AUTHOR_EMAIL : "test@example.com" ,
77+ GIT_COMMITTER_NAME : "Test User" ,
78+ GIT_COMMITTER_EMAIL : "test@example.com" ,
79+ } ;
80+
81+ function runGit ( args : string [ ] , cwd ?: string ) {
82+ execFileSync ( "git" , args , { cwd, env : GIT_ENV } ) ;
83+ }
84+
85+ function gitOutput ( args : string [ ] , cwd ?: string ) : string {
86+ return execFileSync ( "git" , args , { cwd, env : GIT_ENV } ) . toString ( ) . trim ( ) ;
87+ }
88+
89+ function createTestInitLogger ( ) : InitLogger {
90+ return {
91+ logStep : ( ) => { } ,
92+ logStdout : ( ) => { } ,
93+ logStderr : ( ) => { } ,
94+ logComplete : ( ) => { } ,
95+ } ;
96+ }
97+
98+ describe ( "LocalRuntime auto rebase" , ( ) => {
99+ it ( "rebases onto origin when enabled" , async ( ) => {
100+ const tmpRoot = await fsPromises . mkdtemp ( path . join ( os . tmpdir ( ) , "local-runtime-" ) ) ;
101+ const originDir = path . join ( tmpRoot , "origin.git" ) ;
102+ const projectDir = path . join ( tmpRoot , "project" ) ;
103+ const upstreamDir = path . join ( tmpRoot , "upstream" ) ;
104+ const workspacesDir = path . join ( tmpRoot , "workspaces" ) ;
105+ const trunkBranch = "main" ;
106+
107+ try {
108+ runGit ( [ "init" , "--bare" , originDir ] ) ;
109+
110+ fs . mkdirSync ( projectDir , { recursive : true } ) ;
111+ runGit ( [ "init" , "-b" , trunkBranch ] , projectDir ) ;
112+ runGit ( [ "remote" , "add" , "origin" , originDir ] , projectDir ) ;
113+
114+ fs . writeFileSync ( path . join ( projectDir , "README.md" ) , "first\n" ) ;
115+ runGit ( [ "add" , "README.md" ] , projectDir ) ;
116+ runGit ( [ "commit" , "-m" , "initial" ] , projectDir ) ;
117+ runGit ( [ "push" , "-u" , "origin" , trunkBranch ] , projectDir ) ;
118+
119+ runGit ( [ "clone" , "-b" , trunkBranch , originDir , upstreamDir ] ) ;
120+ fs . appendFileSync ( path . join ( upstreamDir , "README.md" ) , "second\n" ) ;
121+ runGit ( [ "commit" , "-am" , "upstream change" ] , upstreamDir ) ;
122+ runGit ( [ "push" , "origin" , trunkBranch ] , upstreamDir ) ;
123+
124+ const runtime = new LocalRuntime ( workspacesDir ) ;
125+ const initLogger = createTestInitLogger ( ) ;
126+ const branchName = "auto-rebase-test" ;
127+
128+ const createResult = await runtime . createWorkspace ( {
129+ projectPath : projectDir ,
130+ branchName,
131+ trunkBranch,
132+ directoryName : branchName ,
133+ initLogger,
134+ } ) ;
135+
136+ expect ( createResult . success ) . toBe ( true ) ;
137+ expect ( createResult . workspacePath ) . toBeTruthy ( ) ;
138+ const workspacePath = createResult . workspacePath ! ;
139+
140+ await runtime . initWorkspace ( {
141+ projectPath : projectDir ,
142+ branchName,
143+ trunkBranch,
144+ workspacePath,
145+ initLogger,
146+ autoRebaseTrunk : true ,
147+ } ) ;
148+
149+ const workspaceHead = gitOutput ( [ "rev-parse" , "HEAD" ] , workspacePath ) ;
150+ const originHead = gitOutput ( [ "rev-parse" , `origin/${ trunkBranch } ` ] , projectDir ) ;
151+ expect ( workspaceHead ) . toBe ( originHead ) ;
152+ } finally {
153+ await fsPromises . rm ( tmpRoot , { recursive : true , force : true } ) ;
154+ }
155+ } ) ;
156+ } ) ;
0 commit comments