mirror of
https://github.com/l0ng-ai/openidea.git
synced 2026-11-08 08:52:12 +00:00
168 lines
6.1 KiB
TypeScript
168 lines
6.1 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { RunConfig } from "@/platform/ipc";
|
|
|
|
const invoked: Array<[string, unknown[]]> = [];
|
|
let shortenCommandLine: string | null = null;
|
|
let kotlinFiles = false;
|
|
vi.mock("@/platform/ipc", async (orig) => {
|
|
const real = await orig<typeof import("@/platform/ipc")>();
|
|
const ok = (data: unknown) => Promise.resolve({ status: "ok", data });
|
|
return {
|
|
...real,
|
|
commands: {
|
|
...real.commands,
|
|
findFiles: (name: string) =>
|
|
ok(
|
|
name === "Main.java"
|
|
? [{ path: "/p/api/src/main/java/a/Main.java", relPath: "api/src/main/java/a/Main.java" }]
|
|
: [],
|
|
),
|
|
fsReadText: () => ok("package a;\npublic class Main {}"),
|
|
runConfigs: () => ok([]),
|
|
fsReadDir: (path: string) =>
|
|
ok(
|
|
kotlinFiles && path.endsWith("/src")
|
|
? [{ name: "Main.kt", path: `${path}/Main.kt`, kind: "file", excluded: false }]
|
|
: [],
|
|
),
|
|
javaResolveLaunch: (...a: unknown[]) => {
|
|
invoked.push(["javaResolveLaunch", a]);
|
|
return ok({
|
|
build: "succeeded",
|
|
projectRoot: "/p",
|
|
classPaths: ["/p/target/classes", "/m2/a.jar"],
|
|
modulePaths: [],
|
|
pathListSeparator: ":",
|
|
javaHome: "/jdk21",
|
|
javaExec: "/jdk21/bin/java",
|
|
shortenCommandLine,
|
|
errors: [],
|
|
errorCount: 0,
|
|
hints: [],
|
|
});
|
|
},
|
|
javaDebugServer: (...a: unknown[]) => {
|
|
invoked.push(["javaDebugServer", a]);
|
|
return ok(41234);
|
|
},
|
|
},
|
|
};
|
|
});
|
|
|
|
const { isJavaDebuggable, javaAttachConfig, javaLaunchConfig } = await import("../java");
|
|
|
|
const app: RunConfig = {
|
|
id: "application:a.Main",
|
|
name: "Main",
|
|
kind: "spring-boot",
|
|
command: "java",
|
|
args: ["-Xmx1g", "-cp", "${classpath}", "a.Main", "--port", "8081 x"],
|
|
cwd: "api",
|
|
module: "api",
|
|
env: { A: "1" },
|
|
detected: true,
|
|
isTest: false,
|
|
debugAdapter: "java-debug",
|
|
};
|
|
|
|
describe("Java debugging (java-debug through jdtls)", () => {
|
|
beforeEach(() => {
|
|
invoked.length = 0;
|
|
shortenCommandLine = null;
|
|
kotlinFiles = false;
|
|
});
|
|
|
|
it("launches Application configs with the resolved classpath on jdtls' debug server", async () => {
|
|
expect(isJavaDebuggable(app)).toBe(true);
|
|
expect(isJavaDebuggable({ ...app, kind: "maven" })).toBe(false);
|
|
const l = await javaLaunchConfig(app, "/p");
|
|
expect(invoked).toEqual([
|
|
["javaResolveLaunch", ["api", false, true, expect.any(Number)]],
|
|
["javaDebugServer", ["api"]],
|
|
]);
|
|
expect(l).toMatchObject({ adapter: "java-debug", request: "launch", cwd: "/p/api", args: [], env: { A: "1" } });
|
|
expect(JSON.parse(l.extraJson!)).toMatchObject({
|
|
debugServer: 41234,
|
|
mainClass: "a.Main",
|
|
classPaths: ["/p/target/classes", "/m2/a.jar"],
|
|
javaExec: "/jdk21/bin/java",
|
|
vmArgs: "-Xmx1g",
|
|
args: '--port "8081 x"',
|
|
console: "internalConsole",
|
|
shortenCommandLine: "none",
|
|
});
|
|
});
|
|
|
|
it("passes the configuration's VM options to java-debug's vmArgs, before the main class", async () => {
|
|
const args = [
|
|
"-Ddemo.flag=on",
|
|
"--add-opens",
|
|
"java.base/java.lang=ALL-UNNAMED",
|
|
"-Dname=a b",
|
|
"-cp",
|
|
"${classpath}",
|
|
];
|
|
const l = await javaLaunchConfig({ ...app, args: [...args, "a.App", "--spring.profiles.active=dev"] }, "/p");
|
|
expect(JSON.parse(l.extraJson!)).toMatchObject({
|
|
mainClass: "a.App",
|
|
vmArgs: '-Ddemo.flag=on --add-opens java.base/java.lang=ALL-UNNAMED "-Dname=a b"',
|
|
args: "--spring.profiles.active=dev",
|
|
});
|
|
});
|
|
|
|
it("lets java-debug shorten a classpath too long for the OS, as Run does", async () => {
|
|
for (const how of ["jarmanifest", "argfile"]) {
|
|
shortenCommandLine = how;
|
|
const l = await javaLaunchConfig(app, "/p");
|
|
expect(JSON.parse(l.extraJson!).shortenCommandLine).toBe(how);
|
|
}
|
|
});
|
|
|
|
it("routes a Kotlin main to the Kotlin adapter and preserves JVM launch arguments", async () => {
|
|
const config = { ...app, debugAdapter: "kotlin-debug-adapter" };
|
|
expect(isJavaDebuggable(config)).toBe(true);
|
|
const l = await javaLaunchConfig(config, "/p");
|
|
expect(l).toMatchObject({ adapter: "kotlin-debug-adapter", request: "launch", cwd: "/p/api", env: { A: "1" } });
|
|
expect(JSON.parse(l.extraJson!)).toMatchObject({
|
|
projectRoot: "/p/api",
|
|
mainClass: "a.Main",
|
|
classPaths: ["/p/target/classes", "/m2/a.jar"],
|
|
javaExec: "/jdk21/bin/java",
|
|
vmArguments: ["-Xmx1g"],
|
|
programArgs: ["--port", "8081 x"],
|
|
});
|
|
expect(invoked.some(([command]) => command === "javaDebugServer")).toBe(false);
|
|
});
|
|
|
|
it("routes launch and JDWP attach in a mixed module to Kotlin without starting jdtls' adapter", async () => {
|
|
kotlinFiles = true;
|
|
expect((await javaLaunchConfig(app, "/p")).adapter).toBe("kotlin-debug-adapter");
|
|
const l = await javaAttachConfig({ name: "mvn test", module: "api", hostName: "remote", port: 5005 }, "/p");
|
|
expect(l.adapter).toBe("kotlin-debug-adapter");
|
|
expect(JSON.parse(l.extraJson!)).toEqual({
|
|
projectRoot: "/p/api",
|
|
hostName: "remote",
|
|
port: 5005,
|
|
timeout: 30_000,
|
|
});
|
|
expect(invoked.some(([command]) => command === "javaDebugServer")).toBe(false);
|
|
});
|
|
|
|
it("attaches to a JDWP agent", async () => {
|
|
const l = await javaAttachConfig({ name: "mvn test", module: "", hostName: "127.0.0.1", port: 5005 }, "/p");
|
|
expect(l).toMatchObject({ request: "attach", cwd: "/p" });
|
|
expect(JSON.parse(l.extraJson!)).toMatchObject({ debugServer: 41234, hostName: "127.0.0.1", port: 5005 });
|
|
});
|
|
});
|
|
|
|
it.each(["sibling", "/outside/modules"])("debugs from %s with the main class module", async (cwd) => {
|
|
kotlinFiles = false;
|
|
for (const module of ["api", undefined]) {
|
|
invoked.length = 0;
|
|
const launch = await javaLaunchConfig({ ...app, module, cwd }, "/p");
|
|
expect(invoked).toContainEqual(["javaResolveLaunch", ["api", false, true, expect.any(Number)]]);
|
|
expect(invoked).toContainEqual(["javaDebugServer", ["api"]]);
|
|
expect(launch.cwd).toBe(cwd.startsWith("/") ? cwd : `/p/${cwd}`);
|
|
}
|
|
});
|