Files
quixos-protocol/test/query-structured.test.ts
T

105 lines
5.2 KiB
TypeScript

import assert from "node:assert/strict";
import { test } from "node:test";
import { compileCapabilityResourceSource } from "../src/capability-language/index.js";
import { compileQuery } from "../src/query/compile.js";
import { querySelectionToWire } from "../src/query/proto.js";
import { defaultQueryBudgets, type QueryDeclaration } from "../src/query/types.js";
const source = { repository: "https://example.test/structured.git", commit: "a".repeat(40) };
const result = compileCapabilityResourceSource(
`interface Highlight id "highlight" revision "highlight@1" {
queryable value range id "range" : record { sourceRevision:string; start:int32; end:int32; } { get id "range:get" execution snapshot targets [browser, server]; }
queryable value content id "content" : record { text:string; tags:list<string>; metadata:optional<record { score:int32; }>; } { get id "content:get" execution snapshot targets [browser, server]; }
}`,
{ source },
);
assert.ok(result.ok && result.resource.kind === "interface", JSON.stringify(result.diagnostics));
const iface = result.resource.revision;
const declaration: QueryDeclaration = {
id: "rows",
displayName: "Rows",
root: { kind: "workspace-interface", interface: iface.revisionId },
document: "rows.graphql",
operation: "Rows",
fragments: [],
views: [],
allowances: [],
budgets: { ...defaultQueryBudgets },
watch: false,
};
const compile = (selection: string) =>
compileQuery(
declaration,
[iface],
async () =>
`query Rows {root {objects(first:10, ${selection}) {entries {node {position:range {begin:start end} content {text tags metadata {score}}}}}}}`,
);
test("record/list query values preserve nested projections and leaf predicates", async () => {
const checked = await compile(
"where:{range:{start:{gte:4}},content:{metadata:{score:{gt:2}}}}, orderBy:{range:{start:ASC}}",
);
const extent = checked.selection[0]!.selection[0]!;
assert.equal(extent.predicate?.kind, "and");
if (extent.predicate?.kind !== "and") return;
const expressions = extent.predicate.children.map((p) => (p.kind === "compare" ? p.expression : undefined));
assert.deepEqual(
expressions.map((e) => e?.leaf),
[
{ kind: "field", interfaceRevisionId: "highlight@1", memberId: "range", valuePath: ["start"] },
{ kind: "field", interfaceRevisionId: "highlight@1", memberId: "content", valuePath: ["metadata", "score"] },
],
);
assert.deepEqual(expressions[1]?.type, { kind: "optional", value: { kind: "scalar", name: "int32" } });
const wire = querySelectionToWire(extent);
assert.equal(wire.predicate?.predicate.case, "and");
if (wire.predicate?.predicate.case === "and") {
const child = wire.predicate.predicate.value.children[0]!;
assert.equal(child.predicate.case, "compare");
if (child.predicate.case === "compare") {
const operand = child.predicate.value.operand?.operand;
assert.ok(operand?.case === "expression" && operand.value.leaf.case === "field");
assert.deepEqual(operand.value.leaf.value.valuePath, ["start"]);
}
}
const raw = JSON.stringify(checked.output);
assert.match(raw, /"begin"/);
assert.match(raw, /"tags":\{"kind":"list"/);
assert.equal(checked.effects.filter((e) => e.memberId === "range").length, 1);
});
test("structured predicates reject whole-record scalar comparisons and implicit list expansion", async () => {
await assert.rejects(compile("where:{range:{eq:4}}"), /not defined/);
await assert.rejects(compile('where:{content:{tags:{eq:"x"}}}'), /not defined/);
});
test("explicit budgets can exceed defaults without exceeding wire bounds", () => {
const compile = (rows: string) =>
compileCapabilityResourceSource(
`import interface Highlight;
package P id "p" revision "p@1" {
query Rows id "rows" root Highlight document "rows.graphql" operation "Rows" { replica; max rows ${rows}; max result-bytes 8388608; }
}`,
{ source, environment: { interfaces: new Map([["Highlight", iface]]), interfaceClosure: [iface] } },
);
const result = compile("5000");
assert.ok(result.ok && result.resource.kind === "package", JSON.stringify(result.diagnostics));
assert.equal(result.resource.revision.queries![0]!.budgets.rows, 5000);
assert.equal(compile("4294967296").ok, false);
});
test("query identity follows public contracts, not source retention commits", async () => {
const document = async () => "query Rows {root {objects(first:10) {entries {node {range {start}}}}}}";
const before = await compileQuery(declaration, [iface], document);
const retained = {
...iface,
source: { ...iface.source, repository: "https://other.test/interfaces.git", commit: "b".repeat(40) },
};
assert.equal((await compileQuery(declaration, [retained], document)).definitionDigest, before.definitionDigest);
const changed = structuredClone(retained);
changed.members[0]!.operations[0]!.id = "changed:get" as (typeof changed.members)[0]["operations"][0]["id"];
assert.notEqual((await compileQuery(declaration, [changed], document)).definitionDigest, before.definitionDigest);
assert.notEqual(
(await compileQuery({ ...declaration, budgets: { ...declaration.budgets, rows: 17 } }, [retained], document))
.definitionDigest,
before.definitionDigest,
);
});