-
Notifications
You must be signed in to change notification settings - Fork 121
Expand file tree
/
Copy pathruntimeHelpers.test.ts
More file actions
181 lines (161 loc) · 5.88 KB
/
Copy pathruntimeHelpers.test.ts
File metadata and controls
181 lines (161 loc) · 5.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
import { describe, expect, it } from "bun:test";
import type { RuntimeConfig } from "@/common/types/runtime";
import { DevcontainerRuntime } from "./DevcontainerRuntime";
import {
createRuntimeContextForWorkspace,
createRuntimeForWorkspace,
resolveWorkspaceExecutionPath,
} from "./runtimeHelpers";
describe("createRuntimeForWorkspace", () => {
it("forwards the persisted workspace path to devcontainer runtimes", () => {
const runtime = createRuntimeForWorkspace({
runtimeConfig: {
type: "devcontainer",
configPath: ".devcontainer/devcontainer.json",
},
projectPath: "/projects/demo",
name: "review-1",
namedWorkspacePath: "/tmp/non-canonical/workspaces/review-1",
});
expect(runtime).toBeInstanceOf(DevcontainerRuntime);
const internal = runtime as unknown as { currentWorkspacePath?: string };
expect(internal.currentWorkspacePath).toBe("/tmp/non-canonical/workspaces/review-1");
});
it("seeds ssh runtimes from the persisted workspace root", () => {
const metadata = {
runtimeConfig: {
type: "ssh",
host: "example.com",
srcBaseDir: "/remote/src",
} satisfies RuntimeConfig,
projectPath: "/projects/demo",
name: "review-1",
namedWorkspacePath: "/remote/src/demo/review-1",
};
const runtime = createRuntimeForWorkspace(metadata);
expect(runtime.getWorkspacePath(metadata.projectPath, "review-2")).toMatch(
/^\/remote\/src\/demo-[a-f0-9]{12}\/review-2$/
);
});
});
describe("resolveWorkspaceExecutionPath", () => {
it("uses the persisted path for non-docker workspaces", () => {
const metadata = {
runtimeConfig: {
type: "worktree",
srcBaseDir: "/tmp/src",
} satisfies RuntimeConfig,
projectPath: "/projects/demo",
name: "review-1",
namedWorkspacePath: "/persisted/review-1",
};
const runtime = createRuntimeForWorkspace(metadata);
expect(resolveWorkspaceExecutionPath(metadata, runtime)).toBe("/persisted/review-1");
});
it("requires the persisted path for SSH workspaces", () => {
const metadata = {
runtimeConfig: {
type: "ssh",
host: "example.com",
srcBaseDir: "/remote/src",
} satisfies RuntimeConfig,
projectPath: "/projects/demo",
name: "review-1",
};
const runtime = createRuntimeForWorkspace(metadata);
expect(() => resolveWorkspaceExecutionPath(metadata, runtime)).toThrow(
/missing a persisted workspace path/
);
});
it("falls back to the runtime path for non-SSH workspaces when persisted metadata is unavailable", () => {
const metadata = {
runtimeConfig: {
type: "worktree",
srcBaseDir: "/tmp/src",
} satisfies RuntimeConfig,
projectPath: "/projects/demo",
name: "review-1",
};
const runtime = createRuntimeForWorkspace(metadata);
const runtimeWorkspacePath = runtime.getWorkspacePath(metadata.projectPath, metadata.name);
expect(resolveWorkspaceExecutionPath(metadata, runtime)).toBe(runtimeWorkspacePath);
});
it("uses the runtime path for docker workspaces", () => {
const metadata = {
runtimeConfig: {
type: "docker",
image: "node:20",
} satisfies RuntimeConfig,
projectPath: "/projects/demo",
name: "review-1",
namedWorkspacePath: "/host/review-1",
};
const runtime = createRuntimeForWorkspace(metadata);
expect(resolveWorkspaceExecutionPath(metadata, runtime)).toBe("/src");
});
it("returns the project root for in-place workspaces", () => {
const metadata = {
runtimeConfig: {
type: "worktree",
srcBaseDir: "/tmp/src",
} satisfies RuntimeConfig,
projectPath: "/projects/cli",
name: "/projects/cli",
};
const runtime = createRuntimeForWorkspace(metadata);
expect(resolveWorkspaceExecutionPath(metadata, runtime)).toBe("/projects/cli");
});
});
it("appends sub-project relative paths to the execution root", () => {
const metadata = {
runtimeConfig: {
type: "worktree",
srcBaseDir: "/tmp/src",
} satisfies RuntimeConfig,
projectPath: "/repo",
name: "feature",
namedWorkspacePath: "/mux/src/repo/feature",
subProjectPath: "/repo/packages/api",
};
const runtime = createRuntimeForWorkspace(metadata);
expect(resolveWorkspaceExecutionPath(metadata, runtime)).toBe(
"/mux/src/repo/feature/packages/api"
);
});
it("self-heals to the workspace root when sub-project metadata is no longer a descendant", () => {
// Persisted metadata can drift: the project may be removed/re-added at a new
// path, or the user may edit ~/.mux/config.json by hand. Rather than throwing
// (which would break workspace startup until manual recovery), we should drop
// the bad sub-project path and execute in the workspace root.
const metadata = {
runtimeConfig: {
type: "worktree",
srcBaseDir: "/tmp/src",
} satisfies RuntimeConfig,
projectPath: "/repo",
name: "feature",
namedWorkspacePath: "/mux/src/repo/feature",
subProjectPath: "/elsewhere/api",
};
const runtime = createRuntimeForWorkspace(metadata);
expect(resolveWorkspaceExecutionPath(metadata, runtime)).toBe("/mux/src/repo/feature");
});
describe("createRuntimeContextForWorkspace", () => {
it("returns a runtime together with the resolved execution path", () => {
const metadata = {
runtimeConfig: {
type: "ssh",
host: "example.com",
srcBaseDir: "/remote/src",
} satisfies RuntimeConfig,
projectPath: "/projects/demo",
name: "review-1",
namedWorkspacePath: "/remote/src/demo/review-1",
};
const context = createRuntimeContextForWorkspace(metadata);
expect(context.workspacePath).toBe("/remote/src/demo/review-1");
expect(context.runtime.getWorkspacePath(metadata.projectPath, "review-2")).toMatch(
/^\/remote\/src\/demo-[a-f0-9]{12}\/review-2$/
);
});
});