diff --git a/README.md b/README.md index be90d3d..7aa00b4 100644 --- a/README.md +++ b/README.md @@ -16,12 +16,11 @@ has stopped being obvious._ the guide and the migration guide, rendered as one set from the version that is `latest` on npm. -> **Status:** `4.1` is the current line. It adds introspection and tooling to -> `4.0.1` — a plan as JSON, a preflight failure as data, a command-line -> tool, an API reference, a migration guide — and changes nothing that existed; -> the VS Code floor stays `^1.134.0`. 2.x was a utility library with a -> different shape; it continues on `v2-maintenance` and anything pinned to -> `^2.x` is unaffected. See [Coming from 2.x](#coming-from-2x). +> **Status:** Active. `2.x` was a utility library with a different shape; it +> continues on `v2-maintenance`, so anything pinned to `^2.x` is unaffected by +> anything here. See [Coming from 2.x](#coming-from-2x). What each release +> changed is in the [CHANGELOG](CHANGELOG.md); the version badge above is the +> one that is current. --- @@ -461,10 +460,10 @@ This is a personal project maintained in spare time. It is active, but support is best-effort: I'll do my best to review issues and PRs, and releases may be a bit slow sometimes — thank you for your patience. -The `4.x` line holds `latest` on npm, so a fresh `npm install` gets the -framework. `2.x` continues on `v2-maintenance` and still takes bug fixes; -anything pinned to `^2.x` resolves there and is unaffected. Breaking changes are -listed in the [CHANGELOG](CHANGELOG.md). +A fresh `npm install` gets the current release. `2.x` continues on +`v2-maintenance` and still takes bug fixes; anything pinned to `^2.x` resolves +there and is unaffected. Breaking changes are listed in the +[CHANGELOG](CHANGELOG.md). Helpful things when reporting bugs: diff --git a/tests/readme-versions.test.ts b/tests/readme-versions.test.ts new file mode 100644 index 0000000..b1bcddb --- /dev/null +++ b/tests/readme-versions.test.ts @@ -0,0 +1,72 @@ +import { readFileSync } from 'node:fs'; +import { join } from 'node:path'; + +import { describe, expect, it } from 'vitest'; + +/** + * The versions the documentation quotes, checked against the manifest. + * + * Prose that names a version is correct on the day it is written and wrong on + * the day the version moves, and nothing fails in between — the reader is the + * one who finds out. This repository already pins the documented *code* to + * sources that compile; these are the documented *numbers*, pinned the same way. + * + * Only requirements are pinned here. A claim about which release is current + * belongs to the npm badge, which is generated: the pages below should not say + * it at all, and the last case asserts they do not. + */ +const PAGES = ['README.md', join('docs', 'guide.md'), join('docs', 'migration-from-2x.md')]; + +const manifest = JSON.parse(readFileSync('package.json', 'utf8')) as { + engines: { vscode: string; node: string }; + devDependencies: Record; +}; + +const pages = PAGES.map((page) => ({ page, text: readFileSync(page, 'utf8') })); + +describe('documented versions', () => { + it('quotes the VS Code floor exactly as the manifest declares it', () => { + const declared = manifest.engines.vscode; + const readme = pages.find((p) => p.page === 'README.md'); + expect(readme?.text).toContain(`\`${declared}\``); + }); + + it('quotes the Node floor exactly as the manifest declares it', () => { + const declared = manifest.engines.node; + const readme = pages.find((p) => p.page === 'README.md'); + expect(readme?.text).toContain(`\`${declared}\``); + }); + + it('names no VS Code version other than the declared floor', () => { + // `1.134.0` on its own is the same floor written without a range, which the + // paragraph under the requirements table does deliberately. Anything else + // is a version that moved without the prose moving with it. + const floor = manifest.engines.vscode.replace(/^[^\d]*/, ''); + const found = pages.flatMap(({ page, text }) => + [...text.matchAll(/`\^?(1\.\d{2,3}\.\d+)`/g)].map((m) => ({ page, version: m[1] ?? '' })) + ); + const stale = found.filter((f) => f.version !== floor); + expect(stale).toEqual([]); + }); + + it('keeps @types/vscode on the same version as the floor', () => { + // Raising only the types would let code compile against an API the declared + // floor does not have, and `vsce` refuses the opposite. The README says the + // two move together; this is that sentence as a check. + const types = (manifest.devDependencies['@types/vscode'] ?? '').replace(/^[^\d]*/, ''); + const floor = manifest.engines.vscode.replace(/^[^\d]*/, ''); + expect(types).toBe(floor); + }); + + it('leaves "which release is current" to the badge', () => { + // The npm badge renders the current version and cannot go stale. Prose that + // repeats it can, and did: `4.1.0 is the current release` survived into the + // release that replaced it. + const claims = pages.flatMap(({ page, text }) => + [...text.matchAll(/^.*\b(?:is the current (?:release|line)|holds `latest`).*$/gm)].map( + (m) => `${page}: ${m[0].trim()}` + ) + ); + expect(claims).toEqual([]); + }); +});