@embedpdf/engine-core 3.0.0-next.10 → 3.0.0-next.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AnnotationListSnapshot-DDxHpJQU.d.cts → AnnotationListSnapshot-x6tKulNV.d.cts} +461 -114
- package/dist/{AnnotationListSnapshot-DDxHpJQU.d.ts → AnnotationListSnapshot-x6tKulNV.d.ts} +461 -114
- package/dist/{DocumentSecurityService-o9aeTHwT.d.ts → DocumentSecurityService-9MawYxP-.d.ts} +2 -2
- package/dist/{DocumentSecurityService-BV4_YXkU.d.cts → DocumentSecurityService-CK0pejAK.d.cts} +2 -2
- package/dist/{Engine-DOoVem7_.d.ts → Engine--0XF0UAK.d.cts} +68 -3
- package/dist/{Engine-D9je6GdU.d.cts → Engine-Ds0ytbl6.d.ts} +68 -3
- package/dist/{builders-Cp_rlGob.cjs → builders-8Hl1AYNU.cjs} +44 -8
- package/dist/builders-8Hl1AYNU.cjs.map +1 -0
- package/dist/{builders-B_KufGJ9.js → builders-DOjcKDWQ.js} +39 -9
- package/dist/builders-DOjcKDWQ.js.map +1 -0
- package/dist/conformance.cjs +769 -101
- package/dist/conformance.cjs.map +1 -1
- package/dist/conformance.d.cts +56 -3
- package/dist/conformance.d.ts +56 -3
- package/dist/conformance.js +767 -102
- package/dist/conformance.js.map +1 -1
- package/dist/index.cjs +3 -2
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- 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 +3 -2
- package/dist/runtime.d.cts +66 -5
- package/dist/runtime.d.ts +66 -5
- package/dist/runtime.js +3 -3
- package/dist/{schemas-DAnu8tuW.js → schemas-DOyVEPk7.js} +206 -84
- package/dist/schemas-DOyVEPk7.js.map +1 -0
- package/dist/{schemas-D1pxEv3t.cjs → schemas-RChsAMWw.cjs} +259 -83
- package/dist/schemas-RChsAMWw.cjs.map +1 -0
- package/dist/wire.cjs +65 -2
- package/dist/wire.cjs.map +1 -1
- package/dist/wire.d.cts +210 -8
- package/dist/wire.d.ts +210 -8
- package/dist/wire.js +54 -3
- package/dist/wire.js.map +1 -1
- package/package.json +1 -1
- package/dist/builders-B_KufGJ9.js.map +0 -1
- package/dist/builders-Cp_rlGob.cjs.map +0 -1
- package/dist/resolver-DAZWVoJL.cjs.map +0 -1
- package/dist/resolver-DiPMTfcy.js.map +0 -1
- package/dist/schemas-D1pxEv3t.cjs.map +0 -1
- package/dist/schemas-DAnu8tuW.js.map +0 -1
package/dist/conformance.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { f as pdfQuadBounds, i as EngineError, n as foldText, u as isRotatedGeometryRun } from "./fold-BfyxxwS6.js";
|
|
2
2
|
import { f as EngineErrorCode, o as sliceTextByChars } from "./PageInsertBlankInput-WKY0tr6S.js";
|
|
3
3
|
import { t as AbortError } from "./AbortError-8-9JAX1Y.js";
|
|
4
|
-
import {
|
|
4
|
+
import { $ as PageListSnapshotSchema, Ft as FormSnapshotSchema, J as PageGeometrySnapshotSchema, M as FormRepairResultSchema, N as FormSetValueResultSchema, Vt as AnnotationDTOSchema, W as PageDeleteResultSchema, br as DocumentActionsSnapshotSchema, d as AnnotationListPageSnapshotSchema, f as AnnotationListSnapshotAllPagesSchema, ft as PageTextSnapshotSchema, j as FormImportResultSchema, l as AnnotationFlattenResultSchema, lt as PageRotateResultSchema, m as AnnotationUpdateResultSchema, mt as RedactionApplyResultSchema, o as AnnotationCreateResultSchema, p as AnnotationMoveResultSchema, q as PageFlattenResultSchema, rt as PageNameResultSchema, s as AnnotationDeleteResultSchema, tt as PageMoveResultSchema, xt as SearchSliceSchema } from "./schemas-DOyVEPk7.js";
|
|
5
5
|
//#region src/conformance/runMetadataConformance.ts
|
|
6
6
|
/**
|
|
7
7
|
* The conformance harness is transport-agnostic. It takes the test runner as
|
|
@@ -18,7 +18,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
18
18
|
if (engine) await engine.destroy();
|
|
19
19
|
});
|
|
20
20
|
test("reads metadata from sample fixture", async () => {
|
|
21
|
-
const doc = await openFixture$
|
|
21
|
+
const doc = await openFixture$20(engine, opts);
|
|
22
22
|
try {
|
|
23
23
|
const meta = await doc.metadata.read();
|
|
24
24
|
expect(meta).toMatchObject(opts.fixture.expected);
|
|
@@ -28,7 +28,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
28
28
|
}
|
|
29
29
|
});
|
|
30
30
|
test("abort() before completion rejects with AbortError", async () => {
|
|
31
|
-
const doc = await openFixture$
|
|
31
|
+
const doc = await openFixture$20(engine, opts);
|
|
32
32
|
try {
|
|
33
33
|
const p = doc.metadata.read();
|
|
34
34
|
p.abort("test");
|
|
@@ -38,7 +38,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
38
38
|
}
|
|
39
39
|
});
|
|
40
40
|
test("aborting one read does not affect a concurrent one", async () => {
|
|
41
|
-
const doc = await openFixture$
|
|
41
|
+
const doc = await openFixture$20(engine, opts);
|
|
42
42
|
try {
|
|
43
43
|
const a = doc.metadata.read();
|
|
44
44
|
const b = doc.metadata.read();
|
|
@@ -50,7 +50,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
52
|
test("metadata after close throws DocNotOpen", async () => {
|
|
53
|
-
const doc = await openFixture$
|
|
53
|
+
const doc = await openFixture$20(engine, opts);
|
|
54
54
|
await doc.close();
|
|
55
55
|
let caught;
|
|
56
56
|
try {
|
|
@@ -62,7 +62,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
62
62
|
expect(EngineError.is(caught, EngineErrorCode.DocNotOpen)).toBe(true);
|
|
63
63
|
});
|
|
64
64
|
test("update() sets standard + custom fields and a subsequent read observes them", async () => {
|
|
65
|
-
const doc = await openFixture$
|
|
65
|
+
const doc = await openFixture$20(engine, opts);
|
|
66
66
|
try {
|
|
67
67
|
const result = await doc.metadata.update({
|
|
68
68
|
title: "Conformance Title",
|
|
@@ -81,7 +81,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
81
81
|
}
|
|
82
82
|
});
|
|
83
83
|
test("update() clears a field with null", async () => {
|
|
84
|
-
const doc = await openFixture$
|
|
84
|
+
const doc = await openFixture$20(engine, opts);
|
|
85
85
|
try {
|
|
86
86
|
await doc.metadata.update({ title: "To Be Cleared" });
|
|
87
87
|
const set = await doc.metadata.read();
|
|
@@ -94,7 +94,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
94
94
|
}
|
|
95
95
|
});
|
|
96
96
|
test("update() after close throws DocNotOpen", async () => {
|
|
97
|
-
const doc = await openFixture$
|
|
97
|
+
const doc = await openFixture$20(engine, opts);
|
|
98
98
|
await doc.close();
|
|
99
99
|
let caught;
|
|
100
100
|
try {
|
|
@@ -107,7 +107,7 @@ function runMetadataConformance(runner, opts) {
|
|
|
107
107
|
});
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
|
-
async function openFixture$
|
|
110
|
+
async function openFixture$20(engine, opts) {
|
|
111
111
|
if (opts.openKind === "bytes") {
|
|
112
112
|
const bytes = await opts.fixture.bytes();
|
|
113
113
|
return engine.open({
|
|
@@ -134,7 +134,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
134
134
|
if (engine) await engine.destroy();
|
|
135
135
|
});
|
|
136
136
|
test("listRawAll returns one entry per page with valid PageState", async () => {
|
|
137
|
-
const doc = await openFixture$
|
|
137
|
+
const doc = await openFixture$19(engine, opts);
|
|
138
138
|
try {
|
|
139
139
|
const snap = await doc.annotations.listRawAll();
|
|
140
140
|
expect(AnnotationListSnapshotAllPagesSchema.safeParse(snap).success).toBe(true);
|
|
@@ -148,7 +148,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
148
148
|
}
|
|
149
149
|
});
|
|
150
150
|
test("listRaw on the test page returns the expected counts and DTO shape", async () => {
|
|
151
|
-
const doc = await openFixture$
|
|
151
|
+
const doc = await openFixture$19(engine, opts);
|
|
152
152
|
try {
|
|
153
153
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
154
154
|
expect(AnnotationListPageSnapshotSchema.safeParse(snap).success).toBe(true);
|
|
@@ -178,7 +178,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
178
178
|
}
|
|
179
179
|
});
|
|
180
180
|
test("shape/vertex/line annotations expose their family fields", async () => {
|
|
181
|
-
const doc = await openFixture$
|
|
181
|
+
const doc = await openFixture$19(engine, opts);
|
|
182
182
|
try {
|
|
183
183
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
184
184
|
for (const a of snap.annotations) {
|
|
@@ -237,7 +237,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
237
237
|
}
|
|
238
238
|
});
|
|
239
239
|
test("full page list dispatches per-subtype and matches raw counts", async () => {
|
|
240
|
-
const doc = await openFixture$
|
|
240
|
+
const doc = await openFixture$19(engine, opts);
|
|
241
241
|
try {
|
|
242
242
|
const full = await doc.page(opts.fixture.pageObjectNumber).annotations.list();
|
|
243
243
|
expect(AnnotationListPageSnapshotSchema.safeParse(full).success).toBe(true);
|
|
@@ -247,7 +247,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
247
247
|
}
|
|
248
248
|
});
|
|
249
249
|
test("every annotation DTO satisfies AnnotationDTOSchema (discriminated union)", async () => {
|
|
250
|
-
const doc = await openFixture$
|
|
250
|
+
const doc = await openFixture$19(engine, opts);
|
|
251
251
|
try {
|
|
252
252
|
const snap = await doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
253
253
|
for (const a of snap.annotations) {
|
|
@@ -287,7 +287,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
287
287
|
});
|
|
288
288
|
if (opts.fixture.expectsWeakAnnotation) {
|
|
289
289
|
test("weak annotations carry identityQuality: weak and ref.kind: index", async () => {
|
|
290
|
-
const doc = await openFixture$
|
|
290
|
+
const doc = await openFixture$19(engine, opts);
|
|
291
291
|
try {
|
|
292
292
|
const weak = (await doc.annotations.listRaw(opts.fixture.pageObjectNumber)).annotations.find((a) => a.identityQuality === "weak");
|
|
293
293
|
expect(weak !== void 0).toBe(true);
|
|
@@ -297,7 +297,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
297
297
|
}
|
|
298
298
|
});
|
|
299
299
|
test("a stale revision token throws InvalidReference", async () => {
|
|
300
|
-
const doc = await openFixture$
|
|
300
|
+
const doc = await openFixture$19(engine, opts);
|
|
301
301
|
try {
|
|
302
302
|
const snap = await doc.page(opts.fixture.pageObjectNumber).annotations.list();
|
|
303
303
|
const weak = snap.annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -313,7 +313,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
313
313
|
});
|
|
314
314
|
}
|
|
315
315
|
test("abort() on listRaw rejects with AbortError", async () => {
|
|
316
|
-
const doc = await openFixture$
|
|
316
|
+
const doc = await openFixture$19(engine, opts);
|
|
317
317
|
try {
|
|
318
318
|
const p = doc.annotations.listRaw(opts.fixture.pageObjectNumber);
|
|
319
319
|
p.abort("test");
|
|
@@ -323,7 +323,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
323
323
|
}
|
|
324
324
|
});
|
|
325
325
|
test("listRaw on an unknown pageObjectNumber throws NotFound", async () => {
|
|
326
|
-
const doc = await openFixture$
|
|
326
|
+
const doc = await openFixture$19(engine, opts);
|
|
327
327
|
try {
|
|
328
328
|
let caught;
|
|
329
329
|
try {
|
|
@@ -339,7 +339,7 @@ function runAnnotationReadConformance(runner, opts) {
|
|
|
339
339
|
});
|
|
340
340
|
});
|
|
341
341
|
}
|
|
342
|
-
async function openFixture$
|
|
342
|
+
async function openFixture$19(engine, opts) {
|
|
343
343
|
if (opts.openKind === "bytes") {
|
|
344
344
|
const bytes = await opts.fixture.bytes();
|
|
345
345
|
return engine.open({
|
|
@@ -369,6 +369,13 @@ function emptyFlags() {
|
|
|
369
369
|
}
|
|
370
370
|
//#endregion
|
|
371
371
|
//#region src/conformance/runActionsConformance.ts
|
|
372
|
+
/** The script payload rides only the javascript/rendition arms. */
|
|
373
|
+
function scriptOf(node) {
|
|
374
|
+
if (!node) return "";
|
|
375
|
+
if (node.type === "javascript") return node.script;
|
|
376
|
+
if (node.type === "rendition") return node.script ?? "";
|
|
377
|
+
return "";
|
|
378
|
+
}
|
|
372
379
|
/** Action extraction parity. These tests assert data only; no script executes. */
|
|
373
380
|
function runActionsConformance(runner, opts) {
|
|
374
381
|
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
@@ -388,10 +395,10 @@ function runActionsConformance(runner, opts) {
|
|
|
388
395
|
expect(DocumentActionsSnapshotSchema.safeParse(snapshot).success).toBe(true);
|
|
389
396
|
expect(snapshot.openAction).toBeNull();
|
|
390
397
|
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
|
|
398
|
+
expect(scriptOf(snapshot.willSave?.root)).toMatch(/Will Save/);
|
|
399
|
+
expect(scriptOf(snapshot.didSave?.root)).toMatch(/Did Save/);
|
|
400
|
+
expect(scriptOf(snapshot.willPrint?.root)).toMatch(/Will Print/);
|
|
401
|
+
expect(scriptOf(snapshot.didPrint?.root)).toMatch(/Did Print/);
|
|
395
402
|
const form = await doc.forms.list();
|
|
396
403
|
expect(form.calculationOrder).toEqual([{
|
|
397
404
|
kind: "objectNumber",
|
|
@@ -438,7 +445,7 @@ function runActionsConformance(runner, opts) {
|
|
|
438
445
|
expect(link?.subtype).toBe("link");
|
|
439
446
|
if (link?.subtype === "link") expect(link.target).toEqual({ kind: "javascript" });
|
|
440
447
|
expect(link?.actions?.activate?.root?.type).toBe("javascript");
|
|
441
|
-
expect(link?.actions?.activate?.root
|
|
448
|
+
expect(scriptOf(link?.actions?.activate?.root)).toMatch(/app\.alert/);
|
|
442
449
|
} finally {
|
|
443
450
|
await doc.close();
|
|
444
451
|
}
|
|
@@ -449,7 +456,7 @@ function runActionsConformance(runner, opts) {
|
|
|
449
456
|
const form = await doc.forms.list();
|
|
450
457
|
expect(form.fields).toHaveLength(1);
|
|
451
458
|
expect(form.fields[0].actions?.format?.root?.type).toBe("javascript");
|
|
452
|
-
expect(form.fields[0].actions?.format?.root
|
|
459
|
+
expect(scriptOf(form.fields[0].actions?.format?.root)).toMatch(/AFDate_FormatEx/);
|
|
453
460
|
const page = (await doc.pages.list()).pages[0];
|
|
454
461
|
const widget = (await doc.page(page.pageObjectNumber).annotations.list()).annotations[0];
|
|
455
462
|
expect(widget.actions).toBe(void 0);
|
|
@@ -457,6 +464,210 @@ function runActionsConformance(runner, opts) {
|
|
|
457
464
|
await doc.close();
|
|
458
465
|
}
|
|
459
466
|
});
|
|
467
|
+
test("carries interpreter payloads on every executable node", async () => {
|
|
468
|
+
const doc = await open(engine, opts, opts.fixtures.payloads);
|
|
469
|
+
try {
|
|
470
|
+
const page = (await doc.pages.list()).pages[0];
|
|
471
|
+
const snapshot = await doc.page(page.pageObjectNumber).annotations.list();
|
|
472
|
+
const pon = page.pageObjectNumber;
|
|
473
|
+
const rootOf = (nm) => {
|
|
474
|
+
const annotation = snapshot.annotations.find((candidate) => candidate.nm === nm);
|
|
475
|
+
expect(Boolean(annotation)).toBe(true);
|
|
476
|
+
return annotation?.actions?.activate?.root ?? null;
|
|
477
|
+
};
|
|
478
|
+
const targetOf = (nm) => {
|
|
479
|
+
const annotation = snapshot.annotations.find((candidate) => candidate.nm === nm);
|
|
480
|
+
return annotation?.subtype === "link" ? annotation.target : null;
|
|
481
|
+
};
|
|
482
|
+
expect(rootOf("goto-fitr")).toMatchObject({
|
|
483
|
+
type: "goto",
|
|
484
|
+
destination: {
|
|
485
|
+
kind: "fitR",
|
|
486
|
+
pageObjectNumber: pon,
|
|
487
|
+
left: 10,
|
|
488
|
+
bottom: 20,
|
|
489
|
+
right: 300,
|
|
490
|
+
top: 400
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
expect(targetOf("goto-fitr")).toMatchObject({
|
|
494
|
+
kind: "goto",
|
|
495
|
+
destination: { kind: "fitR" }
|
|
496
|
+
});
|
|
497
|
+
expect(rootOf("uri-map")).toMatchObject({
|
|
498
|
+
type: "uri",
|
|
499
|
+
uri: "https://example.test/map",
|
|
500
|
+
isMap: true
|
|
501
|
+
});
|
|
502
|
+
expect(rootOf("named-next")).toMatchObject({
|
|
503
|
+
type: "named",
|
|
504
|
+
name: "NextPage"
|
|
505
|
+
});
|
|
506
|
+
const mixed = rootOf("hide-mixed");
|
|
507
|
+
expect(mixed).toMatchObject({
|
|
508
|
+
type: "hide",
|
|
509
|
+
hide: false
|
|
510
|
+
});
|
|
511
|
+
const mixedTargets = mixed?.type === "hide" ? mixed.targets : [];
|
|
512
|
+
expect(mixedTargets).toHaveLength(2);
|
|
513
|
+
expect(mixedTargets[0]).toEqual({
|
|
514
|
+
kind: "name",
|
|
515
|
+
name: "note1"
|
|
516
|
+
});
|
|
517
|
+
expect(mixedTargets[1]?.kind === "objectNumber" && mixedTargets[1].objectNumber > 0).toBe(true);
|
|
518
|
+
expect(rootOf("hide-scalar")).toMatchObject({
|
|
519
|
+
type: "hide",
|
|
520
|
+
targets: [{
|
|
521
|
+
kind: "name",
|
|
522
|
+
name: "fieldB"
|
|
523
|
+
}],
|
|
524
|
+
hide: true
|
|
525
|
+
});
|
|
526
|
+
expect(rootOf("reset-include")).toMatchObject({
|
|
527
|
+
type: "reset-form",
|
|
528
|
+
fields: [{
|
|
529
|
+
kind: "name",
|
|
530
|
+
name: "calc1"
|
|
531
|
+
}],
|
|
532
|
+
exclude: true
|
|
533
|
+
});
|
|
534
|
+
expect(rootOf("reset-absent")).toMatchObject({
|
|
535
|
+
type: "reset-form",
|
|
536
|
+
fields: null,
|
|
537
|
+
exclude: true
|
|
538
|
+
});
|
|
539
|
+
expect(rootOf("reset-empty")).toMatchObject({
|
|
540
|
+
type: "reset-form",
|
|
541
|
+
fields: [],
|
|
542
|
+
exclude: false
|
|
543
|
+
});
|
|
544
|
+
expect(rootOf("submit-urlspec")).toMatchObject({
|
|
545
|
+
type: "submit-form",
|
|
546
|
+
payload: {
|
|
547
|
+
url: "https://uf.example.test/submit",
|
|
548
|
+
fields: [{
|
|
549
|
+
kind: "name",
|
|
550
|
+
name: "parent"
|
|
551
|
+
}],
|
|
552
|
+
flags: {
|
|
553
|
+
raw: 0,
|
|
554
|
+
exclude: false,
|
|
555
|
+
format: "fdf",
|
|
556
|
+
method: "post"
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
});
|
|
560
|
+
expect(rootOf("submit-compat-xfdf")).toMatchObject({
|
|
561
|
+
type: "submit-form",
|
|
562
|
+
payload: {
|
|
563
|
+
url: "https://example.test/xfdf",
|
|
564
|
+
fields: [{
|
|
565
|
+
kind: "name",
|
|
566
|
+
name: "noexport"
|
|
567
|
+
}, {
|
|
568
|
+
kind: "name",
|
|
569
|
+
name: "plain"
|
|
570
|
+
}],
|
|
571
|
+
flags: {
|
|
572
|
+
raw: 35,
|
|
573
|
+
exclude: true,
|
|
574
|
+
includeNoValueFields: true,
|
|
575
|
+
format: "xfdf",
|
|
576
|
+
method: "post"
|
|
577
|
+
},
|
|
578
|
+
charSet: "utf-8"
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
expect(rootOf("submit-pdf-get")).toMatchObject({
|
|
582
|
+
type: "submit-form",
|
|
583
|
+
payload: {
|
|
584
|
+
url: "https://example.test/pdf",
|
|
585
|
+
fields: null,
|
|
586
|
+
flags: {
|
|
587
|
+
raw: 264,
|
|
588
|
+
format: "pdf",
|
|
589
|
+
method: "get"
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
expect(rootOf("launch-app")).toMatchObject({
|
|
594
|
+
type: "launch",
|
|
595
|
+
filePath: "app.exe"
|
|
596
|
+
});
|
|
597
|
+
expect(rootOf("gotor-file")).toMatchObject({
|
|
598
|
+
type: "goto-remote",
|
|
599
|
+
filePath: "other.pdf"
|
|
600
|
+
});
|
|
601
|
+
const chain = rootOf("chain-js-goto-hide");
|
|
602
|
+
expect(chain).toMatchObject({
|
|
603
|
+
type: "javascript",
|
|
604
|
+
script: "app.alert('chain');"
|
|
605
|
+
});
|
|
606
|
+
expect(chain?.next[0]).toMatchObject({
|
|
607
|
+
type: "goto",
|
|
608
|
+
destination: {
|
|
609
|
+
kind: "xyz",
|
|
610
|
+
pageObjectNumber: pon,
|
|
611
|
+
left: 5,
|
|
612
|
+
top: 10,
|
|
613
|
+
zoom: 1.25
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
expect(chain?.next[0]?.next[0]).toMatchObject({
|
|
617
|
+
type: "hide",
|
|
618
|
+
targets: [{
|
|
619
|
+
kind: "name",
|
|
620
|
+
name: "note1"
|
|
621
|
+
}],
|
|
622
|
+
hide: true
|
|
623
|
+
});
|
|
624
|
+
} finally {
|
|
625
|
+
await doc.close();
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
test("degrades unreadable payloads to unknown with payload-dropped", async () => {
|
|
629
|
+
const doc = await open(engine, opts, opts.fixtures.payloads);
|
|
630
|
+
try {
|
|
631
|
+
const page = (await doc.pages.list()).pages[0];
|
|
632
|
+
const snapshot = await doc.page(page.pageObjectNumber).annotations.list();
|
|
633
|
+
for (const [nm, subtype] of [
|
|
634
|
+
["goto-malformed", "GoTo"],
|
|
635
|
+
["hide-partial", "Hide"],
|
|
636
|
+
["submit-not-url", "SubmitForm"],
|
|
637
|
+
["submit-no-f", "SubmitForm"]
|
|
638
|
+
]) {
|
|
639
|
+
const annotation = snapshot.annotations.find((candidate) => candidate.nm === nm);
|
|
640
|
+
const tree = annotation?.actions?.activate;
|
|
641
|
+
expect(tree?.root).toMatchObject({
|
|
642
|
+
type: "unknown",
|
|
643
|
+
subtype
|
|
644
|
+
});
|
|
645
|
+
expect(tree?.warnings ?? []).toContain("payload-dropped");
|
|
646
|
+
if (annotation?.subtype === "link") expect(annotation.target).toEqual({ kind: "unsupported" });
|
|
647
|
+
}
|
|
648
|
+
} finally {
|
|
649
|
+
await doc.close();
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
test("reads a destination-form /OpenAction as openDestination", async () => {
|
|
653
|
+
const doc = await open(engine, opts, opts.fixtures.openDestination);
|
|
654
|
+
try {
|
|
655
|
+
expect(Boolean(doc.actions)).toBe(true);
|
|
656
|
+
const snapshot = await doc.actions.read();
|
|
657
|
+
expect(DocumentActionsSnapshotSchema.safeParse(snapshot).success).toBe(true);
|
|
658
|
+
expect(snapshot.openAction).toBeNull();
|
|
659
|
+
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
660
|
+
expect(snapshot.openDestination).toEqual({
|
|
661
|
+
kind: "xyz",
|
|
662
|
+
pageObjectNumber: pon,
|
|
663
|
+
left: 10,
|
|
664
|
+
top: 700,
|
|
665
|
+
zoom: 1.5
|
|
666
|
+
});
|
|
667
|
+
} finally {
|
|
668
|
+
await doc.close();
|
|
669
|
+
}
|
|
670
|
+
});
|
|
460
671
|
});
|
|
461
672
|
}
|
|
462
673
|
async function open(engine, opts, fixture) {
|
|
@@ -597,7 +808,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
597
808
|
if (engine) await engine.destroy();
|
|
598
809
|
});
|
|
599
810
|
test("create appends without shifting indices and leaves weak refs valid", async () => {
|
|
600
|
-
const doc = await openFixture$
|
|
811
|
+
const doc = await openFixture$18(engine, opts);
|
|
601
812
|
try {
|
|
602
813
|
const page = doc.page(fix.pageObjectNumber);
|
|
603
814
|
const before = await page.annotations.list();
|
|
@@ -633,7 +844,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
633
844
|
}
|
|
634
845
|
});
|
|
635
846
|
test("create + update honor annotation flags (set on create, merge on patch)", async () => {
|
|
636
|
-
const doc = await openFixture$
|
|
847
|
+
const doc = await openFixture$18(engine, opts);
|
|
637
848
|
try {
|
|
638
849
|
const page = doc.page(fix.pageObjectNumber);
|
|
639
850
|
const draft = {
|
|
@@ -668,7 +879,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
668
879
|
}
|
|
669
880
|
});
|
|
670
881
|
test("create shape annotations (circle + square) round-trip shape fields", async () => {
|
|
671
|
-
const doc = await openFixture$
|
|
882
|
+
const doc = await openFixture$18(engine, opts);
|
|
672
883
|
try {
|
|
673
884
|
const page = doc.page(fix.pageObjectNumber);
|
|
674
885
|
const circleDraft = {
|
|
@@ -749,7 +960,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
749
960
|
}
|
|
750
961
|
});
|
|
751
962
|
test("cloudy border (/BE) + rect differences (/RD) are tri-state", async () => {
|
|
752
|
-
const doc = await openFixture$
|
|
963
|
+
const doc = await openFixture$18(engine, opts);
|
|
753
964
|
try {
|
|
754
965
|
const page = doc.page(fix.pageObjectNumber);
|
|
755
966
|
const plainDraft = {
|
|
@@ -828,7 +1039,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
828
1039
|
}
|
|
829
1040
|
});
|
|
830
1041
|
test("update echoes the appearance verdict: moves preserve /AP, restyles re-bake", async () => {
|
|
831
|
-
const doc = await openFixture$
|
|
1042
|
+
const doc = await openFixture$18(engine, opts);
|
|
832
1043
|
try {
|
|
833
1044
|
const page = doc.page(fix.pageObjectNumber);
|
|
834
1045
|
const draft = {
|
|
@@ -903,7 +1114,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
903
1114
|
}
|
|
904
1115
|
});
|
|
905
1116
|
test("a partial /DA patch preserves the unpatched font members", async () => {
|
|
906
|
-
const doc = await openFixture$
|
|
1117
|
+
const doc = await openFixture$18(engine, opts);
|
|
907
1118
|
try {
|
|
908
1119
|
const page = doc.page(fix.pageObjectNumber);
|
|
909
1120
|
const draft = {
|
|
@@ -959,7 +1170,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
959
1170
|
}
|
|
960
1171
|
});
|
|
961
1172
|
test("box transform is tri-state: rect-only moves keep rotation, null flattens", async () => {
|
|
962
|
-
const doc = await openFixture$
|
|
1173
|
+
const doc = await openFixture$18(engine, opts);
|
|
963
1174
|
try {
|
|
964
1175
|
const page = doc.page(fix.pageObjectNumber);
|
|
965
1176
|
const draft = {
|
|
@@ -1020,7 +1231,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1020
1231
|
}
|
|
1021
1232
|
});
|
|
1022
1233
|
test("create vertex + line annotations (polygon/polyline/line) round-trip geometry", async () => {
|
|
1023
|
-
const doc = await openFixture$
|
|
1234
|
+
const doc = await openFixture$18(engine, opts);
|
|
1024
1235
|
try {
|
|
1025
1236
|
const page = doc.page(fix.pageObjectNumber);
|
|
1026
1237
|
const polygonDraft = {
|
|
@@ -1151,7 +1362,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1151
1362
|
}
|
|
1152
1363
|
});
|
|
1153
1364
|
test("create free-text + callout round-trip text/colour/intent fields", async () => {
|
|
1154
|
-
const doc = await openFixture$
|
|
1365
|
+
const doc = await openFixture$18(engine, opts);
|
|
1155
1366
|
try {
|
|
1156
1367
|
const page = doc.page(fix.pageObjectNumber);
|
|
1157
1368
|
const freeTextDraft = {
|
|
@@ -1247,7 +1458,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1247
1458
|
}
|
|
1248
1459
|
});
|
|
1249
1460
|
test("update a free-text patches alignment + colours and is non-structural", async () => {
|
|
1250
|
-
const doc = await openFixture$
|
|
1461
|
+
const doc = await openFixture$18(engine, opts);
|
|
1251
1462
|
try {
|
|
1252
1463
|
const page = doc.page(fix.pageObjectNumber);
|
|
1253
1464
|
const created = await page.annotations.create({
|
|
@@ -1308,7 +1519,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1308
1519
|
}
|
|
1309
1520
|
});
|
|
1310
1521
|
test("create redact (area + text) round-trips label + colour fields", async () => {
|
|
1311
|
-
const doc = await openFixture$
|
|
1522
|
+
const doc = await openFixture$18(engine, opts);
|
|
1312
1523
|
try {
|
|
1313
1524
|
const page = doc.page(fix.pageObjectNumber);
|
|
1314
1525
|
const areaDraft = {
|
|
@@ -1388,7 +1599,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1388
1599
|
}
|
|
1389
1600
|
});
|
|
1390
1601
|
test("update a redact patches the label and clears it, non-structurally", async () => {
|
|
1391
|
-
const doc = await openFixture$
|
|
1602
|
+
const doc = await openFixture$18(engine, opts);
|
|
1392
1603
|
try {
|
|
1393
1604
|
const page = doc.page(fix.pageObjectNumber);
|
|
1394
1605
|
const created = await page.annotations.create({
|
|
@@ -1465,7 +1676,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1465
1676
|
}
|
|
1466
1677
|
});
|
|
1467
1678
|
test("create + update a caret round-trips color/opacity/rect differences", async () => {
|
|
1468
|
-
const doc = await openFixture$
|
|
1679
|
+
const doc = await openFixture$18(engine, opts);
|
|
1469
1680
|
try {
|
|
1470
1681
|
const page = doc.page(fix.pageObjectNumber);
|
|
1471
1682
|
const caretDraft = {
|
|
@@ -1545,7 +1756,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1545
1756
|
}
|
|
1546
1757
|
});
|
|
1547
1758
|
test("update an ink annotation patches strokes + color and is non-structural", async () => {
|
|
1548
|
-
const doc = await openFixture$
|
|
1759
|
+
const doc = await openFixture$18(engine, opts);
|
|
1549
1760
|
try {
|
|
1550
1761
|
const page = doc.page(fix.pageObjectNumber);
|
|
1551
1762
|
const created = await page.annotations.create({
|
|
@@ -1596,7 +1807,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1596
1807
|
}
|
|
1597
1808
|
});
|
|
1598
1809
|
test("ink highlight intent + blend round-trip and unrelated patches preserve blend", async () => {
|
|
1599
|
-
const doc = await openFixture$
|
|
1810
|
+
const doc = await openFixture$18(engine, opts);
|
|
1600
1811
|
try {
|
|
1601
1812
|
const page = doc.page(fix.pageObjectNumber);
|
|
1602
1813
|
const created = await page.annotations.create({
|
|
@@ -1639,7 +1850,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1639
1850
|
}
|
|
1640
1851
|
});
|
|
1641
1852
|
test("update a polyline patches vertices + line endings and is non-structural", async () => {
|
|
1642
|
-
const doc = await openFixture$
|
|
1853
|
+
const doc = await openFixture$18(engine, opts);
|
|
1643
1854
|
try {
|
|
1644
1855
|
const page = doc.page(fix.pageObjectNumber);
|
|
1645
1856
|
const created = await page.annotations.create({
|
|
@@ -1688,7 +1899,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1688
1899
|
}
|
|
1689
1900
|
});
|
|
1690
1901
|
test("update a shape annotation patches color and is non-structural", async () => {
|
|
1691
|
-
const doc = await openFixture$
|
|
1902
|
+
const doc = await openFixture$18(engine, opts);
|
|
1692
1903
|
try {
|
|
1693
1904
|
const page = doc.page(fix.pageObjectNumber);
|
|
1694
1905
|
const created = await page.annotations.create({
|
|
@@ -1737,7 +1948,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1737
1948
|
}
|
|
1738
1949
|
});
|
|
1739
1950
|
if (opts.supportsAppearanceRasters) test("creating a shape bakes an /AP appearance the reader can rasterize", async () => {
|
|
1740
|
-
const doc = await openFixture$
|
|
1951
|
+
const doc = await openFixture$18(engine, opts);
|
|
1741
1952
|
try {
|
|
1742
1953
|
const page = doc.page(fix.pageObjectNumber);
|
|
1743
1954
|
const created = await page.annotations.create({
|
|
@@ -1767,7 +1978,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1767
1978
|
}
|
|
1768
1979
|
});
|
|
1769
1980
|
test("update on a durable annotation is non-structural and never touches /NM", async () => {
|
|
1770
|
-
const doc = await openFixture$
|
|
1981
|
+
const doc = await openFixture$18(engine, opts);
|
|
1771
1982
|
try {
|
|
1772
1983
|
const page = doc.page(fix.pageObjectNumber);
|
|
1773
1984
|
const before = await page.annotations.list();
|
|
@@ -1793,7 +2004,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1793
2004
|
}
|
|
1794
2005
|
});
|
|
1795
2006
|
if (fix.expectsWeakAnnotation) test("update on a weak annotation stamps a UUID v4 /NM and upgrades the ref", async () => {
|
|
1796
|
-
const doc = await openFixture$
|
|
2007
|
+
const doc = await openFixture$18(engine, opts);
|
|
1797
2008
|
try {
|
|
1798
2009
|
const page = doc.page(fix.pageObjectNumber);
|
|
1799
2010
|
const before = await page.annotations.list();
|
|
@@ -1823,7 +2034,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1823
2034
|
}
|
|
1824
2035
|
});
|
|
1825
2036
|
test("delete by objectNumber removes the annotation and reports a stable id", async () => {
|
|
1826
|
-
const doc = await openFixture$
|
|
2037
|
+
const doc = await openFixture$18(engine, opts);
|
|
1827
2038
|
try {
|
|
1828
2039
|
const page = doc.page(fix.pageObjectNumber);
|
|
1829
2040
|
const draft = {
|
|
@@ -1853,7 +2064,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1853
2064
|
}
|
|
1854
2065
|
});
|
|
1855
2066
|
if (fix.expectsWeakAnnotation) test("delete by index of a weak annotation reports deleted: null and refetch reason", async () => {
|
|
1856
|
-
const doc = await openFixture$
|
|
2067
|
+
const doc = await openFixture$18(engine, opts);
|
|
1857
2068
|
try {
|
|
1858
2069
|
const page = doc.page(fix.pageObjectNumber);
|
|
1859
2070
|
const weak = (await page.annotations.list()).annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -1876,7 +2087,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1876
2087
|
}
|
|
1877
2088
|
});
|
|
1878
2089
|
test("abort on create rejects with AbortError", async () => {
|
|
1879
|
-
const doc = await openFixture$
|
|
2090
|
+
const doc = await openFixture$18(engine, opts);
|
|
1880
2091
|
try {
|
|
1881
2092
|
const page = doc.page(fix.pageObjectNumber);
|
|
1882
2093
|
const draft = {
|
|
@@ -1892,7 +2103,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1892
2103
|
}
|
|
1893
2104
|
});
|
|
1894
2105
|
test("update with a stale index revision throws InvalidReference", async () => {
|
|
1895
|
-
const doc = await openFixture$
|
|
2106
|
+
const doc = await openFixture$18(engine, opts);
|
|
1896
2107
|
try {
|
|
1897
2108
|
const page = doc.page(fix.pageObjectNumber);
|
|
1898
2109
|
const weak = (await page.annotations.list()).annotations.find((a) => a.identityQuality === "weak");
|
|
@@ -1919,7 +2130,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1919
2130
|
}
|
|
1920
2131
|
});
|
|
1921
2132
|
test("move single durable annotation reorders within the page (single-as-batch)", async () => {
|
|
1922
|
-
const doc = await openFixture$
|
|
2133
|
+
const doc = await openFixture$18(engine, opts);
|
|
1923
2134
|
try {
|
|
1924
2135
|
const page = doc.page(fix.pageObjectNumber);
|
|
1925
2136
|
const aDraft = {
|
|
@@ -1963,7 +2174,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
1963
2174
|
}
|
|
1964
2175
|
});
|
|
1965
2176
|
test("move multi-block preserves caller-supplied order at the destination", async () => {
|
|
1966
|
-
const doc = await openFixture$
|
|
2177
|
+
const doc = await openFixture$18(engine, opts);
|
|
1967
2178
|
try {
|
|
1968
2179
|
const page = doc.page(fix.pageObjectNumber);
|
|
1969
2180
|
const ids = await Promise.all([
|
|
@@ -2002,7 +2213,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2002
2213
|
}
|
|
2003
2214
|
});
|
|
2004
2215
|
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$
|
|
2216
|
+
const doc = await openFixture$18(engine, opts);
|
|
2006
2217
|
try {
|
|
2007
2218
|
const page = doc.page(fix.pageObjectNumber);
|
|
2008
2219
|
const before = await page.annotations.list();
|
|
@@ -2027,7 +2238,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2027
2238
|
}
|
|
2028
2239
|
});
|
|
2029
2240
|
test("move with a stale index revision rejects (locked rev-token guard)", async () => {
|
|
2030
|
-
const doc = await openFixture$
|
|
2241
|
+
const doc = await openFixture$18(engine, opts);
|
|
2031
2242
|
try {
|
|
2032
2243
|
const page = doc.page(fix.pageObjectNumber);
|
|
2033
2244
|
const a = await page.annotations.create({
|
|
@@ -2065,7 +2276,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2065
2276
|
}
|
|
2066
2277
|
});
|
|
2067
2278
|
test("move with out-of-range toIndex rejects with InvalidArg", async () => {
|
|
2068
|
-
const doc = await openFixture$
|
|
2279
|
+
const doc = await openFixture$18(engine, opts);
|
|
2069
2280
|
try {
|
|
2070
2281
|
const page = doc.page(fix.pageObjectNumber);
|
|
2071
2282
|
const a = await page.annotations.create({
|
|
@@ -2089,7 +2300,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2089
2300
|
}
|
|
2090
2301
|
});
|
|
2091
2302
|
test("move with duplicate refs rejects with InvalidArg", async () => {
|
|
2092
|
-
const doc = await openFixture$
|
|
2303
|
+
const doc = await openFixture$18(engine, opts);
|
|
2093
2304
|
try {
|
|
2094
2305
|
const page = doc.page(fix.pageObjectNumber);
|
|
2095
2306
|
const a = await page.annotations.create({
|
|
@@ -2112,7 +2323,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2112
2323
|
}
|
|
2113
2324
|
});
|
|
2114
2325
|
test("abort on move rejects with AbortError", async () => {
|
|
2115
|
-
const doc = await openFixture$
|
|
2326
|
+
const doc = await openFixture$18(engine, opts);
|
|
2116
2327
|
try {
|
|
2117
2328
|
const page = doc.page(fix.pageObjectNumber);
|
|
2118
2329
|
const a = await page.annotations.create({
|
|
@@ -2133,7 +2344,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2133
2344
|
}
|
|
2134
2345
|
});
|
|
2135
2346
|
test("a page move does NOT bump per-page RevisionTokens (weak refs survive reorder)", async () => {
|
|
2136
|
-
const doc = await openFixture$
|
|
2347
|
+
const doc = await openFixture$18(engine, opts);
|
|
2137
2348
|
try {
|
|
2138
2349
|
const list = await doc.pages.list();
|
|
2139
2350
|
if (list.pages.length < 1) return;
|
|
@@ -2148,7 +2359,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2148
2359
|
}
|
|
2149
2360
|
});
|
|
2150
2361
|
test("create a reply links /IRT and defaults /RT to \"reply\", reporting the parent", async () => {
|
|
2151
|
-
const doc = await openFixture$
|
|
2362
|
+
const doc = await openFixture$18(engine, opts);
|
|
2152
2363
|
try {
|
|
2153
2364
|
const page = doc.page(fix.pageObjectNumber);
|
|
2154
2365
|
const parent = await page.annotations.create({
|
|
@@ -2182,7 +2393,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2182
2393
|
}
|
|
2183
2394
|
});
|
|
2184
2395
|
test("create a grouped subordinate writes /RT /Group", async () => {
|
|
2185
|
-
const doc = await openFixture$
|
|
2396
|
+
const doc = await openFixture$18(engine, opts);
|
|
2186
2397
|
try {
|
|
2187
2398
|
const page = doc.page(fix.pageObjectNumber);
|
|
2188
2399
|
const primary = await page.annotations.create({
|
|
@@ -2213,7 +2424,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2213
2424
|
}
|
|
2214
2425
|
});
|
|
2215
2426
|
test("create link annotations round-trip uri, goto/xyz, goto/fitH, and dead targets", async () => {
|
|
2216
|
-
const doc = await openFixture$
|
|
2427
|
+
const doc = await openFixture$18(engine, opts);
|
|
2217
2428
|
try {
|
|
2218
2429
|
const page = doc.page(fix.pageObjectNumber);
|
|
2219
2430
|
const uri = await page.annotations.create({
|
|
@@ -2290,7 +2501,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2290
2501
|
}
|
|
2291
2502
|
});
|
|
2292
2503
|
test("a link patch retargets in both directions (uri→goto, goto→uri) and moves the rect", async () => {
|
|
2293
|
-
const doc = await openFixture$
|
|
2504
|
+
const doc = await openFixture$18(engine, opts);
|
|
2294
2505
|
try {
|
|
2295
2506
|
const page = doc.page(fix.pageObjectNumber);
|
|
2296
2507
|
const created = await page.annotations.create({
|
|
@@ -2345,7 +2556,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2345
2556
|
}
|
|
2346
2557
|
});
|
|
2347
2558
|
test("a link patch clears the target with null — a dead link on re-read", async () => {
|
|
2348
|
-
const doc = await openFixture$
|
|
2559
|
+
const doc = await openFixture$18(engine, opts);
|
|
2349
2560
|
try {
|
|
2350
2561
|
const page = doc.page(fix.pageObjectNumber);
|
|
2351
2562
|
const created = await page.annotations.create({
|
|
@@ -2384,7 +2595,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2384
2595
|
}
|
|
2385
2596
|
});
|
|
2386
2597
|
test("a link grouped to a highlight round-trips /IRT + /RT /Group with its target", async () => {
|
|
2387
|
-
const doc = await openFixture$
|
|
2598
|
+
const doc = await openFixture$18(engine, opts);
|
|
2388
2599
|
try {
|
|
2389
2600
|
const page = doc.page(fix.pageObjectNumber);
|
|
2390
2601
|
const parent = await page.annotations.create({
|
|
@@ -2418,7 +2629,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2418
2629
|
}
|
|
2419
2630
|
});
|
|
2420
2631
|
test("replace-text round-trips /IT and groups StrikeOut under its Caret", async () => {
|
|
2421
|
-
const doc = await openFixture$
|
|
2632
|
+
const doc = await openFixture$18(engine, opts);
|
|
2422
2633
|
try {
|
|
2423
2634
|
const page = doc.page(fix.pageObjectNumber);
|
|
2424
2635
|
const caret = await page.annotations.create({
|
|
@@ -2470,7 +2681,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2470
2681
|
}
|
|
2471
2682
|
});
|
|
2472
2683
|
test("patch inReplyTo: null clears /IRT and /RT (back to top-level)", async () => {
|
|
2473
|
-
const doc = await openFixture$
|
|
2684
|
+
const doc = await openFixture$18(engine, opts);
|
|
2474
2685
|
try {
|
|
2475
2686
|
const page = doc.page(fix.pageObjectNumber);
|
|
2476
2687
|
const parent = await page.annotations.create({
|
|
@@ -2497,7 +2708,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2497
2708
|
}
|
|
2498
2709
|
});
|
|
2499
2710
|
test("create with a cross-page /IRT parent throws InvalidArg", async () => {
|
|
2500
|
-
const doc = await openFixture$
|
|
2711
|
+
const doc = await openFixture$18(engine, opts);
|
|
2501
2712
|
try {
|
|
2502
2713
|
const page = doc.page(fix.pageObjectNumber);
|
|
2503
2714
|
const parent = await page.annotations.create({
|
|
@@ -2528,7 +2739,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2528
2739
|
}
|
|
2529
2740
|
});
|
|
2530
2741
|
test("a review-status reply round-trips /State + /StateModel + /Subj", async () => {
|
|
2531
|
-
const doc = await openFixture$
|
|
2742
|
+
const doc = await openFixture$18(engine, opts);
|
|
2532
2743
|
try {
|
|
2533
2744
|
const page = doc.page(fix.pageObjectNumber);
|
|
2534
2745
|
const target = await page.annotations.create({
|
|
@@ -2562,7 +2773,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2562
2773
|
}
|
|
2563
2774
|
});
|
|
2564
2775
|
test("a draft /State without /StateModel is rejected with InvalidArg", async () => {
|
|
2565
|
-
const doc = await openFixture$
|
|
2776
|
+
const doc = await openFixture$18(engine, opts);
|
|
2566
2777
|
try {
|
|
2567
2778
|
const page = doc.page(fix.pageObjectNumber);
|
|
2568
2779
|
let caught;
|
|
@@ -2581,7 +2792,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2581
2792
|
}
|
|
2582
2793
|
});
|
|
2583
2794
|
test("null-clear patches truly remove /State, /StateModel, /Subj and /Contents", async () => {
|
|
2584
|
-
const doc = await openFixture$
|
|
2795
|
+
const doc = await openFixture$18(engine, opts);
|
|
2585
2796
|
try {
|
|
2586
2797
|
const page = doc.page(fix.pageObjectNumber);
|
|
2587
2798
|
const note = await page.annotations.create({
|
|
@@ -2628,7 +2839,7 @@ function runAnnotationMutationConformance(runner, opts) {
|
|
|
2628
2839
|
}
|
|
2629
2840
|
});
|
|
2630
2841
|
test("custom state models round-trip verbatim", async () => {
|
|
2631
|
-
const doc = await openFixture$
|
|
2842
|
+
const doc = await openFixture$18(engine, opts);
|
|
2632
2843
|
try {
|
|
2633
2844
|
const page = doc.page(fix.pageObjectNumber);
|
|
2634
2845
|
const custom = await page.annotations.create({
|
|
@@ -2656,7 +2867,7 @@ async function beginWeakEditIfRequired(doc, pageObjectNumber, fix) {
|
|
|
2656
2867
|
if (doc.capabilities.weakAnnotationEditSessions !== "required" || !fix.expectsWeakAnnotation) return null;
|
|
2657
2868
|
return doc.annotations.beginWeakEdit([pageObjectNumber]);
|
|
2658
2869
|
}
|
|
2659
|
-
async function openFixture$
|
|
2870
|
+
async function openFixture$18(engine, opts) {
|
|
2660
2871
|
if (opts.openKind === "bytes") {
|
|
2661
2872
|
const bytes = await opts.fixture.bytes();
|
|
2662
2873
|
return engine.open({
|
|
@@ -3246,7 +3457,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3246
3457
|
if (engine) await engine.destroy();
|
|
3247
3458
|
});
|
|
3248
3459
|
test("renders the expected set of appearances with valid output", async () => {
|
|
3249
|
-
const doc = await openFixture$
|
|
3460
|
+
const doc = await openFixture$17(engine, opts);
|
|
3250
3461
|
try {
|
|
3251
3462
|
const { pageState, appearances } = await collect(doc, opts, useRaw);
|
|
3252
3463
|
expect(pageState.pageObjectNumber).toBe(opts.fixture.pageObjectNumber);
|
|
@@ -3273,7 +3484,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3273
3484
|
}
|
|
3274
3485
|
});
|
|
3275
3486
|
if (opts.fixture.expectsWeakAppearance) test("weak (index-only) annotations are emitted, not dropped", async () => {
|
|
3276
|
-
const doc = await openFixture$
|
|
3487
|
+
const doc = await openFixture$17(engine, opts);
|
|
3277
3488
|
try {
|
|
3278
3489
|
const { appearances } = await collect(doc, opts, useRaw);
|
|
3279
3490
|
const weak = appearances.find((a) => a.ref.kind === "index");
|
|
@@ -3283,7 +3494,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3283
3494
|
}
|
|
3284
3495
|
});
|
|
3285
3496
|
if (useRaw) test("rendered appearances are not blank (non-zero alpha)", async () => {
|
|
3286
|
-
const doc = await openFixture$
|
|
3497
|
+
const doc = await openFixture$17(engine, opts);
|
|
3287
3498
|
try {
|
|
3288
3499
|
const { appearances } = await collect(doc, opts, useRaw);
|
|
3289
3500
|
const anyVisible = appearances.some((a) => a.raster !== null && hasOpaquePixel(a.raster));
|
|
@@ -3293,7 +3504,7 @@ function runAnnotationAppearanceConformance(runner, opts) {
|
|
|
3293
3504
|
}
|
|
3294
3505
|
});
|
|
3295
3506
|
test("abort() rejects with AbortError", async () => {
|
|
3296
|
-
const doc = await openFixture$
|
|
3507
|
+
const doc = await openFixture$17(engine, opts);
|
|
3297
3508
|
try {
|
|
3298
3509
|
const page = doc.page(opts.fixture.pageObjectNumber);
|
|
3299
3510
|
const p = useRaw ? page.annotations.renderAppearances({ scale: 1 }) : page.annotations.renderAppearanceImages({
|
|
@@ -3348,7 +3559,7 @@ function hasOpaquePixel(raster) {
|
|
|
3348
3559
|
}
|
|
3349
3560
|
return false;
|
|
3350
3561
|
}
|
|
3351
|
-
async function openFixture$
|
|
3562
|
+
async function openFixture$17(engine, opts) {
|
|
3352
3563
|
if (opts.openKind === "bytes") {
|
|
3353
3564
|
const bytes = await opts.fixture.bytes();
|
|
3354
3565
|
return engine.open({
|
|
@@ -3417,7 +3628,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3417
3628
|
if (engine) await engine.destroy();
|
|
3418
3629
|
});
|
|
3419
3630
|
test("pages.list() returns every page in display order, durable PONs only", async () => {
|
|
3420
|
-
const doc = await openFixture$
|
|
3631
|
+
const doc = await openFixture$16(engine, opts);
|
|
3421
3632
|
try {
|
|
3422
3633
|
const list = await doc.pages.list();
|
|
3423
3634
|
expect(PageListSnapshotSchema.safeParse(list).success).toBe(true);
|
|
@@ -3436,7 +3647,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3436
3647
|
}
|
|
3437
3648
|
});
|
|
3438
3649
|
test("pages.move() reorders pages and returns the full post-move order", async () => {
|
|
3439
|
-
const doc = await openFixture$
|
|
3650
|
+
const doc = await openFixture$16(engine, opts);
|
|
3440
3651
|
try {
|
|
3441
3652
|
const before = await doc.pages.list();
|
|
3442
3653
|
if (before.pages.length < 3) return;
|
|
@@ -3460,7 +3671,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3460
3671
|
}
|
|
3461
3672
|
});
|
|
3462
3673
|
test("weak index-based annotation refs survive a page reorder", async () => {
|
|
3463
|
-
const doc = await openFixture$
|
|
3674
|
+
const doc = await openFixture$16(engine, opts);
|
|
3464
3675
|
try {
|
|
3465
3676
|
const list = await doc.pages.list();
|
|
3466
3677
|
if (list.pages.length < 2) return;
|
|
@@ -3497,7 +3708,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3497
3708
|
}
|
|
3498
3709
|
});
|
|
3499
3710
|
test("pages.move() rejects duplicate PONs with InvalidArg", async () => {
|
|
3500
|
-
const doc = await openFixture$
|
|
3711
|
+
const doc = await openFixture$16(engine, opts);
|
|
3501
3712
|
try {
|
|
3502
3713
|
const list = await doc.pages.list();
|
|
3503
3714
|
if (list.pages.length < 1) return;
|
|
@@ -3514,7 +3725,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3514
3725
|
}
|
|
3515
3726
|
});
|
|
3516
3727
|
test("pages.move() rejects out-of-range destIndex with InvalidArg", async () => {
|
|
3517
|
-
const doc = await openFixture$
|
|
3728
|
+
const doc = await openFixture$16(engine, opts);
|
|
3518
3729
|
try {
|
|
3519
3730
|
const list = await doc.pages.list();
|
|
3520
3731
|
if (list.pages.length < 1) return;
|
|
@@ -3531,7 +3742,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3531
3742
|
}
|
|
3532
3743
|
});
|
|
3533
3744
|
test("pages.move() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3534
|
-
const doc = await openFixture$
|
|
3745
|
+
const doc = await openFixture$16(engine, opts);
|
|
3535
3746
|
try {
|
|
3536
3747
|
const list = await doc.pages.list();
|
|
3537
3748
|
let bogus = 0;
|
|
@@ -3549,7 +3760,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3549
3760
|
}
|
|
3550
3761
|
});
|
|
3551
3762
|
test("abort on pages.move() rejects with AbortError", async () => {
|
|
3552
|
-
const doc = await openFixture$
|
|
3763
|
+
const doc = await openFixture$16(engine, opts);
|
|
3553
3764
|
try {
|
|
3554
3765
|
const list = await doc.pages.list();
|
|
3555
3766
|
if (list.pages.length < 1) return;
|
|
@@ -3563,7 +3774,7 @@ function runPageReorderConformance(runner, opts) {
|
|
|
3563
3774
|
});
|
|
3564
3775
|
});
|
|
3565
3776
|
}
|
|
3566
|
-
async function openFixture$
|
|
3777
|
+
async function openFixture$16(engine, opts) {
|
|
3567
3778
|
if (opts.openKind === "bytes") {
|
|
3568
3779
|
const bytes = await opts.fixture.bytes();
|
|
3569
3780
|
return engine.open({
|
|
@@ -3637,7 +3848,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3637
3848
|
if (engine) await engine.destroy();
|
|
3638
3849
|
});
|
|
3639
3850
|
test("pages.rotate() sets the absolute rotation and returns the full layout", async () => {
|
|
3640
|
-
const doc = await openFixture$
|
|
3851
|
+
const doc = await openFixture$15(engine, opts);
|
|
3641
3852
|
try {
|
|
3642
3853
|
const before = await doc.pages.list();
|
|
3643
3854
|
const target = before.pages[0];
|
|
@@ -3656,7 +3867,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3656
3867
|
}
|
|
3657
3868
|
});
|
|
3658
3869
|
test("absolute rotation is idempotent: setting the same value twice is a no-op", async () => {
|
|
3659
|
-
const doc = await openFixture$
|
|
3870
|
+
const doc = await openFixture$15(engine, opts);
|
|
3660
3871
|
try {
|
|
3661
3872
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3662
3873
|
const first = await doc.pages.rotate([pon], 180);
|
|
@@ -3667,7 +3878,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3667
3878
|
}
|
|
3668
3879
|
});
|
|
3669
3880
|
test("one rotation applies to EVERY listed page (the multi-select gesture)", async () => {
|
|
3670
|
-
const doc = await openFixture$
|
|
3881
|
+
const doc = await openFixture$15(engine, opts);
|
|
3671
3882
|
try {
|
|
3672
3883
|
const list = await doc.pages.list();
|
|
3673
3884
|
if (list.pages.length < 2) return;
|
|
@@ -3679,7 +3890,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3679
3890
|
}
|
|
3680
3891
|
});
|
|
3681
3892
|
test("weak index-based annotation refs survive a rotate (no revision bump)", async () => {
|
|
3682
|
-
const doc = await openFixture$
|
|
3893
|
+
const doc = await openFixture$15(engine, opts);
|
|
3683
3894
|
try {
|
|
3684
3895
|
const hostPon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3685
3896
|
const hostPage = doc.page(hostPon);
|
|
@@ -3709,7 +3920,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3709
3920
|
}
|
|
3710
3921
|
});
|
|
3711
3922
|
test("pages.rotate() rejects an invalid rotation value with InvalidArg", async () => {
|
|
3712
|
-
const doc = await openFixture$
|
|
3923
|
+
const doc = await openFixture$15(engine, opts);
|
|
3713
3924
|
try {
|
|
3714
3925
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3715
3926
|
let caught;
|
|
@@ -3724,7 +3935,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3724
3935
|
}
|
|
3725
3936
|
});
|
|
3726
3937
|
test("pages.rotate() rejects duplicate PONs with InvalidArg", async () => {
|
|
3727
|
-
const doc = await openFixture$
|
|
3938
|
+
const doc = await openFixture$15(engine, opts);
|
|
3728
3939
|
try {
|
|
3729
3940
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3730
3941
|
let caught;
|
|
@@ -3739,7 +3950,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3739
3950
|
}
|
|
3740
3951
|
});
|
|
3741
3952
|
test("pages.rotate() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3742
|
-
const doc = await openFixture$
|
|
3953
|
+
const doc = await openFixture$15(engine, opts);
|
|
3743
3954
|
try {
|
|
3744
3955
|
const list = await doc.pages.list();
|
|
3745
3956
|
let bogus = 0;
|
|
@@ -3757,7 +3968,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3757
3968
|
}
|
|
3758
3969
|
});
|
|
3759
3970
|
test("abort on pages.rotate() rejects with AbortError", async () => {
|
|
3760
|
-
const doc = await openFixture$
|
|
3971
|
+
const doc = await openFixture$15(engine, opts);
|
|
3761
3972
|
try {
|
|
3762
3973
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3763
3974
|
const p = doc.pages.rotate([pon], 90);
|
|
@@ -3769,7 +3980,7 @@ function runPageRotateConformance(runner, opts) {
|
|
|
3769
3980
|
});
|
|
3770
3981
|
});
|
|
3771
3982
|
}
|
|
3772
|
-
async function openFixture$
|
|
3983
|
+
async function openFixture$15(engine, opts) {
|
|
3773
3984
|
if (opts.openKind === "bytes") {
|
|
3774
3985
|
const bytes = await opts.fixture.bytes();
|
|
3775
3986
|
return engine.open({
|
|
@@ -3832,7 +4043,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3832
4043
|
if (engine) await engine.destroy();
|
|
3833
4044
|
});
|
|
3834
4045
|
test("pages.delete() removes the page and returns the surviving layout", async () => {
|
|
3835
|
-
const doc = await openFixture$
|
|
4046
|
+
const doc = await openFixture$14(engine, opts);
|
|
3836
4047
|
try {
|
|
3837
4048
|
const before = await doc.pages.list();
|
|
3838
4049
|
if (before.pages.length < 2) return;
|
|
@@ -3853,7 +4064,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3853
4064
|
}
|
|
3854
4065
|
});
|
|
3855
4066
|
test("addressing a deleted page afterwards is a clean NotFound", async () => {
|
|
3856
|
-
const doc = await openFixture$
|
|
4067
|
+
const doc = await openFixture$14(engine, opts);
|
|
3857
4068
|
try {
|
|
3858
4069
|
const before = await doc.pages.list();
|
|
3859
4070
|
if (before.pages.length < 2) return;
|
|
@@ -3871,7 +4082,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3871
4082
|
}
|
|
3872
4083
|
});
|
|
3873
4084
|
test("surviving pages keep their weak index-based annotation refs", async () => {
|
|
3874
|
-
const doc = await openFixture$
|
|
4085
|
+
const doc = await openFixture$14(engine, opts);
|
|
3875
4086
|
try {
|
|
3876
4087
|
const list = await doc.pages.list();
|
|
3877
4088
|
if (list.pages.length < 2) return;
|
|
@@ -3904,7 +4115,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3904
4115
|
}
|
|
3905
4116
|
});
|
|
3906
4117
|
test("deleting EVERY page is rejected with InvalidArg", async () => {
|
|
3907
|
-
const doc = await openFixture$
|
|
4118
|
+
const doc = await openFixture$14(engine, opts);
|
|
3908
4119
|
try {
|
|
3909
4120
|
const list = await doc.pages.list();
|
|
3910
4121
|
let caught;
|
|
@@ -3919,7 +4130,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3919
4130
|
}
|
|
3920
4131
|
});
|
|
3921
4132
|
test("pages.delete() rejects duplicate PONs with InvalidArg", async () => {
|
|
3922
|
-
const doc = await openFixture$
|
|
4133
|
+
const doc = await openFixture$14(engine, opts);
|
|
3923
4134
|
try {
|
|
3924
4135
|
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
3925
4136
|
let caught;
|
|
@@ -3934,7 +4145,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3934
4145
|
}
|
|
3935
4146
|
});
|
|
3936
4147
|
test("pages.delete() rejects unknown PON with NotFound or InvalidArg", async () => {
|
|
3937
|
-
const doc = await openFixture$
|
|
4148
|
+
const doc = await openFixture$14(engine, opts);
|
|
3938
4149
|
try {
|
|
3939
4150
|
const list = await doc.pages.list();
|
|
3940
4151
|
let bogus = 0;
|
|
@@ -3952,7 +4163,7 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3952
4163
|
}
|
|
3953
4164
|
});
|
|
3954
4165
|
test("abort on pages.delete() rejects with AbortError", async () => {
|
|
3955
|
-
const doc = await openFixture$
|
|
4166
|
+
const doc = await openFixture$14(engine, opts);
|
|
3956
4167
|
try {
|
|
3957
4168
|
const list = await doc.pages.list();
|
|
3958
4169
|
if (list.pages.length < 2) return;
|
|
@@ -3966,7 +4177,224 @@ function runPageDeleteConformance(runner, opts) {
|
|
|
3966
4177
|
});
|
|
3967
4178
|
});
|
|
3968
4179
|
}
|
|
3969
|
-
async function openFixture$
|
|
4180
|
+
async function openFixture$14(engine, opts) {
|
|
4181
|
+
if (opts.openKind === "bytes") {
|
|
4182
|
+
const bytes = await opts.fixture.bytes();
|
|
4183
|
+
return engine.open({
|
|
4184
|
+
kind: "bytes",
|
|
4185
|
+
id: opts.fixture.id,
|
|
4186
|
+
bytes
|
|
4187
|
+
});
|
|
4188
|
+
}
|
|
4189
|
+
return engine.open({
|
|
4190
|
+
kind: "id",
|
|
4191
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
4192
|
+
});
|
|
4193
|
+
}
|
|
4194
|
+
//#endregion
|
|
4195
|
+
//#region src/conformance/runNamedPagesConformance.ts
|
|
4196
|
+
/**
|
|
4197
|
+
* Named-pages conformance: the catalog's `/Names /Pages` registry as LAYOUT
|
|
4198
|
+
* data. Locks the invariants both engines must share — do not loosen
|
|
4199
|
+
* without re-reading `NamedPageEntry` and `PageNameResult`:
|
|
4200
|
+
*
|
|
4201
|
+
* 1. `pages.list().namedPages` is present (possibly empty) and every
|
|
4202
|
+
* registration resolves to a page in `pages`, a template, or is
|
|
4203
|
+
* reported dangling — never silently dropped.
|
|
4204
|
+
* 2. `pages.setName()` creates or replaces by decoded key (idempotent),
|
|
4205
|
+
* `replace` renames in one job, and the result IS the new layout.
|
|
4206
|
+
* 3. `pages.removeName()` drops the registration and nothing else.
|
|
4207
|
+
* 4. Deleting a page removes every registration pointing at it — inside
|
|
4208
|
+
* the delete, with no plugin in the loop.
|
|
4209
|
+
* 5. Non-ASCII keys round-trip unchanged (Acrobat writes UTF-16 + BOM).
|
|
4210
|
+
*
|
|
4211
|
+
* Skips cleanly when the engine does not implement the optional members.
|
|
4212
|
+
*/
|
|
4213
|
+
function runNamedPagesConformance(runner, opts) {
|
|
4214
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4215
|
+
describe(`named pages conformance: ${opts.label}`, () => {
|
|
4216
|
+
let engine;
|
|
4217
|
+
beforeAll(async () => {
|
|
4218
|
+
engine = await opts.makeEngine();
|
|
4219
|
+
});
|
|
4220
|
+
afterAll(async () => {
|
|
4221
|
+
if (engine) await engine.destroy();
|
|
4222
|
+
});
|
|
4223
|
+
test("pages.list() carries namedPages and every entry resolves", async () => {
|
|
4224
|
+
const doc = await openFixture$13(engine, opts);
|
|
4225
|
+
try {
|
|
4226
|
+
const layout = await doc.pages.list();
|
|
4227
|
+
PageListSnapshotSchema.parse(layout);
|
|
4228
|
+
expect(Array.isArray(layout.namedPages)).toBe(true);
|
|
4229
|
+
const pons = new Set(layout.pages.map((page) => page.pageObjectNumber));
|
|
4230
|
+
for (const entry of layout.namedPages ?? []) {
|
|
4231
|
+
expect(entry.name.length > 0).toBe(true);
|
|
4232
|
+
if (entry.target.kind === "page") expect(pons.has(entry.target.pageObjectNumber)).toBe(true);
|
|
4233
|
+
}
|
|
4234
|
+
} finally {
|
|
4235
|
+
await doc.close();
|
|
4236
|
+
}
|
|
4237
|
+
});
|
|
4238
|
+
test("pages.setName() registers, replaces by key, and renames via `replace`", async () => {
|
|
4239
|
+
const doc = await openFixture$13(engine, opts);
|
|
4240
|
+
try {
|
|
4241
|
+
if (!doc.pages.setName) return;
|
|
4242
|
+
const before = await doc.pages.list();
|
|
4243
|
+
const [first, second] = before.pages;
|
|
4244
|
+
const baseline = (before.namedPages ?? []).length;
|
|
4245
|
+
const created = await doc.pages.setName({
|
|
4246
|
+
name: "Approved=Goedgekeurd",
|
|
4247
|
+
pageObjectNumber: first.pageObjectNumber
|
|
4248
|
+
});
|
|
4249
|
+
PageNameResultSchema.parse(created);
|
|
4250
|
+
expect(created.layout.pages.length).toBe(before.pages.length);
|
|
4251
|
+
expect(find(created, "Approved=Goedgekeurd")).toEqual({
|
|
4252
|
+
kind: "page",
|
|
4253
|
+
pageObjectNumber: first.pageObjectNumber
|
|
4254
|
+
});
|
|
4255
|
+
expect((created.layout.namedPages ?? []).length).toBe(baseline + 1);
|
|
4256
|
+
if (created.cache) {
|
|
4257
|
+
expect(created.cache.docVersion > created.cache.previousDocVersion).toBe(true);
|
|
4258
|
+
expect(created.cache.layoutVersion > 0).toBe(true);
|
|
4259
|
+
}
|
|
4260
|
+
const listed = await doc.pages.list();
|
|
4261
|
+
expect(listed.namedPages).toEqual(created.layout.namedPages);
|
|
4262
|
+
const replaced = await doc.pages.setName({
|
|
4263
|
+
name: "Approved=Goedgekeurd",
|
|
4264
|
+
pageObjectNumber: second.pageObjectNumber
|
|
4265
|
+
});
|
|
4266
|
+
expect(find(replaced, "Approved=Goedgekeurd")).toEqual({
|
|
4267
|
+
kind: "page",
|
|
4268
|
+
pageObjectNumber: second.pageObjectNumber
|
|
4269
|
+
});
|
|
4270
|
+
expect((replaced.layout.namedPages ?? []).length).toBe(baseline + 1);
|
|
4271
|
+
const renamed = await doc.pages.setName({
|
|
4272
|
+
name: "Approved=Approved",
|
|
4273
|
+
pageObjectNumber: second.pageObjectNumber,
|
|
4274
|
+
replace: "Approved=Goedgekeurd"
|
|
4275
|
+
});
|
|
4276
|
+
expect(find(renamed, "Approved=Goedgekeurd")).toBe(void 0);
|
|
4277
|
+
expect(find(renamed, "Approved=Approved")).toEqual({
|
|
4278
|
+
kind: "page",
|
|
4279
|
+
pageObjectNumber: second.pageObjectNumber
|
|
4280
|
+
});
|
|
4281
|
+
expect((renamed.layout.namedPages ?? []).length).toBe(baseline + 1);
|
|
4282
|
+
} finally {
|
|
4283
|
+
await doc.close();
|
|
4284
|
+
}
|
|
4285
|
+
});
|
|
4286
|
+
test("non-ASCII keys round-trip through set → list", async () => {
|
|
4287
|
+
const doc = await openFixture$13(engine, opts);
|
|
4288
|
+
try {
|
|
4289
|
+
if (!doc.pages.setName) return;
|
|
4290
|
+
const before = await doc.pages.list();
|
|
4291
|
+
const key = "Stämpel=Stämpel 日本";
|
|
4292
|
+
const result = await doc.pages.setName({
|
|
4293
|
+
name: key,
|
|
4294
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4295
|
+
});
|
|
4296
|
+
expect(find(result, key)).toEqual({
|
|
4297
|
+
kind: "page",
|
|
4298
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4299
|
+
});
|
|
4300
|
+
const listed = await doc.pages.list();
|
|
4301
|
+
expect((listed.namedPages ?? []).some((entry) => entry.name === key)).toBe(true);
|
|
4302
|
+
} finally {
|
|
4303
|
+
await doc.close();
|
|
4304
|
+
}
|
|
4305
|
+
});
|
|
4306
|
+
test("pages.removeName() drops the registration and keeps the page", async () => {
|
|
4307
|
+
const doc = await openFixture$13(engine, opts);
|
|
4308
|
+
try {
|
|
4309
|
+
if (!doc.pages.setName || !doc.pages.removeName) return;
|
|
4310
|
+
const before = await doc.pages.list();
|
|
4311
|
+
await doc.pages.setName({
|
|
4312
|
+
name: "Draft=Concept",
|
|
4313
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4314
|
+
});
|
|
4315
|
+
const removed = await doc.pages.removeName({ name: "Draft=Concept" });
|
|
4316
|
+
PageNameResultSchema.parse(removed);
|
|
4317
|
+
expect(find(removed, "Draft=Concept")).toBe(void 0);
|
|
4318
|
+
expect(removed.layout.pages.length).toBe(before.pages.length);
|
|
4319
|
+
await expect(doc.pages.removeName({ name: "Draft=Concept" })).rejects.toMatchObject({ code: EngineErrorCode.NotFound });
|
|
4320
|
+
} finally {
|
|
4321
|
+
await doc.close();
|
|
4322
|
+
}
|
|
4323
|
+
});
|
|
4324
|
+
test("pages.setName() rejects an empty name and an unknown page", async () => {
|
|
4325
|
+
const doc = await openFixture$13(engine, opts);
|
|
4326
|
+
try {
|
|
4327
|
+
if (!doc.pages.setName) return;
|
|
4328
|
+
const before = await doc.pages.list();
|
|
4329
|
+
await expect(doc.pages.setName({
|
|
4330
|
+
name: "",
|
|
4331
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4332
|
+
})).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4333
|
+
let unknownPage = null;
|
|
4334
|
+
try {
|
|
4335
|
+
await doc.pages.setName({
|
|
4336
|
+
name: "Ghost=Ghost",
|
|
4337
|
+
pageObjectNumber: 987654321
|
|
4338
|
+
});
|
|
4339
|
+
} catch (error) {
|
|
4340
|
+
unknownPage = error;
|
|
4341
|
+
}
|
|
4342
|
+
expect(EngineError.is(unknownPage, EngineErrorCode.NotFound) || EngineError.is(unknownPage, EngineErrorCode.InvalidArg)).toBe(true);
|
|
4343
|
+
} finally {
|
|
4344
|
+
await doc.close();
|
|
4345
|
+
}
|
|
4346
|
+
});
|
|
4347
|
+
test("deleting a page removes every registration pointing at it", async () => {
|
|
4348
|
+
const doc = await openFixture$13(engine, opts);
|
|
4349
|
+
try {
|
|
4350
|
+
if (!doc.pages.setName) return;
|
|
4351
|
+
const before = await doc.pages.list();
|
|
4352
|
+
if (before.pages.length < 2) return;
|
|
4353
|
+
const victim = before.pages[1].pageObjectNumber;
|
|
4354
|
+
const survivor = before.pages[0].pageObjectNumber;
|
|
4355
|
+
await doc.pages.setName({
|
|
4356
|
+
name: "Victim=One",
|
|
4357
|
+
pageObjectNumber: victim
|
|
4358
|
+
});
|
|
4359
|
+
await doc.pages.setName({
|
|
4360
|
+
name: "Victim=Two",
|
|
4361
|
+
pageObjectNumber: victim
|
|
4362
|
+
});
|
|
4363
|
+
await doc.pages.setName({
|
|
4364
|
+
name: "Survivor",
|
|
4365
|
+
pageObjectNumber: survivor
|
|
4366
|
+
});
|
|
4367
|
+
const deleted = await doc.pages.delete([victim]);
|
|
4368
|
+
const names = (deleted.layout.namedPages ?? []).map((entry) => entry.name);
|
|
4369
|
+
expect(names.includes("Victim=One")).toBe(false);
|
|
4370
|
+
expect(names.includes("Victim=Two")).toBe(false);
|
|
4371
|
+
expect(names).toContain("Survivor");
|
|
4372
|
+
expect((deleted.layout.namedPages ?? []).some((entry) => entry.target.kind === "dangling")).toBe(false);
|
|
4373
|
+
} finally {
|
|
4374
|
+
await doc.close();
|
|
4375
|
+
}
|
|
4376
|
+
});
|
|
4377
|
+
test("abort on pages.setName() rejects with AbortError", async () => {
|
|
4378
|
+
const doc = await openFixture$13(engine, opts);
|
|
4379
|
+
try {
|
|
4380
|
+
if (!doc.pages.setName) return;
|
|
4381
|
+
const before = await doc.pages.list();
|
|
4382
|
+
const promise = doc.pages.setName({
|
|
4383
|
+
name: "Aborted=Aborted",
|
|
4384
|
+
pageObjectNumber: before.pages[0].pageObjectNumber
|
|
4385
|
+
});
|
|
4386
|
+
promise.abort();
|
|
4387
|
+
await expect(promise).rejects.toBeInstanceOf(AbortError);
|
|
4388
|
+
} finally {
|
|
4389
|
+
await doc.close();
|
|
4390
|
+
}
|
|
4391
|
+
});
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4394
|
+
function find(result, name) {
|
|
4395
|
+
return (result.layout.namedPages ?? []).find((entry) => entry.name === name)?.target;
|
|
4396
|
+
}
|
|
4397
|
+
async function openFixture$13(engine, opts) {
|
|
3970
4398
|
if (opts.openKind === "bytes") {
|
|
3971
4399
|
const bytes = await opts.fixture.bytes();
|
|
3972
4400
|
return engine.open({
|
|
@@ -3981,6 +4409,243 @@ async function openFixture$11(engine, opts) {
|
|
|
3981
4409
|
});
|
|
3982
4410
|
}
|
|
3983
4411
|
//#endregion
|
|
4412
|
+
//#region src/conformance/runAnnotationFlattenConformance.ts
|
|
4413
|
+
const square$1 = (left, bottom) => ({
|
|
4414
|
+
subtype: "square",
|
|
4415
|
+
rect: {
|
|
4416
|
+
left,
|
|
4417
|
+
bottom,
|
|
4418
|
+
right: left + 40,
|
|
4419
|
+
top: bottom + 40
|
|
4420
|
+
},
|
|
4421
|
+
color: {
|
|
4422
|
+
r: 20,
|
|
4423
|
+
g: 40,
|
|
4424
|
+
b: 220
|
|
4425
|
+
},
|
|
4426
|
+
strokeWidth: 2
|
|
4427
|
+
});
|
|
4428
|
+
/**
|
|
4429
|
+
* Selective annotation flatten: `page(pon).annotations.flatten(refs)` is
|
|
4430
|
+
* `pages.flatten` for a chosen set. Locks, on every engine:
|
|
4431
|
+
* 1. only the given refs are painted and removed; the rest of the page's
|
|
4432
|
+
* annotations are untouched;
|
|
4433
|
+
* 2. per-ref status (`applied` / `skipped`), one `annotations.flattened`
|
|
4434
|
+
* event, a `meta` with that page's new pins, layout unchanged;
|
|
4435
|
+
* 3. a hidden ref is `skipped`; a ref on another page rejects `InvalidArg`
|
|
4436
|
+
* with nothing mutated.
|
|
4437
|
+
* Skips cleanly when the engine does not implement the optional member.
|
|
4438
|
+
*/
|
|
4439
|
+
function runAnnotationFlattenConformance(runner, opts) {
|
|
4440
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4441
|
+
describe(`annotation flatten conformance: ${opts.label}`, () => {
|
|
4442
|
+
let engine;
|
|
4443
|
+
beforeAll(async () => {
|
|
4444
|
+
engine = await opts.makeEngine();
|
|
4445
|
+
});
|
|
4446
|
+
afterAll(async () => {
|
|
4447
|
+
if (engine) await engine.destroy();
|
|
4448
|
+
});
|
|
4449
|
+
test("flattens exactly the given refs and reports per-ref status", async () => {
|
|
4450
|
+
const doc = await openFixture$12(engine, opts);
|
|
4451
|
+
try {
|
|
4452
|
+
const layoutBefore = await doc.pages.list();
|
|
4453
|
+
const pon = layoutBefore.pages[0].pageObjectNumber;
|
|
4454
|
+
const page = doc.page(pon);
|
|
4455
|
+
if (!page.annotations.flatten) return;
|
|
4456
|
+
const a = (await page.annotations.create(square$1(20, 20))).created.ref;
|
|
4457
|
+
const b = (await page.annotations.create(square$1(80, 20))).created.ref;
|
|
4458
|
+
const c = (await page.annotations.create(square$1(140, 20))).created.ref;
|
|
4459
|
+
await page.annotations.update(c, {
|
|
4460
|
+
subtype: "square",
|
|
4461
|
+
flags: { hidden: true }
|
|
4462
|
+
});
|
|
4463
|
+
const before = await page.annotations.list();
|
|
4464
|
+
const events = [];
|
|
4465
|
+
const unsubscribe = doc.events.subscribe((event) => {
|
|
4466
|
+
if (event.type === "annotations.flattened") events.push(event);
|
|
4467
|
+
});
|
|
4468
|
+
const result = await page.annotations.flatten([a, c], "display");
|
|
4469
|
+
unsubscribe();
|
|
4470
|
+
expect(AnnotationFlattenResultSchema.safeParse(result).success).toBe(true);
|
|
4471
|
+
expect(result.pageObjectNumber).toBe(pon);
|
|
4472
|
+
expect(result.usage).toBe("display");
|
|
4473
|
+
expect(result.results.map((item) => item.status)).toEqual(["applied", "skipped"]);
|
|
4474
|
+
expect(result.meta === null).toBe(false);
|
|
4475
|
+
expect(events).toHaveLength(1);
|
|
4476
|
+
expect(await doc.pages.list()).toEqual(layoutBefore);
|
|
4477
|
+
const after = await page.annotations.list();
|
|
4478
|
+
expect(after.annotations.length).toBe(before.annotations.length - 1);
|
|
4479
|
+
expect(after.annotations.some((dto) => sameRef(dto.ref, b))).toBe(true);
|
|
4480
|
+
expect(after.annotations.some((dto) => sameRef(dto.ref, c))).toBe(true);
|
|
4481
|
+
expect(after.annotations.some((dto) => sameRef(dto.ref, a))).toBe(false);
|
|
4482
|
+
expect(after.pageState.revision.generation > before.pageState.revision.generation).toBe(true);
|
|
4483
|
+
} finally {
|
|
4484
|
+
await doc.close();
|
|
4485
|
+
}
|
|
4486
|
+
});
|
|
4487
|
+
test("a ref on another page rejects InvalidArg and mutates nothing", async () => {
|
|
4488
|
+
const doc = await openFixture$12(engine, opts);
|
|
4489
|
+
try {
|
|
4490
|
+
const layout = await doc.pages.list();
|
|
4491
|
+
if (layout.pages.length < 2) return;
|
|
4492
|
+
const page0 = doc.page(layout.pages[0].pageObjectNumber);
|
|
4493
|
+
const page1 = doc.page(layout.pages[1].pageObjectNumber);
|
|
4494
|
+
if (!page0.annotations.flatten) return;
|
|
4495
|
+
const own = (await page0.annotations.create(square$1(20, 100))).created.ref;
|
|
4496
|
+
const foreign = (await page1.annotations.create(square$1(20, 100))).created.ref;
|
|
4497
|
+
const countBefore = (await page0.annotations.list()).annotations.length;
|
|
4498
|
+
await expect(page0.annotations.flatten([own, foreign])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4499
|
+
expect((await page0.annotations.list()).annotations.length).toBe(countBefore);
|
|
4500
|
+
} finally {
|
|
4501
|
+
await doc.close();
|
|
4502
|
+
}
|
|
4503
|
+
});
|
|
4504
|
+
test("an empty ref list rejects InvalidArg; an unknown ref rejects", async () => {
|
|
4505
|
+
const doc = await openFixture$12(engine, opts);
|
|
4506
|
+
try {
|
|
4507
|
+
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
4508
|
+
const page = doc.page(pon);
|
|
4509
|
+
if (!page.annotations.flatten) return;
|
|
4510
|
+
await expect(page.annotations.flatten([])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4511
|
+
let unknown = null;
|
|
4512
|
+
try {
|
|
4513
|
+
await page.annotations.flatten([{
|
|
4514
|
+
kind: "objectNumber",
|
|
4515
|
+
pageObjectNumber: pon,
|
|
4516
|
+
annotObjectNumber: 987654321
|
|
4517
|
+
}]);
|
|
4518
|
+
} catch (error) {
|
|
4519
|
+
unknown = error;
|
|
4520
|
+
}
|
|
4521
|
+
expect(EngineError.is(unknown, EngineErrorCode.NotFound) || EngineError.is(unknown, EngineErrorCode.InvalidArg) || EngineError.is(unknown, EngineErrorCode.InvalidReference)).toBe(true);
|
|
4522
|
+
} finally {
|
|
4523
|
+
await doc.close();
|
|
4524
|
+
}
|
|
4525
|
+
});
|
|
4526
|
+
});
|
|
4527
|
+
}
|
|
4528
|
+
function sameRef(left, right) {
|
|
4529
|
+
if (left.kind === "objectNumber" && right.kind === "objectNumber") return left.annotObjectNumber === right.annotObjectNumber;
|
|
4530
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
4531
|
+
}
|
|
4532
|
+
async function openFixture$12(engine, opts) {
|
|
4533
|
+
if (opts.openKind === "bytes") return engine.open({
|
|
4534
|
+
kind: "bytes",
|
|
4535
|
+
id: opts.fixture.id,
|
|
4536
|
+
bytes: await opts.fixture.bytes()
|
|
4537
|
+
});
|
|
4538
|
+
return engine.open({
|
|
4539
|
+
kind: "id",
|
|
4540
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
4541
|
+
});
|
|
4542
|
+
}
|
|
4543
|
+
//#endregion
|
|
4544
|
+
//#region src/conformance/runAnnotationAppearanceExportConformance.ts
|
|
4545
|
+
const PDF_MAGIC$1 = [
|
|
4546
|
+
37,
|
|
4547
|
+
80,
|
|
4548
|
+
68,
|
|
4549
|
+
70
|
|
4550
|
+
];
|
|
4551
|
+
const square = (left, bottom, size = 40) => ({
|
|
4552
|
+
subtype: "square",
|
|
4553
|
+
rect: {
|
|
4554
|
+
left,
|
|
4555
|
+
bottom,
|
|
4556
|
+
right: left + size,
|
|
4557
|
+
top: bottom + size
|
|
4558
|
+
},
|
|
4559
|
+
color: {
|
|
4560
|
+
r: 220,
|
|
4561
|
+
g: 20,
|
|
4562
|
+
b: 20
|
|
4563
|
+
},
|
|
4564
|
+
strokeWidth: 2
|
|
4565
|
+
});
|
|
4566
|
+
/**
|
|
4567
|
+
* `page(pon).annotations.exportAppearance(refs)`: the chosen annotations'
|
|
4568
|
+
* appearances as ONE single-page PDF sized to their union /Rect. Locks:
|
|
4569
|
+
* 1. bytes are a PDF; the source page is untouched (no mutation, no
|
|
4570
|
+
* revision bump);
|
|
4571
|
+
* 2. re-opened (local engines), the page is exactly the union size and the
|
|
4572
|
+
* requested count of annotations is gone — they are content now;
|
|
4573
|
+
* 3. a ref on another page rejects `InvalidArg`; an empty list rejects.
|
|
4574
|
+
* Skips cleanly when the engine does not implement the optional member.
|
|
4575
|
+
*/
|
|
4576
|
+
function runAnnotationAppearanceExportConformance(runner, opts) {
|
|
4577
|
+
const { describe, test, beforeAll, afterAll, expect } = runner;
|
|
4578
|
+
describe(`annotation appearance export conformance: ${opts.label}`, () => {
|
|
4579
|
+
let engine;
|
|
4580
|
+
beforeAll(async () => {
|
|
4581
|
+
engine = await opts.makeEngine();
|
|
4582
|
+
});
|
|
4583
|
+
afterAll(async () => {
|
|
4584
|
+
if (engine) await engine.destroy();
|
|
4585
|
+
});
|
|
4586
|
+
test("returns a single-page PDF sized to the union rect; source untouched", async () => {
|
|
4587
|
+
const doc = await openFixture$11(engine, opts);
|
|
4588
|
+
let exported = null;
|
|
4589
|
+
try {
|
|
4590
|
+
const pon = (await doc.pages.list()).pages[0].pageObjectNumber;
|
|
4591
|
+
const page = doc.page(pon);
|
|
4592
|
+
if (!page.annotations.exportAppearance) return;
|
|
4593
|
+
const a = (await page.annotations.create(square(20, 20))).created.ref;
|
|
4594
|
+
const b = (await page.annotations.create(square(100, 60, 30))).created.ref;
|
|
4595
|
+
const before = await page.annotations.list();
|
|
4596
|
+
const bytes = await page.annotations.exportAppearance([a, b]);
|
|
4597
|
+
expect(bytes.length > 4).toBe(true);
|
|
4598
|
+
expect([...bytes.subarray(0, 4)]).toEqual(PDF_MAGIC$1);
|
|
4599
|
+
const after = await page.annotations.list();
|
|
4600
|
+
expect(after.annotations.length).toBe(before.annotations.length);
|
|
4601
|
+
expect(after.pageState.revision.generation).toBe(before.pageState.revision.generation);
|
|
4602
|
+
if (opts.openKind !== "bytes") return;
|
|
4603
|
+
exported = await engine.open({
|
|
4604
|
+
kind: "bytes",
|
|
4605
|
+
id: `${opts.fixture.id}-appearance`,
|
|
4606
|
+
bytes
|
|
4607
|
+
});
|
|
4608
|
+
const layout = await exported.pages.list();
|
|
4609
|
+
expect(layout.pageCount).toBe(1);
|
|
4610
|
+
expect(Math.round(layout.pages[0].size.width)).toBe(110);
|
|
4611
|
+
expect(Math.round(layout.pages[0].size.height)).toBe(70);
|
|
4612
|
+
const exportedPage = exported.page(layout.pages[0].pageObjectNumber);
|
|
4613
|
+
expect((await exportedPage.annotations.list()).annotations).toHaveLength(0);
|
|
4614
|
+
} finally {
|
|
4615
|
+
if (exported) await exported.close();
|
|
4616
|
+
await doc.close();
|
|
4617
|
+
}
|
|
4618
|
+
});
|
|
4619
|
+
test("a ref on another page and an empty list reject InvalidArg", async () => {
|
|
4620
|
+
const doc = await openFixture$11(engine, opts);
|
|
4621
|
+
try {
|
|
4622
|
+
const layout = await doc.pages.list();
|
|
4623
|
+
const page0 = doc.page(layout.pages[0].pageObjectNumber);
|
|
4624
|
+
if (!page0.annotations.exportAppearance) return;
|
|
4625
|
+
await expect(page0.annotations.exportAppearance([])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4626
|
+
if (layout.pages.length < 2) return;
|
|
4627
|
+
const page1 = doc.page(layout.pages[1].pageObjectNumber);
|
|
4628
|
+
const own = (await page0.annotations.create(square(20, 100))).created.ref;
|
|
4629
|
+
const foreign = (await page1.annotations.create(square(20, 100))).created.ref;
|
|
4630
|
+
await expect(page0.annotations.exportAppearance([own, foreign])).rejects.toMatchObject({ code: EngineErrorCode.InvalidArg });
|
|
4631
|
+
} finally {
|
|
4632
|
+
await doc.close();
|
|
4633
|
+
}
|
|
4634
|
+
});
|
|
4635
|
+
});
|
|
4636
|
+
}
|
|
4637
|
+
async function openFixture$11(engine, opts) {
|
|
4638
|
+
if (opts.openKind === "bytes") return engine.open({
|
|
4639
|
+
kind: "bytes",
|
|
4640
|
+
id: opts.fixture.id,
|
|
4641
|
+
bytes: await opts.fixture.bytes()
|
|
4642
|
+
});
|
|
4643
|
+
return engine.open({
|
|
4644
|
+
kind: "id",
|
|
4645
|
+
id: opts.fixture.cloudId ?? opts.fixture.id
|
|
4646
|
+
});
|
|
4647
|
+
}
|
|
4648
|
+
//#endregion
|
|
3984
4649
|
//#region src/conformance/runPageFlattenConformance.ts
|
|
3985
4650
|
/** Transport-neutral coverage for the content + annotation flatten rail. */
|
|
3986
4651
|
function runPageFlattenConformance(runner, opts) {
|
|
@@ -6009,6 +6674,6 @@ function diffAnnotation(i, a, b, errs) {
|
|
|
6009
6674
|
if (a.nm !== b.nm) errs.push(`annotations[${i}].nm mismatch: ${a.nm} vs ${b.nm}`);
|
|
6010
6675
|
}
|
|
6011
6676
|
//#endregion
|
|
6012
|
-
export { TEXT_DIVERGENCE_CASES, diffAnnotationListSnapshot, diffAnnotationListSnapshotAll, runActionsConformance, runAnnotationAppearanceConformance, runAnnotationMutationConformance, runAnnotationReadConformance, runAttachmentConformance, runDocumentEventsConformance, runFormConformance, runMetadataConformance, runPageDeleteConformance, runPageExtractConformance, runPageFlattenConformance, runPageGeometryOrientationConformance, runPageInsertBlankConformance, runPageInsertConformance, runPageReorderConformance, runPageRotateConformance, runPageTextConformance, runPieceInfoConformance, runRedactionApplyConformance, runSearchConformance, runTextDivergenceConformance };
|
|
6677
|
+
export { TEXT_DIVERGENCE_CASES, diffAnnotationListSnapshot, diffAnnotationListSnapshotAll, runActionsConformance, runAnnotationAppearanceConformance, runAnnotationAppearanceExportConformance, runAnnotationFlattenConformance, runAnnotationMutationConformance, runAnnotationReadConformance, runAttachmentConformance, runDocumentEventsConformance, runFormConformance, runMetadataConformance, runNamedPagesConformance, runPageDeleteConformance, runPageExtractConformance, runPageFlattenConformance, runPageGeometryOrientationConformance, runPageInsertBlankConformance, runPageInsertConformance, runPageReorderConformance, runPageRotateConformance, runPageTextConformance, runPieceInfoConformance, runRedactionApplyConformance, runSearchConformance, runTextDivergenceConformance };
|
|
6013
6678
|
|
|
6014
6679
|
//# sourceMappingURL=conformance.js.map
|