Files
BrowserOS/packages/browseros/tools/bdev/internal/engine/engine_test.go
Nikhil 39a7d49c25 feat: add workspace-centric bdev cli (#585)
* fix: clean-up bdev

* feat: add workspace-centric bdev cli

* fix: address review comments for 0326-bdev_cli_redesign

* fix: address review feedback for PR #585

* fix: address review feedback for PR #585
2026-03-27 08:48:23 -07:00

221 lines
6.9 KiB
Go

package engine
import (
"context"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/git"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/patch"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/repo"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/resolve"
"github.com/browseros-ai/BrowserOS/packages/browseros/tools/bdev/internal/workspace"
)
func TestAbortRevertsAppliedOpsAndRestoresPendingStash(t *testing.T) {
ctx := context.Background()
workspacePath := initGitRepo(t)
writeFile(t, filepath.Join(workspacePath, "a.txt"), "a\n")
writeFile(t, filepath.Join(workspacePath, "b.txt"), "b\n")
writeFile(t, filepath.Join(workspacePath, "local.txt"), "local\n")
runGit(t, workspacePath, "add", "a.txt", "b.txt", "local.txt")
runGit(t, workspacePath, "commit", "-m", "base")
baseCommit := gitOutput(t, workspacePath, "rev-parse", "HEAD")
writeFile(t, filepath.Join(workspacePath, "local.txt"), "local changed\n")
runGit(t, workspacePath, "stash", "push", "-m", "test stash", "-u", "--", "local.txt")
stashRef := gitOutput(t, workspacePath, "stash", "list", "-1", "--format=%gd")
if stashRef == "" {
t.Fatalf("expected stash ref")
}
if err := workspace.SaveState(workspacePath, &workspace.State{
Version: 1,
Workspace: workspacePath,
BaseCommit: baseCommit,
PendingStash: stashRef,
}); err != nil {
t.Fatalf("SaveState: %v", err)
}
writeFile(t, filepath.Join(workspacePath, "a.txt"), "applied\n")
writeFile(t, filepath.Join(workspacePath, "b.txt"), "conflict\n")
if err := resolve.Save(workspacePath, &resolve.State{
Workspace: workspacePath,
RepoRoot: workspacePath,
BaseCommit: baseCommit,
Current: 1,
Operations: []resolve.Operation{
{ChromiumPath: "a.txt", PatchRel: "a.txt", Op: patch.OpModify},
{ChromiumPath: "b.txt", PatchRel: "b.txt", Op: patch.OpModify},
},
}); err != nil {
t.Fatalf("resolve.Save: %v", err)
}
if err := Abort(ctx, workspace.Entry{Name: "ws", Path: workspacePath}); err != nil {
t.Fatalf("Abort: %v", err)
}
assertFile(t, filepath.Join(workspacePath, "a.txt"), "a\n")
assertFile(t, filepath.Join(workspacePath, "b.txt"), "b\n")
assertFile(t, filepath.Join(workspacePath, "local.txt"), "local changed\n")
if resolve.Exists(workspacePath) {
t.Fatalf("expected resolve state to be removed")
}
state, err := workspace.LoadState(workspacePath)
if err != nil {
t.Fatalf("LoadState: %v", err)
}
if state.PendingStash != "" {
t.Fatalf("expected pending stash cleared, got %q", state.PendingStash)
}
}
func TestPublishReturnsHelpfulErrorWhenNothingChanged(t *testing.T) {
ctx := context.Background()
repoRoot := initGitRepo(t)
writeFile(t, filepath.Join(repoRoot, "BASE_COMMIT"), "base123\n")
writeFile(t, filepath.Join(repoRoot, "chromium_patches", ".gitkeep"), "")
runGit(t, repoRoot, "add", "BASE_COMMIT", "chromium_patches/.gitkeep")
runGit(t, repoRoot, "commit", "-m", "repo init")
repoInfo, err := repo.Load(repoRoot)
if err != nil {
t.Fatalf("repo.Load: %v", err)
}
if _, err := Publish(ctx, repoInfo, "", ""); err == nil || !strings.Contains(err.Error(), "nothing to publish") {
t.Fatalf("expected helpful no-op error, got %v", err)
}
}
func TestOperationsFromChangesNormalizesOldPath(t *testing.T) {
ops := operationsFromChanges(nil, []git.FileChange{{
Status: "R",
Path: "chromium_patches/chrome/new.cc",
OldPath: "chromium_patches/chrome/old.cc",
}}, nil)
if len(ops) != 1 {
t.Fatalf("expected 1 operation, got %d", len(ops))
}
if ops[0].ChromiumPath != "chrome/new.cc" {
t.Fatalf("unexpected chromium path: %q", ops[0].ChromiumPath)
}
if ops[0].OldPath != "chrome/old.cc" {
t.Fatalf("unexpected old path: %q", ops[0].OldPath)
}
}
func TestSyncClearsPendingStashAfterSuccessfulNonRebaseRun(t *testing.T) {
ctx := context.Background()
workspacePath := initGitRepo(t)
writeFile(t, filepath.Join(workspacePath, "chrome", "browser.cc"), "base\n")
runGit(t, workspacePath, "add", "chrome/browser.cc")
runGit(t, workspacePath, "commit", "-m", "workspace base")
baseCommit := gitOutput(t, workspacePath, "rev-parse", "HEAD")
remoteRepo := t.TempDir()
runGit(t, remoteRepo, "init", "--bare")
repoRoot := initGitRepo(t)
if err := os.MkdirAll(filepath.Join(repoRoot, "chromium_patches"), 0o755); err != nil {
t.Fatalf("MkdirAll: %v", err)
}
writeFile(t, filepath.Join(repoRoot, "BASE_COMMIT"), baseCommit+"\n")
runGit(t, repoRoot, "add", "BASE_COMMIT")
runGit(t, repoRoot, "commit", "-m", "patch repo init")
runGit(t, repoRoot, "remote", "add", "origin", remoteRepo)
runGit(t, repoRoot, "push", "-u", "origin", "HEAD")
repoHead := gitOutput(t, repoRoot, "rev-parse", "HEAD")
repoInfo, err := repo.Load(repoRoot)
if err != nil {
t.Fatalf("repo.Load: %v", err)
}
if err := workspace.SaveState(workspacePath, &workspace.State{
Version: 1,
Workspace: workspacePath,
BaseCommit: baseCommit,
LastSyncRev: repoHead,
PendingStash: "stash@{42}",
}); err != nil {
t.Fatalf("SaveState: %v", err)
}
result, err := Sync(ctx, SyncOptions{
Workspace: workspace.Entry{Name: "ws", Path: workspacePath},
Repo: repoInfo,
Remote: "origin",
Rebase: false,
})
if err != nil {
t.Fatalf("Sync: %v", err)
}
if result.StashRef != "" {
t.Fatalf("expected no new stash ref, got %q", result.StashRef)
}
state, err := workspace.LoadState(workspacePath)
if err != nil {
t.Fatalf("LoadState: %v", err)
}
if state.PendingStash != "" {
t.Fatalf("expected pending stash to be cleared, got %q", state.PendingStash)
}
}
func initGitRepo(t *testing.T) string {
t.Helper()
dir := t.TempDir()
runGit(t, dir, "init")
runGit(t, dir, "config", "user.name", "Test User")
runGit(t, dir, "config", "user.email", "test@example.com")
return dir
}
func runGit(t *testing.T, dir string, args ...string) {
t.Helper()
cmd := exec.Command("git", args...)
cmd.Dir = dir
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("git %s: %v\n%s", strings.Join(args, " "), err, string(output))
}
}
func gitOutput(t *testing.T, dir string, args ...string) string {
t.Helper()
cmd := exec.Command("git", args...)
cmd.Dir = dir
output, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("git %s: %v\n%s", strings.Join(args, " "), err, string(output))
}
return strings.TrimSpace(string(output))
}
func writeFile(t *testing.T, path string, body string) {
t.Helper()
if err := os.MkdirAll(filepath.Dir(path), 0o755); err != nil {
t.Fatalf("MkdirAll: %v", err)
}
if err := os.WriteFile(path, []byte(body), 0o644); err != nil {
t.Fatalf("WriteFile: %v", err)
}
}
func assertFile(t *testing.T, path string, want string) {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("ReadFile %s: %v", path, err)
}
if string(data) != want {
t.Fatalf("unexpected file contents for %s: got %q want %q", path, string(data), want)
}
}