testPatchTakesTemplateLiteralEscapesEitherWay

tcmts.cli.test.e2e.editing.testPatchTakesTemplateLiteralEscapesEitherWay · #r3iubcse · term

Inside a template literal, tcm patch takes an old with its escapes taken the other way (a line break for the source's \n, a bare backtick for its \`, as JSON makes easy to write) when that finds it once, writes new the same way, and says so; a new that would end or split the literal (a bare backtick or ${) changes nothing, and says which and how to escape it.

import { okIn, tcmIn, tempDir } from "#codebase/tcmts/cli/test/e2e/harness";
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";

export const testPatchTakesTemplateLiteralEscapesEitherWay = () => {
  const dir = tempDir("patch template literal");
  const ok = (...args: string[]) => okIn(dir, ...args);
  const fails = (...args: string[]) => {
    const r = tcmIn(dir, ...args);
    assert.notEqual(r.status, 0, r.out);
    return r.out;
  };
  ok("init");
  fs.writeFileSync(
    path.join(dir, "m.ts"),
    "// tcm: namespace m\nexport const GUIDE = `Line one.\\nUse \\`tcm view\\`.\\nA \\${name} here.`;\n",
  );
  ok("add", "m.ts");
  const applied = ok(
    "patch",
    "m.GUIDE",
    "--edits",
    JSON.stringify([{ old: "Line one.\nUse `tcm view`", new: "First line.\nUse `tcm view`" }]),
  );
  assert.match(applied, /found only with escapes as the source writes them/);
  assert.match(applied, /\\n as the source has it, the two characters backslash and n/);
  assert.ok(
    ok("view", "m.GUIDE").includes("`First line.\\nUse \\`tcm view\\`.\\nA \\${name} here.`"),
  );
  assert.match(
    fails("patch", "m.GUIDE", "--old", "here.", "--new", "`here`."),
    /new has a bare backtick inside the template literal at line 1, which would end the literal there: escape it as \\`/,
  );
  assert.match(
    fails("patch", "m.GUIDE", "--old", "here.", "--new", "${here."),
    /new has a bare \$\{ inside the template literal at line 1/,
  );
  assert.ok(ok("view", "m.GUIDE").includes("here.`"));
}

uses