testWatcherSeesChangesMadeElsewhere

tcmts.cli.test.e2e.watch.testWatcherSeesChangesMadeElsewhere · #rust62sk · term

The watcher re-checks incrementally and sees codebase changes made elsewhere.

import { plainEnv, strip, tcmBin, withChildren } from "#codebase/tcmts/cli/test/e2e/harness";
import { setUp, waitFor } from "#codebase/tcmts/cli/test/e2e/watch";
import assert from "node:assert/strict";
import { spawn } from "node:child_process";
import fs from "node:fs";
import path from "node:path";

export const testWatcherSeesChangesMadeElsewhere = () =>
  withChildren(async (keep) => {
    const { dir, tcm, scratch } = setUp();
    scratch("scratch.ts", `// tcm: namespace lib\nexport const greet = (name: string): string => "hi " + name;\n`);
    tcm("add");
    fs.rmSync(path.join(dir, "scratch.ts"));
    scratch("app.ts", `import { greet } from "#codebase/lib";\n\ngreet("ada");\n`);

    const child = keep(spawn(process.execPath, [tcmBin(), "watch"], { cwd: dir, env: plainEnv() }));
    let out = "";
    const plain = (d: string) => (out += strip(d));
    child.stdout.setEncoding("utf8").on("data", plain);
    child.stderr.setEncoding("utf8").on("data", plain);
    await waitFor(() => /⧩ 'hi ada'/.test(out));

    // a type error, then its fix, in quick succession
    out = "";
    scratch("app.ts", `import { greet } from "#codebase/lib";\n\ngreet(42);\n`);
    await waitFor(() => /Argument of type 'number' is not assignable/.test(out));
    out = "";
    scratch("app.ts", `import { greet } from "#codebase/lib";\n\ngreet("grace");\n`);
    await waitFor(() => /⧩ 'hi grace'/.test(out));

    // another process updates greet (its cache module and the shim change on disk): the watcher sees the new code
    scratch("lib.ts", `// tcm: namespace lib\nexport const greet = (name: string, loud = false): string => (loud ? "HI " : "hi ") + name;\n`);
    tcm("update", "lib.ts");
    fs.rmSync(path.join(dir, "lib.ts"));
    await new Promise((r) => setTimeout(r, 300)); // let the watcher settle on lib.ts's own change and removal
    out = "";
    scratch("app.ts", `import { greet } from "#codebase/lib";\n\ngreet("linus", true);\n`);
    await waitFor(() => /⧩ 'HI linus'/.test(out));
    assert.doesNotMatch(out, /Expected 1 arguments/);
  })

uses