testTextVersionsAreBranchScoped

tcmts.store.test.history.testTextVersionsAreBranchScoped · #7p4dcjto · term

Changing only how a definition reads (its comments, layout, doc) is a change of the branch that makes it: the other branches read it as before, it's an entry in the branch's history, and going back to an entry before it brings back the text as it was. Text a definition was first stored with is no version of its own.

import { textHash } from "#codebase/tcmts/store";
import { a, b, open, stored } from "#codebase/tcmts/store/test/history";
import assert from "node:assert/strict";

export const testTextVersionsAreBranchScoped = () => {
  const s = open();
  s.putDefs([stored(a, "const f = 1", "One."), stored(b, "const g = 2")], "5", 2);
  s.addName("f", a, "term", "add");
  s.addName("g", b, "term", "add");
  s.endBatch();
  s.createBranch("side");
  s.switchBranch("side");
  const added = s.head();
  s.setText(
    { hash: a, sourceText: "const f = 1 // one", spans: [], reservedNames: [], doc: "Uno." },
    "update scratch.ts",
  );
  s.endBatch();
  assert.equal(s.getDef(a)!.sourceText, "const f = 1 // one");
  assert.equal(s.getDef(a)!.doc, "Uno.");
  assert.equal(s.names().find((n) => n.path === "f")?.hash, a, "f names the same hash");
  assert.deepEqual(
    s.documentedNames().map((n) => n.doc),
    ["Uno."],
  );
  const entry = s.causal(s.head())!;
  assert.deepEqual(entry.parents, [added], "an entry of its own");
  assert.equal(entry.command, "update scratch.ts");
  assert.deepEqual(
    s.namespaceRows(entry.namespace).find((r) => r.path === "f")?.text,
    textHash({ sourceText: "const f = 1 // one", spans: [], reservedNames: [], doc: "Uno." }),
  );
  // the name log moved: caches keyed by it see the change
  assert.equal(s.history(1)[0]?.path, "f");

  // other branches read it as it was
  s.switchBranch("main");
  assert.equal(s.getDef(a)!.sourceText, "const f = 1");
  assert.equal(s.getDef(a)!.doc, "One.");
  assert.equal(s.texts().size, 0);
  assert.equal(s.texts("side").size, 1);

  // going back to the entry before it brings the text back as it was
  s.switchBranch("side");
  const {
    added: n,
    removed,
    texts,
  } = s.setBranchNames("side", s.namespaceRows(s.causal(added)!.namespace), "reset");
  s.endBatch();
  assert.deepEqual([n, removed, texts], [0, 0, 1]);
  assert.equal(s.getDef(a)!.sourceText, "const f = 1");
  assert.equal(s.causal(s.head())!.namespace, s.causal(added)!.namespace);

  // and the stored text is no version: writing it back changes nothing
  s.setText(
    { hash: a, sourceText: "const f = 1", spans: [], reservedNames: [], doc: "One." },
    "update",
  );
  assert.equal(s.texts().size, 0);
  assert.deepEqual(s.textVersions(a), [
    textHash({ sourceText: "const f = 1 // one", spans: [], reservedNames: [], doc: "Uno." }),
  ]);

  // a removed doc is a version too
  s.setText({ hash: a, sourceText: "const f = 1", spans: [], reservedNames: [] }, "update");
  assert.equal(s.getDef(a)!.doc, undefined);
  s.switchBranch("main");
  assert.equal(s.getDef(a)!.doc, "One.");
}

uses