markz

test

Tests that span the package rather than one module, and the tools that serve them. The statement of the dialect is docs/grammar.md. Here are the inputs, the harness that reads and judges them, the checks, and the tools that measure markz and show it.

  • examples/: examples, each a small input with what it must give. upstream/ holds the vendored suites, one file each, with the sweeps curation keeps off the Quality page in upstream/stress/. markz/ holds markz's own, one file per construct and one for the Not supported rows, numbered as markz:17, some labelled with the edge they try.
  • documents/: real documents written by people and by agents, vendored and pinned. markz's own docs join them as a tier, read in place. The variants built from them are never committed.
  • harness/: the machinery the checks and the Quality page share, with no tests of its own: the grammar, the examples and their filing, the oracles, the cases at each construct's edges, generation and soundness.

The checks:

  • dialect.test.ts: what the others stand on. The grammar is well formed and is syntax.md's, every warning is named there, the filing names real examples and numbers markz's own once, each vendored file is as fences.ts writes it, and the oracles match the suites' own answers.
  • constructs.test.ts: each construct in its own describe, held to its upstream examples, its own examples by edge, and the cases generated at its edges; each Not supported row to its examples.
  • robustness.test.ts: noise, mutated examples and documents written from the grammar, each held to being sound, and the CommonMark and GFM ones to the oracle; and the upstream sweeps, held to finishing, a valid tree and a warning for every bare URL GFM links.
  • documents.test.ts: each real document, sound as written and formatted, its common blocks as micromark reads them, meaning the same after oxfmt, and warning as its snapshot in __snapshots__/ says.
  • docs.test.ts: each page in docs/ read without a warning, and its relative links going to files that exist.
  • complexity.test.ts: every adversarial pattern, and a multi-megabyte document, held to linear time. It runs last, on its own.

The tools are plain Node scripts, each a pnpm command. They aren't part of pnpm test.

  • size.ts is pnpm size, the 20 KB gzip budget and the memory a tree holds. CI runs it on every PR, and it fails above the budget.
  • speed.ts is pnpm speed: markz alone, in MB/s per document tier and per construct, the working tree against origin/main. It is also pnpm hotspots, where the time goes, and pnpm compare, beside other parsers for our own insight. harness/node.ts lets it load src/ and the harness.
  • vendor.ts is pnpm vendor. It turns an upstream suite's tests into examples for examples/upstream/, from a local clone at the pinned commit. It is run by hand when a suite is re-pinned.
  • quality/ is pnpm quality, the Quality page that the site shows beside prose's pages.

pnpm test searches from a fixed seed. pnpm fuzz runs the construct and robustness checks fifty times as far from a random one, and SEARCH and SEED set both by hand. When and how to run it, and what to do with what it finds, is in Development.

Unit tests of offsets and node data live next to their module in src/.

Folders

  • documents/

    Real documents written by people and by agents, vendored as they were at the commit named, and never edited: ../documents.test.ts holds markz to each, and the benchmark times them. They are excluded from the repo's formatter, so they stay exactly as their authors store them. The tier each folder is, and the variants built from them, are in ../harness/corpus.ts. markz's own docs are a tier too, read where they live and never copied here.

  • examples/

    Every example markz is held to that is kept as a file, in the one fence format fences.ts reads.

  • harness/

    What the checks in ../ and the Quality page read and judge with. No tests live here, so one change to how an example is filed or judged reaches both at once.

  • quality/

    The Quality page: the test suite made browsable, as one HTML file beside the site. It shows what markz is held to, what it costs to ship and hold, and how long it takes, all measured on the commit it is built from. pnpm quality writes it, after prose build writes the rest of the site.

Code

  • complexity.test.ts

    markz is linear in its input, and these tests hold it there. Each adversarial pattern is parsed and rendered at a size and at four times that size, and the larger must take less than eight times as long: linear work takes about four, and quadratic work sixteen, so the check sits between them with room for a noisy machine. Each size is timed at its best of three after a warm-up, so a garbage collection or a cold JIT doesn't decide it, and a few milliseconds of slack keeps a fast pattern from failing on timer noise alone.

  • constructs.test.ts

    Each construct in its own describe, by its id, held to everything that tries it: its upstream examples against their oracle, its own examples to their expected output, labelled with the edge each tries, and the cases generated at its edges from the grammar. A Not supported row is held the same way to its examples. A red run names the construct first, whatever caught it.

  • dialect.test.ts

    What every other check stands on, checked before anything is held to it: the statement, the filing and the judges.

  • docs.test.ts

    The root README.md and the documents in docs/ are the site's pages, and prose build links them by repo path, so two things keep the site from drifting: each is read by this commit's markz without a warning (duplicate-id excepted in the grammar, which repeats a heading's id by design: a construct and its side rules), and each relative link in its text goes to a file that exists. The Reference page names every export, Document member and node type the package has, so a new one can't ship undocumented.

  • documents.test.ts

    Every real document in the corpus (harness/corpus.ts), in its own describe, held to what an example can't show: whole documents as people and agents write them. Each must be sound as written and after oxfmt. The blocks of its common variant, which every parser reads alike, must each read as micromark reads them, unless the oracle can't judge one (APART). Formatting must not change what it means: the common variant always, and the whole document when markz cut nothing in it, compared as HTML with the code inside fences and runs of spaces set aside, which oxfmt rewrites and HTML ignores. A document with cut forms is left out of that last check whole, since oxfmt rewrites some of them into what the dialect keeps (*a* to _a_), which is the point of the cut.

  • robustness.test.ts

    Input no example chose, held to what must always be true of any document. Three generated sources feed the same properties: noise drawn from Markdown's characters, known examples with a few random edits, and documents written from the dialect's own grammar. Each must be sound (harness/sound.ts). Where the grammar writes only CommonMark and GFM constructs, from plain letters, markz must also match the oracle, unless it raised a Not supported warning: the side rules often turn a generated document into a form the dialect cuts (a lazy line, * emphasis), which markz reads differently on purpose and reports. Two rules differ without a warning. Emphasis runs never split, and a document that needs one is left out, as the spec examples that need one differ. A * run between digits is text (star-digits), so the oracle's alphabet holds a digit, and a document with one is left out.

  • size.ts

    pnpm size: what markz costs. The 20 KB budget is measured the way a consumer pays for it: everything src/index.ts pulls in, bundled and minified, then gzipped (design: Performance and size). Run as a script, it fails the build above the budget, so growth shows up in the PR that causes it rather than at the end. Brotli is printed for reference only. It also prints what holding the CommonMark spec's tree costs, as a multiple of its source. The Quality page measures both the same way.

  • speed.ts

    pnpm speed: markz alone, this working tree's src/ against origin/main's, in seconds. It answers one question while you work: did this change move it? Each cell is parse + HTML over some text, in MB/s: each document tier read whole, and each construct over its own examples, repeated to a size (examples/markz/<id>.md), so a slower construct shows by name. What a tree holds in memory is a cost, so pnpm size prints it.

  • vendor.ts

    Turns an upstream project's own tests into examples for test/examples/upstream/, in the fence format test/harness/fences.ts reads and writes, from a local clone at the commit its README pins: a micromark extension's, the yaml-test-suite or github-slugger's (below). What markz is held to is the input: every example is compared with markz's oracle, not with the HTML the suite expected, so a test that only configures the HTML side (a directive handler, allowDangerousHtml) keeps its input. A test whose options change the syntax (disable, singleTilde, a frontmatter preset or custom matter) is dropped, as is anything whose input isn't a literal.

No prose yet

__snapshots__/ · env.d.ts