git.delta.rocks / jrsonnet / refs/commits / 9aabcd49c223

difftreelog

source

bindings/jrsonnet-web/mod.test.ts4.6 KiBsourcehistory
1import { assertEquals, assertRejects, assertThrows } from "@std/assert";2import { type ImportResolver, JrsonnetError, State, ValKind } from "./mod.ts";34Deno.test("evaluateSnippet returns numbers", () => {5	const state = new State();6	const v = state.evaluateSnippet("test.jsonnet", "1 + 2");7	assertEquals(v.kind, ValKind.Num);8	assertEquals(v.asNum(), 3);9});1011Deno.test("evaluateSnippet returns booleans", () => {12	const state = new State();13	const v = state.evaluateSnippet("test.jsonnet", "true && !false");14	assertEquals(v.kind, ValKind.Bool);15	assertEquals(v.asBool(), true);16});1718Deno.test("evaluateSnippet returns strings", () => {19	const state = new State();20	const v = state.evaluateSnippet("test.jsonnet", "'hello ' + 'world'");21	assertEquals(v.kind, ValKind.Str);22	assertEquals(v.asString(), "hello world");23});2425Deno.test("evaluateSnippet returns null", () => {26	const state = new State();27	const v = state.evaluateSnippet("test.jsonnet", "null");28	assertEquals(v.kind, ValKind.Null);29	assertEquals(v.asNum(), undefined);30});3132Deno.test("Val.asArr exposes ArrValue", () => {33	const state = new State();34	const arr = state.evaluateSnippet("test.jsonnet", "[10, 20, 30]").asArr();35	if (!arr) throw new Error("expected array");36	assertEquals(arr.length, 3);37	assertEquals(arr.at(1)?.asNum(), 20);38	assertEquals(arr.at(99), undefined);39});4041Deno.test("Val.asObj exposes ObjValue", () => {42	const state = new State();43	const obj = state.evaluateSnippet("test.jsonnet", "{a: 1, b: 'two'}").asObj();44	if (!obj) throw new Error("expected object");45	assertEquals(obj.keys().sort(), ["a", "b"]);46	assertEquals(obj.get("a")?.asNum(), 1);47	assertEquals(obj.get("b")?.asString(), "two");48	assertEquals(obj.get("missing"), undefined);49});5051Deno.test("evaluateSnippet manifests JSON", () => {52	const state = new State();53	const v = state.evaluateSnippet("test.jsonnet", "{a: 1, b: [2, 3]}");54	assertEquals(v.manifestJson(0), '{"a":1,"b":[2,3]}');55});5657Deno.test("evaluateSnippet propagates jsonnet errors", () => {58	const state = new State();59	assertThrows(() => state.evaluateSnippet("test.jsonnet", "error 'boom'"));60});6162Deno.test("evaluateFile without resolver rejects", async () => {63	const state = new State();64	await assertRejects(() => state.evaluateFile("anything.jsonnet"));65});6667Deno.test("resolver errors become JrsonnetError with cause", async () => {68	const original = new Error("disk on fire");69	const resolver: ImportResolver = {70		resolveFrom(_from, path) {71			return Promise.resolve(`memory:///${path}`);72		},73		loadFileContents(_resolved) {74			throw original;75		},76	};77	const state = new State(resolver);78	const err = await assertRejects(79		() => state.evaluateFile("anything.jsonnet"),80		JrsonnetError,81		"loadFileContents",82	);83	assertEquals(err.cause, original);84	assertEquals(err.frames[0]?.desc, "loadFileContents");85	// The wrapped error's own stack must not mention internal wasm frames.86	assertEquals((err.stack ?? "").includes(".wasm"), false);87});8889Deno.test("Val.applyTla calls function with named args", () => {90	const state = new State();91	const fn = state.evaluateSnippet(92		"test.jsonnet",93		"function(x, y) x + y",94	);95	const result = fn.applyTla({96		x: state.evaluateSnippet("x.jsonnet", "10"),97		y: state.evaluateSnippet("y.jsonnet", "32"),98	});99	assertEquals(result.asNum(), 42);100});101102Deno.test("Val.applyTla borrows args without consuming them", () => {103	const state = new State();104	const fn = state.evaluateSnippet("test.jsonnet", "function(x) x * 2");105	const x = state.evaluateSnippet("x.jsonnet", "21");106	assertEquals(fn.applyTla({ x }).asNum(), 42);107	assertEquals(x.asNum(), 21);108	assertEquals(fn.applyTla({ x }).asNum(), 42);109});110111Deno.test("Val.applyTla on non-function returns the value unchanged", () => {112	const state = new State();113	const v = state.evaluateSnippet("test.jsonnet", "123");114	assertEquals(v.applyTla({}).asNum(), 123);115});116117Deno.test("evaluateFileFrom resolves relative paths", async () => {118	const files: Record<string, string> = {119		"memory:///root/main.jsonnet": "import 'lib.jsonnet'",120		"memory:///root/lib.jsonnet": "{ answer: 42 }",121	};122	const resolver: ImportResolver = {123		resolveFrom(from, path) {124			const base = from ?? "memory:///root/";125			return Promise.resolve(new URL(path, base).toString());126		},127		loadFileContents(resolved) {128			const code = files[resolved];129			if (code === undefined) throw new Error(`missing ${resolved}`);130			return Promise.resolve(new TextEncoder().encode(code));131		},132	};133	const state = new State(resolver);134	const v = await state.evaluateFileFrom(135		"memory:///root/main.jsonnet",136		"./lib.jsonnet",137	);138	assertEquals(v.asObj()?.get("answer")?.asNum(), 42);139});