Emitter 2a: the corpus runner, the canonical serializer and the CommonMark subset
CI / gate (push) Successful in 5s
CI / gate (push) Successful in 5s
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync, readdirSync } from 'node:fs'
|
||||
import { dirname, join } from 'node:path'
|
||||
import test from 'node:test'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
import { adfToMarkdown } from './adf-to-markdown.ts'
|
||||
import { isAdfDocument } from './adf-document.ts'
|
||||
import { isJsonValue, serializeCanonicalJson } from './canonical-json.ts'
|
||||
|
||||
const corpusRoot = join(dirname(fileURLToPath(import.meta.url)), '..', 'corpus')
|
||||
const roundTripRoot = join(corpusRoot, 'round-trip')
|
||||
|
||||
const emittingDirectories = ['commonmark-subset']
|
||||
const pendingDirectories = ['block-nodes', 'inline-nodes']
|
||||
|
||||
function directoryNames(root: string): string[] {
|
||||
return readdirSync(root, { withFileTypes: true })
|
||||
.filter((entry) => entry.isDirectory())
|
||||
.map((entry) => entry.name)
|
||||
.sort()
|
||||
}
|
||||
|
||||
function fixtureNames(directory: string, extension: string): string[] {
|
||||
return readdirSync(join(roundTripRoot, directory))
|
||||
.filter((name) => name.endsWith(extension))
|
||||
.map((name) => name.slice(0, -extension.length))
|
||||
.sort()
|
||||
}
|
||||
|
||||
function corpusJsonPaths(): string[] {
|
||||
return readdirSync(corpusRoot, { encoding: 'utf8', recursive: true })
|
||||
.filter((name) => name.endsWith('.json'))
|
||||
.map((name) => join(corpusRoot, name))
|
||||
.sort()
|
||||
}
|
||||
|
||||
test('every round-trip directory is either emitting or explicitly pending', () => {
|
||||
assert.deepEqual(directoryNames(roundTripRoot), [...emittingDirectories, ...pendingDirectories].sort())
|
||||
})
|
||||
|
||||
for (const directory of [...emittingDirectories, ...pendingDirectories].sort()) {
|
||||
test(`${directory} pairs every .json with a .md`, () => {
|
||||
assert.deepEqual(fixtureNames(directory, '.json'), fixtureNames(directory, '.md'))
|
||||
})
|
||||
}
|
||||
|
||||
for (const directory of emittingDirectories) {
|
||||
const names = [...new Set([...fixtureNames(directory, '.json'), ...fixtureNames(directory, '.md')])].sort()
|
||||
|
||||
test(`${directory} holds fixtures`, () => {
|
||||
assert.ok(names.length > 0, `${directory} is expected to emit but holds no fixture pairs`)
|
||||
})
|
||||
|
||||
for (const name of names) {
|
||||
test(`${directory}/${name} emits its markdown byte for byte`, () => {
|
||||
const parsed: unknown = JSON.parse(readFileSync(join(roundTripRoot, directory, `${name}.json`), 'utf8'))
|
||||
assert.ok(isAdfDocument(parsed), `${name}.json is not an ADF document`)
|
||||
const result = adfToMarkdown(parsed)
|
||||
assert.ok(result.ok, result.ok ? '' : `${result.error.code}: ${result.error.message}`)
|
||||
const expected = readFileSync(join(roundTripRoot, directory, `${name}.md`))
|
||||
const emitted = Buffer.from(result.value, 'utf8')
|
||||
if (!emitted.equals(expected)) assert.equal(result.value, expected.toString('utf8'))
|
||||
assert.ok(emitted.equals(expected))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
test('the corpus holds JSON to gate', () => {
|
||||
assert.ok(corpusJsonPaths().length > 0)
|
||||
})
|
||||
|
||||
for (const path of corpusJsonPaths()) {
|
||||
test(`${path.slice(corpusRoot.length + 1)} re-serializes to itself`, () => {
|
||||
const raw = readFileSync(path, 'utf8')
|
||||
const parsed: unknown = JSON.parse(raw)
|
||||
assert.ok(isJsonValue(parsed), `${path} does not hold a JSON value`)
|
||||
assert.equal(`${serializeCanonicalJson(parsed, 'two-space')}\n`, raw)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user