@embedpdf/engine-core 3.0.0-next.11 → 3.0.0-next.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AnnotationListSnapshot-C1U3XUxP.d.cts → AnnotationListSnapshot-x6tKulNV.d.cts} +153 -28
- package/dist/{AnnotationListSnapshot-C1U3XUxP.d.ts → AnnotationListSnapshot-x6tKulNV.d.ts} +153 -28
- package/dist/{DocumentSecurityService-7nL9aY75.d.ts → DocumentSecurityService-9MawYxP-.d.ts} +2 -2
- package/dist/{DocumentSecurityService-6rhztZlz.d.cts → DocumentSecurityService-CK0pejAK.d.cts} +2 -2
- package/dist/{Engine-D3868xIU.d.cts → Engine--0XF0UAK.d.cts} +56 -3
- package/dist/{Engine-CWnAKccD.d.ts → Engine-Ds0ytbl6.d.ts} +56 -3
- package/dist/{builders-Do6_4KnS.cjs → builders-8Hl1AYNU.cjs} +14 -8
- package/dist/builders-8Hl1AYNU.cjs.map +1 -0
- package/dist/{builders-Cdz34nbF.js → builders-DOjcKDWQ.js} +14 -8
- package/dist/builders-DOjcKDWQ.js.map +1 -0
- package/dist/conformance.cjs +552 -95
- package/dist/conformance.cjs.map +1 -1
- package/dist/conformance.d.cts +50 -3
- package/dist/conformance.d.ts +50 -3
- package/dist/conformance.js +550 -96
- package/dist/conformance.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/runtime.cjs +1 -1
- package/dist/runtime.d.cts +66 -5
- package/dist/runtime.d.ts +66 -5
- package/dist/runtime.js +1 -1
- package/dist/{schemas-XGrNVMDd.js → schemas-DOyVEPk7.js} +51 -5
- package/dist/schemas-DOyVEPk7.js.map +1 -0
- package/dist/{schemas-CS5iPpX5.cjs → schemas-RChsAMWw.cjs} +92 -4
- package/dist/schemas-RChsAMWw.cjs.map +1 -0
- package/dist/wire.cjs +23 -1
- package/dist/wire.cjs.map +1 -1
- package/dist/wire.d.cts +32 -3
- package/dist/wire.d.ts +32 -3
- package/dist/wire.js +17 -2
- package/dist/wire.js.map +1 -1
- package/package.json +1 -1
- package/dist/builders-Cdz34nbF.js.map +0 -1
- package/dist/builders-Do6_4KnS.cjs.map +0 -1
- package/dist/schemas-CS5iPpX5.cjs.map +0 -1
- package/dist/schemas-XGrNVMDd.js.map +0 -1
package/dist/conformance.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { f as pdfQuadBounds, i as EngineError, n as foldText, u as isRotatedGeometryRun } from "./fold-BfyxxwS6.js";
|
|
2
2
|
import { f as EngineErrorCode, o as sliceTextByChars } from "./PageInsertBlankInput-WKY0tr6S.js";
|
|
3
3
|
import { t as AbortError } from "./AbortError-8-9JAX1Y.js";
|
|
4
|
-
import {
|
|
4
|
+
import { $ as PageListSnapshotSchema, Ft as FormSnapshotSchema, J as PageGeometrySnapshotSchema, M as FormRepairResultSchema, N as FormSetValueResultSchema, Vt as AnnotationDTOSchema, W as PageDeleteResultSchema, br as DocumentActionsSnapshotSchema, d as AnnotationListPageSnapshotSchema, f as AnnotationListSnapshotAllPagesSchema, ft as PageTextSnapshotSchema, j as FormImportResultSchema, l as AnnotationFlattenResultSchema, lt as PageRotateResultSchema, m as AnnotationUpdateResultSchema, mt as RedactionApplyResultSchema, o as AnnotationCreateResultSchema, p as AnnotationMoveResultSchema, q as PageFlattenResultSchema, rt as PageNameResultSchema, s as AnnotationDeleteResultSchema, tt as PageMoveResultSchema, xt as SearchSliceSchema } from "./schemas-DOyVEPk7.js";
|
|
5
5
|
//#region src/conformance/runMetadataConformance.ts
|
|
6
6
|
/**
|
|
7
7
|
* The conformance harness is transport-agnostic. It takes the test runner as
|
|
@@ -18,7 +18,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
18
18
|
if (engine) await engine.destroy();
|
|
19
19
|
});
|
|
20
20
|
test("reads metadata from sample fixture", async () => {
|
|
21
|
-
const doc = await openFixture$
|
|
21
|
+
const doc = await openFixture$20(engine, opts);
|
|
22
22
|
try {
|
|
23
23
|
const meta = await doc.metadata.read();
|
|
24
24
|
expect(meta).toMatchObject(opts.fixture.expected);
|
|
@@ -28,7 +28,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
30
|
test("abort() before completion rejects with AbortError", async () => {
|
|
31
|
-
const doc = await openFixture$
|
|
31
|
+
const doc = await openFixture$20(engine, opts);
|
|
32
32
|
try {
|
|
33
33
|
const p = doc.metadata.read();
|
|
34
34
|
p.abort("test");
|
|
@@ -38,7 +38,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
test("aborting one read does not affect a concurrent one", async () => {
|
|
41
|
-
const doc = await openFixture$
|
|
41
|
+
const doc = await openFixture$20(engine, opts);
|
|
42
42
|
try {
|
|
43
43
|
const a = doc.metadata.read();
|
|
44
44
|
const b = doc.metadata.read();
|
|
@@ -50,7 +50,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
52
|
test("metadata after close throws DocNotOpen", async () => {
|
|
53
|
-
const doc = await openFixture$
|
|
53
|
+
const doc = await openFixture$20(engine, opts);
|
|
54
54
|
await doc.close();
|
|
55
55
|
let caught;
|
|
56
56
|
try {
|
|
@@ -62,7 +62,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
62
62
|
expect(EngineError.is(caught, EngineErrorCode.DocNotOpen)).toBe(true);
|
|
63
63
|
});
|
|
64
64
|
test("update() sets standard + custom fields and a subsequent read observes them", async () => {
|
|
65
|
-
const doc = await openFixture$
|
|
65
|
+
const doc = await openFixture$20(engine, opts);
|
|
66
66
|
try {
|
|
67
67
|
const result = await doc.metadata.update({
|
|
68
68
|
title: "Conformance Title",
|
|
@@ -81,7 +81,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
81
81
|
}
|
|
82
82
|
});
|
|
83
83
|
test("update() clears a field with null", async () => {
|
|
84
|
-
const doc = await openFixture$
|
|
84
|
+
const doc = await openFixture$20(engine, opts);
|
|
85
85
|
try {
|
|
86
86
|
await doc.metadata.update({ title: "To Be Cleared" });
|
|
87
87
|
const set = await doc.metadata.read();
|
|
@@ -94,7 +94,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
test("update() after close throws DocNotOpen", async () => {
|
|
97
|
-
const doc = await openFixture$
|
|
97
|
+
const doc = await openFixture$20(engine, opts);
|
|
98
98
|
await doc.close();
|
|
99
99
|
let caught;
|
|
100
100
|
try {
|
|
@@ -107,7 +107,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
107
107
|
});
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
|
-
async function openFixture$
|
|
110
|
+
async function openFixture$20(engine, opts) {
|
|
111
111
|
if (opts.openKind === "bytes") {
|
|
112
112
|
const bytes = await opts.fixture.bytes();
|
|
113
113
|
return engine.open({
|
|
@@ -134,7 +134,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
134
134
|
if (engine) await engine.destroy();
|
|
135
135
|
});
|
|
136
136
|
test("listRawAll returns one entry per page with valid PageState", async () => {
|
|
137
|
-
const doc = await openFixture$
|
|
137
|
+
const doc = await openFixture$19(engine, opts);
|
|
138
138
|
try {
|
|
139
139
|
const snap = await doc.annotations.listRawAll();
|
|
140
140
|
expect(AnnotationListSnapshotAllPagesSchema.safeParse(snap).success).toBe(true);
|
|
@@ -148,7 +148,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
150
|
test("listRaw on the test page returns the expected counts and DTO shape", async () => {
|
|
151
|
-
const doc = await openFixture$
|
|
151
|
+
const doc = await openFixture$19(engine, opts);
|
|
152
152
|
try {
|
|
153
153
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
154
154
|
expect(AnnotationListPageSnapshotSchema.safeParse(snap).success).toBe(true);
|
|
@@ -178,7 +178,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
178
178
|
}
|
|
179
179
|
});
|
|
180
180
|
test("shape/vertex/line annotations expose their family fields", async () => {
|
|
181
|
-
const doc = await openFixture$
|
|
181
|
+
const doc = await openFixture$19(engine, opts);
|
|
182
182
|
try {
|
|
183
183
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
184
184
|
for (const a of snap.annotations) {
|
|
@@ -237,7 +237,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
237
237
|
}
|
|
238
238
|
});
|
|
239
239
|
test("full page list dispatches per-subtype and matches raw counts", async () => {
|
|
240
|
-
const doc = await openFixture$
|
|
240
|
+
const doc = await openFixture$19(engine, opts);
|
|
241
241
|
try {
|
|
242
242
|
const full = await doc.page(opts.fixture.pageObjectNumber).annotations.list();
|
|
243
243
|
expect(AnnotationListPageSnapshotSchema.safeParse(full).success).toBe(true);
|
|
@@ -247,7 +247,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
247
247
|
}
|
|
248
248
|
});
|
|
249
249
|
test("every annotation DTO satisfies AnnotationDTOSchema (discriminated union)", async () => {
|
|
250
|
-
const doc = await openFixture$
|
|
250
|
+
const doc = await openFixture$19(engine, opts);
|
|
251
251
|
try {
|
|
252
252
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
253
253
|
for (const a of snap.annotations) {
|
|
@@ -287,7 +287,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
287
287
|
});
|
|
288
288
|
if (opts.fixture.expectsWeakAnnotation) {
|
|
289
289
|
test("weak annotations carry identityQuality: weak and ref.kind: index", async () => {
|
|
290
|
-
const doc = await openFixture$
|
|
290
|
+
const doc = await openFixture$19(engine, opts);
|
|
291
291
|
try {
|
|
292
292
|
const weak = (await doc.annotations.listRaw(opts.fixture.pageObjectNumber)).annotations.find((a) => a.identityQuality === "weak");
|
|
293
293
|
expect(weak !== void 0).toBe(true);
|
|
@@ -297,7 +297,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
297
297
|
}
|
|
298
298
|
});
|
|
299
299
|
test("a stale revision token throws InvalidReference", async () => {
|
|
300
|
-
const doc = await openFixture$
|
|
300
|
+
const doc = await openFixture$19(engine, opts);
|
|
301
301
|
try {
|
|
302
302
|
const snap = await doc.page(opts.fixture.pageObjectNumber).annotations.list();
|
|
303
303
|
const weak = snap.annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -313,7 +313,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
313
313
|
});
|
|
314
314
|
}
|
|
315
315
|
test("abort() on listRaw rejects with AbortError", async () => {
|
|
316
|
-
const doc = await openFixture$
|
|
316
|
+
const doc = await openFixture$19(engine, opts);
|
|
317
317
|
try {
|
|
318
318
|
const p = doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
319
319
|
p.abort("test");
|
|
@@ -323,7 +323,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
323
323
|
}
|
|
324
324
|
});
|
|
325
325
|
test("listRaw on an unknown pageObjectNumber throws NotFound", async () => {
|
|
326
|
-
const doc = await openFixture$
|
|
326
|
+
const doc = await openFixture$19(engine, opts);
|
|
327
327
|
try {
|
|
328
328
|
let caught;
|
|
329
329
|
try {
|
|
@@ -339,7 +339,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
339
339
|
});
|
|
340
340
|
});
|
|
341
341
|
}
|
|
342
|
-
async function openFixture$
|
|
342
|
+
async function openFixture$19(engine, opts) {
|
|
343
343
|
if (opts.openKind === "bytes") {
|
|
344
344
|
const bytes = await opts.fixture.bytes();
|
|
345
345
|
return engine.open({
|
|
@@ -808,7 +808,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
808
808
|
if (engine) await engine.destroy();
|
|
809
809
|
});
|
|
810
810
|
test("create appends without shifting indices and leaves weak refs valid", async () => {
|
|
811
|
-
const doc = await openFixture$
|
|
811
|
+
const doc = await openFixture$18(engine, opts);
|
|
812
812
|
try {
|
|
813
813
|
const page = doc.page(fix.pageObjectNumber);
|
|
814
814
|
const before = await page.annotations.list();
|
|
@@ -844,7 +844,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
844
844
|
}
|
|
845
845
|
});
|
|
846
846
|
test("create + update honor annotation flags (set on create, merge on patch)", async () => {
|
|
847
|
-
const doc = await openFixture$
|
|
847
|
+
const doc = await openFixture$18(engine, opts);
|
|
848
848
|
try {
|
|
849
849
|
const page = doc.page(fix.pageObjectNumber);
|
|
850
850
|
const draft = {
|
|
@@ -879,7 +879,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
879
879
|
}
|
|
880
880
|
});
|
|
881
881
|
test("create shape annotations (circle + square) round-trip shape fields", async () => {
|
|
882
|
-
const doc = await openFixture$
|
|
882
|
+
const doc = await openFixture$18(engine, opts);
|
|
883
883
|
try {
|
|
884
884
|
const page = doc.page(fix.pageObjectNumber);
|
|
885
885
|
const circleDraft = {
|
|
@@ -960,7 +960,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
960
960
|
}
|
|
961
961
|
});
|
|
962
962
|
test("cloudy border (/BE) + rect differences (/RD) are tri-state", async () => {
|
|
963
|
-
const doc = await openFixture$
|
|
963
|
+
const doc = await openFixture$18(engine, opts);
|
|
964
964
|
try {
|
|
965
965
|
const page = doc.page(fix.pageObjectNumber);
|
|
966
966
|
const plainDraft = {
|
|
@@ -1039,7 +1039,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1039
1039
|
}
|
|
1040
1040
|
});
|
|
1041
1041
|
test("update echoes the appearance verdict: moves preserve /AP, restyles re-bake", async () => {
|
|
1042
|
-
const doc = await openFixture$
|
|
1042
|
+
const doc = await openFixture$18(engine, opts);
|
|
1043
1043
|
try {
|
|
1044
1044
|
const page = doc.page(fix.pageObjectNumber);
|
|
1045
1045
|
const draft = {
|
|
@@ -1114,7 +1114,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1114
1114
|
}
|
|
1115
1115
|
});
|
|
1116
1116
|
test("a partial /DA patch preserves the unpatched font members", async () => {
|
|
1117
|
-
const doc = await openFixture$
|
|
1117
|
+
const doc = await openFixture$18(engine, opts);
|
|
1118
1118
|
try {
|
|
1119
1119
|
const page = doc.page(fix.pageObjectNumber);
|
|
1120
1120
|
const draft = {
|
|
@@ -1170,7 +1170,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1170
1170
|
}
|
|
1171
1171
|
});
|
|
1172
1172
|
test("box transform is tri-state: rect-only moves keep rotation, null flattens", async () => {
|
|
1173
|
-
const doc = await openFixture$
|
|
1173
|
+
const doc = await openFixture$18(engine, opts);
|
|
1174
1174
|
try {
|
|
1175
1175
|
const page = doc.page(fix.pageObjectNumber);
|
|
1176
1176
|
const draft = {
|
|
@@ -1231,7 +1231,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1231
1231
|
}
|
|
1232
1232
|
});
|
|
1233
1233
|
test("create vertex + line annotations (polygon/polyline/line) round-trip geometry", async () => {
|
|
1234
|
-
const doc = await openFixture$
|
|
1234
|
+
const doc = await openFixture$18(engine, opts);
|
|
1235
1235
|
try {
|
|
1236
1236
|
const page = doc.page(fix.pageObjectNumber);
|
|
1237
1237
|
const polygonDraft = {
|
|
@@ -1362,7 +1362,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1362
1362
|
}
|
|
1363
1363
|
});
|
|
1364
1364
|
test("create free-text + callout round-trip text/colour/intent fields", async () => {
|
|
1365
|
-
const doc = await openFixture$
|
|
1365
|
+
const doc = await openFixture$18(engine, opts);
|
|
1366
1366
|
try {
|
|
1367
1367
|
const page = doc.page(fix.pageObjectNumber);
|
|
1368
1368
|
const freeTextDraft = {
|
|
@@ -1458,7 +1458,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1458
1458
|
}
|
|
1459
1459
|
});
|
|
1460
1460
|
test("update a free-text patches alignment + colours and is non-structural", async () => {
|
|
1461
|
-
const doc = await openFixture$
|
|
1461
|
+
const doc = await openFixture$18(engine, opts);
|
|
1462
1462
|
try {
|
|
1463
1463
|
const page = doc.page(fix.pageObjectNumber);
|
|
1464
1464
|
const created = await page.annotations.create({
|
|
@@ -1519,7 +1519,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1519
1519
|
}
|
|
1520
1520
|
});
|
|
1521
1521
|
test("create redact (area + text) round-trips label + colour fields", async () => {
|
|
1522
|
-
const doc = await openFixture$
|
|
1522
|
+
const doc = await openFixture$18(engine, opts);
|
|
1523
1523
|
try {
|
|
1524
1524
|
const page = doc.page(fix.pageObjectNumber);
|
|
1525
1525
|
const areaDraft = {
|
|
@@ -1599,7 +1599,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1599
1599
|
}
|
|
1600
1600
|
});
|
|
1601
1601
|
test("update a redact patches the label and clears it, non-structurally", async () => {
|
|
1602
|
-
const doc = await openFixture$
|
|
1602
|
+
const doc = await openFixture$18(engine, opts);
|
|
1603
1603
|
try {
|
|
1604
1604
|
const page = doc.page(fix.pageObjectNumber);
|
|
1605
1605
|
const created = await page.annotations.create({
|
|
@@ -1676,7 +1676,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1676
1676
|
}
|
|
1677
1677
|
});
|
|
1678
1678
|
test("create + update a caret round-trips color/opacity/rect differences", async () => {
|
|
1679
|
-
const doc = await openFixture$
|
|
1679
|
+
const doc = await openFixture$18(engine, opts);
|
|
1680
1680
|
try {
|
|
1681
1681
|
const page = doc.page(fix.pageObjectNumber);
|
|
1682
1682
|
const caretDraft = {
|
|
@@ -1756,7 +1756,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1756
1756
|
}
|
|
1757
1757
|
});
|
|
1758
1758
|
test("update an ink annotation patches strokes + color and is non-structural", async () => {
|
|
1759
|
-
const doc = await openFixture$
|
|
1759
|
+
const doc = await openFixture$18(engine, opts);
|
|
1760
1760
|
try {
|
|
1761
1761
|
const page = doc.page(fix.pageObjectNumber);
|
|
1762
1762
|
const created = await page.annotations.create({
|
|
@@ -1807,7 +1807,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1807
1807
|
}
|
|
1808
1808
|
});
|
|
1809
1809
|
test("ink highlight intent + blend round-trip and unrelated patches preserve blend", async () => {
|
|
1810
|
-
const doc = await openFixture$
|
|
1810
|
+
const doc = await openFixture$18(engine, opts);
|
|
1811
1811
|
try {
|
|
1812
1812
|
const page = doc.page(fix.pageObjectNumber);
|
|
1813
1813
|
const created = await page.annotations.create({
|
|
@@ -1850,7 +1850,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1850
1850
|
}
|
|
1851
1851
|
});
|
|
1852
1852
|
test("update a polyline patches vertices + line endings and is non-structural", async () => {
|
|
1853
|
-
const doc = await openFixture$
|
|
1853
|
+
const doc = await openFixture$18(engine, opts);
|
|
1854
1854
|
try {
|
|
1855
1855
|
const page = doc.page(fix.pageObjectNumber);
|
|
1856
1856
|
const created = await page.annotations.create({
|
|
@@ -1899,7 +1899,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1899
1899
|
}
|
|
1900
1900
|
});
|
|
1901
1901
|
test("update a shape annotation patches color and is non-structural", async () => {
|
|
1902
|
-
const doc = await openFixture$
|
|
1902
|
+
const doc = await openFixture$18(engine, opts);
|
|
1903
1903
|
try {
|
|
1904
1904
|
const page = doc.page(fix.pageObjectNumber);
|
|
1905
1905
|
const created = await page.annotations.create({
|
|
@@ -1948,7 +1948,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1948
1948
|
}
|
|
1949
1949
|
});
|
|
1950
1950
|
if (opts.supportsAppearanceRasters) test("creating a shape bakes an /AP appearance the reader can rasterize", async () => {
|
|
1951
|
-
const doc = await openFixture$
|
|
1951
|
+
const doc = await openFixture$18(engine, opts);
|
|
1952
1952
|
try {
|
|
1953
1953
|
const page = doc.page(fix.pageObjectNumber);
|
|
1954
1954
|
const created = await page.annotations.create({
|
|
@@ -1978,7 +1978,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1978
1978
|
}
|
|
1979
1979
|
});
|
|
1980
1980
|
test("update on a durable annotation is non-structural and never touches /NM", async () => {
|
|
1981
|
-
const doc = await openFixture$
|
|
1981
|
+
const doc = await openFixture$18(engine, opts);
|
|
1982
1982
|
try {
|
|
1983
1983
|
const page = doc.page(fix.pageObjectNumber);
|
|
1984
1984
|
const before = await page.annotations.list();
|
|
@@ -2004,7 +2004,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2004
2004
|
}
|
|
2005
2005
|
});
|
|
2006
2006
|
if (fix.expectsWeakAnnotation) test("update on a weak annotation stamps a UUID v4 /NM and upgrades the ref", async () => {
|
|
2007
|
-
const doc = await openFixture$
|
|
2007
|
+
const doc = await openFixture$18(engine, opts);
|
|
2008
2008
|
try {
|
|
2009
2009
|
const page = doc.page(fix.pageObjectNumber);
|
|
2010
2010
|
const before = await page.annotations.list();
|
|
@@ -2034,7 +2034,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2034
2034
|
}
|
|
2035
2035
|
});
|
|
2036
2036
|
test("delete by objectNumber removes the annotation and reports a stable id", async () => {
|
|
2037
|
-
const doc = await openFixture$
|
|
2037
|
+
const doc = await openFixture$18(engine, opts);
|
|
2038
2038
|
try {
|
|
2039
2039
|
const page = doc.page(fix.pageObjectNumber);
|
|
2040
2040
|
const draft = {
|
|
@@ -2064,7 +2064,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2064
2064
|
}
|
|
2065
2065
|
});
|
|
2066
2066
|
if (fix.expectsWeakAnnotation) test("delete by index of a weak annotation reports deleted: null and refetch reason", async () => {
|
|
2067
|
-
const doc = await openFixture$
|
|
2067
|
+
const doc = await openFixture$18(engine, opts);
|
|
2068
2068
|
try {
|
|
2069
2069
|
const page = doc.page(fix.pageObjectNumber);
|
|
2070
2070
|
const weak = (await page.annotations.list()).annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -2087,7 +2087,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2087
2087
|
}
|
|
2088
2088
|
});
|
|
2089
2089
|
test("abort on create rejects with AbortError", async () => {
|
|
2090
|
-
const doc = await openFixture$
|
|
2090
|
+
const doc = await openFixture$18(engine, opts);
|
|
2091
2091
|
try {
|
|
2092
2092
|
const page = doc.page(fix.pageObjectNumber);
|
|
2093
2093
|
const draft = {
|
|
@@ -2103,7 +2103,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2103
2103
|
}
|
|
2104
2104
|
});
|
|
2105
2105
|
test("update with a stale index revision throws InvalidReference", async () => {
|
|
2106
|
-
const doc = await openFixture$
|
|
2106
|
+
const doc = await openFixture$18(engine, opts);
|
|
2107
2107
|
try {
|
|
2108
2108
|
const page = doc.page(fix.pageObjectNumber);
|
|
2109
2109
|
const weak = (await page.annotations.list()).annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -2130,7 +2130,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2130
2130
|
}
|
|
2131
2131
|
});
|
|
2132
2132
|
test("move single durable annotation reorders within the page (single-as-batch)", async () => {
|
|
2133
|
-
const doc = await openFixture$
|
|
2133
|
+
const doc = await openFixture$18(engine, opts);
|
|
2134
2134
|
try {
|
|
2135
2135
|
const page = doc.page(fix.pageObjectNumber);
|
|
2136
2136
|
const aDraft = {
|
|
@@ -2174,7 +2174,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2174
2174
|
}
|
|
2175
2175
|
});
|
|
2176
2176
|
test("move multi-block preserves caller-supplied order at the destination", async () => {
|
|
2177
|
-
const doc = await openFixture$
|
|
2177
|
+
const doc = await openFixture$18(engine, opts);
|
|
2178
2178
|
try {
|
|
2179
2179
|
const page = doc.page(fix.pageObjectNumber);
|
|
2180
2180
|
const ids = await Promise.all([
|
|
@@ -2213,7 +2213,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2213
2213
|
}
|
|
2214
2214
|
});
|
|
2215
2215
|
if (fix.expectsWeakAnnotation) test("move on a weak annotation upgrades it to durable /NM (one rev bump for batch)", async () => {
|
|
2216
|
-
const doc = await openFixture$
|
|
2216
|
+
const doc = await openFixture$18(engine, opts);
|
|
2217
2217
|
try {
|
|
2218
2218
|
const page = doc.page(fix.pageObjectNumber);
|
|
2219
2219
|
const before = await page.annotations.list();
|
|
@@ -2238,7 +2238,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2238
2238
|
}
|
|
2239
2239
|
});
|
|
2240
2240
|
test("move with a stale index revision rejects (locked rev-token guard)", async () => {
|
|
2241
|
-
const doc = await openFixture$
|
|
2241
|
+
const doc = await openFixture$18(engine, opts);
|
|
2242
2242
|
try {
|
|
2243
2243
|
const page = doc.page(fix.pageObjectNumber);
|
|
2244
2244
|
const a = await page.annotations.create({
|
|
@@ -2276,7 +2276,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2276
2276
|
}
|
|
2277
2277
|
});
|
|
2278
2278
|
test("move with out-of-range toIndex rejects with InvalidArg", async () => {
|
|
2279
|
-
const doc = await openFixture$
|
|
2279
|
+
const doc = await openFixture$18(engine, opts);
|
|
2280
2280
|
try {
|
|
2281
2281
|
const page = doc.page(fix.pageObjectNumber);
|
|
2282
2282
|
const a = await page.annotations.create({
|
|
@@ -2300,7 +2300,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2300
2300
|
}
|
|
2301
2301
|
});
|
|
2302
2302
|
test("move with duplicate refs rejects with InvalidArg", async () => {
|
|
2303
|
-
const doc = await openFixture$
|
|
2303
|
+
const doc = await openFixture$18(engine, opts);
|
|
2304
2304
|
try {
|
|
2305
2305
|
const page = doc.page(fix.pageObjectNumber);
|
|
2306
2306
|
const a = await page.annotations.create({
|
|
@@ -2323,7 +2323,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2323
2323
|
}
|
|
2324
2324
|
});
|
|
2325
2325
|
test("abort on move rejects with AbortError", async () => {
|
|
2326
|
-
const doc = await openFixture$
|
|
2326
|
+
const doc = await openFixture$18(engine, opts);
|
|
2327
2327
|
try {
|
|
2328
2328
|
const page = doc.page(fix.pageObjectNumber);
|
|
2329
2329
|
const a = await page.annotations.create({
|
|
@@ -2344,7 +2344,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2344
2344
|
}
|
|
2345
2345
|
});
|
|
2346
2346
|
test("a page move does NOT bump per-page RevisionTokens (weak refs survive reorder)", async () => {
|
|
2347
|
-
const doc = await openFixture$
|
|
2347
|
+
const doc = await openFixture$18(engine, opts);
|
|
2348
2348
|
try {
|
|
2349
2349
|
const list = await doc.pages.list();
|
|
2350
2350
|
if (list.pages.length < 1) return;
|
|
@@ -2359,7 +2359,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2359
2359
|
}
|
|
2360
2360
|
});
|
|
2361
2361
|
test("create a reply links /IRT and defaults /RT to \"reply\", reporting the parent", async () => {
|
|
2362
|
-
const doc = await openFixture$
|
|
2362
|
+
const doc = await openFixture$18(engine, opts);
|
|
2363
2363
|
try {
|
|
2364
2364
|
const page = doc.page(fix.pageObjectNumber);
|
|
2365
2365
|
const parent = await page.annotations.create({
|
|
@@ -2393,7 +2393,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2393
2393
|
}
|
|
2394
2394
|
});
|
|
2395
2395
|
test("create a grouped subordinate writes /RT /Group", async () => {
|
|
2396
|
-
const doc = await openFixture$
|
|
2396
|
+
const doc = await openFixture$18(engine, opts);
|
|
2397
2397
|
try {
|
|
2398
2398
|
const page = doc.page(fix.pageObjectNumber);
|
|
2399
2399
|
const primary = await page.annotations.create({
|
|
@@ -2424,7 +2424,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2424
2424
|
}
|
|
2425
2425
|
});
|
|
2426
2426
|
test("create link annotations round-trip uri, goto/xyz, goto/fitH, and dead targets", async () => {
|
|
2427
|
-
const doc = await openFixture$
|
|
2427
|
+
const doc = await openFixture$18(engine, opts);
|
|
2428
2428
|
try {
|
|
2429
2429
|
const page = doc.page(fix.pageObjectNumber);
|
|
2430
2430
|
const uri = await page.annotations.create({
|
|
@@ -2501,7 +2501,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2501
2501
|
}
|
|
2502
2502
|
});
|
|
2503
2503
|
test("a link patch retargets in both directions (uri→goto, goto→uri) and moves the rect", async () => {
|
|
2504
|
-
const doc = await openFixture$
|
|
2504
|
+
const doc = await openFixture$18(engine, opts);
|
|
2505
2505
|
try {
|
|
2506
2506
|
const page = doc.page(fix.pageObjectNumber);
|
|
2507
2507
|
const created = await page.annotations.create({
|
|
@@ -2556,7 +2556,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2556
2556
|
}
|
|
2557
2557
|
});
|
|
2558
2558
|
test("a link patch clears the target with null — a dead link on re-read", async () => {
|
|
2559
|
-
const doc = await openFixture$
|
|
2559
|
+
const doc = await openFixture$18(engine, opts);
|
|
2560
2560
|
try {
|
|
2561
2561
|
const page = doc.page(fix.pageObjectNumber);
|
|
2562
2562
|
const created = await page.annotations.create({
|
|
@@ -2595,7 +2595,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2595
2595
|
}
|
|
2596
2596
|
});
|
|
2597
2597
|
test("a link grouped to a highlight round-trips /IRT + /RT /Group with its target", async () => {
|
|
2598
|
-
const doc = await openFixture$
|
|
2598
|
+
const doc = await openFixture$18(engine, opts);
|
|
2599
2599
|
try {
|
|
2600
2600
|
const page = doc.page(fix.pageObjectNumber);
|
|
2601
2601
|
const parent = await page.annotations.create({
|
|
@@ -2629,7 +2629,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2629
2629
|
}
|
|
2630
2630
|
});
|
|
2631
2631
|
test("replace-text round-trips /IT and groups StrikeOut under its Caret", async () => {
|
|
2632
|
-
const doc = await openFixture$
|
|
2632
|
+
const doc = await openFixture$18(engine, opts);
|
|
2633
2633
|
try {
|
|
2634
2634
|
const page = doc.page(fix.pageObjectNumber);
|
|
2635
2635
|
const caret = await page.annotations.create({
|
|
@@ -2681,7 +2681,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2681
2681
|
}
|
|
2682
2682
|
});
|
|
2683
2683
|
test("patch inReplyTo: null clears /IRT and /RT (back to top-level)", async () => {
|
|
2684
|
-
const doc = await openFixture$
|
|
2684
|
+
const doc = await openFixture$18(engine, opts);
|
|
2685
2685
|
try {
|
|
2686
2686
|
const page = doc.page(fix.pageObjectNumber);
|
|
2687
2687
|
const parent = await page.annotations.create({
|
|
@@ -2708,7 +2708,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2708
2708
|
}
|
|
2709
2709
|
});
|
|
2710
2710
|
test("create with a cross-page /IRT parent throws InvalidArg", async () => {
|
|
2711
|
-
const doc = await openFixture$
|
|
2711
|
+
const doc = await openFixture$18(engine, opts);
|
|
2712
2712
|
try {
|
|
2713
2713
|
const page = doc.page(fix.pageObjectNumber);
|
|
2714
2714
|
const parent = await page.annotations.create({
|
|
@@ -2739,7 +2739,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2739
2739
|
}
|
|
2740
2740
|
});
|
|
2741
2741
|
test("a review-status reply round-trips /State + /StateModel + /Subj", async () => {
|
|
2742
|
-
const doc = await openFixture$
|
|
2742
|
+
const doc = await openFixture$18(engine, opts);
|
|
2743
2743
|
try {
|
|
2744
2744
|
const page = doc.page(fix.pageObjectNumber);
|
|
2745
2745
|
const target = await page.annotations.create({
|
|
@@ -2773,7 +2773,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2773
2773
|
}
|
|
2774
2774
|
});
|
|
2775
2775
|
test("a draft /State without /StateModel is rejected with InvalidArg", async () => {
|
|
2776
|
-
const doc = await openFixture$
|
|
2776
|
+
const doc = await openFixture$18(engine, opts);
|
|
2777
2777
|
try {
|
|
2778
2778
|
const page = doc.page(fix.pageObjectNumber);
|
|
2779
2779
|
let caught;
|
|
@@ -2792,7 +2792,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2792
2792
|
}
|
|
2793
2793
|
});
|
|
2794
2794
|
test("null-clear patches truly remove /State, /StateModel, /Subj and /Contents", async () => {
|
|
2795
|
-
const doc = await openFixture$
|
|
2795
|
+
const doc = await openFixture$18(engine, opts);
|
|
2796
2796
|
try {
|
|
2797
2797
|
const page = doc.page(fix.pageObjectNumber);
|
|
2798
2798
|
const note = await page.annotations.create({
|
|
@@ -2839,7 +2839,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2839
2839
|
}
|
|
2840
2840
|
});
|
|
2841
2841
|
test("custom state models round-trip verbatim", async () => {
|
|
2842
|
-
const doc = await openFixture$
|
|
2842
|
+
const doc = await openFixture$18(engine, opts);
|
|
2843
2843
|
try {
|
|
2844
2844
|
const page = doc.page(fix.pageObjectNumber);
|
|
2845
2845
|
const custom = await page.annotations.create({
|
|
@@ -2867,7 +2867,7 @@ async function beginWeakEditIfRequired(doc, pageObjectNumber, fix) {
|
|
|
2867
2867
|
if (doc.capabilities.weakAnnotationEditSessions !== "required" || !fix.expectsWeakAnnotation) return null;
|
|
2868
2868
|
return doc.annotations.beginWeakEdit([pageObjectNumber]);
|
|
2869
2869
|
}
|
|
2870
|
-
async function openFixture$
|
|
2870
|
+
async function openFixture$18(engine, opts) {
|
|
2871
2871
|
if (opts.openKind === "bytes") {
|
|
2872
2872
|
const bytes = await opts.fixture.bytes();
|
|
2873
2873
|
return engine.open({
|
|
@@ -3457,7 +3457,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3457
3457
|
if (engine) await engine.destroy();
|
|
3458
3458
|
});
|
|
3459
3459
|
test("renders the expected set of appearances with valid output", async () => {
|
|
3460
|
-
const doc = await openFixture$
|
|
3460
|
+
const doc = await openFixture$17(engine, opts);
|
|
3461
3461
|
try {
|
|
3462
3462
|
const { pageState, appearances } = await collect(doc, opts, useRaw);
|
|
3463
3463
|
expect(pageState.pageObjectNumber).toBe(opts.fixture.pageObjectNumber);
|
|
@@ -3484,7 +3484,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3484
3484
|
}
|
|
3485
3485
|
});
|
|
3486
3486
|
if (opts.fixture.expectsWeakAppearance) test("weak (index-only) annotations are emitted, not dropped", async () => {
|
|
3487
|
-
const doc = await openFixture$
|
|
3487
|
+
const doc = await openFixture$17(engine, opts);
|
|
3488
3488
|
try {
|
|
3489
3489
|
const { appearances } = await collect(doc, opts, useRaw);
|
|
3490
3490
|
const weak = appearances.find((a) => a.ref.kind === "index");
|
|
@@ -3494,7 +3494,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3494
3494
|
}
|
|
3495
3495
|
});
|
|
3496
3496
|
if (useRaw) test("rendered appearances are not blank (non-zero alpha)", async () => {
|
|
3497
|
-
const doc = await openFixture$
|
|
3497
|
+
const doc = await openFixture$17(engine, opts);
|
|
3498
3498
|
try {
|
|
3499
3499
|
const { appearances } = await collect(doc, opts, useRaw);
|
|
3500
3500
|
const anyVisible = appearances.some((a) => a.raster !== null && hasOpaquePixel(a.raster));
|
|
@@ -3504,7 +3504,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3504
3504
|
}
|
|
3505
3505
|
});
|
|
3506
3506
|
test("abort() rejects with AbortError", async () => {
|
|
3507
|
-
const doc = await openFixture$
|
|
3507
|
+
const doc = await openFixture$17(engine, opts);
|
|
3508
3508
|
try {
|
|
3509
3509
|
const page = doc.page(opts.fixture.pageObjectNumber);
|
|
3510
3510
|
const p = useRaw ? page.annotations.renderAppearances({ scale: 1 }) : page.annotations.renderAppearanceImages({
|
|
@@ -3559,7 +3559,7 @@ function hasOpaquePixel(raster) {
|
|
|
3559
3559
|
}
|
|
3560
3560
|
return false;
|
|
3561
3561
|
}
|
|
3562
|
-
async function openFixture$
|
|
3562
|
+
async function openFixture$17(engine, opts) {
|
|
3563
3563
|
if (opts.openKind === "bytes") {
|
|
3564
3564
|
const bytes = await opts.fixture.bytes();
|
|
3565
3565
|
return engine.open({
|
|
@@ -3628,7 +3628,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3628
3628
|
if (engine) await engine.destroy();
|
|
3629
3629
|
});
|
|
3630
3630
|
test("pages.list() returns every page in display order, durable PONs only", async () => {
|
|
3631
|
-
const doc = await openFixture$
|
|
3631
|
+
const doc = await openFixture$16(engine, opts);
|
|
3632
3632
|
try {
|
|
3633
3633
|
const list = await doc.pages.list();
|
|
3634
3634
|
expect(PageListSnapshotSchema.safeParse(list).success).toBe(true);
|
|
@@ -3647,7 +3647,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3647
3647
|
}
|
|
3648
3648
|
});
|
|
3649
3649
|
test("pages.move() reorders pages and returns the full post-move order", async () => {
|
|
3650
|
-
const doc = await openFixture$
|
|
3650
|
+
const doc = await openFixture$16(engine, opts);
|
|
3651
3651
|
try {
|
|
3652
3652
|
const before = await doc.pages.list();
|
|
3653
3653
|
if (before.pages.length < 3) return;
|
|
@@ -3671,7 +3671,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3671
3671
|
}
|
|
3672
3672
|
});
|
|
3673
3673
|
test("weak index-based annotation refs survive a page reorder", async () => {
|
|
3674
|
-
const doc = await openFixture$
|
|
3674
|
+
const doc = await openFixture$16(engine, opts);
|
|
3675
3675
|
try {
|
|
3676
3676
|
const list = await doc.pages.list();
|
|
3677
3677
|
if (list.pages.length < 2) return;
|
|
@@ -3708,7 +3708,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3708
3708
|
}
|
|
3709
3709
|
});
|
|
3710
3710
|
test("pages.move() rejects duplicate PONs with InvalidArg", async () => {
|
|
3711
|
-
const doc = await openFixture$
|
|
3711
|
+
const doc = await openFixture$16(engine, opts);
|
|
3712
3712
|
try {
|
|
3713
3713
|
const list = await doc.pages.list();
|
|
3714
3714
|
if (list.pages.length < 1) return;
|
|
@@ -3725,7 +3725,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3725
3725
|
}
|
|
3726
3726
|
});
|
|
3727
3727
|
test("pages.move() rejects out-of-range destIndex with InvalidArg", async () => {
|
|
3728
|
-
const doc = await openFixture$
|
|
3728
|
+
const doc = await openFixture$16(engine, opts);
|
|
3729
3729
|
try {
|
|
3730
3730
|
const list = await doc.pages.list();
|
|
3731
3731
|
if (list.pages.length < 1) return;
|
|
@@ -3742,7 +3742,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3742
3742
|
}
|
|
3743
3743
|
});
|
|
3744
3744
|
test("pages.move() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3745
|
-
const doc = await openFixture$
|
|
3745
|
+
const doc = await openFixture$16(engine, opts);
|
|
3746
3746
|
try {
|
|
3747
3747
|
const list = await doc.pages.list();
|
|
3748
3748
|
let bogus = 0;
|
|
@@ -3760,7 +3760,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3760
3760
|
}
|
|
3761
3761
|
});
|
|
3762
3762
|
test("abort on pages.move() rejects with AbortError", async () => {
|
|
3763
|
-
const doc = await openFixture$
|
|
3763
|
+
const doc = await openFixture$16(engine, opts);
|
|
3764
3764
|
try {
|
|
3765
3765
|
const list = await doc.pages.list();
|
|
3766
3766
|
if (list.pages.length < 1) return;
|
|
@@ -3774,7 +3774,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3774
3774
|
});
|
|
3775
3775
|
});
|
|
3776
3776
|
}
|
|
3777
|
-
async function openFixture$
|
|
3777
|
+
async function openFixture$16(engine, opts) {
|
|
3778
3778
|
if (opts.openKind === "bytes") {
|
|
3779
3779
|
const bytes = await opts.fixture.bytes();
|
|
3780
3780
|
return engine.open({
|
|
@@ -3848,7 +3848,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3848
3848
|
if (engine) await engine.destroy();
|
|
3849
3849
|
});
|
|
3850
3850
|
test("pages.rotate() sets the absolute rotation and returns the full layout", async () => {
|
|
3851
|
-
const doc = await openFixture$
|
|
3851
|
+
const doc = await openFixture$15(engine, opts);
|
|
3852
3852
|
try {
|
|
3853
3853
|
const before = await doc.pages.list();
|
|
3854
3854
|
const target = before.pages[0];
|
|
@@ -3867,7 +3867,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3867
3867
|
}
|
|
3868
3868
|
});
|
|
3869
3869
|
test("absolute rotation is idempotent: setting the same value twice is a no-op", async () => {
|
|
3870
|
-
const doc = await openFixture$
|
|
3870
|
+
const doc = await openFixture$15(engine, opts);
|
|
3871
3871
|
try {
|
|
3872
3872
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3873
3873
|
const first = await doc.pages.rotate([pon], 180);
|
|
@@ -3878,7 +3878,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3878
3878
|
}
|
|
3879
3879
|
});
|
|
3880
3880
|
test("one rotation applies to EVERY listed page (the multi-select gesture)", async () => {
|
|
3881
|
-
const doc = await openFixture$
|
|
3881
|
+
const doc = await openFixture$15(engine, opts);
|
|
3882
3882
|
try {
|
|
3883
3883
|
const list = await doc.pages.list();
|
|
3884
3884
|
if (list.pages.length < 2) return;
|
|
@@ -3890,7 +3890,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3890
3890
|
}
|
|
3891
3891
|
});
|
|
3892
3892
|
test("weak index-based annotation refs survive a rotate (no revision bump)", async () => {
|
|
3893
|
-
const doc = await openFixture$
|
|
3893
|
+
const doc = await openFixture$15(engine, opts);
|
|
3894
3894
|
try {
|
|
3895
3895
|
const hostPon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3896
3896
|
const hostPage = doc.page(hostPon);
|
|
@@ -3920,7 +3920,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3920
3920
|
}
|
|
3921
3921
|
});
|
|
3922
3922
|
test("pages.rotate() rejects an invalid rotation value with InvalidArg", async () => {
|
|
3923
|
-
const doc = await openFixture$
|
|
3923
|
+
const doc = await openFixture$15(engine, opts);
|
|
3924
3924
|
try {
|
|
3925
3925
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3926
3926
|
let caught;
|
|
@@ -3935,7 +3935,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3935
3935
|
}
|
|
3936
3936
|
});
|
|
3937
3937
|
test("pages.rotate() rejects duplicate PONs with InvalidArg", async () => {
|
|
3938
|
-
const doc = await openFixture$
|
|
3938
|
+
const doc = await openFixture$15(engine, opts);
|
|
3939
3939
|
try {
|
|
3940
3940
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3941
3941
|
let caught;
|
|
@@ -3950,7 +3950,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3950
3950
|
}
|
|
3951
3951
|
});
|
|
3952
3952
|
test("pages.rotate() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3953
|
-
const doc = await openFixture$
|
|
3953
|
+
const doc = await openFixture$15(engine, opts);
|
|
3954
3954
|
try {
|
|
3955
3955
|
const list = await doc.pages.list();
|
|
3956
3956
|
let bogus = 0;
|
|
@@ -3968,7 +3968,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3968
3968
|
}
|
|
3969
3969
|
});
|
|
3970
3970
|
test("abort on pages.rotate() rejects with AbortError", async () => {
|
|
3971
|
-
const doc = await openFixture$
|
|
3971
|
+
const doc = await openFixture$15(engine, opts);
|
|
3972
3972
|
try {
|
|
3973
3973
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3974
3974
|
const p = doc.pages.rotate([pon], 90);
|
|
@@ -3980,7 +3980,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3980
3980
|
});
|
|
3981
3981
|
});
|
|
3982
3982
|
}
|
|
3983
|
-
async function openFixture$
|
|
3983
|
+
async function openFixture$15(engine, opts) {
|
|
3984
3984
|
if (opts.openKind === "bytes") {
|
|
3985
3985
|
const bytes = await opts.fixture.bytes();
|
|
3986
3986
|
return engine.open({
|
|
@@ -4043,7 +4043,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4043
4043
|
if (engine) await engine.destroy();
|
|
4044
4044
|
});
|
|
4045
4045
|
test("pages.delete() removes the page and returns the surviving layout", async () => {
|
|
4046
|
-
const doc = await openFixture$
|
|
4046
|
+
const doc = await openFixture$14(engine, opts);
|
|
4047
4047
|
try {
|
|
4048
4048
|
const before = await doc.pages.list();
|
|
4049
4049
|
if (before.pages.length < 2) return;
|
|
@@ -4064,7 +4064,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4064
4064
|
}
|
|
4065
4065
|
});
|
|
4066
4066
|
test("addressing a deleted page afterwards is a clean NotFound", async () => {
|
|
4067
|
-
const doc = await openFixture$
|
|
4067
|
+
const doc = await openFixture$14(engine, opts);
|
|
4068
4068
|
try {
|
|
4069
4069
|
const before = await doc.pages.list();
|
|
4070
4070
|
if (before.pages.length < 2) return;
|
|
@@ -4082,7 +4082,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4082
4082
|
}
|
|
4083
4083
|
});
|
|
4084
4084
|
test("surviving pages keep their weak index-based annotation refs", async () => {
|
|
4085
|
-
const doc = await openFixture$
|
|
4085
|
+
const doc = await openFixture$14(engine, opts);
|
|
4086
4086
|
try {
|
|
4087
4087
|
const list = await doc.pages.list();
|
|
4088
4088
|
if (list.pages.length < 2) return;
|
|
@@ -4115,7 +4115,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4115
4115
|
}
|
|
4116
4116
|
});
|
|
4117
4117
|
test("deleting EVERY page is rejected with InvalidArg", async () => {
|
|
4118
|
-
const doc = await openFixture$
|
|
4118
|
+
const doc = await openFixture$14(engine, opts);
|
|
4119
4119
|
try {
|
|
4120
4120
|
const list = await doc.pages.list();
|
|
4121
4121
|
let caught;
|
|
@@ -4130,7 +4130,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4130
4130
|
}
|
|
4131
4131
|
});
|
|
4132
4132
|
test("pages.delete() rejects duplicate PONs with InvalidArg", async () => {
|
|
4133
|
-
const doc = await openFixture$
|
|
4133
|
+
const doc = await openFixture$14(engine, opts);
|
|
4134
4134
|
try {
|
|
4135
4135
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
4136
4136
|
let caught;
|
|
@@ -4145,7 +4145,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4145
4145
|
}
|
|
4146
4146
|
});
|
|
4147
4147
|
test("pages.delete() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
4148
|
-
const doc = await openFixture$
|
|
4148
|
+
const doc = await openFixture$14(engine, opts);
|
|
4149
4149
|
try {
|
|
4150
4150
|
const list = await doc.pages.list();
|
|
4151
4151
|
let bogus = 0;
|
|
@@ -4163,7 +4163,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4163
4163
|
}
|
|
4164
4164
|
});
|
|
4165
4165
|
test("abort on pages.delete() rejects with AbortError", async () => {
|
|
4166
|
-
const doc = await openFixture$
|
|
4166
|
+
const doc = await openFixture$14(engine, opts);
|
|
4167
4167
|
try {
|
|
4168
4168
|
const list = await doc.pages.list();
|
|
4169
4169
|
if (list.pages.length < 2) return;
|
|
@@ -4177,7 +4177,224 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
4177
4177
|
});
|
|
4178
4178
|
});
|
|
4179
4179
|
}
|
|
4180
|
-
async function openFixture$
|
|
4180
|
+
async function openFixture$14(engine, opts) {
|
|
4181
|
+
if (opts.openKind === "bytes") {
|
|
4182
|
+
const bytes = await opts.fixture.bytes();
|
|
4183
|
+
return engine.open({
|
|
4184
|
+
kind: "bytes",
|
|
4185
|
+
id: opts.fixture.id,
|
|
4186
|
+
bytes
|
|
4187
|
+
});
|
|
4188
|
+
}
|
|
4189
|
+
return engine.open({
|
|
4190
|
+
kind: "id",
|
|
4191
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
4192
|
+
});
|
|
4193
|
+
}
|
|
4194
|
+
//#endregion
|
|
4195
|
+
//#region src/conformance/runNamedPagesConformance.ts
|
|
4196
|
+
/**
|
|
4197
|
+
* Named-pages conformance: the catalog's `/Names /Pages` registry as LAYOUT
|
|
4198
|
+
* data. Locks the invariants both engines must share — do not loosen
|
|
4199
|
+
* without re-reading `NamedPageEntry` and `PageNameResult`:
|
|
4200
|
+
*
|
|
4201
|
+
* 1. `pages.list().namedPages` is present (possibly empty) and every
|
|
4202
|
+
* registration resolves to a page in `pages`, a template, or is
|
|
4203
|
+
* reported dangling — never silently dropped.
|
|
4204
|
+
* 2. `pages.setName()` creates or replaces by decoded key (idempotent),
|
|
4205
|
+
* `replace` renames in one job, and the result IS the new layout.
|
|
4206
|
+
* 3. `pages.removeName()` drops the registration and nothing else.
|
|
4207
|
+
* 4. Deleting a page removes every registration pointing at it — inside
|
|
4208
|
+
* the delete, with no plugin in the loop.
|
|
4209
|
+
* 5. Non-ASCII keys round-trip unchanged (Acrobat writes UTF-16 + BOM).
|
|
4210
|
+
*
|
|
4211
|
+
* Skips cleanly when the engine does not implement the optional members.
|
|
4212
|
+
*/
|
|
4213
|
+
function runNamedPagesConformance(runner, opts) {
|
|
4214
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4215
|
+
describe(`named pages conformance: ${opts.label}`, () => {
|
|
4216
|
+
let engine;
|
|
4217
|
+
beforeAll(async () => {
|
|
4218
|
+
engine = await opts.makeEngine();
|
|
4219
|
+
});
|
|
4220
|
+
afterAll(async () => {
|
|
4221
|
+
if (engine) await engine.destroy();
|
|
4222
|
+
});
|
|
4223
|
+
test("pages.list() carries namedPages and every entry resolves", async () => {
|
|
4224
|
+
const doc = await openFixture$13(engine, opts);
|
|
4225
|
+
try {
|
|
4226
|
+
const layout = await doc.pages.list();
|
|
4227
|
+
PageListSnapshotSchema.parse(layout);
|
|
4228
|
+
expect(Array.isArray(layout.namedPages)).toBe(true);
|
|
4229
|
+
const pons = new Set(layout.pages.map((page) => page.pageObjectNumber));
|
|
4230
|
+
for (const entry of layout.namedPages ?? []) {
|
|
4231
|
+
expect(entry.name.length > 0).toBe(true);
|
|
4232
|
+
if (entry.target.kind === "page") expect(pons.has(entry.target.pageObjectNumber)).toBe(true);
|
|
4233
|
+
}
|
|
4234
|
+
} finally {
|
|
4235
|
+
await doc.close();
|
|
4236
|
+
}
|
|
4237
|
+
});
|
|
4238
|
+
test("pages.setName() registers, replaces by key, and renames via `replace`", async () => {
|
|
4239
|
+
const doc = await openFixture$13(engine, opts);
|
|
4240
|
+
try {
|
|
4241
|
+
if (!doc.pages.setName) return;
|
|
4242
|
+
const before = await doc.pages.list();
|
|
4243
|
+
const [first, second] = before.pages;
|
|
4244
|
+
const baseline = (before.namedPages ?? []).length;
|
|
4245
|
+
const created = await doc.pages.setName({
|
|
4246
|
+
name: "Approved=Goedgekeurd",
|
|
4247
|
+
pageObjectNumber: first.pageObjectNumber
|
|
4248
|
+
});
|
|
4249
|
+
PageNameResultSchema.parse(created);
|
|
4250
|
+
expect(created.layout.pages.length).toBe(before.pages.length);
|
|
4251
|
+
expect(find(created, "Approved=Goedgekeurd")).toEqual({
|
|
4252
|
+
kind: "page",
|
|
4253
|
+
pageObjectNumber: first.pageObjectNumber
|
|
4254
|
+
});
|
|
4255
|
+
expect((created.layout.namedPages ?? []).length).toBe(baseline + 1);
|
|
4256
|
+
if (created.cache) {
|
|
4257
|
+
expect(created.cache.docVersion > created.cache.previousDocVersion).toBe(true);
|
|
4258
|
+
expect(created.cache.layoutVersion > 0).toBe(true);
|
|
4259
|
+
}
|
|
4260
|
+
const listed = await doc.pages.list();
|
|
4261
|
+
expect(listed.namedPages).toEqual(created.layout.namedPages);
|
|
4262
|
+
const replaced = await doc.pages.setName({
|
|
4263
|
+
name: "Approved=Goedgekeurd",
|
|
4264
|
+
pageObjectNumber: second.pageObjectNumber
|
|
4265
|
+
});
|
|
4266
|
+
expect(find(replaced, "Approved=Goedgekeurd")).toEqual({
|
|
4267
|
+
kind: "page",
|
|
4268
|
+
pageObjectNumber: second.pageObjectNumber
|
|
4269
|
+
});
|
|
4270
|
+
expect((replaced.layout.namedPages ?? []).length).toBe(baseline + 1);
|
|
4271
|
+
const renamed = await doc.pages.setName({
|
|
4272
|
+
name: "Approved=Approved",
|
|
4273
|
+
pageObjectNumber: second.pageObjectNumber,
|
|
4274
|
+
replace: "Approved=Goedgekeurd"
|
|
4275
|
+
});
|
|
4276
|
+
expect(find(renamed, "Approved=Goedgekeurd")).toBe(void 0);
|
|
4277
|
+
expect(find(renamed, "Approved=Approved")).toEqual({
|
|
4278
|
+
kind: "page",
|
|
4279
|
+
pageObjectNumber: second.pageObjectNumber
|
|
4280
|
+
});
|
|
4281
|
+
expect((renamed.layout.namedPages ?? []).length).toBe(baseline + 1);
|
|
4282
|
+
} finally {
|
|
4283
|
+
await doc.close();
|
|
4284
|
+
}
|
|
4285
|
+
});
|
|
4286
|
+
test("non-ASCII keys round-trip through set → list", async () => {
|
|
4287
|
+
const doc = await openFixture$13(engine, opts);
|
|
4288
|
+
try {
|
|
4289
|
+
if (!doc.pages.setName) return;
|
|
4290
|
+
const before = await doc.pages.list();
|
|
4291
|
+
const key = "Stämpel=Stämpel 日本";
|
|
4292
|
+
const result = await doc.pages.setName({
|
|
4293
|
+
name: key,
|
|
4294
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4295
|
+
});
|
|
4296
|
+
expect(find(result, key)).toEqual({
|
|
4297
|
+
kind: "page",
|
|
4298
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4299
|
+
});
|
|
4300
|
+
const listed = await doc.pages.list();
|
|
4301
|
+
expect((listed.namedPages ?? []).some((entry) => entry.name === key)).toBe(true);
|
|
4302
|
+
} finally {
|
|
4303
|
+
await doc.close();
|
|
4304
|
+
}
|
|
4305
|
+
});
|
|
4306
|
+
test("pages.removeName() drops the registration and keeps the page", async () => {
|
|
4307
|
+
const doc = await openFixture$13(engine, opts);
|
|
4308
|
+
try {
|
|
4309
|
+
if (!doc.pages.setName || !doc.pages.removeName) return;
|
|
4310
|
+
const before = await doc.pages.list();
|
|
4311
|
+
await doc.pages.setName({
|
|
4312
|
+
name: "Draft=Concept",
|
|
4313
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4314
|
+
});
|
|
4315
|
+
const removed = await doc.pages.removeName({ name: "Draft=Concept" });
|
|
4316
|
+
PageNameResultSchema.parse(removed);
|
|
4317
|
+
expect(find(removed, "Draft=Concept")).toBe(void 0);
|
|
4318
|
+
expect(removed.layout.pages.length).toBe(before.pages.length);
|
|
4319
|
+
await expect(doc.pages.removeName({ name: "Draft=Concept" })).rejects.toMatchObject({ code: EngineErrorCode.NotFound });
|
|
4320
|
+
} finally {
|
|
4321
|
+
await doc.close();
|
|
4322
|
+
}
|
|
4323
|
+
});
|
|
4324
|
+
test("pages.setName() rejects an empty name and an unknown page", async () => {
|
|
4325
|
+
const doc = await openFixture$13(engine, opts);
|
|
4326
|
+
try {
|
|
4327
|
+
if (!doc.pages.setName) return;
|
|
4328
|
+
const before = await doc.pages.list();
|
|
4329
|
+
await expect(doc.pages.setName({
|
|
4330
|
+
name: "",
|
|
4331
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4332
|
+
})).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4333
|
+
let unknownPage = null;
|
|
4334
|
+
try {
|
|
4335
|
+
await doc.pages.setName({
|
|
4336
|
+
name: "Ghost=Ghost",
|
|
4337
|
+
pageObjectNumber: 987654321
|
|
4338
|
+
});
|
|
4339
|
+
} catch (error) {
|
|
4340
|
+
unknownPage = error;
|
|
4341
|
+
}
|
|
4342
|
+
expect(EngineError.is(unknownPage, EngineErrorCode.NotFound) || EngineError.is(unknownPage, EngineErrorCode.InvalidArg)).toBe(true);
|
|
4343
|
+
} finally {
|
|
4344
|
+
await doc.close();
|
|
4345
|
+
}
|
|
4346
|
+
});
|
|
4347
|
+
test("deleting a page removes every registration pointing at it", async () => {
|
|
4348
|
+
const doc = await openFixture$13(engine, opts);
|
|
4349
|
+
try {
|
|
4350
|
+
if (!doc.pages.setName) return;
|
|
4351
|
+
const before = await doc.pages.list();
|
|
4352
|
+
if (before.pages.length < 2) return;
|
|
4353
|
+
const victim = before.pages[1].pageObjectNumber;
|
|
4354
|
+
const survivor = before.pages[0].pageObjectNumber;
|
|
4355
|
+
await doc.pages.setName({
|
|
4356
|
+
name: "Victim=One",
|
|
4357
|
+
pageObjectNumber: victim
|
|
4358
|
+
});
|
|
4359
|
+
await doc.pages.setName({
|
|
4360
|
+
name: "Victim=Two",
|
|
4361
|
+
pageObjectNumber: victim
|
|
4362
|
+
});
|
|
4363
|
+
await doc.pages.setName({
|
|
4364
|
+
name: "Survivor",
|
|
4365
|
+
pageObjectNumber: survivor
|
|
4366
|
+
});
|
|
4367
|
+
const deleted = await doc.pages.delete([victim]);
|
|
4368
|
+
const names = (deleted.layout.namedPages ?? []).map((entry) => entry.name);
|
|
4369
|
+
expect(names.includes("Victim=One")).toBe(false);
|
|
4370
|
+
expect(names.includes("Victim=Two")).toBe(false);
|
|
4371
|
+
expect(names).toContain("Survivor");
|
|
4372
|
+
expect((deleted.layout.namedPages ?? []).some((entry) => entry.target.kind === "dangling")).toBe(false);
|
|
4373
|
+
} finally {
|
|
4374
|
+
await doc.close();
|
|
4375
|
+
}
|
|
4376
|
+
});
|
|
4377
|
+
test("abort on pages.setName() rejects with AbortError", async () => {
|
|
4378
|
+
const doc = await openFixture$13(engine, opts);
|
|
4379
|
+
try {
|
|
4380
|
+
if (!doc.pages.setName) return;
|
|
4381
|
+
const before = await doc.pages.list();
|
|
4382
|
+
const promise = doc.pages.setName({
|
|
4383
|
+
name: "Aborted=Aborted",
|
|
4384
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4385
|
+
});
|
|
4386
|
+
promise.abort();
|
|
4387
|
+
await expect(promise).rejects.toBeInstanceOf(AbortError);
|
|
4388
|
+
} finally {
|
|
4389
|
+
await doc.close();
|
|
4390
|
+
}
|
|
4391
|
+
});
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4394
|
+
function find(result, name) {
|
|
4395
|
+
return (result.layout.namedPages ?? []).find((entry) => entry.name === name)?.target;
|
|
4396
|
+
}
|
|
4397
|
+
async function openFixture$13(engine, opts) {
|
|
4181
4398
|
if (opts.openKind === "bytes") {
|
|
4182
4399
|
const bytes = await opts.fixture.bytes();
|
|
4183
4400
|
return engine.open({
|
|
@@ -4192,6 +4409,243 @@ async function openFixture$11(engine, opts) {
|
|
|
4192
4409
|
});
|
|
4193
4410
|
}
|
|
4194
4411
|
//#endregion
|
|
4412
|
+
//#region src/conformance/runAnnotationFlattenConformance.ts
|
|
4413
|
+
const square$1 = (left, bottom) => ({
|
|
4414
|
+
subtype: "square",
|
|
4415
|
+
rect: {
|
|
4416
|
+
left,
|
|
4417
|
+
bottom,
|
|
4418
|
+
right: left + 40,
|
|
4419
|
+
top: bottom + 40
|
|
4420
|
+
},
|
|
4421
|
+
color: {
|
|
4422
|
+
r: 20,
|
|
4423
|
+
g: 40,
|
|
4424
|
+
b: 220
|
|
4425
|
+
},
|
|
4426
|
+
strokeWidth: 2
|
|
4427
|
+
});
|
|
4428
|
+
/**
|
|
4429
|
+
* Selective annotation flatten: `page(pon).annotations.flatten(refs)` is
|
|
4430
|
+
* `pages.flatten` for a chosen set. Locks, on every engine:
|
|
4431
|
+
* 1. only the given refs are painted and removed; the rest of the page's
|
|
4432
|
+
* annotations are untouched;
|
|
4433
|
+
* 2. per-ref status (`applied` / `skipped`), one `annotations.flattened`
|
|
4434
|
+
* event, a `meta` with that page's new pins, layout unchanged;
|
|
4435
|
+
* 3. a hidden ref is `skipped`; a ref on another page rejects `InvalidArg`
|
|
4436
|
+
* with nothing mutated.
|
|
4437
|
+
* Skips cleanly when the engine does not implement the optional member.
|
|
4438
|
+
*/
|
|
4439
|
+
function runAnnotationFlattenConformance(runner, opts) {
|
|
4440
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4441
|
+
describe(`annotation flatten conformance: ${opts.label}`, () => {
|
|
4442
|
+
let engine;
|
|
4443
|
+
beforeAll(async () => {
|
|
4444
|
+
engine = await opts.makeEngine();
|
|
4445
|
+
});
|
|
4446
|
+
afterAll(async () => {
|
|
4447
|
+
if (engine) await engine.destroy();
|
|
4448
|
+
});
|
|
4449
|
+
test("flattens exactly the given refs and reports per-ref status", async () => {
|
|
4450
|
+
const doc = await openFixture$12(engine, opts);
|
|
4451
|
+
try {
|
|
4452
|
+
const layoutBefore = await doc.pages.list();
|
|
4453
|
+
const pon = layoutBefore.pages[0].pageObjectNumber;
|
|
4454
|
+
const page = doc.page(pon);
|
|
4455
|
+
if (!page.annotations.flatten) return;
|
|
4456
|
+
const a = (await page.annotations.create(square$1(20, 20))).created.ref;
|
|
4457
|
+
const b = (await page.annotations.create(square$1(80, 20))).created.ref;
|
|
4458
|
+
const c = (await page.annotations.create(square$1(140, 20))).created.ref;
|
|
4459
|
+
await page.annotations.update(c, {
|
|
4460
|
+
subtype: "square",
|
|
4461
|
+
flags: { hidden: true }
|
|
4462
|
+
});
|
|
4463
|
+
const before = await page.annotations.list();
|
|
4464
|
+
const events = [];
|
|
4465
|
+
const unsubscribe = doc.events.subscribe((event) => {
|
|
4466
|
+
if (event.type === "annotations.flattened") events.push(event);
|
|
4467
|
+
});
|
|
4468
|
+
const result = await page.annotations.flatten([a, c], "display");
|
|
4469
|
+
unsubscribe();
|
|
4470
|
+
expect(AnnotationFlattenResultSchema.safeParse(result).success).toBe(true);
|
|
4471
|
+
expect(result.pageObjectNumber).toBe(pon);
|
|
4472
|
+
expect(result.usage).toBe("display");
|
|
4473
|
+
expect(result.results.map((item) => item.status)).toEqual(["applied", "skipped"]);
|
|
4474
|
+
expect(result.meta === null).toBe(false);
|
|
4475
|
+
expect(events).toHaveLength(1);
|
|
4476
|
+
expect(await doc.pages.list()).toEqual(layoutBefore);
|
|
4477
|
+
const after = await page.annotations.list();
|
|
4478
|
+
expect(after.annotations.length).toBe(before.annotations.length - 1);
|
|
4479
|
+
expect(after.annotations.some((dto) => sameRef(dto.ref, b))).toBe(true);
|
|
4480
|
+
expect(after.annotations.some((dto) => sameRef(dto.ref, c))).toBe(true);
|
|
4481
|
+
expect(after.annotations.some((dto) => sameRef(dto.ref, a))).toBe(false);
|
|
4482
|
+
expect(after.pageState.revision.generation > before.pageState.revision.generation).toBe(true);
|
|
4483
|
+
} finally {
|
|
4484
|
+
await doc.close();
|
|
4485
|
+
}
|
|
4486
|
+
});
|
|
4487
|
+
test("a ref on another page rejects InvalidArg and mutates nothing", async () => {
|
|
4488
|
+
const doc = await openFixture$12(engine, opts);
|
|
4489
|
+
try {
|
|
4490
|
+
const layout = await doc.pages.list();
|
|
4491
|
+
if (layout.pages.length < 2) return;
|
|
4492
|
+
const page0 = doc.page(layout.pages[0].pageObjectNumber);
|
|
4493
|
+
const page1 = doc.page(layout.pages[1].pageObjectNumber);
|
|
4494
|
+
if (!page0.annotations.flatten) return;
|
|
4495
|
+
const own = (await page0.annotations.create(square$1(20, 100))).created.ref;
|
|
4496
|
+
const foreign = (await page1.annotations.create(square$1(20, 100))).created.ref;
|
|
4497
|
+
const countBefore = (await page0.annotations.list()).annotations.length;
|
|
4498
|
+
await expect(page0.annotations.flatten([own, foreign])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4499
|
+
expect((await page0.annotations.list()).annotations.length).toBe(countBefore);
|
|
4500
|
+
} finally {
|
|
4501
|
+
await doc.close();
|
|
4502
|
+
}
|
|
4503
|
+
});
|
|
4504
|
+
test("an empty ref list rejects InvalidArg; an unknown ref rejects", async () => {
|
|
4505
|
+
const doc = await openFixture$12(engine, opts);
|
|
4506
|
+
try {
|
|
4507
|
+
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
4508
|
+
const page = doc.page(pon);
|
|
4509
|
+
if (!page.annotations.flatten) return;
|
|
4510
|
+
await expect(page.annotations.flatten([])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4511
|
+
let unknown = null;
|
|
4512
|
+
try {
|
|
4513
|
+
await page.annotations.flatten([{
|
|
4514
|
+
kind: "objectNumber",
|
|
4515
|
+
pageObjectNumber: pon,
|
|
4516
|
+
annotObjectNumber: 987654321
|
|
4517
|
+
}]);
|
|
4518
|
+
} catch (error) {
|
|
4519
|
+
unknown = error;
|
|
4520
|
+
}
|
|
4521
|
+
expect(EngineError.is(unknown, EngineErrorCode.NotFound) || EngineError.is(unknown, EngineErrorCode.InvalidArg) || EngineError.is(unknown, EngineErrorCode.InvalidReference)).toBe(true);
|
|
4522
|
+
} finally {
|
|
4523
|
+
await doc.close();
|
|
4524
|
+
}
|
|
4525
|
+
});
|
|
4526
|
+
});
|
|
4527
|
+
}
|
|
4528
|
+
function sameRef(left, right) {
|
|
4529
|
+
if (left.kind === "objectNumber" && right.kind === "objectNumber") return left.annotObjectNumber === right.annotObjectNumber;
|
|
4530
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
4531
|
+
}
|
|
4532
|
+
async function openFixture$12(engine, opts) {
|
|
4533
|
+
if (opts.openKind === "bytes") return engine.open({
|
|
4534
|
+
kind: "bytes",
|
|
4535
|
+
id: opts.fixture.id,
|
|
4536
|
+
bytes: await opts.fixture.bytes()
|
|
4537
|
+
});
|
|
4538
|
+
return engine.open({
|
|
4539
|
+
kind: "id",
|
|
4540
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
4541
|
+
});
|
|
4542
|
+
}
|
|
4543
|
+
//#endregion
|
|
4544
|
+
//#region src/conformance/runAnnotationAppearanceExportConformance.ts
|
|
4545
|
+
const PDF_MAGIC$1 = [
|
|
4546
|
+
37,
|
|
4547
|
+
80,
|
|
4548
|
+
68,
|
|
4549
|
+
70
|
|
4550
|
+
];
|
|
4551
|
+
const square = (left, bottom, size = 40) => ({
|
|
4552
|
+
subtype: "square",
|
|
4553
|
+
rect: {
|
|
4554
|
+
left,
|
|
4555
|
+
bottom,
|
|
4556
|
+
right: left + size,
|
|
4557
|
+
top: bottom + size
|
|
4558
|
+
},
|
|
4559
|
+
color: {
|
|
4560
|
+
r: 220,
|
|
4561
|
+
g: 20,
|
|
4562
|
+
b: 20
|
|
4563
|
+
},
|
|
4564
|
+
strokeWidth: 2
|
|
4565
|
+
});
|
|
4566
|
+
/**
|
|
4567
|
+
* `page(pon).annotations.exportAppearance(refs)`: the chosen annotations'
|
|
4568
|
+
* appearances as ONE single-page PDF sized to their union /Rect. Locks:
|
|
4569
|
+
* 1. bytes are a PDF; the source page is untouched (no mutation, no
|
|
4570
|
+
* revision bump);
|
|
4571
|
+
* 2. re-opened (local engines), the page is exactly the union size and the
|
|
4572
|
+
* requested count of annotations is gone — they are content now;
|
|
4573
|
+
* 3. a ref on another page rejects `InvalidArg`; an empty list rejects.
|
|
4574
|
+
* Skips cleanly when the engine does not implement the optional member.
|
|
4575
|
+
*/
|
|
4576
|
+
function runAnnotationAppearanceExportConformance(runner, opts) {
|
|
4577
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4578
|
+
describe(`annotation appearance export conformance: ${opts.label}`, () => {
|
|
4579
|
+
let engine;
|
|
4580
|
+
beforeAll(async () => {
|
|
4581
|
+
engine = await opts.makeEngine();
|
|
4582
|
+
});
|
|
4583
|
+
afterAll(async () => {
|
|
4584
|
+
if (engine) await engine.destroy();
|
|
4585
|
+
});
|
|
4586
|
+
test("returns a single-page PDF sized to the union rect; source untouched", async () => {
|
|
4587
|
+
const doc = await openFixture$11(engine, opts);
|
|
4588
|
+
let exported = null;
|
|
4589
|
+
try {
|
|
4590
|
+
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
4591
|
+
const page = doc.page(pon);
|
|
4592
|
+
if (!page.annotations.exportAppearance) return;
|
|
4593
|
+
const a = (await page.annotations.create(square(20, 20))).created.ref;
|
|
4594
|
+
const b = (await page.annotations.create(square(100, 60, 30))).created.ref;
|
|
4595
|
+
const before = await page.annotations.list();
|
|
4596
|
+
const bytes = await page.annotations.exportAppearance([a, b]);
|
|
4597
|
+
expect(bytes.length > 4).toBe(true);
|
|
4598
|
+
expect([...bytes.subarray(0, 4)]).toEqual(PDF_MAGIC$1);
|
|
4599
|
+
const after = await page.annotations.list();
|
|
4600
|
+
expect(after.annotations.length).toBe(before.annotations.length);
|
|
4601
|
+
expect(after.pageState.revision.generation).toBe(before.pageState.revision.generation);
|
|
4602
|
+
if (opts.openKind !== "bytes") return;
|
|
4603
|
+
exported = await engine.open({
|
|
4604
|
+
kind: "bytes",
|
|
4605
|
+
id: `${opts.fixture.id}-appearance`,
|
|
4606
|
+
bytes
|
|
4607
|
+
});
|
|
4608
|
+
const layout = await exported.pages.list();
|
|
4609
|
+
expect(layout.pageCount).toBe(1);
|
|
4610
|
+
expect(Math.round(layout.pages[0].size.width)).toBe(110);
|
|
4611
|
+
expect(Math.round(layout.pages[0].size.height)).toBe(70);
|
|
4612
|
+
const exportedPage = exported.page(layout.pages[0].pageObjectNumber);
|
|
4613
|
+
expect((await exportedPage.annotations.list()).annotations).toHaveLength(0);
|
|
4614
|
+
} finally {
|
|
4615
|
+
if (exported) await exported.close();
|
|
4616
|
+
await doc.close();
|
|
4617
|
+
}
|
|
4618
|
+
});
|
|
4619
|
+
test("a ref on another page and an empty list reject InvalidArg", async () => {
|
|
4620
|
+
const doc = await openFixture$11(engine, opts);
|
|
4621
|
+
try {
|
|
4622
|
+
const layout = await doc.pages.list();
|
|
4623
|
+
const page0 = doc.page(layout.pages[0].pageObjectNumber);
|
|
4624
|
+
if (!page0.annotations.exportAppearance) return;
|
|
4625
|
+
await expect(page0.annotations.exportAppearance([])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4626
|
+
if (layout.pages.length < 2) return;
|
|
4627
|
+
const page1 = doc.page(layout.pages[1].pageObjectNumber);
|
|
4628
|
+
const own = (await page0.annotations.create(square(20, 100))).created.ref;
|
|
4629
|
+
const foreign = (await page1.annotations.create(square(20, 100))).created.ref;
|
|
4630
|
+
await expect(page0.annotations.exportAppearance([own, foreign])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4631
|
+
} finally {
|
|
4632
|
+
await doc.close();
|
|
4633
|
+
}
|
|
4634
|
+
});
|
|
4635
|
+
});
|
|
4636
|
+
}
|
|
4637
|
+
async function openFixture$11(engine, opts) {
|
|
4638
|
+
if (opts.openKind === "bytes") return engine.open({
|
|
4639
|
+
kind: "bytes",
|
|
4640
|
+
id: opts.fixture.id,
|
|
4641
|
+
bytes: await opts.fixture.bytes()
|
|
4642
|
+
});
|
|
4643
|
+
return engine.open({
|
|
4644
|
+
kind: "id",
|
|
4645
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
4646
|
+
});
|
|
4647
|
+
}
|
|
4648
|
+
//#endregion
|
|
4195
4649
|
//#region src/conformance/runPageFlattenConformance.ts
|
|
4196
4650
|
/** Transport-neutral coverage for the content + annotation flatten rail. */
|
|
4197
4651
|
function runPageFlattenConformance(runner, opts) {
|
|
@@ -6220,6 +6674,6 @@ function diffAnnotation(i, a, b, errs) {
|
|
|
6220
6674
|
if (a.nm !== b.nm) errs.push(`annotations[${i}].nm mismatch: ${a.nm} vs ${b.nm}`);
|
|
6221
6675
|
}
|
|
6222
6676
|
//#endregion
|
|
6223
|
-
export { TEXT_DIVERGENCE_CASES, diffAnnotationListSnapshot, diffAnnotationListSnapshotAll, runActionsConformance, runAnnotationAppearanceConformance, runAnnotationMutationConformance, runAnnotationReadConformance, runAttachmentConformance, runDocumentEventsConformance, runFormConformance, runMetadataConformance, runPageDeleteConformance, runPageExtractConformance, runPageFlattenConformance, runPageGeometryOrientationConformance, runPageInsertBlankConformance, runPageInsertConformance, runPageReorderConformance, runPageRotateConformance, runPageTextConformance, runPieceInfoConformance, runRedactionApplyConformance, runSearchConformance, runTextDivergenceConformance };
|
|
6677
|
+
export { TEXT_DIVERGENCE_CASES, diffAnnotationListSnapshot, diffAnnotationListSnapshotAll, runActionsConformance, runAnnotationAppearanceConformance, runAnnotationAppearanceExportConformance, runAnnotationFlattenConformance, runAnnotationMutationConformance, runAnnotationReadConformance, runAttachmentConformance, runDocumentEventsConformance, runFormConformance, runMetadataConformance, runNamedPagesConformance, runPageDeleteConformance, runPageExtractConformance, runPageFlattenConformance, runPageGeometryOrientationConformance, runPageInsertBlankConformance, runPageInsertConformance, runPageReorderConformance, runPageRotateConformance, runPageTextConformance, runPieceInfoConformance, runRedactionApplyConformance, runSearchConformance, runTextDivergenceConformance };
|
|
6224
6678
|
|
|
6225
6679
|
//# sourceMappingURL=conformance.js.map
|