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