testTextPattern

tcmts.cli.pattern.testTextPattern · #siirorww · term

A pattern is its text as written, or a regular expression written /…/ with its flags; text is matched in or out of case as asked, a written regular expression as its flags say; and what finding nothing says names which it was.

import { noLines, textPattern } from "#codebase/tcmts/cli/pattern";
import assert from "node:assert/strict";

export const testTextPattern = () => {
  const pattern = (text: string, opts = {}) => {
    const p = textPattern(text, opts);
    if (p.error !== undefined) throw new Error(p.error);
    return p;
  };
  const find = (text: string, line: string, opts = {}) => pattern(text, opts).find(line);
  // text, as written: `a|b` is those three characters
  assert.deepEqual(find("a|b", "a b a|b"), [[4, 7]]);
  assert.equal(pattern("a|b").regex, false);
  assert.deepEqual(find("Get", "get GET"), [
    [0, 3],
    [4, 7],
  ]);
  assert.deepEqual(find("Get", "get GET", { caseSensitive: true }), []);
  // a regular expression, written /…/: case as its flags say, whatever caseSensitive says
  assert.deepEqual(find("/a|b/", "a b c"), [
    [0, 1],
    [2, 3],
  ]);
  assert.equal(pattern("/a|b/").regex, true);
  assert.deepEqual(find("/get/", "get GET"), [[0, 3]]);
  assert.deepEqual(find("/get/i", "get GET", { caseSensitive: true }), [
    [0, 3],
    [4, 7],
  ]);
  // g and y are dropped: each line is searched from its start
  const sticky = pattern("/x/gy");
  assert.deepEqual(
    [sticky.find("ax x"), sticky.find("x")],
    [
      [
        [1, 2],
        [3, 4],
      ],
      [[0, 1]],
    ],
  );
  // not /…/: a path, a lone slash pair
  assert.deepEqual(find("/usr/bin", "at /usr/bin"), [[3, 11]]);
  assert.deepEqual(find("//", "a // b"), [[2, 4]]);
  // the old way: all the text a regular expression, no slashes
  assert.deepEqual(find("x \\* x", "x * x", { regex: true }), [[0, 5]]);
  assert.deepEqual(find("/a/", "/a/ a", { regex: true }), [[0, 3]]);
  // whole words, either way
  assert.deepEqual(find("squar", "square squar", { wholeWord: true }), [[7, 12]]);
  assert.deepEqual(find("/sq\\w+/", "square sq", { wholeWord: true }), [[0, 6]]);
  // an empty match finds nothing, and doesn't stop the line's later matches
  assert.deepEqual(find("/b*/", "abb"), [[1, 3]]);
  assert.match(textPattern("/(/").error ?? "", /Invalid regular expression/);
  assert.match(textPattern("(", { regex: true }).error ?? "", /Invalid regular expression/);
  assert.equal(textPattern("(").error, undefined);

  assert.equal(noLines("ab"), 'no lines with the text "ab"');
  assert.equal(
    noLines("a|b", { under: "lib" }),
    'no lines with the text "a|b" under lib (text, as written: a regular expression is written /…/)',
  );
  assert.equal(noLines("/a|b/i"), "no lines matching /a|b/i");
  assert.equal(noLines("a|b", { regex: true }), "no lines matching a|b");
}

uses