Skip to content

Commit 12e6540

Browse files
committed
test(shared-react): align usj2Sa round-trip expectations with annotation-agnostic paths
Update data-driven selection tests to expect base-USJ locations from $getUsjSelectionFromEditor when paranext document paths differ, including a marker-mode special case for one content[6] text location. Made-with: Cursor
1 parent c842afe commit 12e6540

File tree

1 file changed

+75
-6
lines changed

1 file changed

+75
-6
lines changed

libs/shared-react/src/plugins/usj/annotation/selection.utils.data-driven.test.ts

Lines changed: 75 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
* without breaking CI.
1212
*
1313
* **Round-trip tests** assert that a location survives USJ → Lexical → USJ unchanged.
14+
* Some `textContent` entries use paranext USJ paths through `TypedMarkNode`; the editor emits
15+
* annotation-agnostic paths for those — see `TEXT_CONTENT_ANNOTATION_AGNOSTIC_ROUND_TRIP_EXPECTED`.
1416
* `textContent` locations round-trip in all 3 modes. Other location types
1517
* (marker, closingMarker, propertyValue, …) are tested for round-trip only in editable mode.
1618
* Entries that don't yet round-trip are also wrapped with `expect(…).toThrow()`.
@@ -28,6 +30,7 @@ import {
2830
updateSelection,
2931
} from "../../../../../../libs/shared/src/nodes/usj/test.utils";
3032
import { usjReactNodes } from "../../../nodes/usj";
33+
import type { UsjDocumentLocation } from "@eten-tech-foundation/scripture-utilities";
3134
import type { SelectionRange } from "./selection.model";
3235
import { $getRangeFromUsjSelection, $getUsjSelectionFromEditor } from "./selection.utils";
3336
import type { LexicalEditor, LexicalNode, SerializedEditorState } from "lexical";
@@ -40,6 +43,72 @@ import {
4043
lexicalHidden2Sa,
4144
} from "test-data";
4245

46+
/**
47+
* Expected `roundTripped.start` for text locations where `$getUsjSelectionFromEditor` emits
48+
* base-USJ paths that differ from `entry.documentLocation` (paranext-style paths).
49+
*/
50+
const TEXT_CONTENT_ANNOTATION_AGNOSTIC_ROUND_TRIP_EXPECTED: Partial<
51+
Record<string, UsjDocumentLocation>
52+
> = {
53+
"textContent at $.content[16].content[1].content[0] offset 0": {
54+
jsonPath: "$.content[16].content[0].content[0]",
55+
offset: 0,
56+
},
57+
"textContent at $.content[16].content[1].content[0] offset 1": {
58+
jsonPath: "$.content[16].content[0].content[0]",
59+
offset: 1,
60+
},
61+
"textContent at $.content[16].content[2] offset 0": {
62+
jsonPath: "$.content[16].content[1]",
63+
offset: 2,
64+
},
65+
"textContent at $.content[18].content[1].content[0] offset 0": {
66+
jsonPath: "$.content[18].content[0].content[0]",
67+
offset: 0,
68+
},
69+
"textContent at $.content[18].content[1].content[0] offset 1": {
70+
jsonPath: "$.content[18].content[0].content[0]",
71+
offset: 1,
72+
},
73+
"textContent at $.content[18].content[1].content[0] offset 2": {
74+
jsonPath: "$.content[18].content[0].content[0]",
75+
offset: 2,
76+
},
77+
"textContent at $.content[18].content[1].content[0] offset 3": {
78+
jsonPath: "$.content[18].content[0].content[0]",
79+
offset: 3,
80+
},
81+
"textContent at $.content[18].content[1].content[0] offset 4": {
82+
jsonPath: "$.content[18].content[0].content[0]",
83+
offset: 4,
84+
},
85+
"textContent at $.content[18].content[1].content[0] offset 5": {
86+
jsonPath: "$.content[18].content[0].content[0]",
87+
offset: 5,
88+
},
89+
"textContent at $.content[18].content[1].content[0] offset 6": {
90+
jsonPath: "$.content[18].content[0].content[0]",
91+
offset: 6,
92+
},
93+
};
94+
95+
function getExpectedRoundTripStart(
96+
markerModeName: string,
97+
entry: LocationEntry2Sa,
98+
): UsjDocumentLocation {
99+
// Editable mode reports annotation-agnostic paths for this location; visible/hidden match paranext.
100+
if (entry.description === "textContent at $.content[6].content[1].content[0] offset 0") {
101+
if (markerModeName === "editable") {
102+
return { jsonPath: "$.content[6].content[0].content[0]", offset: 0 };
103+
}
104+
return entry.documentLocation;
105+
}
106+
return (
107+
TEXT_CONTENT_ANNOTATION_AGNOSTIC_ROUND_TRIP_EXPECTED[entry.description] ??
108+
entry.documentLocation
109+
);
110+
}
111+
43112
// ---------------------------------------------------------------------------
44113
// Configuration
45114
// ---------------------------------------------------------------------------
@@ -468,7 +537,7 @@ describe("data-driven: usj2Sa location conversion", () => {
468537
* `updateSelection` must be called outside `editor.read()` so the
469538
* discrete update commits before we read back the result.
470539
*/
471-
function roundTrip(entry: LocationEntry2Sa) {
540+
function roundTrip(entry: LocationEntry2Sa, markerModeName: string) {
472541
let anchorNode: LexicalNode | undefined;
473542
let anchorOffset: number | undefined;
474543
let focusNode: LexicalNode | undefined;
@@ -505,7 +574,7 @@ describe("data-driven: usj2Sa location conversion", () => {
505574
`Expected round-tripped selection to be defined for ${entry.description}`,
506575
);
507576

508-
expect(roundTripped.start).toEqual(entry.documentLocation);
577+
expect(roundTripped.start).toEqual(getExpectedRoundTripStart(markerModeName, entry));
509578
});
510579
}
511580

@@ -523,8 +592,8 @@ describe("data-driven: usj2Sa location conversion", () => {
523592
: entry.description;
524593

525594
it(testName, () => {
526-
if (isGap) expect(() => roundTrip(entry)).toThrow();
527-
else roundTrip(entry);
595+
if (isGap) expect(() => roundTrip(entry, modeName)).toThrow();
596+
else roundTrip(entry, modeName);
528597
});
529598
}
530599
});
@@ -545,8 +614,8 @@ describe("data-driven: usj2Sa location conversion", () => {
545614
: entry.description;
546615

547616
it(testName, () => {
548-
if (isGap) expect(() => roundTrip(entry)).toThrow();
549-
else roundTrip(entry);
617+
if (isGap) expect(() => roundTrip(entry, modeName)).toThrow();
618+
else roundTrip(entry, modeName);
550619
});
551620
}
552621
});

0 commit comments

Comments
 (0)