testPatchTakesTemplateLiteralEscapesEitherWay
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.`")); }