fix: resolve frontend and cross-platform CI failures

Цей коміт міститься в:
l0ng-ai committed 2026-10-29 14:45:42 +08:00
1 джерело 4d503ef976
коміт 364bb5ef50
6 files changed
+54 -27

No files matched your search

+1
Переглянути файл
@@ -158,6 +158,7 @@ pub fn path_with_shims(managers: &[Manager], path: &OsStr) -> OsString {
mod tests {
use super::*;
#[cfg(unix)]
fn mkdir(p: &Path) {
std::fs::create_dir_all(p).unwrap();
}
+7 -1
Переглянути файл
@@ -109,7 +109,13 @@ fn server_environment_from_login_shell_and_devcontainer() {
let started = project.join("started.txt");
wait_for("postStartCommand", || std::fs::read_to_string(&started).is_ok_and(|s| s.ends_with('\n')));
assert_eq!(std::fs::read_to_string(&started).unwrap(), "two-demo\n");
wait_for("the task to end", || events.0.lock().iter().any(|e| matches!(e, IdeEvent::Task { done: true, .. })));
wait_for("postStartCommand to end", || {
events
.0
.lock()
.iter()
.any(|e| matches!(e, IdeEvent::Task { title, done: true, .. } if title == "postStartCommand"))
});
assert!(events.0.lock().iter().any(
|e| matches!(e, IdeEvent::Task { message: Some(m), title, .. } if m == "post-start-output" && title == "postStartCommand")
));
+14 -17
Переглянути файл
@@ -86,7 +86,6 @@ export function useStashTabCounts(available: boolean) {
void Promise.all(roots.map((r) => call(commands.vcsStashes(r))))
.then((lists) => live && setStashCount(lists.reduce((n, list) => n + list.length, 0)))
.catch(() => undefined);
else setStashCount(0);
return () => {
live = false;
};
@@ -95,7 +94,7 @@ export function useStashTabCounts(available: boolean) {
useEffect(() => {
if (available) void loadShelves().catch(() => undefined);
}, [available]);
return { stashCount, shelfCount };
return { stashCount: available ? stashCount : 0, shelfCount };
}
/** "Commit" / "Shelf" / "Stash" content tabs; they stand in for the tool window title. */
@@ -842,36 +841,34 @@ export function StashesPanel() {
const repo = useVcs((s) => s.repo);
const repos = useVcs((s) => s.roots);
const version = useVcs((s) => s.version);
const [stashes, setStashes] = useState<(import("@/bindings").Stash & { repo: string | null })[]>([]);
const [loaded, setLoaded] = useState(false);
const [error, setError] = useState<string | null>(null);
const [tick, setTick] = useState(0);
const [active, setActive] = useState(0);
const request = useMemo(() => ({ repos, repo, version, tick }), [repos, repo, version, tick]);
const [result, setResult] = useState<{
request: typeof request;
stashes: (import("@/bindings").Stash & { repo: string | null })[];
error: string | null;
} | null>(null);
const loaded = result?.request === request;
const stashes = loaded ? result.stashes : [];
const error = loaded ? result.error : null;
useEffect(() => {
let live = true;
setLoaded(false);
void Promise.all(
(repos.length ? repos : [repo]).map(async (root) =>
(request.repos.length ? request.repos : [request.repo]).map(async (root) =>
(await call(commands.vcsStashes(root))).map((s) => ({ ...s, repo: root })),
),
)
.then((lists) => {
if (live) {
setStashes(lists.flat());
setError(null);
setLoaded(true);
}
if (live) setResult({ request, stashes: lists.flat(), error: null });
})
.catch((e) => {
if (live) {
setError(String(e));
setLoaded(true);
}
if (live) setResult({ request, stashes: [], error: String(e) });
});
return () => {
live = false;
};
}, [repos, repo, version, tick]);
}, [request]);
const current = stashes[active];
return (
<div className={styles.changes}>
+29 -6
Переглянути файл
@@ -1,17 +1,13 @@
import { beforeEach, expect, it, vi } from "vitest";
import { act, fireEvent, render, screen } from "@testing-library/react";
const apply = vi.hoisted(() => vi.fn());
const { apply, list } = vi.hoisted(() => ({ apply: vi.fn(), list: vi.fn() }));
vi.mock("@/platform/ipc", async (original) => {
const real = await original<typeof import("@/platform/ipc")>();
return {
...real,
commands: {
...real.commands,
vcsStashes: (repo: string) =>
Promise.resolve({
status: "ok",
data: [{ index: 0, message: `On main: ${repo.endsWith("front") ? "First" : "Second"}`, timeMs: 0 }],
}),
vcsStashes: list,
},
};
});
@@ -24,6 +20,12 @@ import { useVcs } from "../store";
beforeEach(() => {
apply.mockReset();
list.mockReset().mockImplementation((repo: string) =>
Promise.resolve({
status: "ok",
data: [{ index: 0, message: `On main: ${repo.endsWith("front") ? "First" : "Second"}`, timeMs: 0 }],
}),
);
useVcs.setState({ root: "/p", roots: ["/p/front", "/p/back"], repo: "/p/front" });
});
@@ -36,3 +38,24 @@ it("lists stashes from every root and applies the selected row in its own reposi
fireEvent.click(screen.getByRole("button", { name: "Apply Stash" }));
expect(apply).toHaveBeenCalledWith(0, false, "/p/front");
});
it("disables stale stash actions while another repository is loading", async () => {
render(<StashesPanel />);
await screen.findByText("front · First");
let resolve!: (value: unknown) => void;
list.mockImplementation(
() =>
new Promise((done) => {
resolve = done;
}),
);
act(() => useVcs.setState({ root: "/other", roots: ["/other"], repo: "/other" }));
expect(screen.queryByText("front · First")).not.toBeInTheDocument();
expect(screen.getByRole("button", { name: "Apply Stash" })).toBeDisabled();
await act(async () => {
resolve({ status: "ok", data: [{ index: 0, message: "On main: New project", timeMs: 0 }] });
});
await screen.findByText("New project");
fireEvent.click(screen.getByRole("button", { name: "Apply Stash" }));
expect(apply).toHaveBeenCalledWith(0, false, "/other");
});
-3
Переглянути файл
@@ -585,8 +585,6 @@
"Duplicate groups": "重复组",
"Duplicates": "重复项",
"Duplicate…": "复制…",
"Eclipse": "Eclipse",
"Eclipse (macOS)": "Eclipse (macOS)",
"Edit": "编辑",
"Edit Cell": "编辑单元格",
"Edit Changelist": "编辑更改列表",
@@ -2849,7 +2847,6 @@
"Test classpath of the module": "模块的测试类路径",
"Run a Java main class": "运行 Java 主类",
"Run a Spring Boot application": "运行 Spring Boot 应用程序",
"Spring Boot": "Spring Boot",
"Passed to the JVM that spring-boot:run or the tests start, not to Maven": "传给 spring-boot:run 或测试启动的 JVM,而不是 Maven 本身",
"Passed to the JVMs the tasks start (bootRun, run, test), not to Gradle": "传给任务启动的 JVM(bootRun、run、test),而不是 Gradle 本身",
"Run a package.json script": "运行 package.json 脚本",
+3
Переглянути файл
@@ -102,6 +102,8 @@ const UNTRANSLATED = new Set<string>([
"Docker",
"Docker Compose",
"Dockerfile",
"Eclipse",
"Eclipse (macOS)",
"Eclipse Temurin",
"EditorConfig",
"Git",
@@ -123,6 +125,7 @@ const UNTRANSLATED = new Set<string>([
"Node.js",
"npm",
"OpenIDEA",
"Spring Boot",
"PostgreSQL",
"Pyright",
"Rust",