"use strict"; const assert = require("node:assert"); const { test } = require("node:test"); const Module = require("node:module"); const originalLoad = Module._load; Module._load = function load(request, parent, isMain) { if (request === "vscode") { return { Diagnostic: class Diagnostic { constructor(range, message, severity) { this.range = range; this.message = message; this.severity = severity; } }, DiagnosticSeverity: { Error: 0, Warning: 1 }, Range: class Range { constructor(start, end) { this.start = start; this.end = end; } }, }; } return originalLoad.call(this, request, parent, isMain); }; const { findTopLevelDeclaration, maskLeadingTrivia, validateBalancedCharacters, validateHtmlTags, validateLayoutUsage, validateRootMembers, } = require("../src/diagnostics"); Module._load = originalLoad; function mockDocument() { return { positionAt(offset) { return offset; }, }; } test("recognizes a WRN declaration after leading line comments", () => { const source = `// Component summary // More details component ThemeToggle { view { } }`; const declaration = findTopLevelDeclaration({}, source); assert.equal(declaration.kind, "component"); assert.equal(declaration.name, "ThemeToggle"); assert.equal(declaration.diagnostic, undefined); }); test("recognizes a WRN declaration after top-level imports", () => { const source = `import { appUrl } from "@wrnexus/helpers"; import type { Context } from "@wrnexus/core"; page Home { view { } }`; const declaration = findTopLevelDeclaration({}, source); assert.equal(declaration.kind, "page"); assert.equal(declaration.name, "Home"); assert.equal(declaration.diagnostic, undefined); }); test("masks only leading trivia and preserves source offsets", () => { const source = "\uFEFF// Summary\r\npage Home {\n // member comment\n}"; const masked = maskLeadingTrivia(source); assert.equal(masked.length, source.length); assert.equal(masked.indexOf("page Home"), source.indexOf("page Home")); assert.match(masked, /\/\/ member comment/); }); test("ignores apostrophes and brackets in line comments when checking balance", () => { const source = `// The framework's theme runtime binds the click } component ThemeToggle { props { label = "Toggle theme" class = "" } view { } }`; const diagnostics = validateBalancedCharacters(mockDocument(source), source); assert.deepEqual(diagnostics, []); }); test("ignores apostrophes in rendered HTML copy when checking balance", () => { const source = `import LanguageSwitcher from "@wrnexus/i18n/components/LanguageSwitcher.wrn" page InternationalizationShowcase { view {

Parameters such as a person's name are inserted safely.

} }`; assert.deepEqual(validateBalancedCharacters(mockDocument(source), source), []); }); test("accepts all WRN 0.3 root members without false unknown-member errors", () => { const source = `page Dashboard { runtime = "universal" hydrate = "visible" computed { doubled = count * 2 } effect { console.log(doubled) } security { auth = "required" } load server { return {} } action save(input) { return input } client { functions { function ready() {} } } view {
{doubled}
} }`; const declaration = findTopLevelDeclaration({}, source); const document = { positionAt(offset) { return offset; }, }; assert.deepEqual(validateRootMembers(document, source, declaration.kind, declaration.match), []); }); test("ignores member-like words inside component line and block comments", () => { const source = `component Counter { // Props are passed as attributes on the mount element. /* State and View are explained here, not declared here. */ props { start = 0 label = "Count" } state count = start view { } }`; const declaration = findTopLevelDeclaration({}, source); assert.deepEqual( validateRootMembers(mockDocument(source), source, declaration.kind, declaration.match), [], ); }); test("allows a component prop named layout but rejects a root layout member", () => { const component = `component Card { props { layout = "vertical" } view {
{layout}
} }`; const componentDeclaration = findTopLevelDeclaration({}, component); assert.deepEqual( validateLayoutUsage( mockDocument(component), component, componentDeclaration.kind, componentDeclaration.match, ), [], ); const invalid = `component Card { layout = "dashboard" view {
} }`; const invalidDeclaration = findTopLevelDeclaration({}, invalid); const diagnostics = validateLayoutUsage( mockDocument(invalid), invalid, invalidDeclaration.kind, invalidDeclaration.match, ); assert.equal(diagnostics.length, 1); assert.equal(diagnostics[0].code, "wrn-invalid-layout-member"); }); test("ignores HTML-like tags inside WRN comments", () => { const source = `// The
below listens for child events. // is only documentation in this comment. page Test { /* Example markup:
Preview
*/ view {
Real content
} }`; assert.deepEqual(validateHtmlTags(mockDocument(source), source), []); }); test("does not interpret TypeScript generic types in outputs as HTML tags", () => { const source = `component AuthForm { outputs { change(payload: { values?: Array; sourceEvent?: Event }) } view {
Sign in
} }`; assert.deepEqual(validateHtmlTags(mockDocument(source), source), []); }); test("allows JavaScript-looking documentation text inside pre and code", () => { const source = `page Docs { view {
// One project, one language
page Dashboard {
  <button>Ship</button>
}
} }`; assert.deepEqual(validateHtmlTags(mockDocument(source), source), []); }); test("still reports genuinely mismatched view tags", () => { const source = `page Broken { view {
Broken
} }`; const diagnostics = validateHtmlTags(mockDocument(source), source); assert.equal(diagnostics.length, 1); assert.equal(diagnostics[0].code, "wrn-mismatched-html-tag"); });