@embedpdf/engine-core 3.0.0-next.1 → 3.0.0-next.11
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/{AbortError-CjSasIlL.js → AbortError-8-9JAX1Y.js} +2 -2
- package/dist/{AbortError-CjSasIlL.js.map → AbortError-8-9JAX1Y.js.map} +1 -1
- package/dist/{AbortError-ByBflvEl.cjs → AbortError-CRSooKsk.cjs} +2 -2
- package/dist/{AbortError-ByBflvEl.cjs.map → AbortError-CRSooKsk.cjs.map} +1 -1
- package/dist/{AnnotationListSnapshot-W0RCsyDE.d.cts → AnnotationListSnapshot-C1U3XUxP.d.cts} +846 -127
- package/dist/{AnnotationListSnapshot-W0RCsyDE.d.ts → AnnotationListSnapshot-C1U3XUxP.d.ts} +846 -127
- package/dist/{DocumentSecurityService-Df79fgpe.d.cts → DocumentSecurityService-6rhztZlz.d.cts} +33 -2
- package/dist/{DocumentSecurityService-B-tULKNY.d.ts → DocumentSecurityService-7nL9aY75.d.ts} +33 -2
- package/dist/{Engine-B7Oe7f5i.d.ts → Engine-CWnAKccD.d.ts} +62 -19
- package/dist/{Engine-D9loFZc1.d.cts → Engine-D3868xIU.d.cts} +62 -19
- package/dist/{subtype-qejjVr6h.cjs → PageInsertBlankInput-CzShuSJI.cjs} +184 -1
- package/dist/PageInsertBlankInput-CzShuSJI.cjs.map +1 -0
- package/dist/{subtype-BvAzLCGC.js → PageInsertBlankInput-WKY0tr6S.js} +149 -2
- package/dist/PageInsertBlankInput-WKY0tr6S.js.map +1 -0
- package/dist/{builders-C548U47M.js → builders-Cdz34nbF.js} +566 -164
- package/dist/builders-Cdz34nbF.js.map +1 -0
- package/dist/{builders-BvikWRuO.cjs → builders-Do6_4KnS.cjs} +628 -220
- package/dist/builders-Do6_4KnS.cjs.map +1 -0
- package/dist/conformance.cjs +1039 -204
- package/dist/conformance.cjs.map +1 -1
- package/dist/conformance.d.cts +130 -6
- package/dist/conformance.d.ts +130 -6
- package/dist/conformance.js +994 -163
- package/dist/conformance.js.map +1 -1
- package/dist/{fold-CB4fAOOy.js → fold-BfyxxwS6.js} +162 -3
- package/dist/fold-BfyxxwS6.js.map +1 -0
- package/dist/{fold-IaMph3CO.cjs → fold-C7I5GpBz.cjs} +235 -4
- package/dist/fold-C7I5GpBz.cjs.map +1 -0
- package/dist/index.cjs +38 -19
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -5
- package/dist/{resolver-DiPMTfcy.js → resolver-CHG4waXL.js} +2 -1
- package/dist/resolver-CHG4waXL.js.map +1 -0
- package/dist/{resolver-DAZWVoJL.cjs → resolver-D-jumvgM.cjs} +2 -1
- package/dist/resolver-D-jumvgM.cjs.map +1 -0
- package/dist/runtime.cjs +43 -24
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +103 -5
- package/dist/runtime.d.ts +103 -5
- package/dist/runtime.js +6 -6
- package/dist/{schemas-B_1VyFsm.cjs → schemas-CS5iPpX5.cjs} +305 -111
- package/dist/schemas-CS5iPpX5.cjs.map +1 -0
- package/dist/{schemas-9OpSSeM6.js → schemas-XGrNVMDd.js} +250 -92
- package/dist/schemas-XGrNVMDd.js.map +1 -0
- package/dist/wire.cjs +131 -4
- package/dist/wire.cjs.map +1 -1
- package/dist/wire.d.cts +277 -20
- package/dist/wire.d.ts +277 -20
- package/dist/wire.js +120 -5
- package/dist/wire.js.map +1 -1
- package/package.json +1 -1
- package/dist/builders-BvikWRuO.cjs.map +0 -1
- package/dist/builders-C548U47M.js.map +0 -1
- package/dist/fold-CB4fAOOy.js.map +0 -1
- package/dist/fold-IaMph3CO.cjs.map +0 -1
- package/dist/resolver-DAZWVoJL.cjs.map +0 -1
- package/dist/resolver-DiPMTfcy.js.map +0 -1
- package/dist/schemas-9OpSSeM6.js.map +0 -1
- package/dist/schemas-B_1VyFsm.cjs.map +0 -1
- package/dist/subtype-BvAzLCGC.js.map +0 -1
- package/dist/subtype-qejjVr6h.cjs.map +0 -1
package/dist/conformance.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const require_AbortError = require("./AbortError-
|
|
5
|
-
const require_schemas = require("./schemas-
|
|
2
|
+
const require_fold = require("./fold-C7I5GpBz.cjs");
|
|
3
|
+
const require_PageInsertBlankInput = require("./PageInsertBlankInput-CzShuSJI.cjs");
|
|
4
|
+
const require_AbortError = require("./AbortError-CRSooKsk.cjs");
|
|
5
|
+
const require_schemas = require("./schemas-CS5iPpX5.cjs");
|
|
6
6
|
//#region src/conformance/runMetadataConformance.ts
|
|
7
7
|
/**
|
|
8
8
|
* The conformance harness is transport-agnostic. It takes the test runner as
|
|
@@ -19,7 +19,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
19
19
|
if (engine) await engine.destroy();
|
|
20
20
|
});
|
|
21
21
|
test("reads metadata from sample fixture", async () => {
|
|
22
|
-
const doc = await openFixture$
|
|
22
|
+
const doc = await openFixture$17(engine, opts);
|
|
23
23
|
try {
|
|
24
24
|
const meta = await doc.metadata.read();
|
|
25
25
|
expect(meta).toMatchObject(opts.fixture.expected);
|
|
@@ -29,7 +29,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
31
|
test("abort() before completion rejects with AbortError", async () => {
|
|
32
|
-
const doc = await openFixture$
|
|
32
|
+
const doc = await openFixture$17(engine, opts);
|
|
33
33
|
try {
|
|
34
34
|
const p = doc.metadata.read();
|
|
35
35
|
p.abort("test");
|
|
@@ -39,7 +39,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
39
39
|
}
|
|
40
40
|
});
|
|
41
41
|
test("aborting one read does not affect a concurrent one", async () => {
|
|
42
|
-
const doc = await openFixture$
|
|
42
|
+
const doc = await openFixture$17(engine, opts);
|
|
43
43
|
try {
|
|
44
44
|
const a = doc.metadata.read();
|
|
45
45
|
const b = doc.metadata.read();
|
|
@@ -51,7 +51,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
test("metadata after close throws DocNotOpen", async () => {
|
|
54
|
-
const doc = await openFixture$
|
|
54
|
+
const doc = await openFixture$17(engine, opts);
|
|
55
55
|
await doc.close();
|
|
56
56
|
let caught;
|
|
57
57
|
try {
|
|
@@ -60,10 +60,10 @@ function runMetadataConformance(runner, opts) {
|
|
|
60
60
|
caught = err;
|
|
61
61
|
}
|
|
62
62
|
expect(caught).toBeTruthy();
|
|
63
|
-
expect(require_fold.EngineError.is(caught,
|
|
63
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.DocNotOpen)).toBe(true);
|
|
64
64
|
});
|
|
65
65
|
test("update() sets standard + custom fields and a subsequent read observes them", async () => {
|
|
66
|
-
const doc = await openFixture$
|
|
66
|
+
const doc = await openFixture$17(engine, opts);
|
|
67
67
|
try {
|
|
68
68
|
const result = await doc.metadata.update({
|
|
69
69
|
title: "Conformance Title",
|
|
@@ -82,7 +82,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
82
82
|
}
|
|
83
83
|
});
|
|
84
84
|
test("update() clears a field with null", async () => {
|
|
85
|
-
const doc = await openFixture$
|
|
85
|
+
const doc = await openFixture$17(engine, opts);
|
|
86
86
|
try {
|
|
87
87
|
await doc.metadata.update({ title: "To Be Cleared" });
|
|
88
88
|
const set = await doc.metadata.read();
|
|
@@ -95,7 +95,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
95
95
|
}
|
|
96
96
|
});
|
|
97
97
|
test("update() after close throws DocNotOpen", async () => {
|
|
98
|
-
const doc = await openFixture$
|
|
98
|
+
const doc = await openFixture$17(engine, opts);
|
|
99
99
|
await doc.close();
|
|
100
100
|
let caught;
|
|
101
101
|
try {
|
|
@@ -104,11 +104,11 @@ function runMetadataConformance(runner, opts) {
|
|
|
104
104
|
caught = err;
|
|
105
105
|
}
|
|
106
106
|
expect(caught).toBeTruthy();
|
|
107
|
-
expect(require_fold.EngineError.is(caught,
|
|
107
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.DocNotOpen)).toBe(true);
|
|
108
108
|
});
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
|
-
async function openFixture$
|
|
111
|
+
async function openFixture$17(engine, opts) {
|
|
112
112
|
if (opts.openKind === "bytes") {
|
|
113
113
|
const bytes = await opts.fixture.bytes();
|
|
114
114
|
return engine.open({
|
|
@@ -135,11 +135,12 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
135
135
|
if (engine) await engine.destroy();
|
|
136
136
|
});
|
|
137
137
|
test("listRawAll returns one entry per page with valid PageState", async () => {
|
|
138
|
-
const doc = await openFixture$
|
|
138
|
+
const doc = await openFixture$16(engine, opts);
|
|
139
139
|
try {
|
|
140
140
|
const snap = await doc.annotations.listRawAll();
|
|
141
141
|
expect(require_schemas.AnnotationListSnapshotAllPagesSchema.safeParse(snap).success).toBe(true);
|
|
142
142
|
expect(snap.pages.length >= 1).toBe(true);
|
|
143
|
+
if (snap.auditHead !== void 0) expect(Number.isInteger(snap.auditHead) && snap.auditHead >= 0).toBe(true);
|
|
143
144
|
const target = snap.pages.find((p) => p.pageState.pageObjectNumber === opts.fixture.pageObjectNumber);
|
|
144
145
|
expect(target !== void 0).toBe(true);
|
|
145
146
|
expect(target.annotations.length).toBe(opts.fixture.expectedAnnotationCount);
|
|
@@ -148,7 +149,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
148
149
|
}
|
|
149
150
|
});
|
|
150
151
|
test("listRaw on the test page returns the expected counts and DTO shape", async () => {
|
|
151
|
-
const doc = await openFixture$
|
|
152
|
+
const doc = await openFixture$16(engine, opts);
|
|
152
153
|
try {
|
|
153
154
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
154
155
|
expect(require_schemas.AnnotationListPageSnapshotSchema.safeParse(snap).success).toBe(true);
|
|
@@ -178,7 +179,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
178
179
|
}
|
|
179
180
|
});
|
|
180
181
|
test("shape/vertex/line annotations expose their family fields", async () => {
|
|
181
|
-
const doc = await openFixture$
|
|
182
|
+
const doc = await openFixture$16(engine, opts);
|
|
182
183
|
try {
|
|
183
184
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
184
185
|
for (const a of snap.annotations) {
|
|
@@ -237,7 +238,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
237
238
|
}
|
|
238
239
|
});
|
|
239
240
|
test("full page list dispatches per-subtype and matches raw counts", async () => {
|
|
240
|
-
const doc = await openFixture$
|
|
241
|
+
const doc = await openFixture$16(engine, opts);
|
|
241
242
|
try {
|
|
242
243
|
const full = await doc.page(opts.fixture.pageObjectNumber).annotations.list();
|
|
243
244
|
expect(require_schemas.AnnotationListPageSnapshotSchema.safeParse(full).success).toBe(true);
|
|
@@ -247,7 +248,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
247
248
|
}
|
|
248
249
|
});
|
|
249
250
|
test("every annotation DTO satisfies AnnotationDTOSchema (discriminated union)", async () => {
|
|
250
|
-
const doc = await openFixture$
|
|
251
|
+
const doc = await openFixture$16(engine, opts);
|
|
251
252
|
try {
|
|
252
253
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
253
254
|
for (const a of snap.annotations) {
|
|
@@ -287,7 +288,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
287
288
|
});
|
|
288
289
|
if (opts.fixture.expectsWeakAnnotation) {
|
|
289
290
|
test("weak annotations carry identityQuality: weak and ref.kind: index", async () => {
|
|
290
|
-
const doc = await openFixture$
|
|
291
|
+
const doc = await openFixture$16(engine, opts);
|
|
291
292
|
try {
|
|
292
293
|
const weak = (await doc.annotations.listRaw(opts.fixture.pageObjectNumber)).annotations.find((a) => a.identityQuality === "weak");
|
|
293
294
|
expect(weak !== void 0).toBe(true);
|
|
@@ -297,7 +298,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
297
298
|
}
|
|
298
299
|
});
|
|
299
300
|
test("a stale revision token throws InvalidReference", async () => {
|
|
300
|
-
const doc = await openFixture$
|
|
301
|
+
const doc = await openFixture$16(engine, opts);
|
|
301
302
|
try {
|
|
302
303
|
const snap = await doc.page(opts.fixture.pageObjectNumber).annotations.list();
|
|
303
304
|
const weak = snap.annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -313,7 +314,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
313
314
|
});
|
|
314
315
|
}
|
|
315
316
|
test("abort() on listRaw rejects with AbortError", async () => {
|
|
316
|
-
const doc = await openFixture$
|
|
317
|
+
const doc = await openFixture$16(engine, opts);
|
|
317
318
|
try {
|
|
318
319
|
const p = doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
319
320
|
p.abort("test");
|
|
@@ -323,7 +324,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
323
324
|
}
|
|
324
325
|
});
|
|
325
326
|
test("listRaw on an unknown pageObjectNumber throws NotFound", async () => {
|
|
326
|
-
const doc = await openFixture$
|
|
327
|
+
const doc = await openFixture$16(engine, opts);
|
|
327
328
|
try {
|
|
328
329
|
let caught;
|
|
329
330
|
try {
|
|
@@ -332,14 +333,14 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
332
333
|
caught = err;
|
|
333
334
|
}
|
|
334
335
|
expect(caught).toBeTruthy();
|
|
335
|
-
expect(require_fold.EngineError.is(caught,
|
|
336
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.NotFound)).toBe(true);
|
|
336
337
|
} finally {
|
|
337
338
|
await doc.close();
|
|
338
339
|
}
|
|
339
340
|
});
|
|
340
341
|
});
|
|
341
342
|
}
|
|
342
|
-
async function openFixture$
|
|
343
|
+
async function openFixture$16(engine, opts) {
|
|
343
344
|
if (opts.openKind === "bytes") {
|
|
344
345
|
const bytes = await opts.fixture.bytes();
|
|
345
346
|
return engine.open({
|
|
@@ -369,6 +370,13 @@ function emptyFlags() {
|
|
|
369
370
|
}
|
|
370
371
|
//#endregion
|
|
371
372
|
//#region src/conformance/runActionsConformance.ts
|
|
373
|
+
/** The script payload rides only the javascript/rendition arms. */
|
|
374
|
+
function scriptOf(node) {
|
|
375
|
+
if (!node) return "";
|
|
376
|
+
if (node.type === "javascript") return node.script;
|
|
377
|
+
if (node.type === "rendition") return node.script ?? "";
|
|
378
|
+
return "";
|
|
379
|
+
}
|
|
372
380
|
/** Action extraction parity. These tests assert data only; no script executes. */
|
|
373
381
|
function runActionsConformance(runner, opts) {
|
|
374
382
|
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
@@ -388,10 +396,10 @@ function runActionsConformance(runner, opts) {
|
|
|
388
396
|
expect(require_schemas.DocumentActionsSnapshotSchema.safeParse(snapshot).success).toBe(true);
|
|
389
397
|
expect(snapshot.openAction).toBeNull();
|
|
390
398
|
expect(snapshot.willSave?.root?.type).toBe("javascript");
|
|
391
|
-
expect(snapshot.willSave?.root
|
|
392
|
-
expect(snapshot.didSave?.root
|
|
393
|
-
expect(snapshot.willPrint?.root
|
|
394
|
-
expect(snapshot.didPrint?.root
|
|
399
|
+
expect(scriptOf(snapshot.willSave?.root)).toMatch(/Will Save/);
|
|
400
|
+
expect(scriptOf(snapshot.didSave?.root)).toMatch(/Did Save/);
|
|
401
|
+
expect(scriptOf(snapshot.willPrint?.root)).toMatch(/Will Print/);
|
|
402
|
+
expect(scriptOf(snapshot.didPrint?.root)).toMatch(/Did Print/);
|
|
395
403
|
const form = await doc.forms.list();
|
|
396
404
|
expect(form.calculationOrder).toEqual([{
|
|
397
405
|
kind: "objectNumber",
|
|
@@ -438,7 +446,7 @@ function runActionsConformance(runner, opts) {
|
|
|
438
446
|
expect(link?.subtype).toBe("link");
|
|
439
447
|
if (link?.subtype === "link") expect(link.target).toEqual({ kind: "javascript" });
|
|
440
448
|
expect(link?.actions?.activate?.root?.type).toBe("javascript");
|
|
441
|
-
expect(link?.actions?.activate?.root
|
|
449
|
+
expect(scriptOf(link?.actions?.activate?.root)).toMatch(/app\.alert/);
|
|
442
450
|
} finally {
|
|
443
451
|
await doc.close();
|
|
444
452
|
}
|
|
@@ -449,7 +457,7 @@ function runActionsConformance(runner, opts) {
|
|
|
449
457
|
const form = await doc.forms.list();
|
|
450
458
|
expect(form.fields).toHaveLength(1);
|
|
451
459
|
expect(form.fields[0].actions?.format?.root?.type).toBe("javascript");
|
|
452
|
-
expect(form.fields[0].actions?.format?.root
|
|
460
|
+
expect(scriptOf(form.fields[0].actions?.format?.root)).toMatch(/AFDate_FormatEx/);
|
|
453
461
|
const page = (await doc.pages.list()).pages[0];
|
|
454
462
|
const widget = (await doc.page(page.pageObjectNumber).annotations.list()).annotations[0];
|
|
455
463
|
expect(widget.actions).toBe(void 0);
|
|
@@ -457,6 +465,210 @@ function runActionsConformance(runner, opts) {
|
|
|
457
465
|
await doc.close();
|
|
458
466
|
}
|
|
459
467
|
});
|
|
468
|
+
test("carries interpreter payloads on every executable node", async () => {
|
|
469
|
+
const doc = await open(engine, opts, opts.fixtures.payloads);
|
|
470
|
+
try {
|
|
471
|
+
const page = (await doc.pages.list()).pages[0];
|
|
472
|
+
const snapshot = await doc.page(page.pageObjectNumber).annotations.list();
|
|
473
|
+
const pon = page.pageObjectNumber;
|
|
474
|
+
const rootOf = (nm) => {
|
|
475
|
+
const annotation = snapshot.annotations.find((candidate) => candidate.nm === nm);
|
|
476
|
+
expect(Boolean(annotation)).toBe(true);
|
|
477
|
+
return annotation?.actions?.activate?.root ?? null;
|
|
478
|
+
};
|
|
479
|
+
const targetOf = (nm) => {
|
|
480
|
+
const annotation = snapshot.annotations.find((candidate) => candidate.nm === nm);
|
|
481
|
+
return annotation?.subtype === "link" ? annotation.target : null;
|
|
482
|
+
};
|
|
483
|
+
expect(rootOf("goto-fitr")).toMatchObject({
|
|
484
|
+
type: "goto",
|
|
485
|
+
destination: {
|
|
486
|
+
kind: "fitR",
|
|
487
|
+
pageObjectNumber: pon,
|
|
488
|
+
left: 10,
|
|
489
|
+
bottom: 20,
|
|
490
|
+
right: 300,
|
|
491
|
+
top: 400
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
expect(targetOf("goto-fitr")).toMatchObject({
|
|
495
|
+
kind: "goto",
|
|
496
|
+
destination: { kind: "fitR" }
|
|
497
|
+
});
|
|
498
|
+
expect(rootOf("uri-map")).toMatchObject({
|
|
499
|
+
type: "uri",
|
|
500
|
+
uri: "https://example.test/map",
|
|
501
|
+
isMap: true
|
|
502
|
+
});
|
|
503
|
+
expect(rootOf("named-next")).toMatchObject({
|
|
504
|
+
type: "named",
|
|
505
|
+
name: "NextPage"
|
|
506
|
+
});
|
|
507
|
+
const mixed = rootOf("hide-mixed");
|
|
508
|
+
expect(mixed).toMatchObject({
|
|
509
|
+
type: "hide",
|
|
510
|
+
hide: false
|
|
511
|
+
});
|
|
512
|
+
const mixedTargets = mixed?.type === "hide" ? mixed.targets : [];
|
|
513
|
+
expect(mixedTargets).toHaveLength(2);
|
|
514
|
+
expect(mixedTargets[0]).toEqual({
|
|
515
|
+
kind: "name",
|
|
516
|
+
name: "note1"
|
|
517
|
+
});
|
|
518
|
+
expect(mixedTargets[1]?.kind === "objectNumber" && mixedTargets[1].objectNumber > 0).toBe(true);
|
|
519
|
+
expect(rootOf("hide-scalar")).toMatchObject({
|
|
520
|
+
type: "hide",
|
|
521
|
+
targets: [{
|
|
522
|
+
kind: "name",
|
|
523
|
+
name: "fieldB"
|
|
524
|
+
}],
|
|
525
|
+
hide: true
|
|
526
|
+
});
|
|
527
|
+
expect(rootOf("reset-include")).toMatchObject({
|
|
528
|
+
type: "reset-form",
|
|
529
|
+
fields: [{
|
|
530
|
+
kind: "name",
|
|
531
|
+
name: "calc1"
|
|
532
|
+
}],
|
|
533
|
+
exclude: true
|
|
534
|
+
});
|
|
535
|
+
expect(rootOf("reset-absent")).toMatchObject({
|
|
536
|
+
type: "reset-form",
|
|
537
|
+
fields: null,
|
|
538
|
+
exclude: true
|
|
539
|
+
});
|
|
540
|
+
expect(rootOf("reset-empty")).toMatchObject({
|
|
541
|
+
type: "reset-form",
|
|
542
|
+
fields: [],
|
|
543
|
+
exclude: false
|
|
544
|
+
});
|
|
545
|
+
expect(rootOf("submit-urlspec")).toMatchObject({
|
|
546
|
+
type: "submit-form",
|
|
547
|
+
payload: {
|
|
548
|
+
url: "https://uf.example.test/submit",
|
|
549
|
+
fields: [{
|
|
550
|
+
kind: "name",
|
|
551
|
+
name: "parent"
|
|
552
|
+
}],
|
|
553
|
+
flags: {
|
|
554
|
+
raw: 0,
|
|
555
|
+
exclude: false,
|
|
556
|
+
format: "fdf",
|
|
557
|
+
method: "post"
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
});
|
|
561
|
+
expect(rootOf("submit-compat-xfdf")).toMatchObject({
|
|
562
|
+
type: "submit-form",
|
|
563
|
+
payload: {
|
|
564
|
+
url: "https://example.test/xfdf",
|
|
565
|
+
fields: [{
|
|
566
|
+
kind: "name",
|
|
567
|
+
name: "noexport"
|
|
568
|
+
}, {
|
|
569
|
+
kind: "name",
|
|
570
|
+
name: "plain"
|
|
571
|
+
}],
|
|
572
|
+
flags: {
|
|
573
|
+
raw: 35,
|
|
574
|
+
exclude: true,
|
|
575
|
+
includeNoValueFields: true,
|
|
576
|
+
format: "xfdf",
|
|
577
|
+
method: "post"
|
|
578
|
+
},
|
|
579
|
+
charSet: "utf-8"
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
expect(rootOf("submit-pdf-get")).toMatchObject({
|
|
583
|
+
type: "submit-form",
|
|
584
|
+
payload: {
|
|
585
|
+
url: "https://example.test/pdf",
|
|
586
|
+
fields: null,
|
|
587
|
+
flags: {
|
|
588
|
+
raw: 264,
|
|
589
|
+
format: "pdf",
|
|
590
|
+
method: "get"
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
expect(rootOf("launch-app")).toMatchObject({
|
|
595
|
+
type: "launch",
|
|
596
|
+
filePath: "app.exe"
|
|
597
|
+
});
|
|
598
|
+
expect(rootOf("gotor-file")).toMatchObject({
|
|
599
|
+
type: "goto-remote",
|
|
600
|
+
filePath: "other.pdf"
|
|
601
|
+
});
|
|
602
|
+
const chain = rootOf("chain-js-goto-hide");
|
|
603
|
+
expect(chain).toMatchObject({
|
|
604
|
+
type: "javascript",
|
|
605
|
+
script: "app.alert('chain');"
|
|
606
|
+
});
|
|
607
|
+
expect(chain?.next[0]).toMatchObject({
|
|
608
|
+
type: "goto",
|
|
609
|
+
destination: {
|
|
610
|
+
kind: "xyz",
|
|
611
|
+
pageObjectNumber: pon,
|
|
612
|
+
left: 5,
|
|
613
|
+
top: 10,
|
|
614
|
+
zoom: 1.25
|
|
615
|
+
}
|
|
616
|
+
});
|
|
617
|
+
expect(chain?.next[0]?.next[0]).toMatchObject({
|
|
618
|
+
type: "hide",
|
|
619
|
+
targets: [{
|
|
620
|
+
kind: "name",
|
|
621
|
+
name: "note1"
|
|
622
|
+
}],
|
|
623
|
+
hide: true
|
|
624
|
+
});
|
|
625
|
+
} finally {
|
|
626
|
+
await doc.close();
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
test("degrades unreadable payloads to unknown with payload-dropped", async () => {
|
|
630
|
+
const doc = await open(engine, opts, opts.fixtures.payloads);
|
|
631
|
+
try {
|
|
632
|
+
const page = (await doc.pages.list()).pages[0];
|
|
633
|
+
const snapshot = await doc.page(page.pageObjectNumber).annotations.list();
|
|
634
|
+
for (const [nm, subtype] of [
|
|
635
|
+
["goto-malformed", "GoTo"],
|
|
636
|
+
["hide-partial", "Hide"],
|
|
637
|
+
["submit-not-url", "SubmitForm"],
|
|
638
|
+
["submit-no-f", "SubmitForm"]
|
|
639
|
+
]) {
|
|
640
|
+
const annotation = snapshot.annotations.find((candidate) => candidate.nm === nm);
|
|
641
|
+
const tree = annotation?.actions?.activate;
|
|
642
|
+
expect(tree?.root).toMatchObject({
|
|
643
|
+
type: "unknown",
|
|
644
|
+
subtype
|
|
645
|
+
});
|
|
646
|
+
expect(tree?.warnings ?? []).toContain("payload-dropped");
|
|
647
|
+
if (annotation?.subtype === "link") expect(annotation.target).toEqual({ kind: "unsupported" });
|
|
648
|
+
}
|
|
649
|
+
} finally {
|
|
650
|
+
await doc.close();
|
|
651
|
+
}
|
|
652
|
+
});
|
|
653
|
+
test("reads a destination-form /OpenAction as openDestination", async () => {
|
|
654
|
+
const doc = await open(engine, opts, opts.fixtures.openDestination);
|
|
655
|
+
try {
|
|
656
|
+
expect(Boolean(doc.actions)).toBe(true);
|
|
657
|
+
const snapshot = await doc.actions.read();
|
|
658
|
+
expect(require_schemas.DocumentActionsSnapshotSchema.safeParse(snapshot).success).toBe(true);
|
|
659
|
+
expect(snapshot.openAction).toBeNull();
|
|
660
|
+
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
661
|
+
expect(snapshot.openDestination).toEqual({
|
|
662
|
+
kind: "xyz",
|
|
663
|
+
pageObjectNumber: pon,
|
|
664
|
+
left: 10,
|
|
665
|
+
top: 700,
|
|
666
|
+
zoom: 1.5
|
|
667
|
+
});
|
|
668
|
+
} finally {
|
|
669
|
+
await doc.close();
|
|
670
|
+
}
|
|
671
|
+
});
|
|
460
672
|
});
|
|
461
673
|
}
|
|
462
674
|
async function open(engine, opts, fixture) {
|
|
@@ -597,7 +809,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
597
809
|
if (engine) await engine.destroy();
|
|
598
810
|
});
|
|
599
811
|
test("create appends without shifting indices and leaves weak refs valid", async () => {
|
|
600
|
-
const doc = await openFixture$
|
|
812
|
+
const doc = await openFixture$15(engine, opts);
|
|
601
813
|
try {
|
|
602
814
|
const page = doc.page(fix.pageObjectNumber);
|
|
603
815
|
const before = await page.annotations.list();
|
|
@@ -633,7 +845,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
633
845
|
}
|
|
634
846
|
});
|
|
635
847
|
test("create + update honor annotation flags (set on create, merge on patch)", async () => {
|
|
636
|
-
const doc = await openFixture$
|
|
848
|
+
const doc = await openFixture$15(engine, opts);
|
|
637
849
|
try {
|
|
638
850
|
const page = doc.page(fix.pageObjectNumber);
|
|
639
851
|
const draft = {
|
|
@@ -668,7 +880,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
668
880
|
}
|
|
669
881
|
});
|
|
670
882
|
test("create shape annotations (circle + square) round-trip shape fields", async () => {
|
|
671
|
-
const doc = await openFixture$
|
|
883
|
+
const doc = await openFixture$15(engine, opts);
|
|
672
884
|
try {
|
|
673
885
|
const page = doc.page(fix.pageObjectNumber);
|
|
674
886
|
const circleDraft = {
|
|
@@ -749,7 +961,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
749
961
|
}
|
|
750
962
|
});
|
|
751
963
|
test("cloudy border (/BE) + rect differences (/RD) are tri-state", async () => {
|
|
752
|
-
const doc = await openFixture$
|
|
964
|
+
const doc = await openFixture$15(engine, opts);
|
|
753
965
|
try {
|
|
754
966
|
const page = doc.page(fix.pageObjectNumber);
|
|
755
967
|
const plainDraft = {
|
|
@@ -828,7 +1040,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
828
1040
|
}
|
|
829
1041
|
});
|
|
830
1042
|
test("update echoes the appearance verdict: moves preserve /AP, restyles re-bake", async () => {
|
|
831
|
-
const doc = await openFixture$
|
|
1043
|
+
const doc = await openFixture$15(engine, opts);
|
|
832
1044
|
try {
|
|
833
1045
|
const page = doc.page(fix.pageObjectNumber);
|
|
834
1046
|
const draft = {
|
|
@@ -903,7 +1115,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
903
1115
|
}
|
|
904
1116
|
});
|
|
905
1117
|
test("a partial /DA patch preserves the unpatched font members", async () => {
|
|
906
|
-
const doc = await openFixture$
|
|
1118
|
+
const doc = await openFixture$15(engine, opts);
|
|
907
1119
|
try {
|
|
908
1120
|
const page = doc.page(fix.pageObjectNumber);
|
|
909
1121
|
const draft = {
|
|
@@ -959,7 +1171,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
959
1171
|
}
|
|
960
1172
|
});
|
|
961
1173
|
test("box transform is tri-state: rect-only moves keep rotation, null flattens", async () => {
|
|
962
|
-
const doc = await openFixture$
|
|
1174
|
+
const doc = await openFixture$15(engine, opts);
|
|
963
1175
|
try {
|
|
964
1176
|
const page = doc.page(fix.pageObjectNumber);
|
|
965
1177
|
const draft = {
|
|
@@ -1020,7 +1232,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1020
1232
|
}
|
|
1021
1233
|
});
|
|
1022
1234
|
test("create vertex + line annotations (polygon/polyline/line) round-trip geometry", async () => {
|
|
1023
|
-
const doc = await openFixture$
|
|
1235
|
+
const doc = await openFixture$15(engine, opts);
|
|
1024
1236
|
try {
|
|
1025
1237
|
const page = doc.page(fix.pageObjectNumber);
|
|
1026
1238
|
const polygonDraft = {
|
|
@@ -1151,7 +1363,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1151
1363
|
}
|
|
1152
1364
|
});
|
|
1153
1365
|
test("create free-text + callout round-trip text/colour/intent fields", async () => {
|
|
1154
|
-
const doc = await openFixture$
|
|
1366
|
+
const doc = await openFixture$15(engine, opts);
|
|
1155
1367
|
try {
|
|
1156
1368
|
const page = doc.page(fix.pageObjectNumber);
|
|
1157
1369
|
const freeTextDraft = {
|
|
@@ -1247,7 +1459,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1247
1459
|
}
|
|
1248
1460
|
});
|
|
1249
1461
|
test("update a free-text patches alignment + colours and is non-structural", async () => {
|
|
1250
|
-
const doc = await openFixture$
|
|
1462
|
+
const doc = await openFixture$15(engine, opts);
|
|
1251
1463
|
try {
|
|
1252
1464
|
const page = doc.page(fix.pageObjectNumber);
|
|
1253
1465
|
const created = await page.annotations.create({
|
|
@@ -1308,7 +1520,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1308
1520
|
}
|
|
1309
1521
|
});
|
|
1310
1522
|
test("create redact (area + text) round-trips label + colour fields", async () => {
|
|
1311
|
-
const doc = await openFixture$
|
|
1523
|
+
const doc = await openFixture$15(engine, opts);
|
|
1312
1524
|
try {
|
|
1313
1525
|
const page = doc.page(fix.pageObjectNumber);
|
|
1314
1526
|
const areaDraft = {
|
|
@@ -1388,7 +1600,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1388
1600
|
}
|
|
1389
1601
|
});
|
|
1390
1602
|
test("update a redact patches the label and clears it, non-structurally", async () => {
|
|
1391
|
-
const doc = await openFixture$
|
|
1603
|
+
const doc = await openFixture$15(engine, opts);
|
|
1392
1604
|
try {
|
|
1393
1605
|
const page = doc.page(fix.pageObjectNumber);
|
|
1394
1606
|
const created = await page.annotations.create({
|
|
@@ -1465,7 +1677,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1465
1677
|
}
|
|
1466
1678
|
});
|
|
1467
1679
|
test("create + update a caret round-trips color/opacity/rect differences", async () => {
|
|
1468
|
-
const doc = await openFixture$
|
|
1680
|
+
const doc = await openFixture$15(engine, opts);
|
|
1469
1681
|
try {
|
|
1470
1682
|
const page = doc.page(fix.pageObjectNumber);
|
|
1471
1683
|
const caretDraft = {
|
|
@@ -1545,7 +1757,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1545
1757
|
}
|
|
1546
1758
|
});
|
|
1547
1759
|
test("update an ink annotation patches strokes + color and is non-structural", async () => {
|
|
1548
|
-
const doc = await openFixture$
|
|
1760
|
+
const doc = await openFixture$15(engine, opts);
|
|
1549
1761
|
try {
|
|
1550
1762
|
const page = doc.page(fix.pageObjectNumber);
|
|
1551
1763
|
const created = await page.annotations.create({
|
|
@@ -1596,7 +1808,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1596
1808
|
}
|
|
1597
1809
|
});
|
|
1598
1810
|
test("ink highlight intent + blend round-trip and unrelated patches preserve blend", async () => {
|
|
1599
|
-
const doc = await openFixture$
|
|
1811
|
+
const doc = await openFixture$15(engine, opts);
|
|
1600
1812
|
try {
|
|
1601
1813
|
const page = doc.page(fix.pageObjectNumber);
|
|
1602
1814
|
const created = await page.annotations.create({
|
|
@@ -1639,7 +1851,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1639
1851
|
}
|
|
1640
1852
|
});
|
|
1641
1853
|
test("update a polyline patches vertices + line endings and is non-structural", async () => {
|
|
1642
|
-
const doc = await openFixture$
|
|
1854
|
+
const doc = await openFixture$15(engine, opts);
|
|
1643
1855
|
try {
|
|
1644
1856
|
const page = doc.page(fix.pageObjectNumber);
|
|
1645
1857
|
const created = await page.annotations.create({
|
|
@@ -1688,7 +1900,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1688
1900
|
}
|
|
1689
1901
|
});
|
|
1690
1902
|
test("update a shape annotation patches color and is non-structural", async () => {
|
|
1691
|
-
const doc = await openFixture$
|
|
1903
|
+
const doc = await openFixture$15(engine, opts);
|
|
1692
1904
|
try {
|
|
1693
1905
|
const page = doc.page(fix.pageObjectNumber);
|
|
1694
1906
|
const created = await page.annotations.create({
|
|
@@ -1737,7 +1949,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1737
1949
|
}
|
|
1738
1950
|
});
|
|
1739
1951
|
if (opts.supportsAppearanceRasters) test("creating a shape bakes an /AP appearance the reader can rasterize", async () => {
|
|
1740
|
-
const doc = await openFixture$
|
|
1952
|
+
const doc = await openFixture$15(engine, opts);
|
|
1741
1953
|
try {
|
|
1742
1954
|
const page = doc.page(fix.pageObjectNumber);
|
|
1743
1955
|
const created = await page.annotations.create({
|
|
@@ -1767,7 +1979,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1767
1979
|
}
|
|
1768
1980
|
});
|
|
1769
1981
|
test("update on a durable annotation is non-structural and never touches /NM", async () => {
|
|
1770
|
-
const doc = await openFixture$
|
|
1982
|
+
const doc = await openFixture$15(engine, opts);
|
|
1771
1983
|
try {
|
|
1772
1984
|
const page = doc.page(fix.pageObjectNumber);
|
|
1773
1985
|
const before = await page.annotations.list();
|
|
@@ -1793,7 +2005,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1793
2005
|
}
|
|
1794
2006
|
});
|
|
1795
2007
|
if (fix.expectsWeakAnnotation) test("update on a weak annotation stamps a UUID v4 /NM and upgrades the ref", async () => {
|
|
1796
|
-
const doc = await openFixture$
|
|
2008
|
+
const doc = await openFixture$15(engine, opts);
|
|
1797
2009
|
try {
|
|
1798
2010
|
const page = doc.page(fix.pageObjectNumber);
|
|
1799
2011
|
const before = await page.annotations.list();
|
|
@@ -1823,7 +2035,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1823
2035
|
}
|
|
1824
2036
|
});
|
|
1825
2037
|
test("delete by objectNumber removes the annotation and reports a stable id", async () => {
|
|
1826
|
-
const doc = await openFixture$
|
|
2038
|
+
const doc = await openFixture$15(engine, opts);
|
|
1827
2039
|
try {
|
|
1828
2040
|
const page = doc.page(fix.pageObjectNumber);
|
|
1829
2041
|
const draft = {
|
|
@@ -1853,7 +2065,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1853
2065
|
}
|
|
1854
2066
|
});
|
|
1855
2067
|
if (fix.expectsWeakAnnotation) test("delete by index of a weak annotation reports deleted: null and refetch reason", async () => {
|
|
1856
|
-
const doc = await openFixture$
|
|
2068
|
+
const doc = await openFixture$15(engine, opts);
|
|
1857
2069
|
try {
|
|
1858
2070
|
const page = doc.page(fix.pageObjectNumber);
|
|
1859
2071
|
const weak = (await page.annotations.list()).annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -1876,7 +2088,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1876
2088
|
}
|
|
1877
2089
|
});
|
|
1878
2090
|
test("abort on create rejects with AbortError", async () => {
|
|
1879
|
-
const doc = await openFixture$
|
|
2091
|
+
const doc = await openFixture$15(engine, opts);
|
|
1880
2092
|
try {
|
|
1881
2093
|
const page = doc.page(fix.pageObjectNumber);
|
|
1882
2094
|
const draft = {
|
|
@@ -1892,7 +2104,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1892
2104
|
}
|
|
1893
2105
|
});
|
|
1894
2106
|
test("update with a stale index revision throws InvalidReference", async () => {
|
|
1895
|
-
const doc = await openFixture$
|
|
2107
|
+
const doc = await openFixture$15(engine, opts);
|
|
1896
2108
|
try {
|
|
1897
2109
|
const page = doc.page(fix.pageObjectNumber);
|
|
1898
2110
|
const weak = (await page.annotations.list()).annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -1913,13 +2125,13 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1913
2125
|
} catch (err) {
|
|
1914
2126
|
caught = err;
|
|
1915
2127
|
}
|
|
1916
|
-
expect(require_fold.EngineError.is(caught,
|
|
2128
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidReference)).toBe(true);
|
|
1917
2129
|
} finally {
|
|
1918
2130
|
await doc.close();
|
|
1919
2131
|
}
|
|
1920
2132
|
});
|
|
1921
2133
|
test("move single durable annotation reorders within the page (single-as-batch)", async () => {
|
|
1922
|
-
const doc = await openFixture$
|
|
2134
|
+
const doc = await openFixture$15(engine, opts);
|
|
1923
2135
|
try {
|
|
1924
2136
|
const page = doc.page(fix.pageObjectNumber);
|
|
1925
2137
|
const aDraft = {
|
|
@@ -1963,7 +2175,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1963
2175
|
}
|
|
1964
2176
|
});
|
|
1965
2177
|
test("move multi-block preserves caller-supplied order at the destination", async () => {
|
|
1966
|
-
const doc = await openFixture$
|
|
2178
|
+
const doc = await openFixture$15(engine, opts);
|
|
1967
2179
|
try {
|
|
1968
2180
|
const page = doc.page(fix.pageObjectNumber);
|
|
1969
2181
|
const ids = await Promise.all([
|
|
@@ -2002,7 +2214,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2002
2214
|
}
|
|
2003
2215
|
});
|
|
2004
2216
|
if (fix.expectsWeakAnnotation) test("move on a weak annotation upgrades it to durable /NM (one rev bump for batch)", async () => {
|
|
2005
|
-
const doc = await openFixture$
|
|
2217
|
+
const doc = await openFixture$15(engine, opts);
|
|
2006
2218
|
try {
|
|
2007
2219
|
const page = doc.page(fix.pageObjectNumber);
|
|
2008
2220
|
const before = await page.annotations.list();
|
|
@@ -2027,7 +2239,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2027
2239
|
}
|
|
2028
2240
|
});
|
|
2029
2241
|
test("move with a stale index revision rejects (locked rev-token guard)", async () => {
|
|
2030
|
-
const doc = await openFixture$
|
|
2242
|
+
const doc = await openFixture$15(engine, opts);
|
|
2031
2243
|
try {
|
|
2032
2244
|
const page = doc.page(fix.pageObjectNumber);
|
|
2033
2245
|
const a = await page.annotations.create({
|
|
@@ -2059,13 +2271,13 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2059
2271
|
} finally {
|
|
2060
2272
|
await weakSession?.release();
|
|
2061
2273
|
}
|
|
2062
|
-
expect(require_fold.EngineError.is(caught,
|
|
2274
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidReference)).toBe(true);
|
|
2063
2275
|
} finally {
|
|
2064
2276
|
await doc.close();
|
|
2065
2277
|
}
|
|
2066
2278
|
});
|
|
2067
2279
|
test("move with out-of-range toIndex rejects with InvalidArg", async () => {
|
|
2068
|
-
const doc = await openFixture$
|
|
2280
|
+
const doc = await openFixture$15(engine, opts);
|
|
2069
2281
|
try {
|
|
2070
2282
|
const page = doc.page(fix.pageObjectNumber);
|
|
2071
2283
|
const a = await page.annotations.create({
|
|
@@ -2083,13 +2295,13 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2083
2295
|
} finally {
|
|
2084
2296
|
await weakSession?.release();
|
|
2085
2297
|
}
|
|
2086
|
-
expect(require_fold.EngineError.is(caught,
|
|
2298
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
2087
2299
|
} finally {
|
|
2088
2300
|
await doc.close();
|
|
2089
2301
|
}
|
|
2090
2302
|
});
|
|
2091
2303
|
test("move with duplicate refs rejects with InvalidArg", async () => {
|
|
2092
|
-
const doc = await openFixture$
|
|
2304
|
+
const doc = await openFixture$15(engine, opts);
|
|
2093
2305
|
try {
|
|
2094
2306
|
const page = doc.page(fix.pageObjectNumber);
|
|
2095
2307
|
const a = await page.annotations.create({
|
|
@@ -2106,13 +2318,13 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2106
2318
|
} finally {
|
|
2107
2319
|
await weakSession?.release();
|
|
2108
2320
|
}
|
|
2109
|
-
expect(require_fold.EngineError.is(caught,
|
|
2321
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
2110
2322
|
} finally {
|
|
2111
2323
|
await doc.close();
|
|
2112
2324
|
}
|
|
2113
2325
|
});
|
|
2114
2326
|
test("abort on move rejects with AbortError", async () => {
|
|
2115
|
-
const doc = await openFixture$
|
|
2327
|
+
const doc = await openFixture$15(engine, opts);
|
|
2116
2328
|
try {
|
|
2117
2329
|
const page = doc.page(fix.pageObjectNumber);
|
|
2118
2330
|
const a = await page.annotations.create({
|
|
@@ -2133,7 +2345,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2133
2345
|
}
|
|
2134
2346
|
});
|
|
2135
2347
|
test("a page move does NOT bump per-page RevisionTokens (weak refs survive reorder)", async () => {
|
|
2136
|
-
const doc = await openFixture$
|
|
2348
|
+
const doc = await openFixture$15(engine, opts);
|
|
2137
2349
|
try {
|
|
2138
2350
|
const list = await doc.pages.list();
|
|
2139
2351
|
if (list.pages.length < 1) return;
|
|
@@ -2148,7 +2360,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2148
2360
|
}
|
|
2149
2361
|
});
|
|
2150
2362
|
test("create a reply links /IRT and defaults /RT to \"reply\", reporting the parent", async () => {
|
|
2151
|
-
const doc = await openFixture$
|
|
2363
|
+
const doc = await openFixture$15(engine, opts);
|
|
2152
2364
|
try {
|
|
2153
2365
|
const page = doc.page(fix.pageObjectNumber);
|
|
2154
2366
|
const parent = await page.annotations.create({
|
|
@@ -2182,7 +2394,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2182
2394
|
}
|
|
2183
2395
|
});
|
|
2184
2396
|
test("create a grouped subordinate writes /RT /Group", async () => {
|
|
2185
|
-
const doc = await openFixture$
|
|
2397
|
+
const doc = await openFixture$15(engine, opts);
|
|
2186
2398
|
try {
|
|
2187
2399
|
const page = doc.page(fix.pageObjectNumber);
|
|
2188
2400
|
const primary = await page.annotations.create({
|
|
@@ -2213,7 +2425,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2213
2425
|
}
|
|
2214
2426
|
});
|
|
2215
2427
|
test("create link annotations round-trip uri, goto/xyz, goto/fitH, and dead targets", async () => {
|
|
2216
|
-
const doc = await openFixture$
|
|
2428
|
+
const doc = await openFixture$15(engine, opts);
|
|
2217
2429
|
try {
|
|
2218
2430
|
const page = doc.page(fix.pageObjectNumber);
|
|
2219
2431
|
const uri = await page.annotations.create({
|
|
@@ -2290,7 +2502,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2290
2502
|
}
|
|
2291
2503
|
});
|
|
2292
2504
|
test("a link patch retargets in both directions (uri→goto, goto→uri) and moves the rect", async () => {
|
|
2293
|
-
const doc = await openFixture$
|
|
2505
|
+
const doc = await openFixture$15(engine, opts);
|
|
2294
2506
|
try {
|
|
2295
2507
|
const page = doc.page(fix.pageObjectNumber);
|
|
2296
2508
|
const created = await page.annotations.create({
|
|
@@ -2345,7 +2557,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2345
2557
|
}
|
|
2346
2558
|
});
|
|
2347
2559
|
test("a link patch clears the target with null — a dead link on re-read", async () => {
|
|
2348
|
-
const doc = await openFixture$
|
|
2560
|
+
const doc = await openFixture$15(engine, opts);
|
|
2349
2561
|
try {
|
|
2350
2562
|
const page = doc.page(fix.pageObjectNumber);
|
|
2351
2563
|
const created = await page.annotations.create({
|
|
@@ -2384,7 +2596,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2384
2596
|
}
|
|
2385
2597
|
});
|
|
2386
2598
|
test("a link grouped to a highlight round-trips /IRT + /RT /Group with its target", async () => {
|
|
2387
|
-
const doc = await openFixture$
|
|
2599
|
+
const doc = await openFixture$15(engine, opts);
|
|
2388
2600
|
try {
|
|
2389
2601
|
const page = doc.page(fix.pageObjectNumber);
|
|
2390
2602
|
const parent = await page.annotations.create({
|
|
@@ -2418,7 +2630,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2418
2630
|
}
|
|
2419
2631
|
});
|
|
2420
2632
|
test("replace-text round-trips /IT and groups StrikeOut under its Caret", async () => {
|
|
2421
|
-
const doc = await openFixture$
|
|
2633
|
+
const doc = await openFixture$15(engine, opts);
|
|
2422
2634
|
try {
|
|
2423
2635
|
const page = doc.page(fix.pageObjectNumber);
|
|
2424
2636
|
const caret = await page.annotations.create({
|
|
@@ -2470,7 +2682,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2470
2682
|
}
|
|
2471
2683
|
});
|
|
2472
2684
|
test("patch inReplyTo: null clears /IRT and /RT (back to top-level)", async () => {
|
|
2473
|
-
const doc = await openFixture$
|
|
2685
|
+
const doc = await openFixture$15(engine, opts);
|
|
2474
2686
|
try {
|
|
2475
2687
|
const page = doc.page(fix.pageObjectNumber);
|
|
2476
2688
|
const parent = await page.annotations.create({
|
|
@@ -2497,7 +2709,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2497
2709
|
}
|
|
2498
2710
|
});
|
|
2499
2711
|
test("create with a cross-page /IRT parent throws InvalidArg", async () => {
|
|
2500
|
-
const doc = await openFixture$
|
|
2712
|
+
const doc = await openFixture$15(engine, opts);
|
|
2501
2713
|
try {
|
|
2502
2714
|
const page = doc.page(fix.pageObjectNumber);
|
|
2503
2715
|
const parent = await page.annotations.create({
|
|
@@ -2522,7 +2734,130 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2522
2734
|
} catch (err) {
|
|
2523
2735
|
caught = err;
|
|
2524
2736
|
}
|
|
2525
|
-
expect(require_fold.EngineError.is(caught,
|
|
2737
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
2738
|
+
} finally {
|
|
2739
|
+
await doc.close();
|
|
2740
|
+
}
|
|
2741
|
+
});
|
|
2742
|
+
test("a review-status reply round-trips /State + /StateModel + /Subj", async () => {
|
|
2743
|
+
const doc = await openFixture$15(engine, opts);
|
|
2744
|
+
try {
|
|
2745
|
+
const page = doc.page(fix.pageObjectNumber);
|
|
2746
|
+
const target = await page.annotations.create({
|
|
2747
|
+
subtype: "highlight",
|
|
2748
|
+
contents: "status target",
|
|
2749
|
+
subject: "Pricing question",
|
|
2750
|
+
quadPoints: quad
|
|
2751
|
+
});
|
|
2752
|
+
expect(target.created.subject).toBe("Pricing question");
|
|
2753
|
+
const status = await page.annotations.create({
|
|
2754
|
+
subtype: "text",
|
|
2755
|
+
rect: shapeRect,
|
|
2756
|
+
inReplyTo: target.created.ref,
|
|
2757
|
+
state: "accepted",
|
|
2758
|
+
stateModel: "review"
|
|
2759
|
+
});
|
|
2760
|
+
expect(require_schemas.AnnotationCreateResultSchema.safeParse(status).success).toBe(true);
|
|
2761
|
+
expect(status.created.subtype).toBe("text");
|
|
2762
|
+
if (status.created.subtype !== "text") return;
|
|
2763
|
+
expect(status.created.state).toBe("accepted");
|
|
2764
|
+
expect(status.created.stateModel).toBe("review");
|
|
2765
|
+
expect(status.created.replyType).toBe("reply");
|
|
2766
|
+
const read = (await page.annotations.list()).annotations.find((a) => a.ref.kind === "objectNumber" && status.created.ref.kind === "objectNumber" && a.ref.annotObjectNumber === status.created.ref.annotObjectNumber);
|
|
2767
|
+
expect(read?.subtype).toBe("text");
|
|
2768
|
+
if (read?.subtype === "text") {
|
|
2769
|
+
expect(read.state).toBe("accepted");
|
|
2770
|
+
expect(read.stateModel).toBe("review");
|
|
2771
|
+
}
|
|
2772
|
+
} finally {
|
|
2773
|
+
await doc.close();
|
|
2774
|
+
}
|
|
2775
|
+
});
|
|
2776
|
+
test("a draft /State without /StateModel is rejected with InvalidArg", async () => {
|
|
2777
|
+
const doc = await openFixture$15(engine, opts);
|
|
2778
|
+
try {
|
|
2779
|
+
const page = doc.page(fix.pageObjectNumber);
|
|
2780
|
+
let caught;
|
|
2781
|
+
try {
|
|
2782
|
+
await page.annotations.create({
|
|
2783
|
+
subtype: "text",
|
|
2784
|
+
rect: shapeRect,
|
|
2785
|
+
state: "accepted"
|
|
2786
|
+
});
|
|
2787
|
+
} catch (err) {
|
|
2788
|
+
caught = err;
|
|
2789
|
+
}
|
|
2790
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
2791
|
+
} finally {
|
|
2792
|
+
await doc.close();
|
|
2793
|
+
}
|
|
2794
|
+
});
|
|
2795
|
+
test("null-clear patches truly remove /State, /StateModel, /Subj and /Contents", async () => {
|
|
2796
|
+
const doc = await openFixture$15(engine, opts);
|
|
2797
|
+
try {
|
|
2798
|
+
const page = doc.page(fix.pageObjectNumber);
|
|
2799
|
+
const note = await page.annotations.create({
|
|
2800
|
+
subtype: "text",
|
|
2801
|
+
rect: shapeRect,
|
|
2802
|
+
contents: "work in progress",
|
|
2803
|
+
subject: "Draft",
|
|
2804
|
+
state: "none",
|
|
2805
|
+
stateModel: "review"
|
|
2806
|
+
});
|
|
2807
|
+
const cycled = await page.annotations.update(note.created.ref, {
|
|
2808
|
+
subtype: "text",
|
|
2809
|
+
state: "rejected"
|
|
2810
|
+
});
|
|
2811
|
+
expect(cycled.appearance.changed).toBe(false);
|
|
2812
|
+
expect(cycled.updated.subtype).toBe("text");
|
|
2813
|
+
if (cycled.updated.subtype === "text") {
|
|
2814
|
+
expect(cycled.updated.state).toBe("rejected");
|
|
2815
|
+
expect(cycled.updated.stateModel).toBe("review");
|
|
2816
|
+
}
|
|
2817
|
+
const cleared = await page.annotations.update(note.created.ref, {
|
|
2818
|
+
subtype: "text",
|
|
2819
|
+
contents: null,
|
|
2820
|
+
subject: null,
|
|
2821
|
+
state: null,
|
|
2822
|
+
stateModel: null
|
|
2823
|
+
});
|
|
2824
|
+
expect(cleared.appearance.changed).toBe(false);
|
|
2825
|
+
expect(cleared.updated.contents).toBe(null);
|
|
2826
|
+
expect(cleared.updated.subject).toBe(null);
|
|
2827
|
+
if (cleared.updated.subtype === "text") {
|
|
2828
|
+
expect(cleared.updated.state).toBe(null);
|
|
2829
|
+
expect(cleared.updated.stateModel).toBe(null);
|
|
2830
|
+
}
|
|
2831
|
+
const read = (await page.annotations.list()).annotations.find((a) => a.ref.kind === "objectNumber" && note.created.ref.kind === "objectNumber" && a.ref.annotObjectNumber === note.created.ref.annotObjectNumber);
|
|
2832
|
+
expect(read?.contents).toBe(null);
|
|
2833
|
+
expect(read?.subject).toBe(null);
|
|
2834
|
+
if (read?.subtype === "text") {
|
|
2835
|
+
expect(read.state).toBe(null);
|
|
2836
|
+
expect(read.stateModel).toBe(null);
|
|
2837
|
+
}
|
|
2838
|
+
} finally {
|
|
2839
|
+
await doc.close();
|
|
2840
|
+
}
|
|
2841
|
+
});
|
|
2842
|
+
test("custom state models round-trip verbatim", async () => {
|
|
2843
|
+
const doc = await openFixture$15(engine, opts);
|
|
2844
|
+
try {
|
|
2845
|
+
const page = doc.page(fix.pageObjectNumber);
|
|
2846
|
+
const custom = await page.annotations.create({
|
|
2847
|
+
subtype: "text",
|
|
2848
|
+
rect: shapeRect,
|
|
2849
|
+
state: "in-progress",
|
|
2850
|
+
stateModel: "X-ReviewWorkflow"
|
|
2851
|
+
});
|
|
2852
|
+
expect(custom.created.subtype).toBe("text");
|
|
2853
|
+
if (custom.created.subtype !== "text") return;
|
|
2854
|
+
expect(custom.created.state).toBe("in-progress");
|
|
2855
|
+
expect(custom.created.stateModel).toBe("X-ReviewWorkflow");
|
|
2856
|
+
const read = (await page.annotations.list()).annotations.find((a) => a.ref.kind === "objectNumber" && custom.created.ref.kind === "objectNumber" && a.ref.annotObjectNumber === custom.created.ref.annotObjectNumber);
|
|
2857
|
+
if (read?.subtype === "text") {
|
|
2858
|
+
expect(read.state).toBe("in-progress");
|
|
2859
|
+
expect(read.stateModel).toBe("X-ReviewWorkflow");
|
|
2860
|
+
}
|
|
2526
2861
|
} finally {
|
|
2527
2862
|
await doc.close();
|
|
2528
2863
|
}
|
|
@@ -2533,7 +2868,7 @@ async function beginWeakEditIfRequired(doc, pageObjectNumber, fix) {
|
|
|
2533
2868
|
if (doc.capabilities.weakAnnotationEditSessions !== "required" || !fix.expectsWeakAnnotation) return null;
|
|
2534
2869
|
return doc.annotations.beginWeakEdit([pageObjectNumber]);
|
|
2535
2870
|
}
|
|
2536
|
-
async function openFixture$
|
|
2871
|
+
async function openFixture$15(engine, opts) {
|
|
2537
2872
|
if (opts.openKind === "bytes") {
|
|
2538
2873
|
const bytes = await opts.fixture.bytes();
|
|
2539
2874
|
return engine.open({
|
|
@@ -2699,7 +3034,7 @@ function runFormConformance(runner, opts) {
|
|
|
2699
3034
|
await expect(doc.forms.setValue(radioRef, {
|
|
2700
3035
|
type: "toggle",
|
|
2701
3036
|
state: null
|
|
2702
|
-
})).rejects.toMatchObject({ code:
|
|
3037
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
2703
3038
|
const check = await doc.forms.setValue({
|
|
2704
3039
|
kind: "fqn",
|
|
2705
3040
|
name: "opt_check"
|
|
@@ -2727,7 +3062,7 @@ function runFormConformance(runner, opts) {
|
|
|
2727
3062
|
}, {
|
|
2728
3063
|
type: "toggle",
|
|
2729
3064
|
state: "On"
|
|
2730
|
-
})).rejects.toMatchObject({ code:
|
|
3065
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
2731
3066
|
const field = await doc.forms.get({
|
|
2732
3067
|
kind: "fqn",
|
|
2733
3068
|
name: "maxlen_text"
|
|
@@ -2831,7 +3166,7 @@ function runFormConformance(runner, opts) {
|
|
|
2831
3166
|
}, {
|
|
2832
3167
|
type: "choice",
|
|
2833
3168
|
values: ["foo", "bar"]
|
|
2834
|
-
})).rejects.toMatchObject({ code:
|
|
3169
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
2835
3170
|
} finally {
|
|
2836
3171
|
await doc.close();
|
|
2837
3172
|
}
|
|
@@ -2901,7 +3236,7 @@ function runFormConformance(runner, opts) {
|
|
|
2901
3236
|
test("rejects garbage import payloads", async () => {
|
|
2902
3237
|
const doc = await open(opts.fixtures.toggleFields);
|
|
2903
3238
|
try {
|
|
2904
|
-
await expect(doc.forms.importData(new TextEncoder().encode("not a form payload"))).rejects.toMatchObject({ code:
|
|
3239
|
+
await expect(doc.forms.importData(new TextEncoder().encode("not a form payload"))).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
2905
3240
|
} finally {
|
|
2906
3241
|
await doc.close();
|
|
2907
3242
|
}
|
|
@@ -3008,7 +3343,7 @@ function runFormConformance(runner, opts) {
|
|
|
3008
3343
|
g: 247,
|
|
3009
3344
|
b: 219
|
|
3010
3345
|
});
|
|
3011
|
-
await expect(page.annotations.delete(widgetRef)).rejects.toMatchObject({ code:
|
|
3346
|
+
await expect(page.annotations.delete(widgetRef)).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
3012
3347
|
await doc.forms.detachWidget(field.field.ref, {
|
|
3013
3348
|
annotObjectNumber: widgetRef.annotObjectNumber,
|
|
3014
3349
|
pageObjectNumber: pon
|
|
@@ -3072,7 +3407,7 @@ function runFormConformance(runner, opts) {
|
|
|
3072
3407
|
await expect(doc.forms.updateField(created.field.ref, {
|
|
3073
3408
|
family: "radio",
|
|
3074
3409
|
name: "unison_radio"
|
|
3075
|
-
})).rejects.toMatchObject({ code:
|
|
3410
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
3076
3411
|
const before = await doc.page(pon).annotations.list();
|
|
3077
3412
|
const removed = await doc.forms.deleteField(created.field.ref);
|
|
3078
3413
|
expect(removed.removedWidgets.length).toBe(2);
|
|
@@ -3081,7 +3416,7 @@ function runFormConformance(runner, opts) {
|
|
|
3081
3416
|
await expect(doc.forms.get({
|
|
3082
3417
|
kind: "fqn",
|
|
3083
3418
|
name: "renamed_radio"
|
|
3084
|
-
})).rejects.toMatchObject({ code:
|
|
3419
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.NotFound });
|
|
3085
3420
|
} finally {
|
|
3086
3421
|
await doc.close();
|
|
3087
3422
|
}
|
|
@@ -3092,7 +3427,7 @@ function runFormConformance(runner, opts) {
|
|
|
3092
3427
|
await expect(doc.forms.get({
|
|
3093
3428
|
kind: "fqn",
|
|
3094
3429
|
name: "no.such.field"
|
|
3095
|
-
})).rejects.toMatchObject({ code:
|
|
3430
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.NotFound });
|
|
3096
3431
|
} finally {
|
|
3097
3432
|
await doc.close();
|
|
3098
3433
|
}
|
|
@@ -3123,7 +3458,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3123
3458
|
if (engine) await engine.destroy();
|
|
3124
3459
|
});
|
|
3125
3460
|
test("renders the expected set of appearances with valid output", async () => {
|
|
3126
|
-
const doc = await openFixture$
|
|
3461
|
+
const doc = await openFixture$14(engine, opts);
|
|
3127
3462
|
try {
|
|
3128
3463
|
const { pageState, appearances } = await collect(doc, opts, useRaw);
|
|
3129
3464
|
expect(pageState.pageObjectNumber).toBe(opts.fixture.pageObjectNumber);
|
|
@@ -3150,7 +3485,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3150
3485
|
}
|
|
3151
3486
|
});
|
|
3152
3487
|
if (opts.fixture.expectsWeakAppearance) test("weak (index-only) annotations are emitted, not dropped", async () => {
|
|
3153
|
-
const doc = await openFixture$
|
|
3488
|
+
const doc = await openFixture$14(engine, opts);
|
|
3154
3489
|
try {
|
|
3155
3490
|
const { appearances } = await collect(doc, opts, useRaw);
|
|
3156
3491
|
const weak = appearances.find((a) => a.ref.kind === "index");
|
|
@@ -3160,7 +3495,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3160
3495
|
}
|
|
3161
3496
|
});
|
|
3162
3497
|
if (useRaw) test("rendered appearances are not blank (non-zero alpha)", async () => {
|
|
3163
|
-
const doc = await openFixture$
|
|
3498
|
+
const doc = await openFixture$14(engine, opts);
|
|
3164
3499
|
try {
|
|
3165
3500
|
const { appearances } = await collect(doc, opts, useRaw);
|
|
3166
3501
|
const anyVisible = appearances.some((a) => a.raster !== null && hasOpaquePixel(a.raster));
|
|
@@ -3170,7 +3505,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3170
3505
|
}
|
|
3171
3506
|
});
|
|
3172
3507
|
test("abort() rejects with AbortError", async () => {
|
|
3173
|
-
const doc = await openFixture$
|
|
3508
|
+
const doc = await openFixture$14(engine, opts);
|
|
3174
3509
|
try {
|
|
3175
3510
|
const page = doc.page(opts.fixture.pageObjectNumber);
|
|
3176
3511
|
const p = useRaw ? page.annotations.renderAppearances({ scale: 1 }) : page.annotations.renderAppearanceImages({
|
|
@@ -3225,7 +3560,7 @@ function hasOpaquePixel(raster) {
|
|
|
3225
3560
|
}
|
|
3226
3561
|
return false;
|
|
3227
3562
|
}
|
|
3228
|
-
async function openFixture$
|
|
3563
|
+
async function openFixture$14(engine, opts) {
|
|
3229
3564
|
if (opts.openKind === "bytes") {
|
|
3230
3565
|
const bytes = await opts.fixture.bytes();
|
|
3231
3566
|
return engine.open({
|
|
@@ -3294,7 +3629,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3294
3629
|
if (engine) await engine.destroy();
|
|
3295
3630
|
});
|
|
3296
3631
|
test("pages.list() returns every page in display order, durable PONs only", async () => {
|
|
3297
|
-
const doc = await openFixture$
|
|
3632
|
+
const doc = await openFixture$13(engine, opts);
|
|
3298
3633
|
try {
|
|
3299
3634
|
const list = await doc.pages.list();
|
|
3300
3635
|
expect(require_schemas.PageListSnapshotSchema.safeParse(list).success).toBe(true);
|
|
@@ -3313,7 +3648,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3313
3648
|
}
|
|
3314
3649
|
});
|
|
3315
3650
|
test("pages.move() reorders pages and returns the full post-move order", async () => {
|
|
3316
|
-
const doc = await openFixture$
|
|
3651
|
+
const doc = await openFixture$13(engine, opts);
|
|
3317
3652
|
try {
|
|
3318
3653
|
const before = await doc.pages.list();
|
|
3319
3654
|
if (before.pages.length < 3) return;
|
|
@@ -3337,7 +3672,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3337
3672
|
}
|
|
3338
3673
|
});
|
|
3339
3674
|
test("weak index-based annotation refs survive a page reorder", async () => {
|
|
3340
|
-
const doc = await openFixture$
|
|
3675
|
+
const doc = await openFixture$13(engine, opts);
|
|
3341
3676
|
try {
|
|
3342
3677
|
const list = await doc.pages.list();
|
|
3343
3678
|
if (list.pages.length < 2) return;
|
|
@@ -3374,7 +3709,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3374
3709
|
}
|
|
3375
3710
|
});
|
|
3376
3711
|
test("pages.move() rejects duplicate PONs with InvalidArg", async () => {
|
|
3377
|
-
const doc = await openFixture$
|
|
3712
|
+
const doc = await openFixture$13(engine, opts);
|
|
3378
3713
|
try {
|
|
3379
3714
|
const list = await doc.pages.list();
|
|
3380
3715
|
if (list.pages.length < 1) return;
|
|
@@ -3385,13 +3720,13 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3385
3720
|
} catch (err) {
|
|
3386
3721
|
caught = err;
|
|
3387
3722
|
}
|
|
3388
|
-
expect(require_fold.EngineError.is(caught,
|
|
3723
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3389
3724
|
} finally {
|
|
3390
3725
|
await doc.close();
|
|
3391
3726
|
}
|
|
3392
3727
|
});
|
|
3393
3728
|
test("pages.move() rejects out-of-range destIndex with InvalidArg", async () => {
|
|
3394
|
-
const doc = await openFixture$
|
|
3729
|
+
const doc = await openFixture$13(engine, opts);
|
|
3395
3730
|
try {
|
|
3396
3731
|
const list = await doc.pages.list();
|
|
3397
3732
|
if (list.pages.length < 1) return;
|
|
@@ -3402,13 +3737,13 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3402
3737
|
} catch (err) {
|
|
3403
3738
|
caught = err;
|
|
3404
3739
|
}
|
|
3405
|
-
expect(require_fold.EngineError.is(caught,
|
|
3740
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3406
3741
|
} finally {
|
|
3407
3742
|
await doc.close();
|
|
3408
3743
|
}
|
|
3409
3744
|
});
|
|
3410
3745
|
test("pages.move() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3411
|
-
const doc = await openFixture$
|
|
3746
|
+
const doc = await openFixture$13(engine, opts);
|
|
3412
3747
|
try {
|
|
3413
3748
|
const list = await doc.pages.list();
|
|
3414
3749
|
let bogus = 0;
|
|
@@ -3420,13 +3755,13 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3420
3755
|
} catch (err) {
|
|
3421
3756
|
caught = err;
|
|
3422
3757
|
}
|
|
3423
|
-
expect(require_fold.EngineError.is(caught,
|
|
3758
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.NotFound) || require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3424
3759
|
} finally {
|
|
3425
3760
|
await doc.close();
|
|
3426
3761
|
}
|
|
3427
3762
|
});
|
|
3428
3763
|
test("abort on pages.move() rejects with AbortError", async () => {
|
|
3429
|
-
const doc = await openFixture$
|
|
3764
|
+
const doc = await openFixture$13(engine, opts);
|
|
3430
3765
|
try {
|
|
3431
3766
|
const list = await doc.pages.list();
|
|
3432
3767
|
if (list.pages.length < 1) return;
|
|
@@ -3440,7 +3775,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3440
3775
|
});
|
|
3441
3776
|
});
|
|
3442
3777
|
}
|
|
3443
|
-
async function openFixture$
|
|
3778
|
+
async function openFixture$13(engine, opts) {
|
|
3444
3779
|
if (opts.openKind === "bytes") {
|
|
3445
3780
|
const bytes = await opts.fixture.bytes();
|
|
3446
3781
|
return engine.open({
|
|
@@ -3514,7 +3849,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3514
3849
|
if (engine) await engine.destroy();
|
|
3515
3850
|
});
|
|
3516
3851
|
test("pages.rotate() sets the absolute rotation and returns the full layout", async () => {
|
|
3517
|
-
const doc = await openFixture$
|
|
3852
|
+
const doc = await openFixture$12(engine, opts);
|
|
3518
3853
|
try {
|
|
3519
3854
|
const before = await doc.pages.list();
|
|
3520
3855
|
const target = before.pages[0];
|
|
@@ -3533,7 +3868,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3533
3868
|
}
|
|
3534
3869
|
});
|
|
3535
3870
|
test("absolute rotation is idempotent: setting the same value twice is a no-op", async () => {
|
|
3536
|
-
const doc = await openFixture$
|
|
3871
|
+
const doc = await openFixture$12(engine, opts);
|
|
3537
3872
|
try {
|
|
3538
3873
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3539
3874
|
const first = await doc.pages.rotate([pon], 180);
|
|
@@ -3544,7 +3879,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3544
3879
|
}
|
|
3545
3880
|
});
|
|
3546
3881
|
test("one rotation applies to EVERY listed page (the multi-select gesture)", async () => {
|
|
3547
|
-
const doc = await openFixture$
|
|
3882
|
+
const doc = await openFixture$12(engine, opts);
|
|
3548
3883
|
try {
|
|
3549
3884
|
const list = await doc.pages.list();
|
|
3550
3885
|
if (list.pages.length < 2) return;
|
|
@@ -3556,7 +3891,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3556
3891
|
}
|
|
3557
3892
|
});
|
|
3558
3893
|
test("weak index-based annotation refs survive a rotate (no revision bump)", async () => {
|
|
3559
|
-
const doc = await openFixture$
|
|
3894
|
+
const doc = await openFixture$12(engine, opts);
|
|
3560
3895
|
try {
|
|
3561
3896
|
const hostPon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3562
3897
|
const hostPage = doc.page(hostPon);
|
|
@@ -3586,7 +3921,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3586
3921
|
}
|
|
3587
3922
|
});
|
|
3588
3923
|
test("pages.rotate() rejects an invalid rotation value with InvalidArg", async () => {
|
|
3589
|
-
const doc = await openFixture$
|
|
3924
|
+
const doc = await openFixture$12(engine, opts);
|
|
3590
3925
|
try {
|
|
3591
3926
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3592
3927
|
let caught;
|
|
@@ -3595,13 +3930,13 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3595
3930
|
} catch (err) {
|
|
3596
3931
|
caught = err;
|
|
3597
3932
|
}
|
|
3598
|
-
expect(require_fold.EngineError.is(caught,
|
|
3933
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3599
3934
|
} finally {
|
|
3600
3935
|
await doc.close();
|
|
3601
3936
|
}
|
|
3602
3937
|
});
|
|
3603
3938
|
test("pages.rotate() rejects duplicate PONs with InvalidArg", async () => {
|
|
3604
|
-
const doc = await openFixture$
|
|
3939
|
+
const doc = await openFixture$12(engine, opts);
|
|
3605
3940
|
try {
|
|
3606
3941
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3607
3942
|
let caught;
|
|
@@ -3610,13 +3945,13 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3610
3945
|
} catch (err) {
|
|
3611
3946
|
caught = err;
|
|
3612
3947
|
}
|
|
3613
|
-
expect(require_fold.EngineError.is(caught,
|
|
3948
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3614
3949
|
} finally {
|
|
3615
3950
|
await doc.close();
|
|
3616
3951
|
}
|
|
3617
3952
|
});
|
|
3618
3953
|
test("pages.rotate() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3619
|
-
const doc = await openFixture$
|
|
3954
|
+
const doc = await openFixture$12(engine, opts);
|
|
3620
3955
|
try {
|
|
3621
3956
|
const list = await doc.pages.list();
|
|
3622
3957
|
let bogus = 0;
|
|
@@ -3628,13 +3963,13 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3628
3963
|
} catch (err) {
|
|
3629
3964
|
caught = err;
|
|
3630
3965
|
}
|
|
3631
|
-
expect(require_fold.EngineError.is(caught,
|
|
3966
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.NotFound) || require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3632
3967
|
} finally {
|
|
3633
3968
|
await doc.close();
|
|
3634
3969
|
}
|
|
3635
3970
|
});
|
|
3636
3971
|
test("abort on pages.rotate() rejects with AbortError", async () => {
|
|
3637
|
-
const doc = await openFixture$
|
|
3972
|
+
const doc = await openFixture$12(engine, opts);
|
|
3638
3973
|
try {
|
|
3639
3974
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3640
3975
|
const p = doc.pages.rotate([pon], 90);
|
|
@@ -3646,7 +3981,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3646
3981
|
});
|
|
3647
3982
|
});
|
|
3648
3983
|
}
|
|
3649
|
-
async function openFixture$
|
|
3984
|
+
async function openFixture$12(engine, opts) {
|
|
3650
3985
|
if (opts.openKind === "bytes") {
|
|
3651
3986
|
const bytes = await opts.fixture.bytes();
|
|
3652
3987
|
return engine.open({
|
|
@@ -3709,7 +4044,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3709
4044
|
if (engine) await engine.destroy();
|
|
3710
4045
|
});
|
|
3711
4046
|
test("pages.delete() removes the page and returns the surviving layout", async () => {
|
|
3712
|
-
const doc = await openFixture$
|
|
4047
|
+
const doc = await openFixture$11(engine, opts);
|
|
3713
4048
|
try {
|
|
3714
4049
|
const before = await doc.pages.list();
|
|
3715
4050
|
if (before.pages.length < 2) return;
|
|
@@ -3730,7 +4065,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3730
4065
|
}
|
|
3731
4066
|
});
|
|
3732
4067
|
test("addressing a deleted page afterwards is a clean NotFound", async () => {
|
|
3733
|
-
const doc = await openFixture$
|
|
4068
|
+
const doc = await openFixture$11(engine, opts);
|
|
3734
4069
|
try {
|
|
3735
4070
|
const before = await doc.pages.list();
|
|
3736
4071
|
if (before.pages.length < 2) return;
|
|
@@ -3742,13 +4077,13 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3742
4077
|
} catch (err) {
|
|
3743
4078
|
caught = err;
|
|
3744
4079
|
}
|
|
3745
|
-
expect(require_fold.EngineError.is(caught,
|
|
4080
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.NotFound)).toBe(true);
|
|
3746
4081
|
} finally {
|
|
3747
4082
|
await doc.close();
|
|
3748
4083
|
}
|
|
3749
4084
|
});
|
|
3750
4085
|
test("surviving pages keep their weak index-based annotation refs", async () => {
|
|
3751
|
-
const doc = await openFixture$
|
|
4086
|
+
const doc = await openFixture$11(engine, opts);
|
|
3752
4087
|
try {
|
|
3753
4088
|
const list = await doc.pages.list();
|
|
3754
4089
|
if (list.pages.length < 2) return;
|
|
@@ -3781,7 +4116,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3781
4116
|
}
|
|
3782
4117
|
});
|
|
3783
4118
|
test("deleting EVERY page is rejected with InvalidArg", async () => {
|
|
3784
|
-
const doc = await openFixture$
|
|
4119
|
+
const doc = await openFixture$11(engine, opts);
|
|
3785
4120
|
try {
|
|
3786
4121
|
const list = await doc.pages.list();
|
|
3787
4122
|
let caught;
|
|
@@ -3790,13 +4125,13 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3790
4125
|
} catch (err) {
|
|
3791
4126
|
caught = err;
|
|
3792
4127
|
}
|
|
3793
|
-
expect(require_fold.EngineError.is(caught,
|
|
4128
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3794
4129
|
} finally {
|
|
3795
4130
|
await doc.close();
|
|
3796
4131
|
}
|
|
3797
4132
|
});
|
|
3798
4133
|
test("pages.delete() rejects duplicate PONs with InvalidArg", async () => {
|
|
3799
|
-
const doc = await openFixture$
|
|
4134
|
+
const doc = await openFixture$11(engine, opts);
|
|
3800
4135
|
try {
|
|
3801
4136
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3802
4137
|
let caught;
|
|
@@ -3805,13 +4140,13 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3805
4140
|
} catch (err) {
|
|
3806
4141
|
caught = err;
|
|
3807
4142
|
}
|
|
3808
|
-
expect(require_fold.EngineError.is(caught,
|
|
4143
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3809
4144
|
} finally {
|
|
3810
4145
|
await doc.close();
|
|
3811
4146
|
}
|
|
3812
4147
|
});
|
|
3813
4148
|
test("pages.delete() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3814
|
-
const doc = await openFixture$
|
|
4149
|
+
const doc = await openFixture$11(engine, opts);
|
|
3815
4150
|
try {
|
|
3816
4151
|
const list = await doc.pages.list();
|
|
3817
4152
|
let bogus = 0;
|
|
@@ -3823,13 +4158,13 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3823
4158
|
} catch (err) {
|
|
3824
4159
|
caught = err;
|
|
3825
4160
|
}
|
|
3826
|
-
expect(require_fold.EngineError.is(caught,
|
|
4161
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.NotFound) || require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
3827
4162
|
} finally {
|
|
3828
4163
|
await doc.close();
|
|
3829
4164
|
}
|
|
3830
4165
|
});
|
|
3831
4166
|
test("abort on pages.delete() rejects with AbortError", async () => {
|
|
3832
|
-
const doc = await openFixture$
|
|
4167
|
+
const doc = await openFixture$11(engine, opts);
|
|
3833
4168
|
try {
|
|
3834
4169
|
const list = await doc.pages.list();
|
|
3835
4170
|
if (list.pages.length < 2) return;
|
|
@@ -3843,7 +4178,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3843
4178
|
});
|
|
3844
4179
|
});
|
|
3845
4180
|
}
|
|
3846
|
-
async function openFixture$
|
|
4181
|
+
async function openFixture$11(engine, opts) {
|
|
3847
4182
|
if (opts.openKind === "bytes") {
|
|
3848
4183
|
const bytes = await opts.fixture.bytes();
|
|
3849
4184
|
return engine.open({
|
|
@@ -3871,7 +4206,7 @@ function runPageFlattenConformance(runner, opts) {
|
|
|
3871
4206
|
if (engine) await engine.destroy();
|
|
3872
4207
|
});
|
|
3873
4208
|
test("flattens eligible appearances once without changing layout", async () => {
|
|
3874
|
-
const doc = await openFixture$
|
|
4209
|
+
const doc = await openFixture$10(engine, opts);
|
|
3875
4210
|
try {
|
|
3876
4211
|
if (!doc.pages.flatten) return;
|
|
3877
4212
|
const layoutBefore = await doc.pages.list();
|
|
@@ -3898,14 +4233,14 @@ function runPageFlattenConformance(runner, opts) {
|
|
|
3898
4233
|
expect(noOp.meta).toBeNull();
|
|
3899
4234
|
expect(events).toHaveLength(1);
|
|
3900
4235
|
unsubscribe();
|
|
3901
|
-
await expect(doc.pages.flatten([pageObjectNumber, pageObjectNumber])).rejects.toMatchObject({ code:
|
|
4236
|
+
await expect(doc.pages.flatten([pageObjectNumber, pageObjectNumber])).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
3902
4237
|
} finally {
|
|
3903
4238
|
await doc.close();
|
|
3904
4239
|
}
|
|
3905
4240
|
});
|
|
3906
4241
|
});
|
|
3907
4242
|
}
|
|
3908
|
-
async function openFixture$
|
|
4243
|
+
async function openFixture$10(engine, opts) {
|
|
3909
4244
|
if (opts.openKind === "bytes") return engine.open({
|
|
3910
4245
|
kind: "bytes",
|
|
3911
4246
|
id: opts.fixture.id,
|
|
@@ -3960,7 +4295,7 @@ function runRedactionApplyConformance(runner, opts) {
|
|
|
3960
4295
|
if (engine) await engine.destroy();
|
|
3961
4296
|
});
|
|
3962
4297
|
test("annotations scope applies the marked redaction and counts collateral", async () => {
|
|
3963
|
-
const doc = await openFixture$
|
|
4298
|
+
const doc = await openFixture$9(engine, opts);
|
|
3964
4299
|
try {
|
|
3965
4300
|
if (!doc.redaction) return;
|
|
3966
4301
|
const layoutBefore = await doc.pages.list();
|
|
@@ -4014,7 +4349,7 @@ function runRedactionApplyConformance(runner, opts) {
|
|
|
4014
4349
|
}
|
|
4015
4350
|
});
|
|
4016
4351
|
test("pages scope applies everything once and validates its input", async () => {
|
|
4017
|
-
const doc = await openFixture$
|
|
4352
|
+
const doc = await openFixture$9(engine, opts);
|
|
4018
4353
|
try {
|
|
4019
4354
|
if (!doc.redaction) return;
|
|
4020
4355
|
const pageObjectNumber = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
@@ -4050,7 +4385,7 @@ function runRedactionApplyConformance(runner, opts) {
|
|
|
4050
4385
|
await expect(doc.redaction.apply({
|
|
4051
4386
|
kind: "pages",
|
|
4052
4387
|
pageObjectNumbers: [pageObjectNumber, pageObjectNumber]
|
|
4053
|
-
})).rejects.toMatchObject({ code:
|
|
4388
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
4054
4389
|
const notRedact = await page.annotations.create({
|
|
4055
4390
|
subtype: "highlight",
|
|
4056
4391
|
quadPoints: COLLATERAL_QUAD
|
|
@@ -4058,14 +4393,14 @@ function runRedactionApplyConformance(runner, opts) {
|
|
|
4058
4393
|
await expect(doc.redaction.apply({
|
|
4059
4394
|
kind: "annotations",
|
|
4060
4395
|
refs: [notRedact.created.ref]
|
|
4061
|
-
})).rejects.toMatchObject({ code:
|
|
4396
|
+
})).rejects.toMatchObject({ code: require_PageInsertBlankInput.EngineErrorCode.InvalidArg });
|
|
4062
4397
|
} finally {
|
|
4063
4398
|
await doc.close();
|
|
4064
4399
|
}
|
|
4065
4400
|
});
|
|
4066
4401
|
});
|
|
4067
4402
|
}
|
|
4068
|
-
async function openFixture$
|
|
4403
|
+
async function openFixture$9(engine, opts) {
|
|
4069
4404
|
if (opts.openKind === "bytes") return engine.open({
|
|
4070
4405
|
kind: "bytes",
|
|
4071
4406
|
id: opts.fixture.id,
|
|
@@ -4105,19 +4440,14 @@ function runPageExtractConformance(runner, opts) {
|
|
|
4105
4440
|
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4106
4441
|
describe(`page extract conformance: ${opts.label}`, () => {
|
|
4107
4442
|
let engine;
|
|
4108
|
-
let supported = false;
|
|
4109
4443
|
beforeAll(async () => {
|
|
4110
4444
|
engine = await opts.makeEngine();
|
|
4111
|
-
const probe = await openFixture$5(engine, opts);
|
|
4112
|
-
supported = probe.pages.extract !== void 0;
|
|
4113
|
-
await probe.close();
|
|
4114
4445
|
});
|
|
4115
4446
|
afterAll(async () => {
|
|
4116
4447
|
if (engine) await engine.destroy();
|
|
4117
4448
|
});
|
|
4118
4449
|
test("pages.extract() returns standalone PDF bytes and leaves the source untouched", async () => {
|
|
4119
|
-
|
|
4120
|
-
const doc = await openFixture$5(engine, opts);
|
|
4450
|
+
const doc = await openFixture$8(engine, opts);
|
|
4121
4451
|
try {
|
|
4122
4452
|
const before = await doc.pages.list();
|
|
4123
4453
|
const target = before.pages[before.pages.length - 1];
|
|
@@ -4132,8 +4462,8 @@ function runPageExtractConformance(runner, opts) {
|
|
|
4132
4462
|
}
|
|
4133
4463
|
});
|
|
4134
4464
|
test("extracted bytes re-open as a document with the requested pages, in caller order", async () => {
|
|
4135
|
-
if (
|
|
4136
|
-
const doc = await openFixture$
|
|
4465
|
+
if (opts.openKind !== "bytes") return;
|
|
4466
|
+
const doc = await openFixture$8(engine, opts);
|
|
4137
4467
|
let extracted = null;
|
|
4138
4468
|
try {
|
|
4139
4469
|
const list = await doc.pages.list();
|
|
@@ -4156,8 +4486,7 @@ function runPageExtractConformance(runner, opts) {
|
|
|
4156
4486
|
}
|
|
4157
4487
|
});
|
|
4158
4488
|
test("pages.extract() rejects empty input with InvalidArg", async () => {
|
|
4159
|
-
|
|
4160
|
-
const doc = await openFixture$5(engine, opts);
|
|
4489
|
+
const doc = await openFixture$8(engine, opts);
|
|
4161
4490
|
try {
|
|
4162
4491
|
let caught;
|
|
4163
4492
|
try {
|
|
@@ -4165,14 +4494,13 @@ function runPageExtractConformance(runner, opts) {
|
|
|
4165
4494
|
} catch (err) {
|
|
4166
4495
|
caught = err;
|
|
4167
4496
|
}
|
|
4168
|
-
expect(require_fold.EngineError.is(caught,
|
|
4497
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
4169
4498
|
} finally {
|
|
4170
4499
|
await doc.close();
|
|
4171
4500
|
}
|
|
4172
4501
|
});
|
|
4173
4502
|
test("pages.extract() rejects duplicate PONs with InvalidArg", async () => {
|
|
4174
|
-
|
|
4175
|
-
const doc = await openFixture$5(engine, opts);
|
|
4503
|
+
const doc = await openFixture$8(engine, opts);
|
|
4176
4504
|
try {
|
|
4177
4505
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
4178
4506
|
let caught;
|
|
@@ -4181,14 +4509,13 @@ function runPageExtractConformance(runner, opts) {
|
|
|
4181
4509
|
} catch (err) {
|
|
4182
4510
|
caught = err;
|
|
4183
4511
|
}
|
|
4184
|
-
expect(require_fold.EngineError.is(caught,
|
|
4512
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
4185
4513
|
} finally {
|
|
4186
4514
|
await doc.close();
|
|
4187
4515
|
}
|
|
4188
4516
|
});
|
|
4189
4517
|
test("pages.extract() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
4190
|
-
|
|
4191
|
-
const doc = await openFixture$5(engine, opts);
|
|
4518
|
+
const doc = await openFixture$8(engine, opts);
|
|
4192
4519
|
try {
|
|
4193
4520
|
const list = await doc.pages.list();
|
|
4194
4521
|
let bogus = 0;
|
|
@@ -4200,14 +4527,13 @@ function runPageExtractConformance(runner, opts) {
|
|
|
4200
4527
|
} catch (err) {
|
|
4201
4528
|
caught = err;
|
|
4202
4529
|
}
|
|
4203
|
-
expect(require_fold.EngineError.is(caught,
|
|
4530
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.NotFound) || require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
4204
4531
|
} finally {
|
|
4205
4532
|
await doc.close();
|
|
4206
4533
|
}
|
|
4207
4534
|
});
|
|
4208
4535
|
test("abort on pages.extract() rejects with AbortError", async () => {
|
|
4209
|
-
|
|
4210
|
-
const doc = await openFixture$5(engine, opts);
|
|
4536
|
+
const doc = await openFixture$8(engine, opts);
|
|
4211
4537
|
try {
|
|
4212
4538
|
const list = await doc.pages.list();
|
|
4213
4539
|
const p = doc.pages.extract([list.pages[0].pageObjectNumber]);
|
|
@@ -4219,7 +4545,7 @@ function runPageExtractConformance(runner, opts) {
|
|
|
4219
4545
|
});
|
|
4220
4546
|
});
|
|
4221
4547
|
}
|
|
4222
|
-
async function openFixture$
|
|
4548
|
+
async function openFixture$8(engine, opts) {
|
|
4223
4549
|
if (opts.openKind === "bytes") {
|
|
4224
4550
|
const bytes = await opts.fixture.bytes();
|
|
4225
4551
|
return engine.open({
|
|
@@ -4481,9 +4807,9 @@ function runAttachmentConformance(runner, opts) {
|
|
|
4481
4807
|
//#endregion
|
|
4482
4808
|
//#region src/conformance/runPageInsertConformance.ts
|
|
4483
4809
|
/**
|
|
4484
|
-
* Page insert conformance. `pages.insert
|
|
4485
|
-
*
|
|
4486
|
-
*
|
|
4810
|
+
* Page insert conformance. `pages.insert` is a REQUIRED member — this suite
|
|
4811
|
+
* runs unconditionally on every engine, so an implementation that loses the
|
|
4812
|
+
* verb fails loudly instead of being skipped past.
|
|
4487
4813
|
*
|
|
4488
4814
|
* Invariants:
|
|
4489
4815
|
* 1. Every page of the source bytes is COPIED in at `destIndex` (omitted →
|
|
@@ -4499,19 +4825,14 @@ function runPageInsertConformance(runner, opts) {
|
|
|
4499
4825
|
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4500
4826
|
describe(`page insert conformance: ${opts.label}`, () => {
|
|
4501
4827
|
let engine;
|
|
4502
|
-
let supported = false;
|
|
4503
4828
|
beforeAll(async () => {
|
|
4504
4829
|
engine = await opts.makeEngine();
|
|
4505
|
-
const probe = await openFixture$4(engine, opts);
|
|
4506
|
-
supported = probe.pages.insert !== void 0 && probe.pages.extract !== void 0;
|
|
4507
|
-
await probe.close();
|
|
4508
4830
|
});
|
|
4509
4831
|
afterAll(async () => {
|
|
4510
4832
|
if (engine) await engine.destroy();
|
|
4511
4833
|
});
|
|
4512
4834
|
test("appends every source page with fresh PONs; existing pages keep identity", async () => {
|
|
4513
|
-
|
|
4514
|
-
const doc = await openFixture$4(engine, opts);
|
|
4835
|
+
const doc = await openFixture$7(engine, opts);
|
|
4515
4836
|
try {
|
|
4516
4837
|
const before = await doc.pages.list();
|
|
4517
4838
|
const beforePons = before.pages.map((p) => p.pageObjectNumber);
|
|
@@ -4529,8 +4850,7 @@ function runPageInsertConformance(runner, opts) {
|
|
|
4529
4850
|
}
|
|
4530
4851
|
});
|
|
4531
4852
|
test("destIndex places the block mid-document, in source order", async () => {
|
|
4532
|
-
|
|
4533
|
-
const doc = await openFixture$4(engine, opts);
|
|
4853
|
+
const doc = await openFixture$7(engine, opts);
|
|
4534
4854
|
try {
|
|
4535
4855
|
const before = await doc.pages.list();
|
|
4536
4856
|
if (before.pages.length < 2) return;
|
|
@@ -4547,8 +4867,8 @@ function runPageInsertConformance(runner, opts) {
|
|
|
4547
4867
|
}
|
|
4548
4868
|
});
|
|
4549
4869
|
test("the inserted pages persist through save → re-open", async () => {
|
|
4550
|
-
if (
|
|
4551
|
-
const doc = await openFixture$
|
|
4870
|
+
if (opts.openKind !== "bytes") return;
|
|
4871
|
+
const doc = await openFixture$7(engine, opts);
|
|
4552
4872
|
let reopened = null;
|
|
4553
4873
|
try {
|
|
4554
4874
|
const before = await doc.pages.list();
|
|
@@ -4568,8 +4888,7 @@ function runPageInsertConformance(runner, opts) {
|
|
|
4568
4888
|
}
|
|
4569
4889
|
});
|
|
4570
4890
|
test("empty bytes reject with InvalidArg; garbage rejects with MalformedPdf", async () => {
|
|
4571
|
-
|
|
4572
|
-
const doc = await openFixture$4(engine, opts);
|
|
4891
|
+
const doc = await openFixture$7(engine, opts);
|
|
4573
4892
|
try {
|
|
4574
4893
|
let caught;
|
|
4575
4894
|
try {
|
|
@@ -4577,14 +4896,14 @@ function runPageInsertConformance(runner, opts) {
|
|
|
4577
4896
|
} catch (err) {
|
|
4578
4897
|
caught = err;
|
|
4579
4898
|
}
|
|
4580
|
-
expect(require_fold.EngineError.is(caught,
|
|
4899
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
4581
4900
|
caught = void 0;
|
|
4582
4901
|
try {
|
|
4583
4902
|
await doc.pages.insert(new TextEncoder().encode("not a pdf at all"));
|
|
4584
4903
|
} catch (err) {
|
|
4585
4904
|
caught = err;
|
|
4586
4905
|
}
|
|
4587
|
-
expect(require_fold.EngineError.is(caught,
|
|
4906
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.MalformedPdf)).toBe(true);
|
|
4588
4907
|
const list = await doc.pages.list();
|
|
4589
4908
|
expect(list.pageCount > 0).toBe(true);
|
|
4590
4909
|
} finally {
|
|
@@ -4592,8 +4911,7 @@ function runPageInsertConformance(runner, opts) {
|
|
|
4592
4911
|
}
|
|
4593
4912
|
});
|
|
4594
4913
|
test("out-of-range destIndex rejects with InvalidArg", async () => {
|
|
4595
|
-
|
|
4596
|
-
const doc = await openFixture$4(engine, opts);
|
|
4914
|
+
const doc = await openFixture$7(engine, opts);
|
|
4597
4915
|
try {
|
|
4598
4916
|
const before = await doc.pages.list();
|
|
4599
4917
|
const single = await doc.pages.extract([before.pages[0].pageObjectNumber]);
|
|
@@ -4603,14 +4921,167 @@ function runPageInsertConformance(runner, opts) {
|
|
|
4603
4921
|
} catch (err) {
|
|
4604
4922
|
caught = err;
|
|
4605
4923
|
}
|
|
4606
|
-
expect(require_fold.EngineError.is(caught,
|
|
4924
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
4607
4925
|
} finally {
|
|
4608
4926
|
await doc.close();
|
|
4609
4927
|
}
|
|
4610
4928
|
});
|
|
4611
4929
|
});
|
|
4612
4930
|
}
|
|
4613
|
-
async function openFixture$
|
|
4931
|
+
async function openFixture$7(engine, opts) {
|
|
4932
|
+
if (opts.openKind === "bytes") {
|
|
4933
|
+
const bytes = await opts.fixture.bytes();
|
|
4934
|
+
return engine.open({
|
|
4935
|
+
kind: "bytes",
|
|
4936
|
+
id: opts.fixture.id,
|
|
4937
|
+
bytes
|
|
4938
|
+
});
|
|
4939
|
+
}
|
|
4940
|
+
return engine.open({
|
|
4941
|
+
kind: "id",
|
|
4942
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
4943
|
+
});
|
|
4944
|
+
}
|
|
4945
|
+
//#endregion
|
|
4946
|
+
//#region src/conformance/runPageInsertBlankConformance.ts
|
|
4947
|
+
/** An on-purpose non-default size so the assertions can't pass by accident. */
|
|
4948
|
+
const SIZE = {
|
|
4949
|
+
width: 396,
|
|
4950
|
+
height: 612
|
|
4951
|
+
};
|
|
4952
|
+
/**
|
|
4953
|
+
* Blank-page insert conformance. `pages.insertBlank` is a REQUIRED member —
|
|
4954
|
+
* the suite runs unconditionally on every engine (no fixture bytes are
|
|
4955
|
+
* needed at all, which is the point of the verb), so an implementation that
|
|
4956
|
+
* loses the verb fails loudly instead of being skipped past.
|
|
4957
|
+
*
|
|
4958
|
+
* Invariants:
|
|
4959
|
+
* 1. `count` blank pages of exactly `size` appear at `destIndex` (omitted
|
|
4960
|
+
* → append), rotation 0; the result lists their fresh PONs in insertion
|
|
4961
|
+
* order and they agree with the returned layout.
|
|
4962
|
+
* 2. Pre-existing pages keep their identity: same PONs before and after,
|
|
4963
|
+
* in the expected positions (an insert never invalidates neighbours).
|
|
4964
|
+
* 3. The mutation persists through save → re-open (bytes engines only).
|
|
4965
|
+
* 4. Non-positive size / count outside [1, PAGE_INSERT_BLANK_MAX_COUNT] /
|
|
4966
|
+
* out-of-range destIndex reject with InvalidArg, leaving the document
|
|
4967
|
+
* untouched.
|
|
4968
|
+
*/
|
|
4969
|
+
function runPageInsertBlankConformance(runner, opts) {
|
|
4970
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4971
|
+
describe(`page insert-blank conformance: ${opts.label}`, () => {
|
|
4972
|
+
let engine;
|
|
4973
|
+
beforeAll(async () => {
|
|
4974
|
+
engine = await opts.makeEngine();
|
|
4975
|
+
});
|
|
4976
|
+
afterAll(async () => {
|
|
4977
|
+
if (engine) await engine.destroy();
|
|
4978
|
+
});
|
|
4979
|
+
test("appends one blank page of the requested size with a fresh PON", async () => {
|
|
4980
|
+
const doc = await openFixture$6(engine, opts);
|
|
4981
|
+
try {
|
|
4982
|
+
const before = await doc.pages.list();
|
|
4983
|
+
const beforePons = before.pages.map((p) => p.pageObjectNumber);
|
|
4984
|
+
const result = await doc.pages.insertBlank({ size: SIZE });
|
|
4985
|
+
expect(result.insertedPageObjectNumbers.length).toBe(1);
|
|
4986
|
+
expect(result.layout.pageCount).toBe(before.pageCount + 1);
|
|
4987
|
+
expect(result.layout.pages.slice(0, before.pageCount).map((p) => p.pageObjectNumber)).toEqual(beforePons);
|
|
4988
|
+
const newPon = result.insertedPageObjectNumbers[0];
|
|
4989
|
+
expect(beforePons.includes(newPon)).toBe(false);
|
|
4990
|
+
const appended = result.layout.pages[before.pageCount];
|
|
4991
|
+
expect(appended.pageObjectNumber).toBe(newPon);
|
|
4992
|
+
expect(appended.size).toEqual(SIZE);
|
|
4993
|
+
expect(appended.rotation).toBe(0);
|
|
4994
|
+
} finally {
|
|
4995
|
+
await doc.close();
|
|
4996
|
+
}
|
|
4997
|
+
});
|
|
4998
|
+
test("destIndex + count places the blank block mid-document", async () => {
|
|
4999
|
+
const doc = await openFixture$6(engine, opts);
|
|
5000
|
+
try {
|
|
5001
|
+
const before = await doc.pages.list();
|
|
5002
|
+
if (before.pages.length < 2) return;
|
|
5003
|
+
const beforePons = before.pages.map((p) => p.pageObjectNumber);
|
|
5004
|
+
const result = await doc.pages.insertBlank({
|
|
5005
|
+
size: SIZE,
|
|
5006
|
+
count: 2
|
|
5007
|
+
}, 1);
|
|
5008
|
+
expect(result.insertedPageObjectNumbers.length).toBe(2);
|
|
5009
|
+
expect(result.insertedPageObjectNumbers[0] === result.insertedPageObjectNumbers[1]).toBe(false);
|
|
5010
|
+
const pons = result.layout.pages.map((p) => p.pageObjectNumber);
|
|
5011
|
+
expect(pons[0]).toBe(beforePons[0]);
|
|
5012
|
+
expect(pons.slice(1, 3)).toEqual(result.insertedPageObjectNumbers);
|
|
5013
|
+
expect(pons.slice(3)).toEqual(beforePons.slice(1));
|
|
5014
|
+
expect(result.layout.pages[1].size).toEqual(SIZE);
|
|
5015
|
+
expect(result.layout.pages[2].size).toEqual(SIZE);
|
|
5016
|
+
} finally {
|
|
5017
|
+
await doc.close();
|
|
5018
|
+
}
|
|
5019
|
+
});
|
|
5020
|
+
test("the blank pages persist through save → re-open", async () => {
|
|
5021
|
+
if (opts.openKind !== "bytes") return;
|
|
5022
|
+
const doc = await openFixture$6(engine, opts);
|
|
5023
|
+
let reopened = null;
|
|
5024
|
+
try {
|
|
5025
|
+
const before = await doc.pages.list();
|
|
5026
|
+
await doc.pages.insertBlank({ size: SIZE });
|
|
5027
|
+
const bytes = await doc.download();
|
|
5028
|
+
reopened = await engine.open({
|
|
5029
|
+
kind: "bytes",
|
|
5030
|
+
id: `${opts.fixture.id}-insert-blank-reopen`,
|
|
5031
|
+
bytes
|
|
5032
|
+
});
|
|
5033
|
+
const after = await reopened.pages.list();
|
|
5034
|
+
expect(after.pageCount).toBe(before.pageCount + 1);
|
|
5035
|
+
const tail = after.pages[after.pageCount - 1];
|
|
5036
|
+
expect(Math.round(tail.size.width)).toBe(SIZE.width);
|
|
5037
|
+
expect(Math.round(tail.size.height)).toBe(SIZE.height);
|
|
5038
|
+
} finally {
|
|
5039
|
+
if (reopened) await reopened.close();
|
|
5040
|
+
await doc.close();
|
|
5041
|
+
}
|
|
5042
|
+
});
|
|
5043
|
+
test("non-positive size, bad count, and out-of-range destIndex reject with InvalidArg", async () => {
|
|
5044
|
+
const doc = await openFixture$6(engine, opts);
|
|
5045
|
+
try {
|
|
5046
|
+
const before = await doc.pages.list();
|
|
5047
|
+
const rejects = [
|
|
5048
|
+
() => doc.pages.insertBlank({ size: {
|
|
5049
|
+
width: 0,
|
|
5050
|
+
height: 612
|
|
5051
|
+
} }),
|
|
5052
|
+
() => doc.pages.insertBlank({ size: {
|
|
5053
|
+
width: 396,
|
|
5054
|
+
height: -10
|
|
5055
|
+
} }),
|
|
5056
|
+
() => doc.pages.insertBlank({
|
|
5057
|
+
size: SIZE,
|
|
5058
|
+
count: 0
|
|
5059
|
+
}),
|
|
5060
|
+
() => doc.pages.insertBlank({
|
|
5061
|
+
size: SIZE,
|
|
5062
|
+
count: 101
|
|
5063
|
+
}),
|
|
5064
|
+
() => doc.pages.insertBlank({ size: SIZE }, before.pageCount + 1)
|
|
5065
|
+
];
|
|
5066
|
+
for (const attempt of rejects) {
|
|
5067
|
+
let caught;
|
|
5068
|
+
try {
|
|
5069
|
+
await attempt();
|
|
5070
|
+
} catch (err) {
|
|
5071
|
+
caught = err;
|
|
5072
|
+
}
|
|
5073
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
5074
|
+
}
|
|
5075
|
+
const list = await doc.pages.list();
|
|
5076
|
+
expect(list.pageCount).toBe(before.pageCount);
|
|
5077
|
+
expect(list.pages.map((p) => p.pageObjectNumber)).toEqual(before.pages.map((p) => p.pageObjectNumber));
|
|
5078
|
+
} finally {
|
|
5079
|
+
await doc.close();
|
|
5080
|
+
}
|
|
5081
|
+
});
|
|
5082
|
+
});
|
|
5083
|
+
}
|
|
5084
|
+
async function openFixture$6(engine, opts) {
|
|
4614
5085
|
if (opts.openKind === "bytes") {
|
|
4615
5086
|
const bytes = await opts.fixture.bytes();
|
|
4616
5087
|
return engine.open({
|
|
@@ -4651,7 +5122,7 @@ function runPieceInfoConformance(runner, opts) {
|
|
|
4651
5122
|
let supported = false;
|
|
4652
5123
|
beforeAll(async () => {
|
|
4653
5124
|
engine = await opts.makeEngine();
|
|
4654
|
-
const probe = await openFixture$
|
|
5125
|
+
const probe = await openFixture$5(engine, opts);
|
|
4655
5126
|
supported = probe.pieceInfo !== void 0;
|
|
4656
5127
|
await probe.close();
|
|
4657
5128
|
});
|
|
@@ -4660,7 +5131,7 @@ function runPieceInfoConformance(runner, opts) {
|
|
|
4660
5131
|
});
|
|
4661
5132
|
test("doc-level: the full value vocabulary round-trips with tags intact", async () => {
|
|
4662
5133
|
if (!supported) return;
|
|
4663
|
-
const doc = await openFixture$
|
|
5134
|
+
const doc = await openFixture$5(engine, opts);
|
|
4664
5135
|
try {
|
|
4665
5136
|
await doc.pieceInfo.update(APP, {
|
|
4666
5137
|
name: "Standard Stamps",
|
|
@@ -4700,7 +5171,7 @@ function runPieceInfoConformance(runner, opts) {
|
|
|
4700
5171
|
});
|
|
4701
5172
|
test("page-level: the stamp schema round-trips on a page", async () => {
|
|
4702
5173
|
if (!supported) return;
|
|
4703
|
-
const doc = await openFixture$
|
|
5174
|
+
const doc = await openFixture$5(engine, opts);
|
|
4704
5175
|
try {
|
|
4705
5176
|
const list = await doc.pages.list();
|
|
4706
5177
|
const page = doc.page(list.pages[0].pageObjectNumber);
|
|
@@ -4726,7 +5197,7 @@ function runPieceInfoConformance(runner, opts) {
|
|
|
4726
5197
|
});
|
|
4727
5198
|
test("writes persist through save → re-open", async () => {
|
|
4728
5199
|
if (!supported || opts.openKind !== "bytes") return;
|
|
4729
|
-
const doc = await openFixture$
|
|
5200
|
+
const doc = await openFixture$5(engine, opts);
|
|
4730
5201
|
let reopened = null;
|
|
4731
5202
|
try {
|
|
4732
5203
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
@@ -4759,7 +5230,7 @@ function runPieceInfoConformance(runner, opts) {
|
|
|
4759
5230
|
});
|
|
4760
5231
|
test("null deletes a key; clear removes an entry; siblings survive", async () => {
|
|
4761
5232
|
if (!supported) return;
|
|
4762
|
-
const doc = await openFixture$
|
|
5233
|
+
const doc = await openFixture$5(engine, opts);
|
|
4763
5234
|
try {
|
|
4764
5235
|
await doc.pieceInfo.update(APP, {
|
|
4765
5236
|
name: "A",
|
|
@@ -4785,7 +5256,7 @@ function runPieceInfoConformance(runner, opts) {
|
|
|
4785
5256
|
});
|
|
4786
5257
|
test("an application that was never written reads as null", async () => {
|
|
4787
5258
|
if (!supported) return;
|
|
4788
|
-
const doc = await openFixture$
|
|
5259
|
+
const doc = await openFixture$5(engine, opts);
|
|
4789
5260
|
try {
|
|
4790
5261
|
expect(await doc.pieceInfo.read("EMBD_NeverWritten")).toBe(null);
|
|
4791
5262
|
const list = await doc.pages.list();
|
|
@@ -4796,7 +5267,7 @@ function runPieceInfoConformance(runner, opts) {
|
|
|
4796
5267
|
});
|
|
4797
5268
|
});
|
|
4798
5269
|
}
|
|
4799
|
-
async function openFixture$
|
|
5270
|
+
async function openFixture$5(engine, opts) {
|
|
4800
5271
|
if (opts.openKind === "bytes") {
|
|
4801
5272
|
const bytes = await opts.fixture.bytes();
|
|
4802
5273
|
return engine.open({
|
|
@@ -4859,7 +5330,7 @@ function runDocumentEventsConformance(runner, opts) {
|
|
|
4859
5330
|
if (engine) await engine.destroy();
|
|
4860
5331
|
});
|
|
4861
5332
|
test("every confirmed mutation publishes exactly one event, results verbatim", async () => {
|
|
4862
|
-
const doc = await openFixture$
|
|
5333
|
+
const doc = await openFixture$4(engine, opts);
|
|
4863
5334
|
try {
|
|
4864
5335
|
const events = [];
|
|
4865
5336
|
doc.events.subscribe((event) => events.push(event));
|
|
@@ -4906,19 +5377,46 @@ function runDocumentEventsConformance(runner, opts) {
|
|
|
4906
5377
|
expect(evDeleted.layout).toEqual(deleted.layout);
|
|
4907
5378
|
}
|
|
4908
5379
|
if (evMeta.type === "metadata.updated") expect(evMeta.metadata).toEqual(meta.metadata);
|
|
5380
|
+
const first = events[0];
|
|
5381
|
+
expect(first !== void 0 && "origin" in first).toBe(true);
|
|
5382
|
+
if (first === void 0 || !("origin" in first)) return;
|
|
4909
5383
|
for (const event of events) {
|
|
5384
|
+
expect("origin" in event).toBe(true);
|
|
5385
|
+
if (!("origin" in event)) continue;
|
|
4910
5386
|
expect(event.origin.kind).toBe("local");
|
|
4911
5387
|
expect(typeof event.origin.sessionId).toBe("string");
|
|
4912
5388
|
expect(event.origin.sessionId.length > 0).toBe(true);
|
|
4913
|
-
expect(event.origin.sessionId).toBe(
|
|
5389
|
+
expect(event.origin.sessionId).toBe(first.origin.sessionId);
|
|
4914
5390
|
expect(typeof event.origin.ts).toBe("number");
|
|
4915
5391
|
}
|
|
4916
5392
|
} finally {
|
|
4917
5393
|
await doc.close();
|
|
4918
5394
|
}
|
|
4919
5395
|
});
|
|
5396
|
+
test("pages.inserted rides verbatim", async () => {
|
|
5397
|
+
const doc = await openFixture$4(engine, opts);
|
|
5398
|
+
try {
|
|
5399
|
+
const events = [];
|
|
5400
|
+
doc.events.subscribe((event) => events.push(event));
|
|
5401
|
+
const inserted = await doc.pages.insertBlank({ size: {
|
|
5402
|
+
width: 396,
|
|
5403
|
+
height: 612
|
|
5404
|
+
} }, 0);
|
|
5405
|
+
expect(events.map((event) => event.type)).toEqual(["pages.inserted"]);
|
|
5406
|
+
const [evInserted] = events;
|
|
5407
|
+
if (evInserted.type === "pages.inserted") {
|
|
5408
|
+
expect(evInserted.insertedPageObjectNumbers).toEqual(inserted.insertedPageObjectNumbers);
|
|
5409
|
+
expect(evInserted.layout).toEqual(inserted.layout);
|
|
5410
|
+
expect(evInserted.cache).toEqual(inserted.cache);
|
|
5411
|
+
expect(evInserted.destIndex).toBe(0);
|
|
5412
|
+
expect(evInserted.origin.kind).toBe("local");
|
|
5413
|
+
}
|
|
5414
|
+
} finally {
|
|
5415
|
+
await doc.close();
|
|
5416
|
+
}
|
|
5417
|
+
});
|
|
4920
5418
|
test("a FAILED mutation publishes nothing (events are ground truth)", async () => {
|
|
4921
|
-
const doc = await openFixture$
|
|
5419
|
+
const doc = await openFixture$4(engine, opts);
|
|
4922
5420
|
try {
|
|
4923
5421
|
const events = [];
|
|
4924
5422
|
doc.events.subscribe((event) => events.push(event));
|
|
@@ -4936,7 +5434,7 @@ function runDocumentEventsConformance(runner, opts) {
|
|
|
4936
5434
|
}
|
|
4937
5435
|
});
|
|
4938
5436
|
test("unsubscribe stops delivery", async () => {
|
|
4939
|
-
const doc = await openFixture$
|
|
5437
|
+
const doc = await openFixture$4(engine, opts);
|
|
4940
5438
|
try {
|
|
4941
5439
|
const events = [];
|
|
4942
5440
|
doc.events.subscribe((event) => events.push(event))();
|
|
@@ -4949,7 +5447,7 @@ function runDocumentEventsConformance(runner, opts) {
|
|
|
4949
5447
|
});
|
|
4950
5448
|
});
|
|
4951
5449
|
}
|
|
4952
|
-
async function openFixture$
|
|
5450
|
+
async function openFixture$4(engine, opts) {
|
|
4953
5451
|
if (opts.openKind === "bytes") {
|
|
4954
5452
|
const bytes = await opts.fixture.bytes();
|
|
4955
5453
|
return engine.open({
|
|
@@ -4976,7 +5474,7 @@ function runPageTextConformance(runner, opts) {
|
|
|
4976
5474
|
if (engine) await engine.destroy();
|
|
4977
5475
|
});
|
|
4978
5476
|
test("read() returns a PageTextSnapshot with non-empty text", async () => {
|
|
4979
|
-
const doc = await openFixture$
|
|
5477
|
+
const doc = await openFixture$3(engine, opts);
|
|
4980
5478
|
try {
|
|
4981
5479
|
const snap = await doc.page(opts.fixture.pageObjectNumber).text.read();
|
|
4982
5480
|
expect(require_schemas.PageTextSnapshotSchema.safeParse(snap).success).toBe(true);
|
|
@@ -4987,7 +5485,7 @@ function runPageTextConformance(runner, opts) {
|
|
|
4987
5485
|
}
|
|
4988
5486
|
});
|
|
4989
5487
|
test("extracted text contains the expected substring", async () => {
|
|
4990
|
-
const doc = await openFixture$
|
|
5488
|
+
const doc = await openFixture$3(engine, opts);
|
|
4991
5489
|
try {
|
|
4992
5490
|
const snap = await doc.page(opts.fixture.pageObjectNumber).text.read();
|
|
4993
5491
|
expect(snap.text.includes(opts.fixture.expectedSubstring)).toBe(true);
|
|
@@ -4996,7 +5494,7 @@ function runPageTextConformance(runner, opts) {
|
|
|
4996
5494
|
}
|
|
4997
5495
|
});
|
|
4998
5496
|
test("read() on an unknown pageObjectNumber throws NotFound", async () => {
|
|
4999
|
-
const doc = await openFixture$
|
|
5497
|
+
const doc = await openFixture$3(engine, opts);
|
|
5000
5498
|
try {
|
|
5001
5499
|
let caught;
|
|
5002
5500
|
try {
|
|
@@ -5005,13 +5503,13 @@ function runPageTextConformance(runner, opts) {
|
|
|
5005
5503
|
caught = err;
|
|
5006
5504
|
}
|
|
5007
5505
|
expect(caught).toBeTruthy();
|
|
5008
|
-
expect(require_fold.EngineError.is(caught,
|
|
5506
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.NotFound)).toBe(true);
|
|
5009
5507
|
} finally {
|
|
5010
5508
|
await doc.close();
|
|
5011
5509
|
}
|
|
5012
5510
|
});
|
|
5013
5511
|
test("abort() on read rejects with AbortError", async () => {
|
|
5014
|
-
const doc = await openFixture$
|
|
5512
|
+
const doc = await openFixture$3(engine, opts);
|
|
5015
5513
|
try {
|
|
5016
5514
|
const p = doc.page(opts.fixture.pageObjectNumber).text.read();
|
|
5017
5515
|
p.abort("test");
|
|
@@ -5021,7 +5519,7 @@ function runPageTextConformance(runner, opts) {
|
|
|
5021
5519
|
}
|
|
5022
5520
|
});
|
|
5023
5521
|
test("read after close throws DocNotOpen", async () => {
|
|
5024
|
-
const doc = await openFixture$
|
|
5522
|
+
const doc = await openFixture$3(engine, opts);
|
|
5025
5523
|
const page = doc.page(opts.fixture.pageObjectNumber);
|
|
5026
5524
|
await doc.close();
|
|
5027
5525
|
let caught;
|
|
@@ -5031,10 +5529,324 @@ function runPageTextConformance(runner, opts) {
|
|
|
5031
5529
|
caught = err;
|
|
5032
5530
|
}
|
|
5033
5531
|
expect(caught).toBeTruthy();
|
|
5034
|
-
expect(require_fold.EngineError.is(caught,
|
|
5532
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.DocNotOpen)).toBe(true);
|
|
5533
|
+
});
|
|
5534
|
+
});
|
|
5535
|
+
}
|
|
5536
|
+
async function openFixture$3(engine, opts) {
|
|
5537
|
+
if (opts.openKind === "bytes") {
|
|
5538
|
+
const bytes = await opts.fixture.bytes();
|
|
5539
|
+
return engine.open({
|
|
5540
|
+
kind: "bytes",
|
|
5541
|
+
id: opts.fixture.id,
|
|
5542
|
+
bytes
|
|
5543
|
+
});
|
|
5544
|
+
}
|
|
5545
|
+
return engine.open({
|
|
5546
|
+
kind: "id",
|
|
5547
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
5548
|
+
});
|
|
5549
|
+
}
|
|
5550
|
+
//#endregion
|
|
5551
|
+
//#region src/conformance/runTextDivergenceConformance.ts
|
|
5552
|
+
function runTextDivergenceConformance(runner, opts) {
|
|
5553
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
5554
|
+
const fixture = opts.fixture;
|
|
5555
|
+
describe(`text divergence conformance: ${opts.label} [${fixture.id}]`, () => {
|
|
5556
|
+
let engine;
|
|
5557
|
+
beforeAll(async () => {
|
|
5558
|
+
engine = await opts.makeEngine();
|
|
5559
|
+
});
|
|
5560
|
+
afterAll(async () => {
|
|
5561
|
+
if (engine) await engine.destroy();
|
|
5562
|
+
});
|
|
5563
|
+
test("snapshot is schema-valid with the exact text, charCount, and charMap", async () => {
|
|
5564
|
+
const doc = await openFixture$2(engine, opts);
|
|
5565
|
+
try {
|
|
5566
|
+
const snap = await doc.page(fixture.pageObjectNumber).text.read();
|
|
5567
|
+
expect(require_schemas.PageTextSnapshotSchema.safeParse(snap).success).toBe(true);
|
|
5568
|
+
expect(snap.text).toBe(fixture.exactText);
|
|
5569
|
+
expect(snap.charCount).toBe(fixture.expectedCharCount);
|
|
5570
|
+
const anchors = snap.charMap ?? null;
|
|
5571
|
+
if (fixture.expectedCharMap === null) expect(anchors === null || anchors.length === 0).toBe(true);
|
|
5572
|
+
else expect(anchors === null ? null : anchors.map((a) => [a[0], a[1]])).toEqual(fixture.expectedCharMap.map((a) => [a[0], a[1]]));
|
|
5573
|
+
} finally {
|
|
5574
|
+
await doc.close();
|
|
5575
|
+
}
|
|
5576
|
+
});
|
|
5577
|
+
test("char-space slicing round-trips through the map", async () => {
|
|
5578
|
+
const doc = await openFixture$2(engine, opts);
|
|
5579
|
+
try {
|
|
5580
|
+
const snap = await doc.page(fixture.pageObjectNumber).text.read();
|
|
5581
|
+
expect(require_PageInsertBlankInput.sliceTextByChars(snap, 0, snap.charCount)).toBe(snap.text);
|
|
5582
|
+
for (const s of fixture.slices ?? []) expect(require_PageInsertBlankInput.sliceTextByChars(snap, s.from, s.to)).toBe(s.text);
|
|
5583
|
+
} finally {
|
|
5584
|
+
await doc.close();
|
|
5585
|
+
}
|
|
5035
5586
|
});
|
|
5587
|
+
if (fixture.search) {
|
|
5588
|
+
const probe = fixture.search;
|
|
5589
|
+
test("search hits address character space and join the text by slicing", async () => {
|
|
5590
|
+
const doc = await openFixture$2(engine, opts);
|
|
5591
|
+
try {
|
|
5592
|
+
const hit = (await doc.search.query({
|
|
5593
|
+
query: { text: probe.query },
|
|
5594
|
+
mode: "rects"
|
|
5595
|
+
})).matches.find((m) => m.pageObjectNumber === fixture.pageObjectNumber);
|
|
5596
|
+
expect(hit === void 0).toBe(false);
|
|
5597
|
+
expect(hit.charStart).toBe(probe.charStart);
|
|
5598
|
+
expect(hit.charCount).toBe(probe.charCount);
|
|
5599
|
+
expect(hit.segments.length > 0).toBe(true);
|
|
5600
|
+
const snap = await doc.page(fixture.pageObjectNumber).text.read();
|
|
5601
|
+
expect(require_PageInsertBlankInput.sliceTextByChars(snap, hit.charStart, hit.charStart + hit.charCount)).toBe(probe.matchedText);
|
|
5602
|
+
} finally {
|
|
5603
|
+
await doc.close();
|
|
5604
|
+
}
|
|
5605
|
+
});
|
|
5606
|
+
}
|
|
5036
5607
|
});
|
|
5037
5608
|
}
|
|
5609
|
+
async function openFixture$2(engine, opts) {
|
|
5610
|
+
if (opts.openKind === "bytes") {
|
|
5611
|
+
const bytes = await opts.fixture.bytes();
|
|
5612
|
+
return engine.open({
|
|
5613
|
+
kind: "bytes",
|
|
5614
|
+
id: opts.fixture.id,
|
|
5615
|
+
bytes
|
|
5616
|
+
});
|
|
5617
|
+
}
|
|
5618
|
+
return engine.open({
|
|
5619
|
+
kind: "id",
|
|
5620
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
5621
|
+
});
|
|
5622
|
+
}
|
|
5623
|
+
/**
|
|
5624
|
+
* THE pinned divergence cases — one table, consumed by both engines' suites
|
|
5625
|
+
* so expected values cannot drift. Values verified against the wasm runtime
|
|
5626
|
+
* (see each case). All fixtures are single-page; the page's indirect object
|
|
5627
|
+
* number is 3 in each.
|
|
5628
|
+
*/
|
|
5629
|
+
const TEXT_DIVERGENCE_CASES = {
|
|
5630
|
+
/** Leading NON-PRINTING character: 31 character slots, 30 text units —
|
|
5631
|
+
* every text offset shifts by one, encoded by the single anchor [1, 0].
|
|
5632
|
+
* The searchex embeddertest for this fixture pins the same +1 shift. */
|
|
5633
|
+
bug1139: {
|
|
5634
|
+
resource: "bug_1139.pdf",
|
|
5635
|
+
pageObjectNumber: 3,
|
|
5636
|
+
exactText: "Hello, world!\r\nGoodbye, world!",
|
|
5637
|
+
expectedCharCount: 31,
|
|
5638
|
+
expectedCharMap: [[1, 0]],
|
|
5639
|
+
slices: [
|
|
5640
|
+
{
|
|
5641
|
+
from: 0,
|
|
5642
|
+
to: 1,
|
|
5643
|
+
text: ""
|
|
5644
|
+
},
|
|
5645
|
+
{
|
|
5646
|
+
from: 1,
|
|
5647
|
+
to: 7,
|
|
5648
|
+
text: "Hello,"
|
|
5649
|
+
},
|
|
5650
|
+
{
|
|
5651
|
+
from: 16,
|
|
5652
|
+
to: 23,
|
|
5653
|
+
text: "Goodbye"
|
|
5654
|
+
}
|
|
5655
|
+
],
|
|
5656
|
+
search: {
|
|
5657
|
+
query: "Goodbye",
|
|
5658
|
+
charStart: 16,
|
|
5659
|
+
charCount: 7,
|
|
5660
|
+
matchedText: "Goodbye"
|
|
5661
|
+
}
|
|
5662
|
+
},
|
|
5663
|
+
/** `/ActualText` replacement: the span's real glyphs are REPLACED by one
|
|
5664
|
+
* synthetic kPiece character per ActualText character, lockstep with the
|
|
5665
|
+
* text (identity map), with synthesized evenly-divided boxes — so search
|
|
5666
|
+
* segments exist and extraction yields the ActualText, not the glyphs. */
|
|
5667
|
+
actualText: {
|
|
5668
|
+
resource: "bug_384770169.pdf",
|
|
5669
|
+
pageObjectNumber: 3,
|
|
5670
|
+
exactText: "What is my favorite food?",
|
|
5671
|
+
expectedCharCount: 25,
|
|
5672
|
+
expectedCharMap: null,
|
|
5673
|
+
slices: [{
|
|
5674
|
+
from: 11,
|
|
5675
|
+
to: 19,
|
|
5676
|
+
text: "favorite"
|
|
5677
|
+
}],
|
|
5678
|
+
search: {
|
|
5679
|
+
query: "favorite",
|
|
5680
|
+
charStart: 11,
|
|
5681
|
+
charCount: 8,
|
|
5682
|
+
matchedText: "favorite"
|
|
5683
|
+
}
|
|
5684
|
+
},
|
|
5685
|
+
/** Supplementary-plane text via a ToUnicode surrogate pair: PDFium stores
|
|
5686
|
+
* one character-list entry PER SURROGATE HALF in lockstep with the text
|
|
5687
|
+
* (identity map, no divergence in this representation) — and the emoji
|
|
5688
|
+
* SURVIVES extraction end to end. The combined-astral representation
|
|
5689
|
+
* (font-cmap path, one entry per code point → a [+2] anchor) is covered
|
|
5690
|
+
* by the charmap unit tests and the reader's divergent walk. */
|
|
5691
|
+
astralToUnicode: {
|
|
5692
|
+
resource: "embedpdf_astral_tounicode.pdf",
|
|
5693
|
+
pageObjectNumber: 3,
|
|
5694
|
+
exactText: "😀B!",
|
|
5695
|
+
expectedCharCount: 4,
|
|
5696
|
+
expectedCharMap: null,
|
|
5697
|
+
slices: [{
|
|
5698
|
+
from: 0,
|
|
5699
|
+
to: 2,
|
|
5700
|
+
text: "😀"
|
|
5701
|
+
}, {
|
|
5702
|
+
from: 2,
|
|
5703
|
+
to: 3,
|
|
5704
|
+
text: "B"
|
|
5705
|
+
}],
|
|
5706
|
+
search: {
|
|
5707
|
+
query: "B!",
|
|
5708
|
+
charStart: 2,
|
|
5709
|
+
charCount: 2,
|
|
5710
|
+
matchedText: "B!"
|
|
5711
|
+
}
|
|
5712
|
+
}
|
|
5713
|
+
};
|
|
5714
|
+
//#endregion
|
|
5715
|
+
//#region src/conformance/runPageGeometryOrientationConformance.ts
|
|
5716
|
+
const FLAG_EMPTY = 2;
|
|
5717
|
+
/** Absolute tolerance for coordinate assertions (PDF points). */
|
|
5718
|
+
const COORD_TOLERANCE = .001;
|
|
5719
|
+
/** Tolerance for baseline-angle assertions (radians). */
|
|
5720
|
+
const ANGLE_TOLERANCE = .001;
|
|
5721
|
+
function runPageGeometryOrientationConformance(runner, opts) {
|
|
5722
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
5723
|
+
describe(`page geometry orientation conformance: ${opts.label} [${opts.fixture.id}]`, () => {
|
|
5724
|
+
let engine;
|
|
5725
|
+
beforeAll(async () => {
|
|
5726
|
+
engine = await opts.makeEngine();
|
|
5727
|
+
});
|
|
5728
|
+
afterAll(async () => {
|
|
5729
|
+
if (engine) await engine.destroy();
|
|
5730
|
+
});
|
|
5731
|
+
const readSnapshot = async () => {
|
|
5732
|
+
const doc = await openFixture$1(engine, opts);
|
|
5733
|
+
return {
|
|
5734
|
+
snapshot: await doc.page(opts.fixture.pageObjectNumber).geometry.read(),
|
|
5735
|
+
close: () => doc.close()
|
|
5736
|
+
};
|
|
5737
|
+
};
|
|
5738
|
+
test("snapshot round-trips the wire schema", async () => {
|
|
5739
|
+
const { snapshot, close } = await readSnapshot();
|
|
5740
|
+
try {
|
|
5741
|
+
const parsed = require_schemas.PageGeometrySnapshotSchema.safeParse(snapshot);
|
|
5742
|
+
expect(parsed.success).toBe(true);
|
|
5743
|
+
if (parsed.success) expect(parsed.data).toEqual(snapshot);
|
|
5744
|
+
} finally {
|
|
5745
|
+
await close();
|
|
5746
|
+
}
|
|
5747
|
+
});
|
|
5748
|
+
test("run charStart indices tile the page glyph sequence", async () => {
|
|
5749
|
+
const { snapshot, close } = await readSnapshot();
|
|
5750
|
+
try {
|
|
5751
|
+
let next = 0;
|
|
5752
|
+
for (const run of snapshot.runs) {
|
|
5753
|
+
expect(run.charStart).toBe(next);
|
|
5754
|
+
next += run.glyphs.length;
|
|
5755
|
+
}
|
|
5756
|
+
} finally {
|
|
5757
|
+
await close();
|
|
5758
|
+
}
|
|
5759
|
+
});
|
|
5760
|
+
test("runs match the fixture orientation expectation", async () => {
|
|
5761
|
+
const { snapshot, close } = await readSnapshot();
|
|
5762
|
+
try {
|
|
5763
|
+
const expectation = opts.fixture.expectation;
|
|
5764
|
+
if (expectation.kind === "upright") {
|
|
5765
|
+
for (const run of snapshot.runs) {
|
|
5766
|
+
expect(require_fold.isRotatedGeometryRun(run)).toBe(false);
|
|
5767
|
+
if (require_fold.isRotatedGeometryRun(run)) continue;
|
|
5768
|
+
for (const glyph of run.glyphs) {
|
|
5769
|
+
expect("looseQuad" in glyph).toBe(false);
|
|
5770
|
+
if (glyph.flags & FLAG_EMPTY) expect(glyph.looseBox).toEqual({
|
|
5771
|
+
left: 0,
|
|
5772
|
+
bottom: 0,
|
|
5773
|
+
right: 0,
|
|
5774
|
+
top: 0
|
|
5775
|
+
});
|
|
5776
|
+
}
|
|
5777
|
+
}
|
|
5778
|
+
return;
|
|
5779
|
+
}
|
|
5780
|
+
if (expectation.kind === "empty-only") {
|
|
5781
|
+
for (const run of snapshot.runs) {
|
|
5782
|
+
expect(require_fold.isRotatedGeometryRun(run)).toBe(false);
|
|
5783
|
+
if (require_fold.isRotatedGeometryRun(run)) continue;
|
|
5784
|
+
for (const glyph of run.glyphs) {
|
|
5785
|
+
expect(glyph.flags & FLAG_EMPTY).toBe(FLAG_EMPTY);
|
|
5786
|
+
expect(glyph.looseBox).toEqual({
|
|
5787
|
+
left: 0,
|
|
5788
|
+
bottom: 0,
|
|
5789
|
+
right: 0,
|
|
5790
|
+
top: 0
|
|
5791
|
+
});
|
|
5792
|
+
}
|
|
5793
|
+
}
|
|
5794
|
+
return;
|
|
5795
|
+
}
|
|
5796
|
+
const rotatedRuns = snapshot.runs.filter(require_fold.isRotatedGeometryRun);
|
|
5797
|
+
expect(rotatedRuns.length >= (expectation.minRotatedRuns ?? 1)).toBe(true);
|
|
5798
|
+
for (const run of rotatedRuns) {
|
|
5799
|
+
expect(expectation.rotations.some((angle) => angleClose(run.rotation, angle, ANGLE_TOLERANCE))).toBe(true);
|
|
5800
|
+
expect(run.ascentFlip).toBe(expectation.ascentFlip);
|
|
5801
|
+
assertRotatedRunGeometry(run);
|
|
5802
|
+
}
|
|
5803
|
+
if (expectation.sheared) {
|
|
5804
|
+
const shearedGlyphs = rotatedRuns.flatMap((run) => run.glyphs).filter((glyph) => (glyph.flags & FLAG_EMPTY) === 0 && Math.abs(glyph.looseQuad.p3.x - glyph.looseQuad.p1.x) > 1);
|
|
5805
|
+
expect(shearedGlyphs.length > 0).toBe(true);
|
|
5806
|
+
}
|
|
5807
|
+
} finally {
|
|
5808
|
+
await close();
|
|
5809
|
+
}
|
|
5810
|
+
});
|
|
5811
|
+
function assertRotatedRunGeometry(run) {
|
|
5812
|
+
for (const glyph of run.glyphs) {
|
|
5813
|
+
if (glyph.flags & FLAG_EMPTY) {
|
|
5814
|
+
expect(glyph.looseQuad).toEqual({
|
|
5815
|
+
p1: {
|
|
5816
|
+
x: 0,
|
|
5817
|
+
y: 0
|
|
5818
|
+
},
|
|
5819
|
+
p2: {
|
|
5820
|
+
x: 0,
|
|
5821
|
+
y: 0
|
|
5822
|
+
},
|
|
5823
|
+
p3: {
|
|
5824
|
+
x: 0,
|
|
5825
|
+
y: 0
|
|
5826
|
+
},
|
|
5827
|
+
p4: {
|
|
5828
|
+
x: 0,
|
|
5829
|
+
y: 0
|
|
5830
|
+
}
|
|
5831
|
+
});
|
|
5832
|
+
continue;
|
|
5833
|
+
}
|
|
5834
|
+
const q = glyph.looseQuad;
|
|
5835
|
+
expect(Math.abs(q.p2.x - q.p1.x - (q.p4.x - q.p3.x)) <= COORD_TOLERANCE).toBe(true);
|
|
5836
|
+
expect(Math.abs(q.p2.y - q.p1.y - (q.p4.y - q.p3.y)) <= COORD_TOLERANCE).toBe(true);
|
|
5837
|
+
const bounds = require_fold.pdfQuadBounds(q);
|
|
5838
|
+
expect(bounds.left >= run.rect.left - COORD_TOLERANCE).toBe(true);
|
|
5839
|
+
expect(bounds.right <= run.rect.right + COORD_TOLERANCE).toBe(true);
|
|
5840
|
+
expect(bounds.bottom >= run.rect.bottom - COORD_TOLERANCE).toBe(true);
|
|
5841
|
+
expect(bounds.top <= run.rect.top + COORD_TOLERANCE).toBe(true);
|
|
5842
|
+
}
|
|
5843
|
+
}
|
|
5844
|
+
});
|
|
5845
|
+
}
|
|
5846
|
+
function angleClose(a, b, tolerance) {
|
|
5847
|
+
const delta = a - b;
|
|
5848
|
+
return Math.abs(Math.atan2(Math.sin(delta), Math.cos(delta))) <= tolerance;
|
|
5849
|
+
}
|
|
5038
5850
|
async function openFixture$1(engine, opts) {
|
|
5039
5851
|
if (opts.openKind === "bytes") {
|
|
5040
5852
|
const bytes = await opts.fixture.bytes();
|
|
@@ -5090,10 +5902,27 @@ function runSearchConformance(runner, opts) {
|
|
|
5090
5902
|
expect(matches.some((m) => m.pageObjectNumber === fixture.presentPageObjectNumber)).toBe(true);
|
|
5091
5903
|
for (const m of matches) {
|
|
5092
5904
|
expect(m.charCount > 0).toBe(true);
|
|
5093
|
-
expect(m.
|
|
5094
|
-
for (const
|
|
5095
|
-
expect(
|
|
5096
|
-
expect(
|
|
5905
|
+
expect(m.segments.length > 0).toBe(true);
|
|
5906
|
+
for (const s of m.segments) {
|
|
5907
|
+
expect(s.rect.right > s.rect.left).toBe(true);
|
|
5908
|
+
expect(s.rect.top > s.rect.bottom).toBe(true);
|
|
5909
|
+
const xs = [
|
|
5910
|
+
s.quad.p1.x,
|
|
5911
|
+
s.quad.p2.x,
|
|
5912
|
+
s.quad.p3.x,
|
|
5913
|
+
s.quad.p4.x
|
|
5914
|
+
];
|
|
5915
|
+
const ys = [
|
|
5916
|
+
s.quad.p1.y,
|
|
5917
|
+
s.quad.p2.y,
|
|
5918
|
+
s.quad.p3.y,
|
|
5919
|
+
s.quad.p4.y
|
|
5920
|
+
];
|
|
5921
|
+
expect(Math.abs(s.rect.left - Math.min(...xs)) < .001).toBe(true);
|
|
5922
|
+
expect(Math.abs(s.rect.right - Math.max(...xs)) < .001).toBe(true);
|
|
5923
|
+
expect(Math.abs(s.rect.bottom - Math.min(...ys)) < .001).toBe(true);
|
|
5924
|
+
expect(Math.abs(s.rect.top - Math.max(...ys)) < .001).toBe(true);
|
|
5925
|
+
expect(s.advance === 1 || s.advance === -1).toBe(true);
|
|
5097
5926
|
}
|
|
5098
5927
|
}
|
|
5099
5928
|
} finally {
|
|
@@ -5193,7 +6022,7 @@ function runSearchConformance(runner, opts) {
|
|
|
5193
6022
|
} catch (err) {
|
|
5194
6023
|
caught = err;
|
|
5195
6024
|
}
|
|
5196
|
-
expect(require_fold.EngineError.is(caught,
|
|
6025
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
5197
6026
|
} finally {
|
|
5198
6027
|
await doc.close();
|
|
5199
6028
|
}
|
|
@@ -5210,7 +6039,7 @@ function runSearchConformance(runner, opts) {
|
|
|
5210
6039
|
} catch (err) {
|
|
5211
6040
|
caught = err;
|
|
5212
6041
|
}
|
|
5213
|
-
expect(require_fold.EngineError.is(caught,
|
|
6042
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
5214
6043
|
} finally {
|
|
5215
6044
|
await doc.close();
|
|
5216
6045
|
}
|
|
@@ -5225,7 +6054,7 @@ function runSearchConformance(runner, opts) {
|
|
|
5225
6054
|
expect(matches.length > 0).toBe(true);
|
|
5226
6055
|
for (const m of matches) {
|
|
5227
6056
|
expect(m.charCount > 0).toBe(true);
|
|
5228
|
-
expect(m.
|
|
6057
|
+
expect(m.segments.length > 0).toBe(true);
|
|
5229
6058
|
}
|
|
5230
6059
|
} finally {
|
|
5231
6060
|
await doc.close();
|
|
@@ -5266,7 +6095,7 @@ function runSearchConformance(runner, opts) {
|
|
|
5266
6095
|
} catch (err) {
|
|
5267
6096
|
caught = err;
|
|
5268
6097
|
}
|
|
5269
|
-
expect(require_fold.EngineError.is(caught,
|
|
6098
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
5270
6099
|
} finally {
|
|
5271
6100
|
await doc.close();
|
|
5272
6101
|
}
|
|
@@ -5288,7 +6117,7 @@ function runSearchConformance(runner, opts) {
|
|
|
5288
6117
|
} catch (err) {
|
|
5289
6118
|
caught = err;
|
|
5290
6119
|
}
|
|
5291
|
-
expect(require_fold.EngineError.is(caught,
|
|
6120
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.InvalidArg)).toBe(true);
|
|
5292
6121
|
}
|
|
5293
6122
|
} finally {
|
|
5294
6123
|
await doc.close();
|
|
@@ -5323,7 +6152,7 @@ function runSearchConformance(runner, opts) {
|
|
|
5323
6152
|
} catch (err) {
|
|
5324
6153
|
caught = err;
|
|
5325
6154
|
}
|
|
5326
|
-
expect(require_fold.EngineError.is(caught,
|
|
6155
|
+
expect(require_fold.EngineError.is(caught, require_PageInsertBlankInput.EngineErrorCode.DocNotOpen)).toBe(true);
|
|
5327
6156
|
});
|
|
5328
6157
|
});
|
|
5329
6158
|
}
|
|
@@ -5352,6 +6181,8 @@ async function openFixture(engine, opts) {
|
|
|
5352
6181
|
* are disjoint. We do compare `pageObjectNumber` and `generation` (which
|
|
5353
6182
|
* should be 0 for fresh reads on both sides). Page order is no longer part
|
|
5354
6183
|
* of `PageState`; it lives in `PageLayout.index` (see `pages.list()`).
|
|
6184
|
+
* `auditHead` is likewise not compared: it is a cloud-only reconciliation
|
|
6185
|
+
* cursor, absent on local snapshots by design.
|
|
5355
6186
|
*/
|
|
5356
6187
|
function diffAnnotationListSnapshot(a, b) {
|
|
5357
6188
|
const errs = [];
|
|
@@ -5390,6 +6221,7 @@ function diffAnnotation(i, a, b, errs) {
|
|
|
5390
6221
|
if (a.nm !== b.nm) errs.push(`annotations[${i}].nm mismatch: ${a.nm} vs ${b.nm}`);
|
|
5391
6222
|
}
|
|
5392
6223
|
//#endregion
|
|
6224
|
+
exports.TEXT_DIVERGENCE_CASES = TEXT_DIVERGENCE_CASES;
|
|
5393
6225
|
exports.diffAnnotationListSnapshot = diffAnnotationListSnapshot;
|
|
5394
6226
|
exports.diffAnnotationListSnapshotAll = diffAnnotationListSnapshotAll;
|
|
5395
6227
|
exports.runActionsConformance = runActionsConformance;
|
|
@@ -5403,6 +6235,8 @@ exports.runMetadataConformance = runMetadataConformance;
|
|
|
5403
6235
|
exports.runPageDeleteConformance = runPageDeleteConformance;
|
|
5404
6236
|
exports.runPageExtractConformance = runPageExtractConformance;
|
|
5405
6237
|
exports.runPageFlattenConformance = runPageFlattenConformance;
|
|
6238
|
+
exports.runPageGeometryOrientationConformance = runPageGeometryOrientationConformance;
|
|
6239
|
+
exports.runPageInsertBlankConformance = runPageInsertBlankConformance;
|
|
5406
6240
|
exports.runPageInsertConformance = runPageInsertConformance;
|
|
5407
6241
|
exports.runPageReorderConformance = runPageReorderConformance;
|
|
5408
6242
|
exports.runPageRotateConformance = runPageRotateConformance;
|
|
@@ -5410,5 +6244,6 @@ exports.runPageTextConformance = runPageTextConformance;
|
|
|
5410
6244
|
exports.runPieceInfoConformance = runPieceInfoConformance;
|
|
5411
6245
|
exports.runRedactionApplyConformance = runRedactionApplyConformance;
|
|
5412
6246
|
exports.runSearchConformance = runSearchConformance;
|
|
6247
|
+
exports.runTextDivergenceConformance = runTextDivergenceConformance;
|
|
5413
6248
|
|
|
5414
6249
|
//# sourceMappingURL=conformance.cjs.map
|