@dral/toml-tests 5.0.0 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dral/toml-tests",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "description": "Testing utility that loads TOML test suites and runs them against a function",
5
5
  "type": "module",
6
6
  "exports": {
package/src/index.js CHANGED
@@ -149,7 +149,7 @@ function processSuite(suite, parentOptions, fn, harness, lineInfo, source) {
149
149
  `Result contains non-TOML-expressible values at: ${nonTomlPaths.join(", ")}`
150
150
  );
151
151
  }
152
- harness.equal(actual, t.output);
152
+ await harness.equal(actual, t.output);
153
153
  } else if (hasThrows) {
154
154
  throw new Error("Expected function to throw");
155
155
  } else if (hasDoesntThrow) {
package/src/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts"],
4
- "sourcesContent": ["import { parse } from \"smol-toml\";\nimport { z } from \"zod\";\n\n/**\n * A value expressible in TOML: primitives, Dates, arrays, or string-keyed objects thereof.\n */\nexport type TomlValue =\n | string\n | number\n | bigint\n | boolean\n | Date\n | TomlValue[]\n | { [key: string]: TomlValue };\n\n/**\n * Type alias for the function under test.\n * Generic over Input, Options, and Output so callers can narrow the types.\n * Defaults preserve backward compatibility with untyped usage.\n */\nexport type TomlTestFn<\n Input extends TomlValue = TomlValue,\n Options extends Record<string, TomlValue> = Record<string, TomlValue>,\n Output extends TomlValue = TomlValue,\n> = (input: Input, options: Options) => Output | Promise<Output>;\n\n/**\n * Recursive structure mirroring suite nesting, containing only line numbers.\n */\ninterface SuiteLineInfo {\n testLines: number[]; // line number for each [[tests]] entry at this level\n suiteLines: SuiteLineInfo[]; // line info for each [[suites]] entry\n}\n\n/**\n * Zod schemas for validating the TOML test document structure.\n */\n\n// A TOML value: string, number, bigint, boolean, Date, or recursively arrays/objects of TOML values\nconst TomlValueSchema: z.ZodType<unknown> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.bigint(),\n z.boolean(),\n z.instanceof(Date),\n z.array(TomlValueSchema),\n z.record(z.string(), TomlValueSchema),\n ]),\n);\n\n// A single test case \u2014 name is optional (falls back to stringified input)\n// Exactly one of: output, throws, doesntThrow must be present\nconst TestCaseSchema = z\n .object({\n name: z.string().optional(),\n input: TomlValueSchema,\n output: TomlValueSchema.optional(),\n throws: z.union([z.literal(true), z.string()]).optional(),\n doesntThrow: z.literal(true).optional(),\n options: z.record(z.string(), TomlValueSchema).optional(),\n })\n .refine(\n (t) => {\n const count = [\n t.output !== undefined,\n t.throws !== undefined,\n t.doesntThrow !== undefined,\n ].filter(Boolean).length;\n return count === 1;\n },\n {\n message:\n \"Each test must have exactly one of: output, throws, or doesntThrow\",\n },\n );\n\n// Recursive suite schema\nconst TestSuiteSchema: z.ZodType<any> = z.lazy(() =>\n z.object({\n name: z.string().optional(),\n options: z.record(z.string(), TomlValueSchema).optional(),\n tests: z.array(TestCaseSchema).optional(),\n suites: z.array(TestSuiteSchema).optional(),\n }),\n);\n\n/**\n * Framework-agnostic test harness interface.\n * The caller provides these functions from whatever test framework they use\n * (node:test, vitest, jest, mocha, etc.).\n */\nexport interface TestHarness {\n /** Register a test suite / group (like `describe` in most frameworks) */\n describe: (name: string, fn: () => void) => void;\n /** Register a single test case (like `it` or `test`) */\n it: (name: string, fn: () => void | Promise<void>) => void;\n /**\n * Assert deep equality between actual and expected values.\n * Should throw on mismatch.\n */\n equal: (actual: unknown, expected: unknown) => void;\n}\n\n/**\n * Scans TOML source for array-of-tables headers and builds a tree of line numbers\n * mirroring the suite nesting structure.\n */\nfunction scanTestLines(toml: string): SuiteLineInfo {\n const lines = toml.split(\"\\n\");\n const headerRegex = /^\\s*\\[\\[(.+?)\\]\\]\\s*$/;\n\n // Collect all array-of-tables headers with their line numbers\n const headers: Array<{ path: string; line: number }> = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line) {\n const match = line.match(headerRegex);\n if (match && match[1]) {\n headers.push({ path: match[1].trim(), line: i + 1 }); // 1-indexed\n }\n }\n }\n\n // Build the tree from the flat list of headers\n const root: SuiteLineInfo = { testLines: [], suiteLines: [] };\n\n for (const { path, line } of headers) {\n // Split path into segments: \"suites.suites.tests\" -> [\"suites\", \"suites\", \"tests\"]\n const segments = path.split(\".\");\n\n // Navigate to the right suite\n let current: SuiteLineInfo = root;\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (seg === \"suites\") {\n // Navigate into the last suite at this level\n if (current.suiteLines.length > 0) {\n current = current.suiteLines[current.suiteLines.length - 1]!;\n }\n }\n // Skip other segments \u2014 they're not suite navigation\n }\n\n const lastSegment = segments[segments.length - 1];\n if (lastSegment === \"tests\") {\n current.testLines.push(line);\n } else if (lastSegment === \"suites\") {\n current.suiteLines.push({ testLines: [], suiteLines: [] });\n }\n // Ignore other paths like \"tests.options\", \"suites.options\" etc.\n }\n\n return root;\n}\n\n/**\n * Recursively finds all paths in a value that contain non-TOML-expressible types.\n * TOML-expressible types are: string, number, bigint, boolean, Date, plain objects, and arrays.\n * Returns an array of dot-path strings where non-TOML values are found.\n */\nfunction findNonTomlPaths(value: unknown, path: string = \"result\"): string[] {\n const nonTomlPaths: string[] = [];\n\n function isPlainObject(obj: unknown): boolean {\n if (obj === null || typeof obj !== \"object\") return false;\n const proto = Object.getPrototypeOf(obj) as unknown;\n return proto === Object.prototype || proto === null;\n }\n\n function isTomlExpressible(val: unknown): boolean {\n const type = typeof val;\n\n // Primitive TOML types\n if (\n type === \"string\"\n || type === \"number\"\n || type === \"bigint\"\n || type === \"boolean\"\n ) {\n return true;\n }\n\n // Date instances (including smol-toml's TomlDate)\n if (val instanceof Date) {\n return true;\n }\n\n // null is NOT TOML-expressible\n if (val === null) {\n return false;\n }\n\n // Arrays: check elements recursively\n if (Array.isArray(val)) {\n return true;\n }\n\n // Plain objects: check values recursively\n if (isPlainObject(val)) {\n return true;\n }\n\n // Everything else (undefined, Symbol, Function, Set, Map, RegExp, class instances, etc.)\n return false;\n }\n\n function walk(val: unknown, currentPath: string): void {\n if (!isTomlExpressible(val)) {\n nonTomlPaths.push(currentPath);\n return;\n }\n\n if (Array.isArray(val)) {\n for (let i = 0; i < val.length; i++) {\n walk(val[i], `${currentPath}[${i}]`);\n }\n return;\n }\n\n if (val !== null && typeof val === \"object\" && isPlainObject(val)) {\n for (const [key, value] of Object.entries(\n val as Record<string, unknown>,\n )) {\n walk(value, `${currentPath}.${key}`);\n }\n return;\n }\n }\n\n walk(value, path);\n return nonTomlPaths;\n}\n\n/**\n * Processes a test suite recursively, creating describe/it blocks as needed.\n * Handles options merging from parent to child scope.\n */\nfunction processSuite<\n Input extends TomlValue,\n Options extends Record<string, TomlValue>,\n Output extends TomlValue,\n>(\n suite: Record<string, unknown>,\n parentOptions: Record<string, unknown>,\n fn: TomlTestFn<Input, Options, Output>,\n harness: TestHarness,\n lineInfo: SuiteLineInfo,\n source?: string,\n): void {\n // Merge options: parent options + suite options\n const suiteOptions = (suite.options ?? {}) as Record<string, unknown>;\n const mergedOptions = { ...parentOptions, ...suiteOptions };\n\n const runContents = () => {\n // Process test cases\n const tests = suite.tests;\n if (Array.isArray(tests)) {\n for (let testIndex = 0; testIndex < tests.length; testIndex++) {\n const test = tests[testIndex];\n const t = test as Record<string, unknown>;\n\n // Use name if provided, otherwise fall back to stringified input\n const testName = (t.name as string | undefined) ?? String(t.input);\n\n harness.it(testName, async () => {\n // Merge test-level options on top of suite options\n const testOptions = (t.options ?? {}) as Record<string, unknown>;\n const finalOptions = { ...mergedOptions, ...testOptions };\n\n // Get line number for this test\n const line = lineInfo.testLines[testIndex];\n const location =\n line ?\n source ? `${source}:${line}`\n : `line ${line}`\n : undefined;\n\n try {\n // Call the test function (await in case it's async)\n const actual = await fn(t.input as Input, finalOptions as Options);\n\n // Determine which assertion type is being used\n const hasOutput = t.output !== undefined;\n const hasThrows = t.throws !== undefined;\n const hasDoesntThrow = t.doesntThrow !== undefined;\n\n if (hasOutput) {\n // output assertion: validate non-TOML types, then compare\n const nonTomlPaths = findNonTomlPaths(actual);\n if (nonTomlPaths.length > 0) {\n throw new Error(\n `Result contains non-TOML-expressible values at: ${nonTomlPaths.join(\", \")}`,\n );\n }\n harness.equal(actual, t.output);\n } else if (hasThrows) {\n // throws assertion: should have thrown, but didn't\n throw new Error(\"Expected function to throw\");\n } else if (hasDoesntThrow) {\n // doesntThrow assertion: just verify it didn't throw (already passed)\n // No additional checks needed\n }\n } catch (err) {\n // Check if this is a \"throws\" test that actually threw\n const hasThrows = t.throws !== undefined;\n if (hasThrows && err instanceof Error) {\n const throwsValue = t.throws;\n if (throwsValue === true) {\n // Any error is fine, test passes\n return;\n } else if (typeof throwsValue === \"string\") {\n // Check if error message matches the pattern\n const pattern = new RegExp(throwsValue);\n if (pattern.test(err.message)) {\n // Pattern matches, test passes\n return;\n } else {\n // Pattern doesn't match, fail with descriptive message\n const newErr = new Error(\n `Expected error message to match pattern \"${throwsValue}\", but got: \"${err.message}\"`,\n );\n if (location) {\n newErr.message = `${location}: ${newErr.message}`;\n }\n throw newErr;\n }\n }\n }\n\n // For non-throws tests or other errors, add location and re-throw\n if (err instanceof Error && location) {\n err.message = `${location}: ${err.message}`;\n }\n throw err;\n }\n });\n }\n }\n\n // Process nested suites\n const suites = suite.suites;\n if (Array.isArray(suites)) {\n for (let suiteIndex = 0; suiteIndex < suites.length; suiteIndex++) {\n const nestedSuite = suites[suiteIndex];\n const nestedLineInfo = lineInfo.suiteLines[suiteIndex] ?? {\n testLines: [],\n suiteLines: [],\n };\n processSuite(\n nestedSuite as Record<string, unknown>,\n mergedOptions,\n fn,\n harness,\n nestedLineInfo,\n source,\n );\n }\n }\n };\n\n // If the suite has a name, wrap in describe block\n if (suite.name && typeof suite.name === \"string\") {\n harness.describe(suite.name, runContents);\n } else {\n // Nameless suites run contents directly at the current nesting level\n runContents();\n }\n}\n\n/**\n * Parses a TOML test document and registers test suites/cases using the\n * provided test harness. Framework-agnostic \u2014 works with node:test, vitest,\n * jest, mocha, or any framework that provides describe/it/equal.\n *\n * @param toml - TOML source string describing the test suite\n * @param fn - The function under test\n * @param harness - Test framework bindings (describe, it, equal)\n * @param source - Optional source label (e.g. filename) for error messages\n */\nexport function toml_test<\n Input extends TomlValue = TomlValue,\n Options extends Record<string, TomlValue> = Record<string, TomlValue>,\n Output extends TomlValue = TomlValue,\n>(\n toml: string,\n fn: TomlTestFn<Input, Options, Output>,\n harness: TestHarness,\n source?: string,\n): void {\n const suite = parse(toml);\n const lineInfo = scanTestLines(toml);\n\n // Validate the parsed suite against the schema\n const validationResult = TestSuiteSchema.safeParse(suite);\n\n if (!validationResult.success) {\n // Register failing tests for each validation error\n for (const issue of validationResult.error.issues) {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"root\";\n const errorMessage = `Validation error at ${path}: ${issue.message}`;\n harness.it(`Schema validation error: ${path}`, () => {\n throw new Error(errorMessage);\n });\n }\n return;\n }\n\n processSuite(suite, {}, fn, harness, lineInfo, source);\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { parse } from \"smol-toml\";\nimport { z } from \"zod\";\n\n/**\n * A value expressible in TOML: primitives, Dates, arrays, or string-keyed objects thereof.\n */\nexport type TomlValue =\n | string\n | number\n | bigint\n | boolean\n | Date\n | TomlValue[]\n | { [key: string]: TomlValue };\n\n/**\n * Type alias for the function under test.\n * Generic over Input, Options, and Output so callers can narrow the types.\n * Defaults preserve backward compatibility with untyped usage.\n */\nexport type TomlTestFn<\n Input extends TomlValue = TomlValue,\n Options extends Record<string, TomlValue> = Record<string, TomlValue>,\n Output extends TomlValue = TomlValue,\n> = (input: Input, options: Options) => Output | Promise<Output>;\n\n/**\n * Recursive structure mirroring suite nesting, containing only line numbers.\n */\ninterface SuiteLineInfo {\n testLines: number[]; // line number for each [[tests]] entry at this level\n suiteLines: SuiteLineInfo[]; // line info for each [[suites]] entry\n}\n\n/**\n * Zod schemas for validating the TOML test document structure.\n */\n\n// A TOML value: string, number, bigint, boolean, Date, or recursively arrays/objects of TOML values\nconst TomlValueSchema: z.ZodType<unknown> = z.lazy(() =>\n z.union([\n z.string(),\n z.number(),\n z.bigint(),\n z.boolean(),\n z.instanceof(Date),\n z.array(TomlValueSchema),\n z.record(z.string(), TomlValueSchema),\n ]),\n);\n\n// A single test case \u2014 name is optional (falls back to stringified input)\n// Exactly one of: output, throws, doesntThrow must be present\nconst TestCaseSchema = z\n .object({\n name: z.string().optional(),\n input: TomlValueSchema,\n output: TomlValueSchema.optional(),\n throws: z.union([z.literal(true), z.string()]).optional(),\n doesntThrow: z.literal(true).optional(),\n options: z.record(z.string(), TomlValueSchema).optional(),\n })\n .refine(\n (t) => {\n const count = [\n t.output !== undefined,\n t.throws !== undefined,\n t.doesntThrow !== undefined,\n ].filter(Boolean).length;\n return count === 1;\n },\n {\n message:\n \"Each test must have exactly one of: output, throws, or doesntThrow\",\n },\n );\n\n// Recursive suite schema\nconst TestSuiteSchema: z.ZodType<any> = z.lazy(() =>\n z.object({\n name: z.string().optional(),\n options: z.record(z.string(), TomlValueSchema).optional(),\n tests: z.array(TestCaseSchema).optional(),\n suites: z.array(TestSuiteSchema).optional(),\n }),\n);\n\n/**\n * Framework-agnostic test harness interface.\n * The caller provides these functions from whatever test framework they use\n * (node:test, vitest, jest, mocha, etc.).\n */\nexport interface TestHarness {\n /** Register a test suite / group (like `describe` in most frameworks) */\n describe: (name: string, fn: () => void) => void;\n /** Register a single test case (like `it` or `test`) */\n it: (name: string, fn: () => void | Promise<void>) => void;\n /**\n * Assert deep equality between actual and expected values.\n * Should throw on mismatch.\n */\n equal: (actual: unknown, expected: unknown) => void;\n}\n\n/**\n * Scans TOML source for array-of-tables headers and builds a tree of line numbers\n * mirroring the suite nesting structure.\n */\nfunction scanTestLines(toml: string): SuiteLineInfo {\n const lines = toml.split(\"\\n\");\n const headerRegex = /^\\s*\\[\\[(.+?)\\]\\]\\s*$/;\n\n // Collect all array-of-tables headers with their line numbers\n const headers: Array<{ path: string; line: number }> = [];\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (line) {\n const match = line.match(headerRegex);\n if (match && match[1]) {\n headers.push({ path: match[1].trim(), line: i + 1 }); // 1-indexed\n }\n }\n }\n\n // Build the tree from the flat list of headers\n const root: SuiteLineInfo = { testLines: [], suiteLines: [] };\n\n for (const { path, line } of headers) {\n // Split path into segments: \"suites.suites.tests\" -> [\"suites\", \"suites\", \"tests\"]\n const segments = path.split(\".\");\n\n // Navigate to the right suite\n let current: SuiteLineInfo = root;\n for (let i = 0; i < segments.length - 1; i++) {\n const seg = segments[i];\n if (seg === \"suites\") {\n // Navigate into the last suite at this level\n if (current.suiteLines.length > 0) {\n current = current.suiteLines[current.suiteLines.length - 1]!;\n }\n }\n // Skip other segments \u2014 they're not suite navigation\n }\n\n const lastSegment = segments[segments.length - 1];\n if (lastSegment === \"tests\") {\n current.testLines.push(line);\n } else if (lastSegment === \"suites\") {\n current.suiteLines.push({ testLines: [], suiteLines: [] });\n }\n // Ignore other paths like \"tests.options\", \"suites.options\" etc.\n }\n\n return root;\n}\n\n/**\n * Recursively finds all paths in a value that contain non-TOML-expressible types.\n * TOML-expressible types are: string, number, bigint, boolean, Date, plain objects, and arrays.\n * Returns an array of dot-path strings where non-TOML values are found.\n */\nfunction findNonTomlPaths(value: unknown, path: string = \"result\"): string[] {\n const nonTomlPaths: string[] = [];\n\n function isPlainObject(obj: unknown): boolean {\n if (obj === null || typeof obj !== \"object\") return false;\n const proto = Object.getPrototypeOf(obj) as unknown;\n return proto === Object.prototype || proto === null;\n }\n\n function isTomlExpressible(val: unknown): boolean {\n const type = typeof val;\n\n // Primitive TOML types\n if (\n type === \"string\"\n || type === \"number\"\n || type === \"bigint\"\n || type === \"boolean\"\n ) {\n return true;\n }\n\n // Date instances (including smol-toml's TomlDate)\n if (val instanceof Date) {\n return true;\n }\n\n // null is NOT TOML-expressible\n if (val === null) {\n return false;\n }\n\n // Arrays: check elements recursively\n if (Array.isArray(val)) {\n return true;\n }\n\n // Plain objects: check values recursively\n if (isPlainObject(val)) {\n return true;\n }\n\n // Everything else (undefined, Symbol, Function, Set, Map, RegExp, class instances, etc.)\n return false;\n }\n\n function walk(val: unknown, currentPath: string): void {\n if (!isTomlExpressible(val)) {\n nonTomlPaths.push(currentPath);\n return;\n }\n\n if (Array.isArray(val)) {\n for (let i = 0; i < val.length; i++) {\n walk(val[i], `${currentPath}[${i}]`);\n }\n return;\n }\n\n if (val !== null && typeof val === \"object\" && isPlainObject(val)) {\n for (const [key, value] of Object.entries(\n val as Record<string, unknown>,\n )) {\n walk(value, `${currentPath}.${key}`);\n }\n return;\n }\n }\n\n walk(value, path);\n return nonTomlPaths;\n}\n\n/**\n * Processes a test suite recursively, creating describe/it blocks as needed.\n * Handles options merging from parent to child scope.\n */\nfunction processSuite<\n Input extends TomlValue,\n Options extends Record<string, TomlValue>,\n Output extends TomlValue,\n>(\n suite: Record<string, unknown>,\n parentOptions: Record<string, unknown>,\n fn: TomlTestFn<Input, Options, Output>,\n harness: TestHarness,\n lineInfo: SuiteLineInfo,\n source?: string,\n): void {\n // Merge options: parent options + suite options\n const suiteOptions = (suite.options ?? {}) as Record<string, unknown>;\n const mergedOptions = { ...parentOptions, ...suiteOptions };\n\n const runContents = () => {\n // Process test cases\n const tests = suite.tests;\n if (Array.isArray(tests)) {\n for (let testIndex = 0; testIndex < tests.length; testIndex++) {\n const test = tests[testIndex];\n const t = test as Record<string, unknown>;\n\n // Use name if provided, otherwise fall back to stringified input\n const testName = (t.name as string | undefined) ?? String(t.input);\n\n harness.it(testName, async () => {\n // Merge test-level options on top of suite options\n const testOptions = (t.options ?? {}) as Record<string, unknown>;\n const finalOptions = { ...mergedOptions, ...testOptions };\n\n // Get line number for this test\n const line = lineInfo.testLines[testIndex];\n const location =\n line ?\n source ? `${source}:${line}`\n : `line ${line}`\n : undefined;\n\n try {\n // Call the test function (await in case it's async)\n const actual = await fn(t.input as Input, finalOptions as Options);\n\n // Determine which assertion type is being used\n const hasOutput = t.output !== undefined;\n const hasThrows = t.throws !== undefined;\n const hasDoesntThrow = t.doesntThrow !== undefined;\n\n if (hasOutput) {\n // output assertion: validate non-TOML types, then compare\n const nonTomlPaths = findNonTomlPaths(actual);\n if (nonTomlPaths.length > 0) {\n throw new Error(\n `Result contains non-TOML-expressible values at: ${nonTomlPaths.join(\", \")}`,\n );\n }\n await harness.equal(actual, t.output);\n } else if (hasThrows) {\n // throws assertion: should have thrown, but didn't\n throw new Error(\"Expected function to throw\");\n } else if (hasDoesntThrow) {\n // doesntThrow assertion: just verify it didn't throw (already passed)\n // No additional checks needed\n }\n } catch (err) {\n // Check if this is a \"throws\" test that actually threw\n const hasThrows = t.throws !== undefined;\n if (hasThrows && err instanceof Error) {\n const throwsValue = t.throws;\n if (throwsValue === true) {\n // Any error is fine, test passes\n return;\n } else if (typeof throwsValue === \"string\") {\n // Check if error message matches the pattern\n const pattern = new RegExp(throwsValue);\n if (pattern.test(err.message)) {\n // Pattern matches, test passes\n return;\n } else {\n // Pattern doesn't match, fail with descriptive message\n const newErr = new Error(\n `Expected error message to match pattern \"${throwsValue}\", but got: \"${err.message}\"`,\n );\n if (location) {\n newErr.message = `${location}: ${newErr.message}`;\n }\n throw newErr;\n }\n }\n }\n\n // For non-throws tests or other errors, add location and re-throw\n if (err instanceof Error && location) {\n err.message = `${location}: ${err.message}`;\n }\n throw err;\n }\n });\n }\n }\n\n // Process nested suites\n const suites = suite.suites;\n if (Array.isArray(suites)) {\n for (let suiteIndex = 0; suiteIndex < suites.length; suiteIndex++) {\n const nestedSuite = suites[suiteIndex];\n const nestedLineInfo = lineInfo.suiteLines[suiteIndex] ?? {\n testLines: [],\n suiteLines: [],\n };\n processSuite(\n nestedSuite as Record<string, unknown>,\n mergedOptions,\n fn,\n harness,\n nestedLineInfo,\n source,\n );\n }\n }\n };\n\n // If the suite has a name, wrap in describe block\n if (suite.name && typeof suite.name === \"string\") {\n harness.describe(suite.name, runContents);\n } else {\n // Nameless suites run contents directly at the current nesting level\n runContents();\n }\n}\n\n/**\n * Parses a TOML test document and registers test suites/cases using the\n * provided test harness. Framework-agnostic \u2014 works with node:test, vitest,\n * jest, mocha, or any framework that provides describe/it/equal.\n *\n * @param toml - TOML source string describing the test suite\n * @param fn - The function under test\n * @param harness - Test framework bindings (describe, it, equal)\n * @param source - Optional source label (e.g. filename) for error messages\n */\nexport function toml_test<\n Input extends TomlValue = TomlValue,\n Options extends Record<string, TomlValue> = Record<string, TomlValue>,\n Output extends TomlValue = TomlValue,\n>(\n toml: string,\n fn: TomlTestFn<Input, Options, Output>,\n harness: TestHarness,\n source?: string,\n): void {\n const suite = parse(toml);\n const lineInfo = scanTestLines(toml);\n\n // Validate the parsed suite against the schema\n const validationResult = TestSuiteSchema.safeParse(suite);\n\n if (!validationResult.success) {\n // Register failing tests for each validation error\n for (const issue of validationResult.error.issues) {\n const path = issue.path.length > 0 ? issue.path.join(\".\") : \"root\";\n const errorMessage = `Validation error at ${path}: ${issue.message}`;\n harness.it(`Schema validation error: ${path}`, () => {\n throw new Error(errorMessage);\n });\n }\n return;\n }\n\n processSuite(suite, {}, fn, harness, lineInfo, source);\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["value"]
7
7
  }