дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 03:05:40 +02:00
Indexed markers (Edges.markers) were always drawn with the navigation glyph, so a plugin couldn't tell its marker kinds apart. A [[contributes.markerIcons]] entry can now claim them by key prefix (`markers`), with an optional `tooltip` shown above the targets. The host matches the longest prefix and sends the declaration id with each marker; the editor resolves the icon and the translated tooltip from the projected declaration. Manifest only, under the existing API 1.3 gate of markerIcons. Closes #2194
54 рядки
2.1 KiB
TypeScript
54 рядки
2.1 KiB
TypeScript
import { afterEach, expect, it, vi } from "vitest";
|
|
import { watchPluginMarkers, usePluginMarkers, invalidatePluginMarkers } from "./markerStore";
|
|
import { invalidateNavigationProviders } from "@/editor/navigationProviders";
|
|
const mock = vi.hoisted(() => vi.fn());
|
|
vi.mock("@/platform/ipc", async (original) => ({
|
|
...(await original<typeof import("@/platform/ipc")>()),
|
|
isTauri: () => true,
|
|
commands: { pluginNavigationMarkers: mock },
|
|
}));
|
|
const off: (() => void)[] = [];
|
|
afterEach(() => {
|
|
off.splice(0).forEach((f) => f());
|
|
vi.useRealTimers();
|
|
mock.mockReset();
|
|
});
|
|
it("batches visible paths, shares watchers and does no polling while idle", async () => {
|
|
vi.useFakeTimers();
|
|
mock.mockResolvedValue({ status: "ok", data: [] });
|
|
for (let i = 0; i < 130; i++) off.push(watchPluginMarkers(`/p/${i}.java`));
|
|
off.push(watchPluginMarkers("/p/0.java"));
|
|
await vi.advanceTimersByTimeAsync(250);
|
|
expect(mock.mock.calls.map((a) => a[0].length)).toEqual([64, 64, 2]);
|
|
await vi.advanceTimersByTimeAsync(5000);
|
|
expect(mock).toHaveBeenCalledTimes(3);
|
|
});
|
|
it("discards in-flight results after the project/provider epoch changes", async () => {
|
|
vi.useFakeTimers();
|
|
let finish!: (r: unknown) => void;
|
|
mock.mockImplementationOnce(() => new Promise((r) => (finish = r))).mockResolvedValue({ status: "ok", data: [] });
|
|
off.push(watchPluginMarkers("/old/A.xml"));
|
|
await vi.advanceTimersByTimeAsync(250);
|
|
invalidateNavigationProviders();
|
|
finish({ status: "ok", data: [{ path: "/old/A.xml", version: 1, markers: [] }] });
|
|
await vi.advanceTimersByTimeAsync(250);
|
|
expect(usePluginMarkers.getState().entries.size).toBe(0);
|
|
});
|
|
it("invalidates both changed files and markers targeting them", () => {
|
|
const range = { start: { line: 0, col: 0 }, end: { line: 0, col: 1 } };
|
|
usePluginMarkers.setState({
|
|
entries: new Map([
|
|
[
|
|
"/p/A.xml",
|
|
{
|
|
path: "/p/A.xml",
|
|
version: 1,
|
|
markers: [{ range, targets: [{ path: "/p/A.java", range }], pluginId: "p", icon: null }],
|
|
},
|
|
],
|
|
]),
|
|
});
|
|
invalidatePluginMarkers(["/p/A.java"]);
|
|
expect(usePluginMarkers.getState().entries.size).toBe(0);
|
|
});
|