Files
obsidian-penny/test/command-ids.test.ts
james.maesandClaude Opus 4.6 568c3f38db test: add 22 tests for recent fixes (TDD catch-up)
- Block scope edge cases: empty blocks, nested markers, inline {{ }},
  scope isolation between blocks (5 tests)
- Streaming fallback: all 4 providers verified to use httpFn when
  globalThis.fetch unavailable, onToken accepted without errors (12 tests)
- Command ID validation: no penny: prefix, kebab-case, no dupes (4 tests)
- Pipeline upsert paths: first-run create and subsequent modify (2 tests)

415 total tests across 19 test files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-17 08:55:59 -05:00

60 lines
1.7 KiB
TypeScript

/**
* PENNY - Command ID Prefix Test
*
* Verifies that command IDs registered in commands.ts do NOT include
* the "penny:" prefix. Obsidian automatically prepends the plugin manifest
* ID to command IDs, so including "penny:" in the id field would produce
* double-prefixed IDs like "penny:penny:process-chapter".
*
* This is a structural test that reads the source file directly rather
* than importing the module (which depends on Obsidian APIs).
*/
import { describe, it, expect } from "vitest";
import { readFileSync } from "fs";
import { resolve } from "path";
const COMMANDS_SOURCE = readFileSync(
resolve(__dirname, "../src/commands.ts"),
"utf-8",
);
/**
* Extract all command ID strings from addCommand({ id: "..." }) calls.
* Matches both single-quoted and double-quoted id values.
*/
function extractCommandIds(source: string): string[] {
const pattern = /id:\s*["']([^"']+)["']/g;
const ids: string[] = [];
let match;
while ((match = pattern.exec(source)) !== null) {
ids.push(match[1]);
}
return ids;
}
describe("command registration IDs", () => {
const ids = extractCommandIds(COMMANDS_SOURCE);
it("finds at least one command ID in the source", () => {
expect(ids.length).toBeGreaterThan(0);
});
it("no command ID starts with 'penny:' (Obsidian adds the prefix automatically)", () => {
for (const id of ids) {
expect(id).not.toMatch(/^penny:/);
}
});
it("all command IDs are kebab-case (lowercase alphanumeric with hyphens)", () => {
for (const id of ids) {
expect(id).toMatch(/^[a-z][a-z0-9-]*$/);
}
});
it("no duplicate command IDs exist", () => {
const unique = new Set(ids);
expect(unique.size).toBe(ids.length);
});
});