A world-class math input for the web
1import { describe, expect, test } from "vitest";
2import { Cursor } from "./cursor";
3
4describe("Cursor Update After Insertion", () => {
5 test("Insertion before cursor in same strand", () => {
6 const loc = new Cursor([], 5);
7 loc.updateAfterInsertion(new Cursor([], 4), 2);
8 expect(loc).toEqual(new Cursor([], 7));
9 });
10
11 test("Insertion at cursor in same strand", () => {
12 const loc = new Cursor([], 5);
13 loc.updateAfterInsertion(new Cursor([], 5), 3);
14 expect(loc).toEqual(new Cursor([], 8));
15 });
16
17 test("Insertion after cursor in same strand", () => {
18 const loc = new Cursor([], 5);
19 loc.updateAfterInsertion(new Cursor([], 6), 2);
20 expect(loc).toEqual(new Cursor([], 5));
21 });
22
23 test("Insertion in parent strand before cursor", () => {
24 const loc = new Cursor(
25 [
26 { tokenIndex: 1, childIndex: 0 },
27 { tokenIndex: 2, childIndex: 1 },
28 ],
29 4
30 );
31 loc.updateAfterInsertion(
32 new Cursor([{ tokenIndex: 1, childIndex: 0 }], 2),
33 2
34 );
35 expect(loc).toEqual(
36 new Cursor(
37 [
38 { tokenIndex: 1, childIndex: 0 },
39 { tokenIndex: 4, childIndex: 1 },
40 ],
41 4
42 )
43 );
44 });
45
46 test("Insertion in grandparent strand before cursor", () => {
47 const loc = new Cursor(
48 [
49 { tokenIndex: 2, childIndex: 0 },
50 { tokenIndex: 0, childIndex: 2 },
51 ],
52 3
53 );
54 loc.updateAfterInsertion(new Cursor([], 2), 1);
55 expect(loc).toEqual(
56 new Cursor(
57 [
58 { tokenIndex: 3, childIndex: 0 },
59 { tokenIndex: 0, childIndex: 2 },
60 ],
61 3
62 )
63 );
64 });
65
66 test("Insertion in parent strand after cursor", () => {
67 const loc = new Cursor(
68 [
69 { tokenIndex: 1, childIndex: 0 },
70 { tokenIndex: 2, childIndex: 1 },
71 ],
72 4
73 );
74 loc.updateAfterInsertion(
75 new Cursor([{ tokenIndex: 1, childIndex: 0 }], 3),
76 2
77 );
78 expect(loc).toEqual(
79 new Cursor(
80 [
81 { tokenIndex: 1, childIndex: 0 },
82 { tokenIndex: 2, childIndex: 1 },
83 ],
84 4
85 )
86 );
87 });
88
89 test("Insertion in grandparent strand after cursor", () => {
90 const loc = new Cursor(
91 [
92 { tokenIndex: 2, childIndex: 0 },
93 { tokenIndex: 0, childIndex: 2 },
94 ],
95 3
96 );
97 loc.updateAfterInsertion(new Cursor([], 3), 1);
98 expect(loc).toEqual(
99 new Cursor(
100 [
101 { tokenIndex: 2, childIndex: 0 },
102 { tokenIndex: 0, childIndex: 2 },
103 ],
104 3
105 )
106 );
107 });
108});
109
110describe("Cursor Update After Token Deletion", () => {
111 test("Same-strand deletion before token", () => {
112 const loc = new Cursor([], 2);
113 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 1 });
114 expect(loc).toEqual(new Cursor([], 1));
115 });
116
117 test("Same-strand deletion after token", () => {
118 const loc = new Cursor([], 2);
119 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 2 });
120 expect(loc).toEqual(new Cursor([], 2));
121 });
122
123 test("Parent-strand deletion before token", () => {
124 const loc = new Cursor([{ tokenIndex: 2, childIndex: 0 }], 3);
125 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 1 });
126 expect(loc).toEqual(new Cursor([{ tokenIndex: 1, childIndex: 0 }], 3));
127 });
128
129 test("Parent-strand deletion after token", () => {
130 const loc = new Cursor([{ tokenIndex: 2, childIndex: 0 }], 3);
131 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 3 });
132 expect(loc).toEqual(new Cursor([{ tokenIndex: 2, childIndex: 0 }], 3));
133 });
134
135 test("Parent-strand deletion of current token's parent", () => {
136 const loc = new Cursor([{ tokenIndex: 2, childIndex: 0 }], 3);
137 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 2 });
138 expect(loc).toEqual(new Cursor([], 2));
139 });
140
141 test("Grandparent-strand deletion before token", () => {
142 const loc = new Cursor(
143 [
144 { tokenIndex: 1, childIndex: 0 },
145 { tokenIndex: 2, childIndex: 1 },
146 ],
147 4
148 );
149 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 0 });
150 expect(loc).toEqual(
151 new Cursor(
152 [
153 { tokenIndex: 0, childIndex: 0 },
154 { tokenIndex: 2, childIndex: 1 },
155 ],
156 4
157 )
158 );
159 });
160
161 test("Grandparent-strand deletion after token", () => {
162 const loc = new Cursor(
163 [
164 { tokenIndex: 1, childIndex: 0 },
165 { tokenIndex: 2, childIndex: 1 },
166 ],
167 4
168 );
169 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 2 });
170 expect(loc).toEqual(
171 new Cursor(
172 [
173 { tokenIndex: 1, childIndex: 0 },
174 { tokenIndex: 2, childIndex: 1 },
175 ],
176 4
177 )
178 );
179 });
180
181 test("Grandparent-strand deletion of current token's grandparent", () => {
182 const loc = new Cursor(
183 [
184 { tokenIndex: 1, childIndex: 0 },
185 { tokenIndex: 2, childIndex: 1 },
186 ],
187 4
188 );
189 loc.updateAfterTokenDeletion({ strandPath: [], tokenIndex: 1 });
190 expect(loc).toEqual(new Cursor([], 1));
191 });
192});