Skip to content

Commit 9bf26c4

Browse files
committed
test(core/xref-db): add regression tests for empty result caching
Two tests using real IDB: 1. Queries with empty results are not cached (write path) 2. Pre-existing empty cache entries are deleted on read (migration) Address Copilot feedback requesting test coverage.
1 parent c0f7e81 commit 9bf26c4

1 file changed

Lines changed: 70 additions & 1 deletion

File tree

tests/spec/core/xref-spec.js

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
"use strict";
22

3+
import {
4+
cacheXrefData,
5+
clearXrefData,
6+
resolveXrefCache,
7+
} from "../../../src/core/xref-db.js";
38
import {
49
errorFilters,
510
flushIframes,
611
makeDefaultBody,
712
makeRSDoc,
813
makeStandardOps,
914
} from "../SpecHelper.js";
10-
import { clearXrefData } from "../../../src/core/xref-db.js";
1115

1216
describe("Core — xref", () => {
1317
afterAll(flushIframes);
@@ -1118,3 +1122,68 @@ describe("Core — xref", () => {
11181122
);
11191123
});
11201124
});
1125+
1126+
describe("Core — xref-db caching", () => {
1127+
beforeEach(async () => {
1128+
await clearXrefData();
1129+
localStorage.setItem("XREF:LAST_VERSION_CHECK", Date.now().toString());
1130+
});
1131+
1132+
afterEach(async () => {
1133+
await clearXrefData();
1134+
});
1135+
1136+
it("does not cache queries with empty results", async () => {
1137+
const queries = [
1138+
{ id: "found-term", term: "found", types: ["dfn"] },
1139+
{ id: "missing-term", term: "missing", types: ["dfn"] },
1140+
];
1141+
const results = new Map();
1142+
results.set("found-term", [{ uri: "#found", shortname: "spec" }]);
1143+
1144+
await cacheXrefData(queries, results);
1145+
const cached = await resolveXrefCache(queries);
1146+
1147+
expect(cached.has("found-term")).toBeTrue();
1148+
expect(cached.has("missing-term")).toBeFalse();
1149+
});
1150+
1151+
it("cleans up pre-existing empty cache entries on read", async () => {
1152+
const queries = [{ id: "stale-term", term: "stale", types: ["dfn"] }];
1153+
1154+
const { promise: dbReady, resolve, reject } = Promise.withResolvers();
1155+
const req = indexedDB.open("xref", 2);
1156+
req.onsuccess = () => resolve(req.result);
1157+
req.onerror = () => reject(req.error);
1158+
const db = await dbReady;
1159+
1160+
const tx = db.transaction("xrefs", "readwrite");
1161+
tx.objectStore("xrefs").add({ query: queries[0], result: [] });
1162+
const { promise: txDone, resolve: txResolve } = Promise.withResolvers();
1163+
tx.oncomplete = txResolve;
1164+
await txDone;
1165+
db.close();
1166+
1167+
const cached = await resolveXrefCache(queries);
1168+
expect(cached.has("stale-term")).toBeFalse();
1169+
1170+
const {
1171+
promise: verifyDbReady,
1172+
resolve: resolveVerifyDb,
1173+
reject: rejectVerifyDb,
1174+
} = Promise.withResolvers();
1175+
const req2 = indexedDB.open("xref", 2);
1176+
req2.onsuccess = () => resolveVerifyDb(req2.result);
1177+
req2.onerror = () => rejectVerifyDb(req2.error);
1178+
const verifyDb = await verifyDbReady;
1179+
1180+
const verifyTx = verifyDb.transaction("xrefs", "readonly");
1181+
const getReq = verifyTx.objectStore("xrefs").get("stale-term");
1182+
const { promise: getReady, resolve: resolveGet } = Promise.withResolvers();
1183+
getReq.onsuccess = () => resolveGet(getReq.result);
1184+
const remaining = await getReady;
1185+
verifyDb.close();
1186+
1187+
expect(remaining).toBeUndefined();
1188+
});
1189+
});

0 commit comments

Comments
 (0)