From 63df24118a894f0e15a97b7b984d33bbcac23d2a Mon Sep 17 00:00:00 2001 From: Remco Haszing Date: Tue, 8 Oct 2024 19:58:54 +0200 Subject: [PATCH] Use snapshot-fixtures for testing --- package-lock.json | 69 +++++++++++++++++ package.json | 1 + src/rehype-mermaid.test.ts | 152 +++++++++++++------------------------ 3 files changed, 121 insertions(+), 101 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4610821..4461b4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,7 @@ "rehype": "^13.0.0", "remark-cli": "^12.0.0", "remark-preset-remcohaszing": "^3.0.0", + "snapshot-fixtures": "^1.0.0", "typescript": "^5.0.0", "unist-util-remove-position": "^5.0.0", "vfile-message": "^4.0.0" @@ -9214,6 +9215,60 @@ "node": ">=8" } }, + "node_modules/snapshot-fixtures": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/snapshot-fixtures/-/snapshot-fixtures-1.2.0.tgz", + "integrity": "sha512-+JH/QfYxlFCD64/ifTAk39dHFzv+cHHeu+U1ocyBNcYhgTath5CFHH8m6yW7I27xODKQc8gIDQbsl8HwRnyWRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.0.0", + "ci-info": "^4.0.0", + "diff": "^5.0.0", + "to-vfile": "^8.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/remcohaszing" + }, + "peerDependencies": { + "prettier": ">=3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, + "node_modules/snapshot-fixtures/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/snapshot-fixtures/node_modules/ci-info": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/space-separated-tokens": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", @@ -9581,6 +9636,20 @@ "node": ">=8.0" } }, + "node_modules/to-vfile": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-8.0.0.tgz", + "integrity": "sha512-IcmH1xB5576MJc9qcfEC/m/nQCFt3fzMHz45sSlgJyTWjRbKW1HAkJpuf3DgE57YzIlZcwcBZA5ENQbBo4aLkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", diff --git a/package.json b/package.json index 664ca3c..e3bd67d 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "rehype": "^13.0.0", "remark-cli": "^12.0.0", "remark-preset-remcohaszing": "^3.0.0", + "snapshot-fixtures": "^1.0.0", "typescript": "^5.0.0", "unist-util-remove-position": "^5.0.0", "vfile-message": "^4.0.0" diff --git a/src/rehype-mermaid.test.ts b/src/rehype-mermaid.test.ts index 7374896..f7ce3ad 100644 --- a/src/rehype-mermaid.test.ts +++ b/src/rehype-mermaid.test.ts @@ -1,135 +1,85 @@ import assert from 'node:assert/strict' -import { readdir, readFile, writeFile } from 'node:fs/promises' -import { describe, test } from 'node:test' -import { fileURLToPath } from 'node:url' +import { test } from 'node:test' import { type Element, type Root } from 'hast' -import prettier from 'prettier' import { rehype } from 'rehype' import rehypeMermaid from 'rehype-mermaid' +import { testFixturesDirectory } from 'snapshot-fixtures' import { removePosition } from 'unist-util-remove-position' import { type VFile } from 'vfile' import { VFileMessage } from 'vfile-message' -const fixturesPath = new URL('../fixtures/', import.meta.url) -const fixtureNames = (await readdir(fixturesPath)).sort() - -interface FixtureTest { - input: string - validate: (actual: VFile, verify?: boolean) => Promise -} - -async function readFixture(name: string, expectedName: string): Promise { - const fixturePath = new URL(`${name}/`, fixturesPath) - const inputPath = new URL('input.html', fixturePath) - const expectedPath = new URL(expectedName, fixturePath) +testFixturesDirectory({ + directory: new URL('../fixtures', import.meta.url), + prettier: true, + tests: { + 'img-png.html': { + // PNG generation isn’t pixel perfect. + ignore: true, + generate(input) { + const processor = rehype().use(rehypeMermaid, { strategy: 'img-png' }) + + return processor.process(input) + } + }, - const input = await readFile(inputPath, 'utf8') - let expected: string | undefined - try { - expected = await readFile(expectedPath, 'utf8') - } catch { - await writeFile(expectedPath, '') - } + 'img-png-dark.html': { + // PNG generation isn’t pixel perfect. + ignore: true, + generate(input) { + const processor = rehype().use(rehypeMermaid, { strategy: 'img-png', dark: true }) - return { - input, - async validate(actual, verify = true) { - const config = await prettier.resolveConfig(fileURLToPath(expectedPath), { - editorconfig: true - }) - const normalized = await prettier.format(String(actual), { ...config, parser: 'html' }) - if (process.argv.includes('update') || !expected) { - await writeFile(expectedPath, normalized) + return processor.process(input) } - if (verify) { - assert.equal(normalized, expected) + }, + + 'img-png-dark-custom.html': { + // PNG generation isn’t pixel perfect. + ignore: true, + generate(input) { + const processor = rehype().use(rehypeMermaid, { + strategy: 'img-png', + dark: { theme: 'forest' } + }) + + return processor.process(input) } - } - } -} - -for (const name of fixtureNames) { - describe(name, () => { - test('img-png', async () => { - const { input, validate } = await readFixture(name, 'img-png.html') - const processor = rehype().use(rehypeMermaid, { strategy: 'img-png' }) - - const result = await processor.process(input) - - await validate(result, false) - }) - - test('img-png (dark)', async () => { - const { input, validate } = await readFixture(name, 'img-png-dark.html') - const processor = rehype().use(rehypeMermaid, { strategy: 'img-png', dark: true }) - - const result = await processor.process(input) - - await validate(result, false) - }) - - test('img-png (dark custom)', async () => { - const { input, validate } = await readFixture(name, 'img-png-dark-custom.html') - const processor = rehype().use(rehypeMermaid, { - strategy: 'img-png', - dark: { theme: 'forest' } - }) - - const result = await processor.process(input) + }, - await validate(result, false) - }) - - test('img-svg', async () => { - const { input, validate } = await readFixture(name, 'img-svg.html') + 'img-svg.html'(input) { const processor = rehype().use(rehypeMermaid, { strategy: 'img-svg' }) - const result = await processor.process(input) - - await validate(result) - }) + return processor.process(input) + }, - test('img-svg (dark)', async () => { - const { input, validate } = await readFixture(name, 'img-svg-dark.html') + 'img-svg-dark.html'(input) { const processor = rehype().use(rehypeMermaid, { strategy: 'img-svg', dark: true }) - const result = await processor.process(input) - - await validate(result) - }) + return processor.process(input) + }, - test('img-svg (dark custom)', async () => { - const { input, validate } = await readFixture(name, 'img-svg-dark-custom.html') + 'img-svg-dark-custom.html'(input) { const processor = rehype().use(rehypeMermaid, { strategy: 'img-svg', dark: { theme: 'forest' } }) - const result = await processor.process(input) + return processor.process(input) + }, - await validate(result) - }) - - test('inline-svg', async () => { - const { input, validate } = await readFixture(name, 'inline-svg.html') + 'inline-svg.html'(input) { const processor = rehype().use(rehypeMermaid) - const result = await processor.process(input) - - await validate(result) - }) + return processor.process(input) + }, - test('pre-mermaid', async () => { - const { input, validate } = await readFixture(name, 'pre-mermaid.html') + 'pre-mermaid.html'(input) { const processor = rehype().use(rehypeMermaid, { strategy: 'pre-mermaid' }) - const result = processor.processSync(input) - - await validate(result) - }) - }) -} + return processor.processSync(input) + } + } +}) test('invalid strategy', () => { const processor = rehype()