@khanacademy/math-input 17.0.3 → 17.0.5

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.
Files changed (84) hide show
  1. package/dist/es/index.js +2 -2
  2. package/dist/es/index.js.map +1 -1
  3. package/dist/index.js +2 -2
  4. package/dist/index.js.map +1 -1
  5. package/package.json +5 -2
  6. package/.eslintrc.js +0 -18
  7. package/CHANGELOG.md +0 -654
  8. package/less/main.less +0 -2
  9. package/less/overrides.less +0 -122
  10. package/src/components/__tests__/integration.test.tsx +0 -300
  11. package/src/components/aphrodite-css-transition-group/index.tsx +0 -78
  12. package/src/components/aphrodite-css-transition-group/transition-child.tsx +0 -192
  13. package/src/components/aphrodite-css-transition-group/types.ts +0 -20
  14. package/src/components/aphrodite-css-transition-group/util.ts +0 -97
  15. package/src/components/input/__tests__/context-tracking.test.ts +0 -176
  16. package/src/components/input/__tests__/mathquill-helpers.test.ts +0 -105
  17. package/src/components/input/__tests__/mathquill.test.ts +0 -747
  18. package/src/components/input/__tests__/test-math-wrapper.ts +0 -29
  19. package/src/components/input/cursor-contexts.ts +0 -37
  20. package/src/components/input/cursor-handle.tsx +0 -137
  21. package/src/components/input/cursor-styles.ts +0 -10
  22. package/src/components/input/drag-listener.ts +0 -79
  23. package/src/components/input/math-input.tsx +0 -1036
  24. package/src/components/input/math-wrapper.ts +0 -189
  25. package/src/components/input/mathquill-helpers.ts +0 -262
  26. package/src/components/input/mathquill-instance.ts +0 -106
  27. package/src/components/input/mathquill-types.ts +0 -32
  28. package/src/components/input/scroll-into-view.ts +0 -65
  29. package/src/components/key-handlers/__tests__/handle-jump-out.test.ts +0 -94
  30. package/src/components/key-handlers/handle-arrow.ts +0 -70
  31. package/src/components/key-handlers/handle-backspace.ts +0 -277
  32. package/src/components/key-handlers/handle-exponent.ts +0 -53
  33. package/src/components/key-handlers/handle-jump-out.ts +0 -107
  34. package/src/components/key-handlers/key-translator.ts +0 -222
  35. package/src/components/keypad/__tests__/__snapshots__/keypad.test.tsx.snap +0 -1913
  36. package/src/components/keypad/__tests__/__snapshots__/mobile-keypad.test.tsx.snap +0 -600
  37. package/src/components/keypad/__tests__/keypad-button.test.tsx +0 -84
  38. package/src/components/keypad/__tests__/keypad-v2-mathquill.test.tsx +0 -304
  39. package/src/components/keypad/__tests__/keypad-v2.cypress.ts +0 -16
  40. package/src/components/keypad/__tests__/keypad.test.tsx +0 -321
  41. package/src/components/keypad/__tests__/mobile-keypad.test.tsx +0 -115
  42. package/src/components/keypad/__tests__/test-data-tabs.ts +0 -21
  43. package/src/components/keypad/button-assets.tsx +0 -1880
  44. package/src/components/keypad/index.tsx +0 -2
  45. package/src/components/keypad/keypad-button.stories.tsx +0 -81
  46. package/src/components/keypad/keypad-button.tsx +0 -124
  47. package/src/components/keypad/keypad-mathquill.stories.tsx +0 -109
  48. package/src/components/keypad/keypad-pages/extras-page.tsx +0 -35
  49. package/src/components/keypad/keypad-pages/fractions-page.tsx +0 -125
  50. package/src/components/keypad/keypad-pages/geometry-page.tsx +0 -34
  51. package/src/components/keypad/keypad-pages/keypad-pages.stories.tsx +0 -37
  52. package/src/components/keypad/keypad-pages/numbers-page.tsx +0 -94
  53. package/src/components/keypad/keypad-pages/operators-page.tsx +0 -117
  54. package/src/components/keypad/keypad.tsx +0 -233
  55. package/src/components/keypad/mobile-keypad-internals.tsx +0 -240
  56. package/src/components/keypad/mobile-keypad.tsx +0 -24
  57. package/src/components/keypad/navigation-button.tsx +0 -127
  58. package/src/components/keypad/navigation-pad.stories.tsx +0 -26
  59. package/src/components/keypad/navigation-pad.tsx +0 -67
  60. package/src/components/keypad/shared-keys.tsx +0 -109
  61. package/src/components/keypad/utils.ts +0 -34
  62. package/src/components/keypad-context.tsx +0 -70
  63. package/src/components/prop-types.ts +0 -16
  64. package/src/components/tabbar/__tests__/tabbar.test.tsx +0 -105
  65. package/src/components/tabbar/icons.tsx +0 -122
  66. package/src/components/tabbar/index.ts +0 -1
  67. package/src/components/tabbar/item.tsx +0 -146
  68. package/src/components/tabbar/tabbar.stories.tsx +0 -83
  69. package/src/components/tabbar/tabbar.tsx +0 -65
  70. package/src/data/key-configs.ts +0 -770
  71. package/src/data/keys.ts +0 -123
  72. package/src/enums.ts +0 -27
  73. package/src/fake-react-native-web/index.ts +0 -11
  74. package/src/fake-react-native-web/text.tsx +0 -55
  75. package/src/fake-react-native-web/view.tsx +0 -91
  76. package/src/full-keypad.stories.tsx +0 -142
  77. package/src/full-mobile-input.stories.tsx +0 -115
  78. package/src/index.ts +0 -52
  79. package/src/types.ts +0 -70
  80. package/src/utils.test.ts +0 -33
  81. package/src/utils.ts +0 -61
  82. package/src/version.ts +0 -10
  83. package/tsconfig-build.json +0 -11
  84. package/tsconfig-build.tsbuildinfo +0 -1
@@ -1,747 +0,0 @@
1
- import TestMathWrapper from "./test-math-wrapper";
2
-
3
- const MQ = {L: "-1", R: "1"};
4
- const END_OF_EXPR = 0;
5
-
6
- const isInsideEmptyParens = (cursor) => {
7
- return (
8
- cursor[MQ.L] === END_OF_EXPR &&
9
- cursor[MQ.R] === END_OF_EXPR &&
10
- cursor.parent.parent.ctrlSeq === "\\left("
11
- );
12
- };
13
-
14
- describe("MathQuill", () => {
15
- let mathField;
16
- let span;
17
-
18
- beforeEach(() => {
19
- span = document.createElement("span");
20
- document.body.appendChild(span);
21
-
22
- mathField = new TestMathWrapper(span);
23
- });
24
-
25
- afterEach(() => {
26
- document.body.removeChild(span);
27
- });
28
-
29
- // TODO(charlie): Add tests for "FRAC_EXCLUSIVE" (the mixed-number
30
- // fraction key).
31
- describe("Fraction Bar", () => {
32
- it("should work with no content", () => {
33
- mathField.pressKey("FRAC_INCLUSIVE");
34
- expect(mathField.getContent()).toEqual("\\frac{ }{ }");
35
- });
36
-
37
- it("should work after an expression", () => {
38
- mathField.setContent("35x^{2}");
39
- mathField.pressKey("FRAC_INCLUSIVE");
40
- expect(mathField.getContent()).toEqual("\\frac{35x^{2}}{ }");
41
- });
42
-
43
- it("should work before an expression", () => {
44
- mathField.setContent("35x^{2}");
45
- mathField.moveToStart();
46
- mathField.pressKey("FRAC_INCLUSIVE");
47
- expect(mathField.getContent()).toEqual("\\frac{ }{ }35x^{2}");
48
- });
49
-
50
- it("should work with a selected expression", () => {
51
- mathField.setContent("35x^{2}");
52
- mathField.selectAll();
53
- mathField.pressKey("FRAC_INCLUSIVE");
54
- expect(mathField.getContent()).toEqual("\\frac{35x^{2}}{ }");
55
- });
56
- });
57
-
58
- describe("Parentheses", () => {
59
- it("should work with no content", () => {
60
- mathField.setContent("");
61
- mathField.pressKey("LEFT_PAREN");
62
- expect(mathField.getContent()).toEqual("\\left(\\right)");
63
- });
64
-
65
- it("should work after an expression", () => {
66
- mathField.setContent("35x^{2}");
67
- mathField.pressKey("RIGHT_PAREN");
68
- expect(mathField.getContent()).toEqual("\\left(35x^{2}\\right)");
69
- });
70
-
71
- it("should work before an expression", () => {
72
- mathField.setContent("35x^{2}");
73
- mathField.moveToStart();
74
- mathField.pressKey("LEFT_PAREN");
75
- expect(mathField.getContent()).toEqual("\\left(35x^{2}\\right)");
76
- });
77
-
78
- it.skip("should work on a selected expression", () => {
79
- mathField.setContent("35x + 5");
80
- mathField.selectAll();
81
- mathField.pressKey("LEFT_PAREN");
82
- expect(mathField.getContent()).toEqual("\\left(35x^{2}\\right)");
83
- });
84
- });
85
-
86
- describe("Squared", () => {
87
- it("should prefix with empty parens after no content", () => {
88
- mathField.pressKey("EXP_2");
89
- expect(mathField.getContent()).toEqual("\\left(\\right)^{2}");
90
-
91
- // Verify that the cursor is in parens.
92
- expect(isInsideEmptyParens(mathField.getCursor())).toBeTruthy();
93
- });
94
-
95
- it("should prefix with empty parens after an operator", () => {
96
- mathField.pressKey("DIVIDE");
97
- mathField.pressKey("EXP_2");
98
- expect(mathField.getContent()).toEqual("\\div\\left(\\right)^{2}");
99
- });
100
-
101
- it("should work after an expression", () => {
102
- mathField.setContent("35x");
103
- mathField.pressKey("EXP_2");
104
- expect(mathField.getContent()).toEqual("35x^{2}");
105
- });
106
-
107
- it.skip("should work on a selected expression", () => {
108
- mathField.setContent("35x+5");
109
- mathField.selectAll();
110
- mathField.pressKey("EXP_2");
111
- expect(mathField.getContent()).toEqual("\\left(35x+5\\right)^{2}");
112
- });
113
- });
114
-
115
- describe("Cubed", () => {
116
- it("should prefix with empty parens after no content", () => {
117
- mathField.pressKey("EXP_3");
118
- expect(mathField.getContent()).toEqual("\\left(\\right)^{3}");
119
-
120
- // Verify that the cursor is in parens.
121
- expect(isInsideEmptyParens(mathField.getCursor())).toBeTruthy();
122
- });
123
-
124
- it("should prefix with empty parens after an operator", () => {
125
- mathField.pressKey("EQUAL");
126
- mathField.pressKey("EXP_3");
127
- expect(mathField.getContent()).toEqual("=\\left(\\right)^{3}");
128
- });
129
-
130
- it("should work after an expression", () => {
131
- mathField.setContent("35x");
132
- mathField.pressKey("EXP_3");
133
- expect(mathField.getContent()).toEqual("35x^{3}");
134
- });
135
-
136
- it.skip("should work on a selected expression", () => {
137
- mathField.setContent("35x+5");
138
- mathField.selectAll();
139
- mathField.pressKey("EXP_3");
140
- expect(mathField.getContent()).toEqual("\\left(35x+5\\right)^{3}");
141
- });
142
- });
143
-
144
- describe("Exponent", () => {
145
- it("should prefix with empty parens after no content", () => {
146
- mathField.pressKey("EXP");
147
- expect(mathField.getContent()).toEqual("\\left(\\right)^{ }");
148
-
149
- // Verify that the cursor is in the exponent, not within the parens,
150
- // writing a unique character to verify cursor position.
151
- expect(isInsideEmptyParens(mathField.getCursor())).toBeFalsy();
152
- mathField.pressKey("PLUS");
153
- expect(mathField.getContent()).toEqual("\\left(\\right)^{+}");
154
- });
155
-
156
- it("should prefix with empty parens after an operator", () => {
157
- mathField.pressKey("PLUS");
158
- mathField.pressKey("EXP");
159
- expect(mathField.getContent()).toEqual("+\\left(\\right)^{ }");
160
- });
161
-
162
- it("should work after an expression", () => {
163
- mathField.setContent("35x");
164
- mathField.pressKey("EXP");
165
- expect(mathField.getContent()).toEqual("35x^{ }");
166
- });
167
-
168
- // TODO(kevinb): makes the expression an exponent when it shouldn't
169
- it.skip("should work on a selected expression", () => {
170
- mathField.setContent("35x+5");
171
- mathField.selectAll();
172
- mathField.pressKey("EXP");
173
- expect(mathField.getContent()).toEqual("\\left(35x+5\\right)^{ }");
174
- });
175
- });
176
-
177
- describe("Square Root", () => {
178
- it("should work with no content", () => {
179
- mathField.pressKey("SQRT");
180
- expect(mathField.getContent()).toEqual("\\sqrt{ }");
181
- });
182
-
183
- it("should work after an expression", () => {
184
- mathField.setContent("35x^{2}");
185
- mathField.pressKey("SQRT");
186
- expect(mathField.getContent()).toEqual("35x^{2}\\sqrt{ }");
187
- });
188
-
189
- it("should work on a selected expression", () => {
190
- mathField.setContent("35x+5");
191
- mathField.selectAll();
192
- mathField.pressKey("SQRT");
193
- expect(mathField.getContent()).toEqual("\\sqrt{35x+5}");
194
- });
195
- });
196
-
197
- describe("Radical", () => {
198
- it("should work with no content", () => {
199
- mathField.pressKey("RADICAL");
200
- expect(mathField.getContent()).toEqual("\\sqrt[]{}");
201
- });
202
-
203
- it("should work after an expression", () => {
204
- mathField.setContent("35x^{2}");
205
- mathField.pressKey("RADICAL");
206
- expect(mathField.getContent()).toEqual("35x^{2}\\sqrt[]{}");
207
- });
208
-
209
- it.skip("should work on a selected expression", () => {
210
- mathField.setContent("35x+5");
211
- mathField.selectAll();
212
- mathField.pressKey("RADICAL");
213
- // TODO(kevinb): check cursor location
214
- expect(mathField.getContent()).toEqual("\\sqrt[ ]{35x+5}");
215
- });
216
- });
217
-
218
- describe("Log", () => {
219
- it("should work with no content", () => {
220
- mathField.pressKey("LOG");
221
- expect(mathField.getContent()).toEqual("\\log\\left(\\right)");
222
- });
223
-
224
- it("should work after an expression", () => {
225
- mathField.setContent("35x^{2}");
226
- mathField.pressKey("LOG");
227
- expect(mathField.getContent()).toEqual(
228
- "35x^{2}\\log\\left(\\right)",
229
- );
230
- });
231
-
232
- it.skip("should work on a selected expression", () => {
233
- mathField.setContent("35x+5");
234
- mathField.selectAll();
235
- mathField.pressKey("LOG");
236
- expect(mathField.getContent()).toEqual("\\log\\left(35x+5\\right)");
237
- });
238
- });
239
-
240
- describe("Log w/ base n", () => {
241
- it("should work with no content", () => {
242
- mathField.pressKey("LOG_N");
243
- expect(mathField.getContent()).toEqual("\\log_{ }\\left(\\right)");
244
- });
245
-
246
- it("should work after an expression", () => {
247
- mathField.setContent("35x^{2}");
248
- mathField.pressKey("LOG_N");
249
- expect(mathField.getContent()).toEqual(
250
- "35x^{2}\\log_{ }\\left(\\right)",
251
- );
252
- });
253
-
254
- it.skip("should work on a selected expression", () => {
255
- mathField.setContent("35x+5");
256
- mathField.selectAll();
257
- mathField.pressKey("LOG_N");
258
- expect(mathField.getContent()).toEqual(
259
- "\\log_{ }\\left(35x+5\\right)",
260
- );
261
- });
262
- });
263
-
264
- describe("Backspace", () => {
265
- it("should delete an empty fraction from the numerator", () => {
266
- mathField.setContent("\\frac{ }{ }");
267
- mathField.moveToStart();
268
- mathField.pressKey("RIGHT");
269
- mathField.pressKey("BACKSPACE");
270
- expect(mathField.getContent()).toEqual("");
271
- });
272
-
273
- it("should convert a fraction when deleting the denominator", () => {
274
- mathField.setContent("\\frac{35x^{2}}{ }");
275
- mathField.pressKey("LEFT");
276
- mathField.pressKey("BACKSPACE");
277
- expect(mathField.getContent()).toEqual("35x^{2}");
278
- });
279
-
280
- // TODO(kevinb) math isn't selected
281
- it("should select a fraction when deleting from outside of it", () => {
282
- const expr = "\\frac{35x+5}{x^{2}}";
283
- mathField.setContent(expr);
284
- mathField.pressKey("BACKSPACE");
285
- expect(mathField.isSelected()).toBeTruthy();
286
- expect(mathField.getContent()).toEqual(expr);
287
- });
288
-
289
- it("should delete parens when inside empty parens", () => {
290
- mathField.setContent("\\left(\\right)");
291
- mathField.pressKey("LEFT");
292
- mathField.pressKey("BACKSPACE");
293
- expect(mathField.getContent()).toEqual("");
294
- });
295
-
296
- it("deletes only the first parens when inside empty parens", () => {
297
- mathField.setContent("\\left(\\right)\\left(\\right)");
298
- mathField.pressKey("LEFT");
299
- mathField.pressKey("BACKSPACE");
300
- expect(mathField.getContent()).toEqual("\\left(\\right)");
301
- });
302
-
303
- it("should select an expression when deleting from outside (1)", () => {
304
- const expr = "\\left(35x+5\\right)";
305
- mathField.setContent(expr);
306
- mathField.pressKey("BACKSPACE");
307
- expect(mathField.isSelected()).toBeTruthy();
308
- expect(mathField.getContent()).toEqual(expr);
309
- });
310
-
311
- it("should select an expression when deleting from outside (2)", () => {
312
- const expr = "1+\\left(35x+5\\right)";
313
- mathField.setContent(expr);
314
- mathField.pressKey("BACKSPACE");
315
- const selection = mathField.getSelection();
316
- const left = selection.ends[MQ.L][MQ.L];
317
- const right = selection.ends[MQ.R][MQ.R];
318
-
319
- expect(left.ctrlSeq).toEqual("+");
320
- expect(right).toEqual(END_OF_EXPR);
321
- expect(mathField.getContent()).toEqual(expr);
322
- });
323
-
324
- it("should select an expression when deleting from outside (3)", () => {
325
- const expr = "1+\\left(35x+5\\right)-1";
326
- mathField.setContent(expr);
327
- mathField.pressKey("LEFT");
328
- mathField.pressKey("LEFT");
329
- mathField.pressKey("BACKSPACE");
330
- const selection = mathField.getSelection();
331
- const left = selection.ends[MQ.L][MQ.L];
332
- const right = selection.ends[MQ.R][MQ.R];
333
-
334
- expect(left.ctrlSeq).toEqual("+");
335
- expect(right.ctrlSeq).toEqual("-");
336
- expect(mathField.getContent()).toEqual(expr);
337
- });
338
-
339
- it("should select an expression when deleting from outside (4)", () => {
340
- const expr = "\\left(35x+5\\right)-1";
341
- mathField.setContent(expr);
342
- mathField.pressKey("LEFT");
343
- mathField.pressKey("LEFT");
344
- mathField.pressKey("BACKSPACE");
345
- const selection = mathField.getSelection();
346
- const left = selection.ends[MQ.L][MQ.L];
347
- const right = selection.ends[MQ.R][MQ.R];
348
-
349
- expect(left).toEqual(END_OF_EXPR);
350
- expect(right.ctrlSeq).toEqual("-");
351
- expect(mathField.getContent()).toEqual(expr);
352
- });
353
-
354
- it("should select an expression when deleting from outside", () => {
355
- mathField.setContent("\\left(35x+5\\right)");
356
- mathField.pressKey("BACKSPACE");
357
- expect(mathField.isSelected()).toBeTruthy();
358
- expect(mathField.getContent()).toEqual("\\left(35x+5\\right)");
359
- });
360
-
361
- // TODO(kevinb) fix this behavior so that we delete the exponent too
362
- it.skip("should not delete squared exponents", () => {
363
- mathField.setContent("35x^{2}");
364
- mathField.pressKey("BACKSPACE");
365
- expect(mathField.getContent()).toEqual("35x^{2}");
366
- mathField.pressKey("BACKSPACE");
367
- expect(mathField.getContent()).toEqual("35x^{ }");
368
- });
369
-
370
- it("should not delete non-square exponents", () => {
371
- mathField.setContent("35x^5");
372
- mathField.pressKey("BACKSPACE");
373
- expect(mathField.getContent()).toEqual("35x^{5}");
374
- mathField.pressKey("BACKSPACE");
375
- expect(mathField.getContent()).toEqual("35x^{ }");
376
- });
377
-
378
- it("should delete an empty exponent", () => {
379
- mathField.setContent("35x^{}");
380
- mathField.pressKey("LEFT");
381
- mathField.pressKey("BACKSPACE");
382
- expect(mathField.getContent()).toEqual("35x");
383
- });
384
-
385
- it("should delete an empty square root", () => {
386
- mathField.setContent("\\sqrt{}");
387
- mathField.pressKey("LEFT");
388
- mathField.pressKey("BACKSPACE");
389
- expect(mathField.getContent()).toEqual("");
390
- });
391
-
392
- it("should delete an empty radical when cursor is in index", () => {
393
- mathField.setContent("\\sqrt[]{}");
394
- mathField.moveToStart();
395
- mathField.pressKey("RIGHT");
396
- mathField.pressKey("BACKSPACE");
397
- expect(mathField.getContent()).toEqual("");
398
- });
399
-
400
- it("should delete an empty radical when cursor is in body", () => {
401
- mathField.pressKey("RADICAL");
402
- mathField.pressKey("RIGHT");
403
- mathField.pressKey("BACKSPACE");
404
- expect(mathField.getContent()).toEqual("");
405
- });
406
-
407
- it("should select an empty radical with non-empty root", () => {
408
- mathField.pressKey("CUBE_ROOT");
409
- const expr = mathField.getContent();
410
- mathField.pressKey("BACKSPACE");
411
-
412
- expect(mathField.isSelected()).toBeTruthy();
413
- expect(mathField.getContent()).toEqual(expr);
414
- });
415
-
416
- it("should normally delete within a non-empty radical", () => {
417
- mathField.pressKey("CUBE_ROOT");
418
- const expr = mathField.getContent();
419
-
420
- mathField.pressKey("NUM_2");
421
- mathField.pressKey("BACKSPACE");
422
-
423
- expect(mathField.getContent()).toEqual(expr);
424
- });
425
-
426
- it("deletes nthroot index normally", () => {
427
- mathField.setContent("\\sqrt[3]{35x+5}");
428
- mathField.moveToStart();
429
- mathField.pressKey("RIGHT");
430
- mathField.pressKey("RIGHT");
431
- mathField.pressKey("BACKSPACE");
432
-
433
- const cursor = mathField.getCursor();
434
-
435
- expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
436
- expect(mathField.getContent()).toEqual("\\sqrt[]{35x+5}");
437
- });
438
-
439
- it("converts nthroot to sqrt when deleting from index (1)", () => {
440
- mathField.setContent("\\sqrt[]{35x+5}");
441
- mathField.moveToStart();
442
- mathField.pressKey("RIGHT");
443
- mathField.pressKey("BACKSPACE");
444
-
445
- const cursor = mathField.getCursor();
446
-
447
- expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
448
- expect(mathField.getContent()).toEqual("\\sqrt{35x+5}");
449
- });
450
-
451
- it("converts nthroot to sqrt when deleting from index (2)", () => {
452
- mathField.setContent("1+\\sqrt[]{35x+5}");
453
- mathField.moveToStart();
454
- mathField.pressKey("RIGHT");
455
- mathField.pressKey("RIGHT");
456
- mathField.pressKey("RIGHT");
457
- mathField.pressKey("BACKSPACE");
458
-
459
- const cursor = mathField.getCursor();
460
-
461
- expect(cursor[MQ.L].ctrlSeq).toEqual("+");
462
- expect(mathField.getContent()).toEqual("1+\\sqrt{35x+5}");
463
- });
464
-
465
- it("should not delete if the index has contents", () => {
466
- const expr = "\\sqrt[3]{35x+5}";
467
- mathField.setContent(expr);
468
- mathField.moveToStart();
469
- mathField.pressKey("RIGHT");
470
- mathField.pressKey("BACKSPACE");
471
-
472
- expect(mathField.getContent()).toEqual(expr);
473
- });
474
-
475
- it("should select a full square root before deleting it", () => {
476
- const expr = "\\sqrt{35x+5}";
477
- mathField.setContent(expr);
478
- mathField.pressKey("BACKSPACE");
479
-
480
- expect(mathField.isSelected()).toBeTruthy();
481
- expect(mathField.getContent()).toEqual(expr);
482
- });
483
-
484
- it("should select a full nth-root before deleting it", () => {
485
- const expr = "\\sqrt[3]{35x+5}";
486
- mathField.setContent(expr);
487
- mathField.pressKey("BACKSPACE");
488
-
489
- expect(mathField.isSelected()).toBeTruthy();
490
- expect(mathField.getContent()).toEqual(expr);
491
- });
492
-
493
- it("should delete log when inside empty log", () => {
494
- mathField.setContent("\\log\\left(\\right)");
495
- mathField.pressKey("LEFT");
496
- mathField.pressKey("BACKSPACE");
497
- expect(mathField.getContent()).toEqual("");
498
- });
499
-
500
- it("should select log when inside full log at head", () => {
501
- const expr = "\\log\\left(35x\\right)";
502
- mathField.setContent(expr);
503
- mathField.moveToStart();
504
- mathField.pressKey("RIGHT");
505
- mathField.pressKey("BACKSPACE");
506
- expect(mathField.isSelected()).toBeTruthy();
507
- expect(mathField.getContent()).toEqual(expr);
508
- });
509
-
510
- it("should select log when outside full log at tail (1)", () => {
511
- const expr = "\\log\\left(35x\\right)";
512
- mathField.setContent(expr);
513
- mathField.pressKey("BACKSPACE");
514
- expect(mathField.isSelected()).toBeTruthy();
515
- expect(mathField.getContent()).toEqual(expr);
516
- });
517
-
518
- it("should select log when outside full log at tail (2)", () => {
519
- const expr = "1+\\log\\left(35x\\right)";
520
- mathField.setContent(expr);
521
- mathField.pressKey("BACKSPACE");
522
- const selection = mathField.getSelection();
523
- const left = selection.ends[MQ.L][MQ.L];
524
- const right = selection.ends[MQ.R][MQ.R];
525
-
526
- expect(left.ctrlSeq).toEqual("+");
527
- expect(right).toEqual(END_OF_EXPR);
528
- expect(mathField.getContent()).toEqual(expr);
529
- });
530
-
531
- it("should select log when outside full log at tail (3)", () => {
532
- const expr = "1+\\log\\left(35x\\right)-1";
533
- mathField.setContent(expr);
534
- mathField.pressKey("LEFT");
535
- mathField.pressKey("LEFT");
536
- mathField.pressKey("BACKSPACE");
537
- const selection = mathField.getSelection();
538
- const left = selection.ends[MQ.L][MQ.L];
539
- const right = selection.ends[MQ.R][MQ.R];
540
-
541
- expect(left.ctrlSeq).toEqual("+");
542
- expect(right.ctrlSeq).toEqual("-");
543
- expect(mathField.getContent()).toEqual(expr);
544
- });
545
-
546
- it("should select log when outside full log at tail (4)", () => {
547
- const expr = "\\log\\left(35x\\right)-1";
548
- mathField.setContent(expr);
549
- mathField.pressKey("LEFT");
550
- mathField.pressKey("LEFT");
551
- mathField.pressKey("BACKSPACE");
552
- const selection = mathField.getSelection();
553
- const left = selection.ends[MQ.L][MQ.L];
554
- const right = selection.ends[MQ.R][MQ.R];
555
-
556
- expect(left).toEqual(END_OF_EXPR);
557
- expect(right.ctrlSeq).toEqual("-");
558
- expect(mathField.getContent()).toEqual(expr);
559
- });
560
-
561
- it("should delete empty log when at index", () => {
562
- mathField.setContent("\\log_{ }\\left(\\right)");
563
- mathField.moveToStart();
564
-
565
- // Move right once to get into the parens, and then left twice to
566
- // get to the empty index.
567
- mathField.pressKey("RIGHT");
568
- mathField.pressKey("LEFT");
569
- mathField.pressKey("LEFT");
570
-
571
- mathField.pressKey("BACKSPACE");
572
- expect(mathField.getContent()).toEqual("");
573
- });
574
-
575
- it("should delete log index normally", () => {
576
- mathField.setContent("\\log_5\\left(\\right)");
577
- mathField.moveToStart();
578
-
579
- // Move right once to get into the parens, and then left twice to
580
- // get to the index.
581
- mathField.pressKey("RIGHT");
582
- mathField.pressKey("LEFT");
583
- mathField.pressKey("LEFT");
584
-
585
- mathField.pressKey("BACKSPACE");
586
- expect(mathField.getContent()).toEqual("\\log_{ }\\left(\\right)");
587
- });
588
-
589
- it("should move to index from inside empty log with index", () => {
590
- mathField.setContent("\\log_5\\left(\\right)");
591
- mathField.pressKey("LEFT");
592
- mathField.pressKey("BACKSPACE");
593
-
594
- const cursor = mathField.getCursor();
595
-
596
- expect(cursor[MQ.L].ctrlSeq).toEqual("5");
597
- expect(mathField.getContent()).toEqual("\\log_{5}\\left(\\right)");
598
- });
599
-
600
- it("should select full log when deleting from empty index (1)", () => {
601
- const expr = "\\log_{ }\\left(x\\right)";
602
- mathField.setContent(expr);
603
- mathField.moveToStart();
604
-
605
- // Move right once to get into the parens, and then left twice to
606
- // get to the empty index.
607
- mathField.pressKey("RIGHT");
608
- mathField.pressKey("LEFT");
609
- mathField.pressKey("LEFT");
610
-
611
- mathField.pressKey("BACKSPACE");
612
-
613
- expect(mathField.isSelected()).toBeTruthy();
614
- expect(mathField.getContent()).toEqual(expr);
615
- });
616
-
617
- it("should select full log when deleting from empty index (2)", () => {
618
- const expr = "1+\\log_{ }\\left(x\\right)";
619
- mathField.setContent(expr);
620
- mathField.moveToStart();
621
-
622
- // Move right once to get into the parens, and then left twice to
623
- // get to the empty index.
624
- mathField.pressKey("RIGHT");
625
- mathField.pressKey("RIGHT");
626
- mathField.pressKey("RIGHT");
627
- mathField.pressKey("LEFT");
628
- mathField.pressKey("LEFT");
629
-
630
- mathField.pressKey("BACKSPACE");
631
-
632
- const selection = mathField.getSelection();
633
- const left = selection.ends[MQ.L][MQ.L];
634
- const right = selection.ends[MQ.R][MQ.R];
635
-
636
- expect(left.ctrlSeq).toEqual("+");
637
- expect(right).toEqual(END_OF_EXPR);
638
- expect(mathField.getContent()).toEqual(expr);
639
- });
640
-
641
- it("should select full log when deleting from empty index (3)", () => {
642
- const expr = "1+\\log_{ }\\left(x\\right)-1";
643
- mathField.setContent(expr);
644
- mathField.moveToStart();
645
-
646
- // Move right three times to get into the parens, and then left
647
- // twice to get to the start of the empty index.
648
- mathField.pressKey("RIGHT");
649
- mathField.pressKey("RIGHT");
650
- mathField.pressKey("RIGHT");
651
- mathField.pressKey("LEFT");
652
- mathField.pressKey("LEFT");
653
-
654
- mathField.pressKey("BACKSPACE");
655
-
656
- const selection = mathField.getSelection();
657
- const left = selection.ends[MQ.L][MQ.L];
658
- const right = selection.ends[MQ.R][MQ.R];
659
-
660
- expect(left.ctrlSeq).toEqual("+");
661
- expect(right.ctrlSeq).toEqual("-");
662
- expect(mathField.getContent()).toEqual(expr);
663
- });
664
-
665
- it("should select full log when deleting from empty index (4)", () => {
666
- const expr = "\\log_{ }\\left(x\\right)-1";
667
- mathField.setContent(expr);
668
- mathField.moveToStart();
669
-
670
- // Move right once to get into the parens, and then left twice to
671
- // get to the start of the empty index.
672
- mathField.pressKey("RIGHT");
673
- mathField.pressKey("LEFT");
674
- mathField.pressKey("LEFT");
675
-
676
- mathField.pressKey("BACKSPACE");
677
-
678
- const selection = mathField.getSelection();
679
- const left = selection.ends[MQ.L][MQ.L];
680
- const right = selection.ends[MQ.R][MQ.R];
681
-
682
- expect(left).toEqual(END_OF_EXPR);
683
- expect(right.ctrlSeq).toEqual("-");
684
- expect(mathField.getContent()).toEqual(expr);
685
- });
686
- });
687
-
688
- describe("Left arrow", () => {
689
- it("skips function names", () => {
690
- mathField.pressKey("COS");
691
- const cursor = mathField.getCursor();
692
-
693
- // Verify that we're inside the function.
694
- expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
695
- expect(cursor[MQ.R]).toEqual(END_OF_EXPR);
696
-
697
- // Navigate left.
698
- mathField.pressKey("LEFT");
699
-
700
- // Verify that we moved beyond the body of the function.
701
- expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
702
- expect(cursor[MQ.R].ctrlSeq).toEqual("\\c");
703
- });
704
-
705
- it("does not skip out of a function with valid content present", () => {
706
- mathField.pressKey("COS");
707
- mathField.pressKey("PLUS");
708
- const cursor = mathField.getCursor();
709
-
710
- // Verify that we're inside the function.
711
- expect(cursor[MQ.L].ctrlSeq).toEqual("+");
712
- expect(cursor[MQ.R]).toEqual(END_OF_EXPR);
713
-
714
- // Navigate left.
715
- mathField.pressKey("LEFT");
716
-
717
- // Verify that we didn't move out of the function.
718
- expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
719
- expect(cursor[MQ.R].ctrlSeq).toEqual("+");
720
- });
721
- });
722
-
723
- describe("Right arrow", () => {
724
- it("skips function names", () => {
725
- mathField.setContent("\\cos\\left(5\\right)");
726
- mathField.moveToStart();
727
- const cursor = mathField.getCursor();
728
-
729
- // Verify that we're outside the function.
730
- expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
731
- expect(cursor[MQ.R].ctrlSeq).toEqual("\\c");
732
-
733
- // Navigate right.
734
- mathField.pressKey("RIGHT");
735
-
736
- // Verify that we moved into the body of the function.
737
- expect(cursor[MQ.L]).toEqual(END_OF_EXPR);
738
- expect(cursor[MQ.R].ctrlSeq).toEqual("5");
739
- });
740
- });
741
-
742
- describe.skip("Jump out", () => {
743
- // TODO(charlie): Write extensive tests for the 'Jump out' behavior.
744
- });
745
-
746
- describe.skip("Equals =, !=, <, <=, >, >=", () => {});
747
- });