Skip to content

Commit 4e5f73b

Browse files
authored
Removed reorganizing verse numbers automatically (#458)
* Removed reorganizing verse numbers automatically * Removed extraneous testing comments * Fixed verse ref not being updated when a verse marker is created or deleted
1 parent 9f09780 commit 4e5f73b

File tree

7 files changed

+59
-339
lines changed

7 files changed

+59
-339
lines changed

.claude/settings.local.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"permissions": {
3+
"allow": ["Bash(pnpm nx test shared-react -- --reporter=verbose UsjNodesMenuPlugin)"]
4+
}
5+
}

CLAUDE.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ nx run-many -t typecheck # Type check all packages
3131
nx format:check # Check formatting
3232
nx format:write # Fix formatting
3333

34+
# API extraction (run after changing a package's public API)
35+
nx extract-api <package-name> # Update API report for specific package
36+
nx run-many -t extract-api # Update API reports for all packages
37+
3438
# Development environments
3539
nx dev perf-react # React-based PERF editor
3640
nx dev perf-vanilla # Vanilla JS PERF editor
@@ -136,6 +140,7 @@ shared-react (React-specific extensions)
136140
3. **Testing**: Run `nx test <package-name>` for specific package tests
137141
4. **Linting**: Run `nx run-many -t lint` before committing
138142
5. **Building**: Use `nx build <package-name>` to build specific packages
143+
6. **API Changes**: Run `nx extract-api <package-name>` after changing a package's public API to update its API report
139144

140145
### Key Files and Directories
141146

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,22 @@ To run all TS unit tests watching for file changes:
179179

180180
You can also use the [recommended VS Code extensions](/.vscode/extensions.json) to run tests there. This is particularly useful for running individual tests and debugging.
181181

182+
## API Extraction
183+
184+
If you change the public API of a package, run `nx extract-api` to update its API report:
185+
186+
```bash
187+
nx extract-api <package-name> # e.g., nx extract-api platform-editor
188+
```
189+
190+
Or update all packages at once:
191+
192+
```bash
193+
nx run-many -t extract-api
194+
```
195+
196+
The generated API report files should be committed alongside your changes.
197+
182198
## Formatting, Linting and Typechecking
183199

184200
Formatting happens automatically when you commit. If you use VS Code with this repo's recommended extensions, files will be formatted when you save.

libs/shared-react/src/plugins/usj/UsjNodesMenuPlugin.test.tsx

Lines changed: 12 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,7 @@ import { $isReactNodeWithMarker } from "../../nodes/usj/node-react.utils";
33
import * as useUsfmMarkersForMenuModule from "../PerfNodesItems/useUsfmMarkersForMenu";
44
import { UsjNodesMenuPlugin } from "./UsjNodesMenuPlugin";
55
import { baseTestEnvironment } from "./react-test.utils";
6-
import { act } from "@testing-library/react";
7-
import {
8-
$getRoot,
9-
$createTextNode,
10-
LexicalEditor,
11-
$getSelection,
12-
$setSelection,
13-
$createRangeSelection,
14-
$createPoint,
15-
TextNode,
16-
} from "lexical";
6+
import { $getRoot, $createTextNode, LexicalEditor, $getSelection, TextNode } from "lexical";
177
import {
188
$createImmutableChapterNode,
199
$createImpliedParaNode,
@@ -60,127 +50,19 @@ describe("UsjNodesMenuPlugin", () => {
6050
});
6151
});
6252

63-
describe("Verse Renumbering", () => {
64-
it("should insert verse 3 before 3a and renumber to 4a (with verse ranges and segments)", async () => {
65-
const { editor } = await testEnvironment();
66-
67-
await insertVerseNodeAtSelection(editor, "3", firstVerseTextNode);
68-
69-
editor.getEditorState().read(() => {
70-
expect(firstVerseNode.getNumber()).toBe("1-2");
71-
expect(secondVerseNode.getNumber()).toBe("4a");
72-
expect(thirdVerseNode.getNumber()).toBe("5-6a");
73-
});
74-
});
75-
76-
it("should insert verse 3b before 4-5 and not renumber (with verse ranges and segments)", async () => {
77-
const { editor } = await testEnvironment();
78-
79-
await insertVerseNodeAtSelection(editor, "3b", secondVerseTextNode);
80-
81-
editor.getEditorState().read(() => {
82-
expect(firstVerseNode.getNumber()).toBe("1-2");
83-
expect(secondVerseNode.getNumber()).toBe("3a");
84-
expect(thirdVerseNode.getNumber()).toBe("4-5a");
85-
});
86-
});
87-
88-
it("should insert verse 2 before 2 and renumber to 3 (with normal verse numbers)", async () => {
89-
const { editor } = await testEnvironment(() => {
90-
$defaultInitialEditorState();
91-
firstVerseNode.setNumber("1");
92-
secondVerseNode.setNumber("2");
93-
thirdVerseNode.setNumber("3");
94-
});
95-
editor.getEditorState().read(() => {
96-
expect(firstVerseNode.getNumber()).toBe("1");
97-
expect(secondVerseNode.getNumber()).toBe("2");
98-
expect(thirdVerseNode.getNumber()).toBe("3");
99-
});
100-
101-
await insertVerseNodeAtSelection(editor, "2", firstVerseTextNode);
102-
103-
editor.getEditorState().read(() => {
104-
expect(firstVerseNode.getNumber()).toBe("1");
105-
expect(secondVerseNode.getNumber()).toBe("3");
106-
expect(thirdVerseNode.getNumber()).toBe("4");
107-
});
108-
});
109-
110-
it("should insert verse 2 before 2 and renumber to 3 but only in chapter 1 (with normal verse numbers)", async () => {
111-
let ch2FirstVerseNode: ImmutableVerseNode;
112-
let ch2SecondVerseNode: ImmutableVerseNode;
113-
const { editor } = await testEnvironment(() => {
114-
$defaultInitialEditorState();
115-
firstVerseNode.setNumber("1");
116-
secondVerseNode.setNumber("2");
117-
thirdVerseNode.setNumber("3");
118-
ch2FirstVerseNode = $createImmutableVerseNode("1");
119-
ch2SecondVerseNode = $createImmutableVerseNode("2");
120-
$getRoot().append(
121-
$createImmutableChapterNode("2"),
122-
$createParaNode().append(ch2FirstVerseNode, $createTextNode("first verse text ")),
123-
$createParaNode().append(ch2SecondVerseNode, $createTextNode("second verse text ")),
124-
);
125-
});
126-
editor.getEditorState().read(() => {
127-
expect(firstVerseNode.getNumber()).toBe("1");
128-
expect(secondVerseNode.getNumber()).toBe("2");
129-
expect(thirdVerseNode.getNumber()).toBe("3");
130-
expect(ch2FirstVerseNode.getNumber()).toBe("1");
131-
expect(ch2SecondVerseNode.getNumber()).toBe("2");
132-
});
133-
134-
await insertVerseNodeAtSelection(editor, "2", firstVerseTextNode);
135-
136-
editor.getEditorState().read(() => {
137-
expect(firstVerseNode.getNumber()).toBe("1");
138-
expect(secondVerseNode.getNumber()).toBe("3");
139-
expect(thirdVerseNode.getNumber()).toBe("4");
140-
expect(ch2FirstVerseNode.getNumber()).toBe("1");
141-
expect(ch2SecondVerseNode.getNumber()).toBe("2");
142-
});
53+
it("should get 'p' marker from implied para to enable menu there", async () => {
54+
let impliedPara: ImpliedParaNode;
55+
const { editor } = await testEnvironment(() => {
56+
impliedPara = $createImpliedParaNode();
57+
$getRoot().append($createImmutableChapterNode("1"), impliedPara);
14358
});
14459

145-
it("should get 'p' marker from implied para to enable menu there", async () => {
146-
let impliedPara: ImpliedParaNode;
147-
const { editor } = await testEnvironment(() => {
148-
impliedPara = $createImpliedParaNode();
149-
$getRoot().append($createImmutableChapterNode("1"), impliedPara);
150-
});
151-
152-
editor.getEditorState().read(() => {
153-
if (!$isImpliedParaNode(impliedPara))
154-
throw new Error("impliedPara is not an implied para node");
155-
if (!$isReactNodeWithMarker(impliedPara))
156-
throw new Error("impliedPara is not a React node with marker");
157-
expect(impliedPara.getMarker()).toBe("p");
158-
});
159-
});
160-
161-
it("should insert a verse when the paragraph is implied", async () => {
162-
const { editor } = await testEnvironment(() => {
163-
firstVerseNode = $createImmutableVerseNode("1");
164-
firstVerseTextNode = $createTextNode("first verse text ");
165-
secondVerseNode = $createImmutableVerseNode("2");
166-
secondVerseTextNode = $createTextNode("second verse text ");
167-
$getRoot().append(
168-
$createImmutableChapterNode("1"),
169-
$createImpliedParaNode().append(
170-
firstVerseNode,
171-
firstVerseTextNode,
172-
secondVerseNode,
173-
secondVerseTextNode,
174-
),
175-
);
176-
});
177-
178-
await insertVerseNodeAtSelection(editor, "2", firstVerseTextNode);
179-
180-
editor.getEditorState().read(() => {
181-
expect(firstVerseNode.getNumber()).toBe("1");
182-
expect(secondVerseNode.getNumber()).toBe("3");
183-
});
60+
editor.getEditorState().read(() => {
61+
if (!$isImpliedParaNode(impliedPara))
62+
throw new Error("impliedPara is not an implied para node");
63+
if (!$isReactNodeWithMarker(impliedPara))
64+
throw new Error("impliedPara is not a React node with marker");
65+
expect(impliedPara.getMarker()).toBe("p");
18466
});
18567
});
18668

@@ -238,37 +120,3 @@ async function testEnvironment(
238120
/>,
239121
);
240122
}
241-
242-
/**
243-
* Insert a VerseNode at the selection range in the LexicalEditor.
244-
*
245-
* @param editor - The LexicalEditor instance where the selection will be set.
246-
* @param verseToInsert - The verse to insert at the selection.
247-
* @param startNode - The starting TextNode of the selection.
248-
* @param startOffset - The offset within the startNode where the selection begins. Defaults to the
249-
* end of the startNode's text content.
250-
* @param endNode - The ending TextNode of the selection. Defaults to the startNode.
251-
* @param endOffset - The offset within the endNode where the selection ends. Defaults to the
252-
* end of the endNode's text content.
253-
*/
254-
async function insertVerseNodeAtSelection(
255-
editor: LexicalEditor,
256-
verseToInsert: string,
257-
startNode: TextNode,
258-
startOffset?: number,
259-
endNode?: TextNode,
260-
endOffset?: number,
261-
) {
262-
await act(async () => {
263-
editor.update(() => {
264-
startOffset ??= startNode.getTextContentSize();
265-
endOffset ??= endNode ? endNode.getTextContentSize() : startOffset;
266-
endNode ??= startNode;
267-
const rangeSelection = $createRangeSelection();
268-
rangeSelection.anchor = $createPoint(startNode.getKey(), startOffset, "text");
269-
rangeSelection.focus = $createPoint(endNode.getKey(), endOffset, "text");
270-
$setSelection(rangeSelection);
271-
rangeSelection.insertNodes([$createImmutableVerseNode(verseToInsert)]);
272-
});
273-
});
274-
}

0 commit comments

Comments
 (0)