





























@@ -1,4 +1,5 @@
11import { describe, expect, it } from "vitest";
2+import type { JsoncValue } from "../../jsonc/ast.js";
23import { parseJsonl } from "../../jsonl/parse.js";
34import { resolveJsonlOcPath } from "../../jsonl/resolve.js";
45import { parseOcPath } from "../../oc-path.js";
@@ -7,6 +8,20 @@ function rs(raw: string, ocPath: string) {
78return resolveJsonlOcPath(parseJsonl(raw).ast, parseOcPath(ocPath));
89}
91011+function expectNumberValue(node: JsoncValue, value: number) {
12+expect(node.kind).toBe("number");
13+if (node.kind === "number") {
14+expect(node.value).toBe(value);
15+}
16+}
17+18+function expectStringValue(node: JsoncValue, value: string) {
19+expect(node.kind).toBe("string");
20+if (node.kind === "string") {
21+expect(node.value).toBe(value);
22+}
23+}
24+1025describe("jsonl resolver edges", () => {
1126it("root resolves with no segments", () => {
1227expect(rs('{"a":1}\n', "oc://log")?.kind).toBe("root");
@@ -25,15 +40,15 @@ describe("jsonl resolver edges", () => {
2540const m = rs('{"a":1}\n{"a":2}\n{"a":3}\n', "oc://log/$last/a");
2641expect(m?.kind).toBe("object-entry");
2742if (m?.kind === "object-entry") {
28-expect(m.node.value).toMatchObject({ kind: "number", value: 3 });
43+expectNumberValue(m.node.value, 3);
2944}
3045});
31463247it("$last skips trailing blank lines", () => {
3348const m = rs('{"a":1}\n\n\n', "oc://log/$last/a");
3449expect(m?.kind).toBe("object-entry");
3550if (m?.kind === "object-entry") {
36-expect(m.node.value).toMatchObject({ kind: "number", value: 1 });
51+expectNumberValue(m.node.value, 1);
3752}
3853});
3954@@ -76,30 +91,30 @@ describe("jsonl resolver edges", () => {
7691const m = rs('{"r":{"ok":true,"d":"x"}}\n', "oc://log/L1/r.d");
7792expect(m?.kind).toBe("object-entry");
7893if (m?.kind === "object-entry") {
79-expect(m.node.value).toMatchObject({ kind: "string", value: "x" });
94+expectStringValue(m.node.value, "x");
8095}
8196});
82978398it("array index inside a line resolves", () => {
8499const m = rs('{"items":["a","b","c"]}\n', "oc://log/L1/items.2");
85100expect(m?.kind).toBe("value");
86101if (m?.kind === "value") {
87-expect(m.node).toMatchObject({ kind: "string", value: "c" });
102+expectStringValue(m.node, "c");
88103}
89104});
9010591106it("line numbers are 1-indexed", () => {
92107const m = rs('{"a":1}\n{"a":2}\n', "oc://log/L1/a");
93108if (m?.kind === "object-entry") {
94-expect(m.node.value).toMatchObject({ kind: "number", value: 1 });
109+expectNumberValue(m.node.value, 1);
95110}
96111});
9711298113it("line numbers preserved across blank/malformed entries", () => {
99114const m = rs('{"a":1}\n\nbroken\n{"a":4}\n', "oc://log/L4/a");
100115expect(m?.kind).toBe("object-entry");
101116if (m?.kind === "object-entry") {
102-expect(m.node.value).toMatchObject({ kind: "number", value: 4 });
117+expectNumberValue(m.node.value, 4);
103118}
104119});
105120此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。