дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
feat(vcs): tint test files green in the changes tree (#940)
The changes tree in the Commit and Local Changes views now gives test files a light green background, so test changes stand out from production ones. A file counts as a test when it lies under a test source root (detected or marked by hand) or is named like a test (`*.test.ts`, `*Test.java`, …), the same check the project tree uses; folders under a test root get the tint too. Hover and selection still win. The colour is a new `--bg-file-tests` token derived from `--success` and `--bg-island`, so every theme gets a matching tint, and it follows test roots as they are marked or unmarked. Fixes #931. Co-authored-by: jaw52 <[email protected]>
Цей коміт міститься в:
4 files changed
+76
No files matched your search
@@ -218,6 +218,10 @@
|
||||
gap: 4px;
|
||||
border-radius: var(--radius-small);
|
||||
}
|
||||
/* Test files and the folders under a test root, as IDEA's green "Tests" file colour; hover and selection win. */
|
||||
.testFile:not(:hover):not([aria-selected="true"]) {
|
||||
background: var(--bg-file-tests);
|
||||
}
|
||||
.dropTarget {
|
||||
box-shadow: inset 0 0 0 1px var(--accent);
|
||||
background: color-mix(in srgb, var(--accent) 12%, transparent);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { tx } from "@/platform/i18n";
|
||||
import clsx from "clsx";
|
||||
import { executeAction } from "@/platform/actions";
|
||||
import { dirname } from "@/platform/project";
|
||||
import { isTestFile, useEffectiveRoots } from "@/platform/projectRoots";
|
||||
import {
|
||||
Button,
|
||||
Checkbox,
|
||||
@@ -398,6 +399,7 @@ export function ChangesTree({ mode }: { mode: "commit" | "local" | "dialog" }) {
|
||||
const viewRef = useRef<HTMLButtonElement>(null);
|
||||
|
||||
const repos = useVcs((s) => s.roots);
|
||||
const projectRoots = useEffectiveRoots();
|
||||
const roots = useMemo(
|
||||
() => buildChangeTree(status, root, groupByDir, lists, repos),
|
||||
[status, root, groupByDir, lists, repos],
|
||||
@@ -524,6 +526,9 @@ export function ChangesTree({ mode }: { mode: "commit" | "local" | "dialog" }) {
|
||||
getLabel={nodeText}
|
||||
getDirectory={(n) => (n.path && n.type !== "group" ? (n.type === "dir" ? n.path : dirname(n.path)) : null)}
|
||||
getChildren={(n) => n.children}
|
||||
rowClassName={(n) =>
|
||||
n.type !== "group" && n.path && isTestFile(n.path, projectRoots) ? styles.testFile : undefined
|
||||
}
|
||||
isExpandable={(n) => n.type !== "file"}
|
||||
expanded={expanded}
|
||||
onExpandedChange={(_next, node, open) =>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
import { act, render, screen } from "@testing-library/react";
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
vi.mock("@/platform/ipc", async (importOriginal) => {
|
||||
const real = await importOriginal<typeof import("@/platform/ipc")>();
|
||||
return { ...real, call: vi.fn() };
|
||||
});
|
||||
|
||||
vi.mock("../DiffEditor", () => ({ DiffEditor: () => <div /> }));
|
||||
|
||||
import { ChangesTree } from "../CommitView";
|
||||
import { useVcs } from "../store";
|
||||
import { useProject } from "@/platform/project";
|
||||
import { useProjectRoots } from "@/platform/projectRoots";
|
||||
|
||||
const change = (relPath: string) => ({
|
||||
path: `/p/${relPath}`,
|
||||
relPath,
|
||||
staged: null,
|
||||
unstaged: "modified" as const,
|
||||
renamedFrom: null,
|
||||
});
|
||||
|
||||
/** The tree row (`role=treeitem`) showing `name`. */
|
||||
const row = (name: string) => screen.getByText(name).closest('[role="treeitem"]') as HTMLElement;
|
||||
|
||||
describe("test files in the changes tree (#931)", () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
useProject.setState({
|
||||
project: { name: "p", root: "/p", trusted: true, isGit: true, settings: {} } as never,
|
||||
settings: {} as never,
|
||||
});
|
||||
useProjectRoots.setState({
|
||||
root: "/p",
|
||||
detected: [{ path: "src/test/java", kind: "test", detectedFrom: "pom.xml" }],
|
||||
});
|
||||
useVcs.setState({
|
||||
root: "/p",
|
||||
repo: "/p",
|
||||
roots: ["/p"],
|
||||
status: [
|
||||
change("src/main/java/App.java"),
|
||||
change("src/test/java/AppTest.java"),
|
||||
change("web/button.test.ts"),
|
||||
change("web/button.ts"),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
it("tints files under a test root or named like a test, as IDEA's Tests scope does", () => {
|
||||
render(<ChangesTree mode="local" />);
|
||||
expect(row("AppTest.java").className).toMatch(/testFile/);
|
||||
expect(row("button.test.ts").className).toMatch(/testFile/);
|
||||
expect(row("App.java").className).not.toMatch(/testFile/);
|
||||
expect(row("button.ts").className).not.toMatch(/testFile/);
|
||||
});
|
||||
|
||||
it("follows a folder being marked as test sources", () => {
|
||||
render(<ChangesTree mode="local" />);
|
||||
expect(row("App.java").className).not.toMatch(/testFile/);
|
||||
act(() => useProjectRoots.setState({ detected: [{ path: "src/main/java", kind: "test", detectedFrom: null }] }));
|
||||
expect(row("App.java").className).toMatch(/testFile/);
|
||||
});
|
||||
});
|
||||
@@ -314,6 +314,8 @@ html {
|
||||
--bg-tree-selected: #2a4371;
|
||||
--bg-tree-selected-inactive: #33353b;
|
||||
--bg-tree-hover: #ffffff10;
|
||||
/* IDEA's "Tests" file colour (FileColor.Green), derived so every theme gets a matching tint. */
|
||||
--bg-file-tests: color-mix(in srgb, var(--success) 14%, var(--bg-island));
|
||||
--bg-list-selected: var(--bg-tree-selected);
|
||||
--bg-toolbar-hover: #ffffff17;
|
||||
--bg-toolbar-pressed: #ffffff29;
|
||||
|
||||
Reference in new issue
Заблокувати користувача