Ctrl K
ComunidadGuías…

scripts/verify-engines-ui.test.mjs

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

Archivo original ↗Preguntar a KiBot
import { afterEach, beforeEach, expect, it, vi } from "vitest";

const fixture = vi.hoisted(() => ({
  launch: vi.fn(), createServer: vi.fn(), close: vi.fn(),
  listen: vi.fn(), closeUi: vi.fn(), closeHttp: vi.fn(), closeConnections: vi.fn(), signals: new Map(),
}));
vi.mock("./control-omb.ts", () => ({ launchVerificationServer: fixture.launch }));
vi.mock("vite", () => ({ createServer: fixture.createServer }));
vi.mock("node:http", () => ({ createServer: () => ({
  on: vi.fn(), once: vi.fn(), removeListener: vi.fn(), listen: fixture.listen,
  close: fixture.closeHttp, closeAllConnections: fixture.closeConnections, address: () => ({ port: 2 }),
}) }));

beforeEach(() => {
  vi.resetModules();
  vi.resetAllMocks();
  fixture.signals.clear();
  const once = process.once;
  vi.spyOn(process, "once").mockImplementation(function (event, listener) {
    if (event === "SIGINT" || event === "SIGTERM") {
      fixture.signals.set(event, listener);
      return this;
    }
    return once.call(this, event, listener);
  });
  vi.spyOn(process, "removeListener");
  vi.spyOn(console, "log").mockImplementation(() => {});
  fixture.launch.mockResolvedValue({
    info: { dataDir: "/fixture-only", url: "http://127.0.0.1:1" }, close: fixture.close,
  });
  fixture.createServer.mockResolvedValue({
    middlewares: vi.fn(), close: fixture.closeUi,
  });
  fixture.listen.mockImplementation((_port, _host, ready) => ready());
  fixture.closeHttp.mockImplementation(closed => closed());
});
afterEach(() => vi.restoreAllMocks());

function expectSignalsRemoved() {
  for (const [event, handler] of fixture.signals) {
    expect(process.removeListener).toHaveBeenCalledWith(event, handler);
  }
}

it("registers cancellation before launch and removes handlers if startup aborts", async () => {
  fixture.launch.mockImplementation(async (env, signal) => {
    expect(env).toBe(process.env);
    expect([...fixture.signals.keys()]).toEqual(["SIGINT", "SIGTERM"]);
    fixture.signals.get("SIGINT")();
    expect(signal.aborted).toBe(true);
    throw new Error("verification launch cancelled");
  });
  await expect(import("./verify-engines-ui.ts")).rejects.toThrow("verification launch cancelled");
  expect(fixture.createServer).not.toHaveBeenCalled();
  expectSignalsRemoved();
});

it("closes the isolated fixture when UI creation fails", async () => {
  fixture.createServer.mockRejectedValue(new Error("UI startup failed"));
  await expect(import("./verify-engines-ui.ts")).rejects.toThrow("UI startup failed");
  expect(fixture.close).toHaveBeenCalledOnce();
  expectSignalsRemoved();
});

it("uses the same cancellation signal after startup", async () => {
  const run = import("./verify-engines-ui.ts");
  await vi.waitFor(() => expect(fixture.listen).toHaveBeenCalledOnce());
  fixture.signals.get("SIGTERM")();
  await run;
  expect(fixture.launch.mock.calls[0][1].aborted).toBe(true);
  expect(fixture.closeUi).toHaveBeenCalledOnce();
  expect(fixture.closeHttp).toHaveBeenCalledOnce();
  expect(fixture.closeConnections).toHaveBeenCalledOnce();
  expect(fixture.close).toHaveBeenCalledOnce();
  expectSignalsRemoved();
});

it("stops the app and deletes fixture data before waiting on Vite shutdown", async () => {
  let releaseHttp;
  let releaseFixture;
  let releaseUi;
  fixture.closeHttp.mockImplementationOnce(closed => { releaseHttp = closed; });
  fixture.close.mockImplementationOnce(() => new Promise(resolve => { releaseFixture = resolve; }));
  fixture.closeUi.mockImplementationOnce(() => new Promise(resolve => { releaseUi = resolve; }));
  const run = import("./verify-engines-ui.ts");
  await vi.waitFor(() => expect(fixture.listen).toHaveBeenCalledOnce());
  const server = fixture.createServer.mock.calls[0][0].server;
  expect(server.middlewareMode.server).toBe(server.hmr.server);
  fixture.signals.get("SIGTERM")();
  await vi.waitFor(() => expect(fixture.close).toHaveBeenCalledOnce());
  expect(fixture.closeHttp).toHaveBeenCalledOnce();
  expect(fixture.closeUi).not.toHaveBeenCalled();
  releaseFixture();
  await vi.waitFor(() => expect(fixture.closeUi).toHaveBeenCalledOnce());
  releaseUi();
  releaseHttp();
  await run;
  expect(fixture.close).toHaveBeenCalledOnce();
});

it("does not miss cancellation during UI startup or skip fixture cleanup if UI close fails", async () => {
  fixture.listen.mockImplementation((_port, _host, ready) => { fixture.signals.get("SIGINT")(); ready(); });
  fixture.closeUi.mockRejectedValue(new Error("UI close failed"));
  await expect(import("./verify-engines-ui.ts")).rejects.toThrow("UI close failed");
  expect(fixture.close).toHaveBeenCalledOnce();
  expectSignalsRemoved();
});