71 lines
2.5 KiB
TypeScript
71 lines
2.5 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { parse } from "@wrnexus/syntax";
|
|
import { generateBrowserModule } from "../src/client-codegen.ts";
|
|
|
|
const source = `component FunctionDefaults {
|
|
props { timezone = "UTC" }
|
|
state selected = ""
|
|
functions {
|
|
client function choose(section = "connections", hour = 9) { selected = section; return hour }
|
|
shared function label(prefix = "event", suffix = prefix + " details", zone = timezone) { return [prefix, suffix, zone] }
|
|
}
|
|
view { <button @click="choose()">Choose</button> }
|
|
}`;
|
|
|
|
test("browser state named pending or values does not collide with commit bookkeeping", () => {
|
|
const source = `component CommitNames {
|
|
state pending = "ready"
|
|
state values = 1
|
|
state committed = false
|
|
state __v = 3
|
|
state __p = false
|
|
state __c = "safe"
|
|
functions {
|
|
shared function status() { return pending + values + __c + __v }
|
|
client function advance() { pending = "done"; values += 1; committed = true }
|
|
}
|
|
view { <button @click="advance()">Advance</button> }
|
|
}`;
|
|
const module = generateBrowserModule(parse(source));
|
|
const functions = new Function(
|
|
module.replace(/\bexport\s+(?=const|function)/g, "") + ";return __wrnexusClientFunctions;",
|
|
)();
|
|
const context = {
|
|
state: { pending: "ready", values: 1, committed: false, __v: 3, __p: false, __c: "safe" },
|
|
props: {},
|
|
batch: (apply: () => void) => apply(),
|
|
};
|
|
expect(functions.status(context)).toBe("ready1safe3");
|
|
functions.advance(context);
|
|
expect(context.state).toEqual({
|
|
pending: "done",
|
|
values: 2,
|
|
committed: true,
|
|
__v: 3,
|
|
__p: false,
|
|
__c: "safe",
|
|
});
|
|
expect(functions.status(context)).toBe("done2safe3");
|
|
});
|
|
test("browser functions retain defaults, prior-argument references and prop references", () => {
|
|
const module = generateBrowserModule(parse(source));
|
|
const functions = new Function(
|
|
module.replace(/\bexport\s+(?=const|function)/g, "") + ";return __wrnexusClientFunctions;",
|
|
)();
|
|
const context = {
|
|
state: { selected: "" },
|
|
props: { timezone: "Asia/Kolkata" },
|
|
batch: (apply: () => void) => apply(),
|
|
};
|
|
expect(functions.choose(context)).toBe(9);
|
|
expect(context.state.selected).toBe("connections");
|
|
expect(functions.label(context)).toEqual(["event", "event details", "Asia/Kolkata"]);
|
|
expect(functions.label(context, "meeting")).toEqual([
|
|
"meeting",
|
|
"meeting details",
|
|
"Asia/Kolkata",
|
|
]);
|
|
expect(functions.choose(context, undefined, 0)).toBe(0);
|
|
expect(functions.label(context, null, "explicit", "UTC")).toEqual([null, "explicit", "UTC"]);
|
|
});
|