dotwee_obsidian-raindropio-.../tests/block-parser.test.ts
Lukas Wolfsteiner ad2baee012 test: cover show and hide parsing and field resolution
Verify parsing of show and hide block options, including casing, duplicates and unknown field warnings.

Verify display field resolution layers show before hide and leaves the defaults untouched.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-06 11:32:36 +02:00

128 lines
3.6 KiB
TypeScript

import { extractFirstRaindropBlock, parseRaindropBlock } from "../src/block-parser";
import { DEFAULT_DISPLAY_FIELDS, resolveRaindropDisplayFields } from "../src/renderer";
describe("parseRaindropBlock", () => {
it("parses supported key-value options", () => {
const parsed = parseRaindropBlock(`
# Favorite references
collection: 42
search: obsidian plugin
tag: read later
sort: -created
limit: 25
`);
expect(parsed).toEqual({
options: {
collectionId: 42,
search: "obsidian plugin",
tag: "read later",
sort: "-created",
limit: 25,
},
warnings: [],
});
});
it("ignores invalid collections and warns", () => {
const parsed = parseRaindropBlock("collection: -1");
expect(parsed.options.collectionId).toBeUndefined();
expect(parsed.warnings).toEqual(["Invalid `collection`; using the default collection."]);
});
it("clamps valid numeric limits", () => {
expect(parseRaindropBlock("limit: 250").options.limit).toBe(100);
expect(parseRaindropBlock("limit: 0").options.limit).toBe(1);
});
it("warns and falls back when the limit is not numeric", () => {
const parsed = parseRaindropBlock("limit: many");
expect(parsed.options.limit).toBe(1);
expect(parsed.warnings).toEqual(["Invalid `limit`; using the plugin default."]);
});
it("parses show and hide field lists", () => {
const parsed = parseRaindropBlock(`
show: collection, cover
hide: excerpt, tags
`);
expect(parsed.options.showFields).toEqual(["collection", "cover"]);
expect(parsed.options.hideFields).toEqual(["excerpt", "tags"]);
expect(parsed.warnings).toEqual([]);
});
it("normalizes casing and duplicates in field lists", () => {
const parsed = parseRaindropBlock("show: Cover, cover, ,DOMAIN");
expect(parsed.options.showFields).toEqual(["cover", "domain"]);
expect(parsed.warnings).toEqual([]);
});
it("warns about unknown field names and keeps valid ones", () => {
const parsed = parseRaindropBlock("hide: excerpt, banana");
expect(parsed.options.hideFields).toEqual(["excerpt"]);
expect(parsed.warnings).toEqual([
"Unknown field `banana` in `hide`; expected one of cover, domain, created, excerpt, tags, collection.",
]);
});
it("omits field lists when no valid names remain", () => {
const parsed = parseRaindropBlock("show: banana");
expect(parsed.options.showFields).toBeUndefined();
expect(parsed.warnings).toHaveLength(1);
});
});
describe("resolveRaindropDisplayFields", () => {
it("returns the defaults when no overrides are given", () => {
expect(resolveRaindropDisplayFields(DEFAULT_DISPLAY_FIELDS)).toEqual(DEFAULT_DISPLAY_FIELDS);
});
it("layers show and hide on top of the defaults", () => {
const fields = resolveRaindropDisplayFields(DEFAULT_DISPLAY_FIELDS, ["collection", "cover"], ["excerpt", "tags"]);
expect(fields).toEqual({
cover: true,
domain: true,
created: true,
excerpt: false,
tags: false,
collection: true,
});
});
it("applies hide after show and does not mutate the defaults", () => {
const defaults = { ...DEFAULT_DISPLAY_FIELDS };
const fields = resolveRaindropDisplayFields(defaults, ["excerpt"], ["excerpt"]);
expect(fields.excerpt).toBe(false);
expect(defaults).toEqual(DEFAULT_DISPLAY_FIELDS);
});
});
describe("extractFirstRaindropBlock", () => {
it("returns the first raindrop code block body", () => {
const block = extractFirstRaindropBlock(`
Before
\`\`\`raindrop
tag: docs
\`\`\`
\`\`\`raindrop
tag: later
\`\`\`
`);
expect(block).toBe("tag: docs\n");
});
it("returns null when no raindrop block exists", () => {
expect(extractFirstRaindropBlock("```ts\nconsole.log('nope');\n```")).toBeNull();
});
});