release: WRNexusJS 0.5.10

This commit is contained in:
2026-07-30 13:36:29 +05:30
parent 8fc6f15402
commit d1b0c55b53
159 changed files with 7509 additions and 604 deletions
+36
View File
@@ -31,6 +31,7 @@ const {
maskLeadingTrivia,
validateBalancedCharacters,
validateHtmlTags,
validateLayoutUsage,
validateRootMembers,
} = require("../src/diagnostics");
Module._load = originalLoad;
@@ -136,6 +137,41 @@ test("ignores member-like words inside component line and block comments", () =>
);
});
test("allows a component prop named layout but rejects a root layout member", () => {
const component = `component Card {
props {
layout = "vertical"
}
view { <article>{layout}</article> }
}`;
const componentDeclaration = findTopLevelDeclaration({}, component);
assert.deepEqual(
validateLayoutUsage(
mockDocument(component),
component,
componentDeclaration.kind,
componentDeclaration.match,
),
[],
);
const invalid = `component Card {
layout = "dashboard"
view { <article></article> }
}`;
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 <section> below listens for child events.
// <ComboBox> is only documentation in this comment.
+63
View File
@@ -20,6 +20,69 @@ test("preserves nested prop defaults while formatting", () => {
assert.equal(formatWrn(formatted, { insertSpaces: true, tabSize: 2 }), formatted);
});
test("formats native JSON state values with readable indentation", () => {
const source = `component Footer {
state footerItems = [{"label":"Accessibility","href":"/accessibility","value":"accessibility"},{"label":"Privacy","href":"/privacy","value":"privacy"}]
view { <footer></footer> }
}
`;
const expected = `component Footer {
state footerItems = [
{
"label": "Accessibility",
"href": "/accessibility",
"value": "accessibility"
},
{
"label": "Privacy",
"href": "/privacy",
"value": "privacy"
}
]
view { <footer></footer> }
}
`;
const options = { insertSpaces: true, tabSize: 2 };
assert.equal(formatWrn(source, options), expected);
assert.equal(formatWrn(expected, options), expected);
});
test("formats direct structured component props and preserves expression props", () => {
const source = `component Demo {
view {
<Footer items={footerItems} options={{"dense":true,"theme":"public"}} links={[{"label":"Privacy","href":"/privacy"},{"label":"Contact","href":"/contact"}]} />
}
}
`;
const expected = `component Demo {
view {
<Footer
items={footerItems}
options={{
"dense": true,
"theme": "public"
}}
links={[
{
"label": "Privacy",
"href": "/privacy"
},
{
"label": "Contact",
"href": "/contact"
}
]}
/>
}
}
`;
const options = { insertSpaces: true, tabSize: 2, multilineAttributes: true };
assert.equal(formatWrn(source, options), expected);
assert.equal(formatWrn(expected, options), expected);
});
test("formats public event declarations as individual props members", () => {
const source = `component Search {\nprops { value = "" @event search = function @event clear = function }\nview { <input/> }\n}\n`;
const formatted = formatWrn(source, { insertSpaces: true, tabSize: 2 });
+19
View File
@@ -102,6 +102,25 @@ try {
compiler.compileWireFile(good);
ok("compiler accepts valid .wrn");
const structuredProps = `page FooterExample {
state footerItems = [
{
"label": "Accessibility",
"href": "/accessibility",
"value": "accessibility"
}
]
view {
<Footer
items={footerItems}
options={{"dense":true}}
links={[{"label":"Privacy","href":"/privacy"}]}
/>
}
}`;
compiler.compileWireFile(structuredProps);
ok("compiler accepts native structured state and unquoted prop expressions");
const badSrc = `page Home {\n view { <h1>Hi</h2> }\n}`;
let threw = false;
try {