From 4d9af00a9709ed338b412a0814d2acfd1d5bb2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lohrer?= Date: Sat, 18 Apr 2026 05:40:29 +0200 Subject: [PATCH] publish(task 17): validate-post-subcommand MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit validatePostFile(path) liest post-datei, parst frontmatter, ruft validatePost aus core/validation. liefert { ok, slug?, error? }. offline-befehl ohne netz-zugriff. 3 tests grün. Co-Authored-By: Claude Opus 4.6 (1M context) --- publish/src/subcommands/validate-post.ts | 24 ++++++++++++++++++++ publish/tests/validate-post_test.ts | 29 ++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 publish/src/subcommands/validate-post.ts create mode 100644 publish/tests/validate-post_test.ts diff --git a/publish/src/subcommands/validate-post.ts b/publish/src/subcommands/validate-post.ts new file mode 100644 index 0000000..ed3b1c3 --- /dev/null +++ b/publish/src/subcommands/validate-post.ts @@ -0,0 +1,24 @@ +import { parseFrontmatter } from '../core/frontmatter.ts' +import { validatePost } from '../core/validation.ts' + +export interface ValidateResult { + ok: boolean + slug?: string + error?: string +} + +export async function validatePostFile(path: string): Promise { + let text: string + try { + text = await Deno.readTextFile(path) + } catch (err) { + return { ok: false, error: `cannot read ${path}: ${err instanceof Error ? err.message : err}` } + } + try { + const { fm } = parseFrontmatter(text) + validatePost(fm) + return { ok: true, slug: fm.slug } + } catch (err) { + return { ok: false, error: err instanceof Error ? err.message : String(err) } + } +} diff --git a/publish/tests/validate-post_test.ts b/publish/tests/validate-post_test.ts new file mode 100644 index 0000000..4cbf115 --- /dev/null +++ b/publish/tests/validate-post_test.ts @@ -0,0 +1,29 @@ +import { assertEquals } from '@std/assert' +import { validatePostFile } from '../src/subcommands/validate-post.ts' + +Deno.test('validatePostFile: ok bei fixture-post', async () => { + const result = await validatePostFile('./tests/fixtures/sample-post.md') + assertEquals(result.ok, true) + assertEquals(result.slug, 'sample-slug') +}) + +Deno.test('validatePostFile: fehler bei fehlender datei', async () => { + const result = await validatePostFile('./does-not-exist.md') + assertEquals(result.ok, false) + assertEquals(result.error?.includes('read'), true) +}) + +Deno.test('validatePostFile: fehler bei ungültigem slug', async () => { + const tmp = await Deno.makeTempFile({ suffix: '.md' }) + try { + await Deno.writeTextFile( + tmp, + '---\ntitle: "T"\nslug: "Bad Slug"\ndate: 2024-01-01\n---\n\nbody', + ) + const result = await validatePostFile(tmp) + assertEquals(result.ok, false) + assertEquals(result.error?.includes('slug'), true) + } finally { + await Deno.remove(tmp) + } +})