Ctrl K
ComunidadGuías…

electron/cua-hyprland.test.mjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import { describe, expect, it, vi } from "vitest";
import { createRequire } from "node:module";

const require = createRequire(import.meta.url);
const {
  HYPRCTL,
  PACMAN,
  PLUGIN_REQUIRED_MESSAGE,
  isHyprlandSession,
  parseCuaPluginStatus,
  probeCuaHyprlandPlugin,
  runBounded,
  systemDriverPackageVersion,
} = require("./cua-hyprland.cjs");

const HYPRLAND = {
  XDG_SESSION_TYPE: "wayland",
  WAYLAND_DISPLAY: "wayland-1",
  XDG_CURRENT_DESKTOP: "Hyprland",
  HYPRLAND_INSTANCE_SIGNATURE: "6f2a0c1e_1762560000_123456789",
};

/** `hyprctl -j cua:status` from an input build with input enabled (libs/cua-driver/hyprland-plugin/src/plugin.cpp). */
function activeStatus(overrides = {}) {
  return {
    name: "cua-hyprland-plugin",
    plugin_version: "0.41.3",
    state: "input_v3_candidate",
    protocol: { major: 1, minor: 0, max_frame_bytes: 65536 },
    compositor_epoch: 1,
    abi: { compiled_hash: "abc", runtime_hash: "abc", match: true },
    configured: true,
    transport: { ready: true, socket: "/run/user/1000/hypr/x/.cua.sock", mode: "0600", peer_policy: "same_uid", last_error: "" },
    capabilities: { supported: ["discovery"], enabled: ["discovery"], mutation: "trusted_local_per_action" },
    input: { protocol: 3, test_only: false, transport_ready: true, lanes: [] },
    ...overrides,
  };
}

describe("isHyprlandSession", () => {
  it("needs Hyprland's instance signature and a desktop named Hyprland", () => {
    expect(isHyprlandSession(HYPRLAND)).toBe(true);
    expect(isHyprlandSession({ ...HYPRLAND, XDG_CURRENT_DESKTOP: "", XDG_SESSION_DESKTOP: "hyprland" })).toBe(true);
    expect(isHyprlandSession({ ...HYPRLAND, XDG_CURRENT_DESKTOP: "ubuntu:GNOME" })).toBe(false);
    expect(isHyprlandSession({ ...HYPRLAND, XDG_CURRENT_DESKTOP: "sway" })).toBe(false);
    expect(isHyprlandSession({ ...HYPRLAND, HYPRLAND_INSTANCE_SIGNATURE: "" })).toBe(false);
    expect(isHyprlandSession({ ...HYPRLAND, HYPRLAND_INSTANCE_SIGNATURE: "../../evil" })).toBe(false);
    expect(isHyprlandSession({})).toBe(false);
  });
});

describe("parseCuaPluginStatus", () => {
  it("is active only for a configured input build with a ready transport and matching ABI", () => {
    expect(parseCuaPluginStatus(JSON.stringify(activeStatus()))).toBe("active");
    for (const status of [
      activeStatus({ state: "discovery_only" }),
      activeStatus({ state: "input_experiment" }),
      activeStatus({ configured: false }),
      activeStatus({ abi: { compiled_hash: "a", runtime_hash: "b", match: false } }),
      activeStatus({ transport: { ready: false } }),
      activeStatus({ input: { protocol: 3, test_only: false, transport_ready: false } }),
      activeStatus({ input: { protocol: 3, test_only: true, transport_ready: true } }),
      activeStatus({ input: { protocol: 2, test_only: false, transport_ready: true } }),
      activeStatus({ input: undefined }),
      activeStatus({ name: "some-other-plugin" }),
    ]) {
      expect(parseCuaPluginStatus(JSON.stringify(status)), JSON.stringify(status)).toBe("inactive");
    }
  });

  it("treats hyprctl's text for an unknown request and malformed output as inactive", () => {
    for (const output of ["unknown request", "", "null", "[]", "{", '"active"', undefined]) {
      expect(parseCuaPluginStatus(output)).toBe("inactive");
    }
  });
});

describe("probeCuaHyprlandPlugin", () => {
  it("asks the system hyprctl, never one from PATH, with the session's instance signature", async () => {
    const run = vi.fn(async () => ({ exitCode: 0, stdout: JSON.stringify(activeStatus()) }));
    await expect(probeCuaHyprlandPlugin({ env: { ...HYPRLAND, PATH: "/tmp/evil" }, run, exists: () => true })).resolves.toBe("active");
    expect(run).toHaveBeenCalledOnce();
    const [command, args, options] = run.mock.calls[0];
    expect(command).toBe(HYPRCTL);
    expect(args).toEqual(["-j", "cua:status"]);
    expect(options.env.HYPRLAND_INSTANCE_SIGNATURE).toBe(HYPRLAND.HYPRLAND_INSTANCE_SIGNATURE);
    expect(options.env.LC_ALL).toBe("C");
  });

  it("does not run anything outside a Hyprland session or without the system hyprctl", async () => {
    const run = vi.fn();
    await expect(probeCuaHyprlandPlugin({ env: { XDG_SESSION_TYPE: "wayland", XDG_CURRENT_DESKTOP: "GNOME" }, run, exists: () => true })).resolves.toBe("inactive");
    await expect(probeCuaHyprlandPlugin({ env: HYPRLAND, run, exists: () => false })).resolves.toBe("inactive");
    expect(run).not.toHaveBeenCalled();
  });

  it("is inactive when hyprctl fails or times out", async () => {
    await expect(probeCuaHyprlandPlugin({ env: HYPRLAND, run: async () => ({ exitCode: 1, stdout: JSON.stringify(activeStatus()) }), exists: () => true })).resolves.toBe("inactive");
    await expect(probeCuaHyprlandPlugin({ env: HYPRLAND, run: async () => ({ exitCode: null, stdout: "" }), exists: () => true })).resolves.toBe("inactive");
  });
});

describe("systemDriverPackageVersion", () => {
  const owned = (stdout, exitCode = 0) => vi.fn(async () => ({ exitCode, stdout }));

  it("returns the version only when cua-driver-bin owns exactly that file", async () => {
    const run = owned("/usr/bin/cua-driver is owned by cua-driver-bin 0.41.3-1\n");
    await expect(systemDriverPackageVersion("/usr/bin/cua-driver", { run, exists: () => true })).resolves.toBe("0.41.3-1");
    const [command, args, options] = run.mock.calls[0];
    expect(command).toBe(PACMAN);
    expect(args).toEqual(["-Qo", "/usr/bin/cua-driver"]);
    expect(options.env).toEqual({ PATH: "/usr/bin:/bin", LANG: "C", LC_ALL: "C" });
  });

  it("refuses another owner, another file, a failed query or a relative path", async () => {
    const exists = () => true;
    await expect(systemDriverPackageVersion("/usr/bin/cua-driver", { run: owned("/usr/bin/cua-driver is owned by cua-driver-git 9.9.9-1"), exists })).resolves.toBeNull();
    await expect(systemDriverPackageVersion("/usr/bin/cua-driver", { run: owned("/usr/bin/cua-driverx is owned by cua-driver-bin 0.41.3-1"), exists })).resolves.toBeNull();
    await expect(systemDriverPackageVersion("/usr/bin/cua-driver", { run: owned("error: No package owns /usr/bin/cua-driver", 1), exists })).resolves.toBeNull();
    await expect(systemDriverPackageVersion("/usr/bin/cua-driver", { run: owned("/usr/bin/cua-driver is owned by cua-driver-bin 0.41.3-1\nextra"), exists })).resolves.toBeNull();
    const never = vi.fn();
    await expect(systemDriverPackageVersion("usr/bin/cua-driver", { run: never, exists })).resolves.toBeNull();
    await expect(systemDriverPackageVersion("/usr/bin/cua-driver", { run: never, exists: () => false })).resolves.toBeNull();
    expect(never).not.toHaveBeenCalled();
  });
});

describe("runBounded", () => {
  it("kills a command that runs past its deadline", async () => {
    const started = Date.now();
    await expect(runBounded(process.execPath, ["-e", "setTimeout(() => {}, 10_000)"], { timeoutMs: 200 })).resolves.toEqual({ exitCode: null, stdout: "" });
    expect(Date.now() - started).toBeLessThan(5_000);
  });

  it("returns a quick command's output", async () => {
    await expect(runBounded(process.execPath, ["-e", "process.stdout.write('ok')"])).resolves.toEqual({ exitCode: 0, stdout: "ok" });
  });
});

it("tells the person how to turn the plugin on in one sentence with Cua's guide", () => {
  expect(PLUGIN_REQUIRED_MESSAGE).toMatch(/cua-hyprland-plugin/);
  expect(PLUGIN_REQUIRED_MESSAGE).toMatch(/https:\/\/cua\.ai\/docs\/cua-sdk\/guides\/omarchy/);
  expect(PLUGIN_REQUIRED_MESSAGE.split(/\.\s/).length).toBe(1);
});