@khanacademy/math-input 17.0.4 → 17.0.6

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 (86) hide show
  1. package/dist/components/input/math-wrapper.d.ts +2 -2
  2. package/dist/components/input/mathquill-types.d.ts +49 -6
  3. package/dist/es/index.js +8 -6
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.js +8 -7
  6. package/dist/index.js.map +1 -1
  7. package/package.json +6 -3
  8. package/.eslintrc.js +0 -18
  9. package/CHANGELOG.md +0 -660
  10. package/less/main.less +0 -2
  11. package/less/overrides.less +0 -122
  12. package/src/components/__tests__/integration.test.tsx +0 -300
  13. package/src/components/aphrodite-css-transition-group/index.tsx +0 -78
  14. package/src/components/aphrodite-css-transition-group/transition-child.tsx +0 -192
  15. package/src/components/aphrodite-css-transition-group/types.ts +0 -20
  16. package/src/components/aphrodite-css-transition-group/util.ts +0 -97
  17. package/src/components/input/__tests__/context-tracking.test.ts +0 -176
  18. package/src/components/input/__tests__/mathquill-helpers.test.ts +0 -105
  19. package/src/components/input/__tests__/mathquill.test.ts +0 -747
  20. package/src/components/input/__tests__/test-math-wrapper.ts +0 -29
  21. package/src/components/input/cursor-contexts.ts +0 -37
  22. package/src/components/input/cursor-handle.tsx +0 -137
  23. package/src/components/input/cursor-styles.ts +0 -10
  24. package/src/components/input/drag-listener.ts +0 -79
  25. package/src/components/input/math-input.tsx +0 -1036
  26. package/src/components/input/math-wrapper.ts +0 -189
  27. package/src/components/input/mathquill-helpers.ts +0 -262
  28. package/src/components/input/mathquill-instance.ts +0 -106
  29. package/src/components/input/mathquill-types.ts +0 -32
  30. package/src/components/input/scroll-into-view.ts +0 -65
  31. package/src/components/key-handlers/__tests__/handle-jump-out.test.ts +0 -94
  32. package/src/components/key-handlers/handle-arrow.ts +0 -70
  33. package/src/components/key-handlers/handle-backspace.ts +0 -277
  34. package/src/components/key-handlers/handle-exponent.ts +0 -53
  35. package/src/components/key-handlers/handle-jump-out.ts +0 -107
  36. package/src/components/key-handlers/key-translator.ts +0 -222
  37. package/src/components/keypad/__tests__/__snapshots__/keypad.test.tsx.snap +0 -1913
  38. package/src/components/keypad/__tests__/__snapshots__/mobile-keypad.test.tsx.snap +0 -600
  39. package/src/components/keypad/__tests__/keypad-button.test.tsx +0 -84
  40. package/src/components/keypad/__tests__/keypad-v2-mathquill.test.tsx +0 -304
  41. package/src/components/keypad/__tests__/keypad-v2.cypress.ts +0 -16
  42. package/src/components/keypad/__tests__/keypad.test.tsx +0 -321
  43. package/src/components/keypad/__tests__/mobile-keypad.test.tsx +0 -115
  44. package/src/components/keypad/__tests__/test-data-tabs.ts +0 -21
  45. package/src/components/keypad/button-assets.tsx +0 -1880
  46. package/src/components/keypad/index.tsx +0 -2
  47. package/src/components/keypad/keypad-button.stories.tsx +0 -81
  48. package/src/components/keypad/keypad-button.tsx +0 -124
  49. package/src/components/keypad/keypad-mathquill.stories.tsx +0 -109
  50. package/src/components/keypad/keypad-pages/extras-page.tsx +0 -35
  51. package/src/components/keypad/keypad-pages/fractions-page.tsx +0 -125
  52. package/src/components/keypad/keypad-pages/geometry-page.tsx +0 -34
  53. package/src/components/keypad/keypad-pages/keypad-pages.stories.tsx +0 -37
  54. package/src/components/keypad/keypad-pages/numbers-page.tsx +0 -94
  55. package/src/components/keypad/keypad-pages/operators-page.tsx +0 -117
  56. package/src/components/keypad/keypad.tsx +0 -233
  57. package/src/components/keypad/mobile-keypad-internals.tsx +0 -240
  58. package/src/components/keypad/mobile-keypad.tsx +0 -24
  59. package/src/components/keypad/navigation-button.tsx +0 -127
  60. package/src/components/keypad/navigation-pad.stories.tsx +0 -26
  61. package/src/components/keypad/navigation-pad.tsx +0 -67
  62. package/src/components/keypad/shared-keys.tsx +0 -109
  63. package/src/components/keypad/utils.ts +0 -34
  64. package/src/components/keypad-context.tsx +0 -70
  65. package/src/components/prop-types.ts +0 -16
  66. package/src/components/tabbar/__tests__/tabbar.test.tsx +0 -105
  67. package/src/components/tabbar/icons.tsx +0 -122
  68. package/src/components/tabbar/index.ts +0 -1
  69. package/src/components/tabbar/item.tsx +0 -146
  70. package/src/components/tabbar/tabbar.stories.tsx +0 -83
  71. package/src/components/tabbar/tabbar.tsx +0 -65
  72. package/src/data/key-configs.ts +0 -770
  73. package/src/data/keys.ts +0 -123
  74. package/src/enums.ts +0 -27
  75. package/src/fake-react-native-web/index.ts +0 -11
  76. package/src/fake-react-native-web/text.tsx +0 -55
  77. package/src/fake-react-native-web/view.tsx +0 -91
  78. package/src/full-keypad.stories.tsx +0 -142
  79. package/src/full-mobile-input.stories.tsx +0 -115
  80. package/src/index.ts +0 -52
  81. package/src/types.ts +0 -70
  82. package/src/utils.test.ts +0 -33
  83. package/src/utils.ts +0 -61
  84. package/src/version.ts +0 -10
  85. package/tsconfig-build.json +0 -11
  86. 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
- });