@khanacademy/kas 0.3.6 → 0.3.8

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.
@@ -1,505 +0,0 @@
1
- import _ from "underscore";
2
-
3
- import * as KAS from "../index";
4
-
5
- expect.extend({
6
- toParseAs(
7
- input: string,
8
- expected: string,
9
- options?: any,
10
- ): jest.CustomMatcherResult {
11
- const actual = KAS.parse(input, options).expr.print();
12
-
13
- if (actual !== expected) {
14
- return {
15
- pass: false,
16
- message: () => `${input} parses as ${expected}`,
17
- };
18
- }
19
-
20
- return {
21
- pass: !this.isNot,
22
- message: () => "",
23
- };
24
- },
25
- toParseWithStructure(
26
- input: string,
27
- expected: string,
28
- options?: any,
29
- ): jest.CustomMatcherResult {
30
- const actual = KAS.parse(input, options).expr.repr();
31
-
32
- if (actual !== expected) {
33
- return {
34
- pass: false,
35
- message: () => `${input} parses as ${expected}`,
36
- };
37
- }
38
-
39
- return {
40
- pass: !this.isNot,
41
- message: () => "",
42
- };
43
- },
44
- });
45
-
46
- // TODO(FEI-5054): Figure out how to get global .d.ts files working with monorepos
47
- declare global {
48
- // eslint-disable-next-line @typescript-eslint/no-namespace
49
- namespace jest {
50
- interface Matchers<R> {
51
- toParseAs(expected: string, options?: any): R;
52
- toParseWithStructure(expected: string, options?: any): R;
53
- }
54
- }
55
- }
56
-
57
- describe("parsing", () => {
58
- test("empty", () => {
59
- expect("").toParseAs("");
60
- });
61
-
62
- test("positive and negative primitives", () => {
63
- expect("0").toParseAs("0");
64
- expect("1.").toParseAs("1");
65
- expect("3.14").toParseAs("3.14");
66
- expect(".14").toParseAs("0.14");
67
- expect("pi").toParseAs("pi");
68
- expect("e").toParseAs("e");
69
- expect("x").toParseAs("x");
70
- expect("theta").toParseAs("theta");
71
-
72
- expect("-0").toParseAs("-1*0");
73
- expect("-1.").toParseAs("-1");
74
- expect("-3.14").toParseAs("-3.14");
75
- expect("-.14").toParseAs("-0.14");
76
- expect("-pi").toParseAs("-1*pi");
77
- expect("-e").toParseAs("-1*e");
78
- expect("-theta").toParseAs("-1*theta");
79
- });
80
-
81
- test("LaTeX constants", () => {
82
- expect("\\theta").toParseAs("theta");
83
- expect("\\pi").toParseAs("pi");
84
- expect("\\phi").toParseAs("phi");
85
- });
86
-
87
- test("ignore TeX spaces", () => {
88
- expect("a\\space b").toParseAs("a*b");
89
- expect("a\\ b").toParseAs("a*b");
90
- });
91
-
92
- test("positive and negative rationals", () => {
93
- expect("1/2").toParseAs("1/2");
94
- expect("-1/2").toParseAs("-1/2");
95
- expect("1/-2").toParseAs("-1/2");
96
- expect("-1/-2").toParseAs("-1*-1/2");
97
- expect("42/42").toParseAs("42/42");
98
- expect("42/1").toParseAs("42/1");
99
- expect("0/42").toParseAs("0/42");
100
-
101
- expect("2 (1/2)").toParseAs("2*1/2");
102
- expect("1/2 1/2").toParseAs("1/2*1/2");
103
- expect("-1/2").toParseAs("-1/2");
104
- expect("1/2 2").toParseAs("1/2*2");
105
- });
106
-
107
- test("rationals using \\frac", () => {
108
- expect("\\frac{1}{2}").toParseAs("1/2");
109
- expect("\\frac{-1}{2}").toParseAs("-1/2");
110
- expect("\\frac{1}{-2}").toParseAs("-1/2");
111
- expect("\\frac{-1}{-2}").toParseAs("-1*-1/2");
112
- expect("\\frac{42}{42}").toParseAs("42/42");
113
- expect("\\frac{42}{1}").toParseAs("42/1");
114
- expect("\\frac{0}{42}").toParseAs("0/42");
115
-
116
- expect("2\\frac{1}{2}").toParseAs("2*1/2");
117
- expect("\\frac{1}{2}\\frac{1}{2}").toParseAs("1/2*1/2");
118
- expect("-\\frac{1}{2}").toParseAs("-1/2");
119
- expect("\\frac{1}{2}2").toParseAs("1/2*2");
120
- });
121
-
122
- test("rationals using \\dfrac", () => {
123
- expect("\\dfrac{1}{2}").toParseAs("1/2");
124
- expect("\\dfrac{-1}{2}").toParseAs("-1/2");
125
- expect("\\dfrac{1}{-2}").toParseAs("-1/2");
126
- expect("\\dfrac{-1}{-2}").toParseAs("-1*-1/2");
127
- expect("\\dfrac{42}{42}").toParseAs("42/42");
128
- expect("\\dfrac{42}{1}").toParseAs("42/1");
129
- expect("\\dfrac{0}{42}").toParseAs("0/42");
130
-
131
- expect("2\\dfrac{1}{2}").toParseAs("2*1/2");
132
- expect("\\dfrac{1}{2}\\dfrac{1}{2}").toParseAs("1/2*1/2");
133
- expect("-\\dfrac{1}{2}").toParseAs("-1/2");
134
- expect("\\dfrac{1}{2}2").toParseAs("1/2*2");
135
- });
136
-
137
- test("parens", () => {
138
- expect("(0)").toParseAs("0");
139
- expect("(ab)").toParseAs("a*b");
140
- expect("(a/b)").toParseAs("a*b^(-1)");
141
- expect("(a^b)").toParseAs("a^(b)");
142
- expect("(ab)c").toParseAs("a*b*c");
143
- expect("a(bc)").toParseAs("a*b*c");
144
- expect("a+(b+c)").toParseAs("a+b+c");
145
- expect("(a+b)+c").toParseAs("a+b+c");
146
- expect("a(b+c)").toParseAs("a*(b+c)");
147
- expect("(a+b)^c").toParseAs("(a+b)^(c)");
148
- expect("(ab)^c").toParseAs("(a*b)^(c)");
149
- });
150
-
151
- test("subscripts", () => {
152
- expect("a").toParseAs("a");
153
- expect("a_0").toParseAs("a_(0)");
154
- expect("a_i").toParseAs("a_(i)");
155
- expect("a_n").toParseAs("a_(n)");
156
- expect("a_n+1").toParseAs("a_(n)+1");
157
- expect("a_(n+1)").toParseAs("a_(n+1)");
158
- expect("a_{n+1}").toParseAs("a_(n+1)");
159
- });
160
-
161
- test("negation", () => {
162
- expect("-x").toParseAs("-1*x");
163
- expect("--x").toParseAs("-1*-1*x");
164
- expect("---x").toParseAs("-1*-1*-1*x");
165
- expect("-1").toParseAs("-1");
166
- expect("--1").toParseAs("-1*-1");
167
- expect("---1").toParseAs("-1*-1*-1");
168
- expect("-3x").toParseAs("-3*x");
169
- expect("--3x").toParseAs("-1*-3*x");
170
- expect("-x*3").toParseAs("x*-3");
171
- expect("--x*3").toParseAs("-1*x*-3");
172
- expect("\u2212x").toParseAs("-1*x");
173
- });
174
-
175
- test("addition and subtraction", () => {
176
- expect("a+b").toParseAs("a+b");
177
- expect("a-b").toParseAs("a+-1*b");
178
- expect("a--b").toParseAs("a+-1*-1*b");
179
- expect("a---b").toParseAs("a+-1*-1*-1*b");
180
- expect("2-4").toParseAs("2+-4");
181
- expect("2--4").toParseAs("2+-1*-4");
182
- expect("2---4").toParseAs("2+-1*-1*-4");
183
- expect("2-x*4").toParseAs("2+x*-4");
184
- expect("1-2+a-b+pi-e").toParseAs("1+-2+a+-1*b+pi+-1*e");
185
- expect("x+1").toParseAs("x+1");
186
- expect("x-1").toParseAs("x+-1");
187
- expect("(x-1)").toParseAs("x+-1");
188
- expect("a(x-1)").toParseAs("a*(x+-1)");
189
- expect("a\u2212b").toParseAs("a+-1*b");
190
- });
191
-
192
- test("multiplication", () => {
193
- expect("a*b").toParseAs("a*b");
194
- expect("-a*b").toParseAs("-1*a*b");
195
- expect("a*-b").toParseAs("a*-1*b");
196
- expect("-ab").toParseAs("-1*a*b");
197
- expect("-a*b").toParseAs("-1*a*b");
198
- expect("-(ab)").toParseAs("-1*a*b");
199
- expect("a\u00b7b").toParseAs("a*b");
200
- expect("a\u00d7b").toParseAs("a*b");
201
- expect("a\\cdotb").toParseAs("a*b");
202
- expect("a\\timesb").toParseAs("a*b");
203
- expect("a\\astb").toParseAs("a*b");
204
- });
205
-
206
- test("division", () => {
207
- expect("a/b").toParseAs("a*b^(-1)");
208
- expect("a/bc").toParseAs("a*b^(-1)*c");
209
- expect("(ab)/c").toParseAs("a*b*c^(-1)");
210
- expect("ab/c").toParseAs("a*b*c^(-1)");
211
- expect("ab/cd").toParseAs("a*b*c^(-1)*d");
212
- expect("a\\divb").toParseAs("a*b^(-1)");
213
- expect("a\u00F7b").toParseAs("a*b^(-1)");
214
- });
215
-
216
- test("exponentiation", () => {
217
- expect("x^y").toParseAs("x^(y)");
218
- expect("x^y^z").toParseAs("x^(y^(z))");
219
- expect("x^yz").toParseAs("x^(y)*z");
220
- expect("-x^2").toParseAs("-1*x^(2)");
221
- expect("-(x^2)").toParseAs("-1*x^(2)");
222
- expect("0-x^2").toParseAs("0+-1*x^(2)");
223
- expect("x^-y").toParseAs("x^(-1*y)");
224
- expect("x^(-y)").toParseAs("x^(-1*y)");
225
- expect("x^-(y)").toParseAs("x^(-1*y)");
226
- expect("x^-(-y)").toParseAs("x^(-1*-1*y)");
227
- expect("x^--y").toParseAs("x^(-1*-1*y)");
228
- expect("x^-yz").toParseAs("x^(-1*y)*z");
229
- expect("x^-y^z").toParseAs("x^(-1*y^(z))");
230
- expect("x**y").toParseAs("x^(y)");
231
-
232
- expect("x^{a}").toParseAs("x^(a)");
233
- expect("x^{ab}").toParseAs("x^(a*b)");
234
- });
235
-
236
- test("square root", () => {
237
- expect("sqrt(x)").toParseAs("x^(1/2)");
238
- expect("sqrt(x)y").toParseAs("x^(1/2)*y");
239
- expect("1/sqrt(x)").toParseAs("x^(-1/2)");
240
- expect("1/sqrt(x)y").toParseAs("x^(-1/2)*y");
241
-
242
- expect("sqrt(2)/2").toParseAs("2^(1/2)*1/2");
243
- expect("sqrt(2)^2").toParseAs("(2^(1/2))^(2)");
244
-
245
- expect("\\sqrt(x)").toParseAs("x^(1/2)");
246
- expect("\\sqrt(x)y").toParseAs("x^(1/2)*y");
247
- expect("1/\\sqrt(x)").toParseAs("x^(-1/2)");
248
- expect("1/\\sqrt(x)y").toParseAs("x^(-1/2)*y");
249
-
250
- expect("\\sqrt(2)/2").toParseAs("2^(1/2)*1/2");
251
- expect("\\sqrt(2)^2").toParseAs("(2^(1/2))^(2)");
252
-
253
- expect("\\sqrt{2}").toParseAs("2^(1/2)");
254
- expect("\\sqrt{2+2}").toParseAs("(2+2)^(1/2)");
255
- });
256
-
257
- test("nth root", () => {
258
- expect("sqrt[3]{x}").toParseAs("x^(1/3)");
259
- expect("sqrt[4]{x}y").toParseAs("x^(1/4)*y");
260
- expect("1/sqrt[5]{x}").toParseAs("x^(-1/5)");
261
- expect("1/sqrt[7]{x}y").toParseAs("x^(-1/7)*y");
262
-
263
- expect("sqrt[3]{2}/2").toParseAs("2^(1/3)*1/2");
264
- expect("sqrt[3]{2}^2").toParseAs("(2^(1/3))^(2)");
265
-
266
- expect("\\sqrt[4]{x}").toParseAs("x^(1/4)");
267
- expect("\\sqrt[4]{x}y").toParseAs("x^(1/4)*y");
268
- expect("1/\\sqrt[4]{x}").toParseAs("x^(-1/4)");
269
- expect("1/\\sqrt[4]{x}y").toParseAs("x^(-1/4)*y");
270
-
271
- expect("\\sqrt[5]{2}/2").toParseAs("2^(1/5)*1/2");
272
- expect("\\sqrt[5]{2}^2").toParseAs("(2^(1/5))^(2)");
273
-
274
- expect("\\sqrt[6]{2}").toParseAs("2^(1/6)");
275
- expect("\\sqrt[6]{2+2}").toParseAs("(2+2)^(1/6)");
276
-
277
- expect("\\sqrt[2]{2}").toParseAs("2^(1/2)");
278
- expect("\\sqrt[2]{2+2}").toParseAs("(2+2)^(1/2)");
279
- });
280
-
281
- test("absolute value", () => {
282
- expect("abs(x)").toParseAs("abs(x)");
283
- expect("abs(abs(x))").toParseAs("abs(abs(x))");
284
- expect("abs(x)abs(y)").toParseAs("abs(x)*abs(y)");
285
-
286
- expect("|x|").toParseAs("abs(x)");
287
- expect("||x||").toParseAs("abs(abs(x))");
288
- // TODO(alex): fix the below so it doesn't require an *
289
- // may require own lexer/preprocessor
290
- expect("|x|*|y|").toParseAs("abs(x)*abs(y)");
291
-
292
- expect("\\abs(x)").toParseAs("abs(x)");
293
- expect("\\abs(\\abs(x))").toParseAs("abs(abs(x))");
294
- expect("\\abs(x)\\abs(y)").toParseAs("abs(x)*abs(y)");
295
-
296
- expect("\\left|x\\right|").toParseAs("abs(x)");
297
- expect("\\left|\\left|x\\right|\\right|").toParseAs("abs(abs(x))");
298
- expect("\\left|x\\right|\\left|y\\right|").toParseAs("abs(x)*abs(y)");
299
- });
300
-
301
- test("logarithms", () => {
302
- expect("lnx").toParseAs("ln(x)");
303
- expect("ln x").toParseAs("ln(x)");
304
- expect("ln x^y").toParseAs("ln(x^(y))");
305
- expect("ln xy").toParseAs("ln(x*y)");
306
- expect("ln x/y").toParseAs("ln(x*y^(-1))");
307
- expect("ln x+y").toParseAs("ln(x)+y");
308
- expect("ln x-y").toParseAs("ln(x)+-1*y");
309
-
310
- expect("ln xyz").toParseAs("ln(x*y*z)");
311
- expect("ln xy/z").toParseAs("ln(x*y*z^(-1))");
312
- expect("ln xy/z+1").toParseAs("ln(x*y*z^(-1))+1");
313
-
314
- expect("ln x(y)").toParseAs("ln(x)*y");
315
-
316
- expect("logx").toParseAs("log_(10) (x)");
317
- expect("log x").toParseAs("log_(10) (x)");
318
- expect("log_2x").toParseAs("log_(2) (x)");
319
- expect("log _ 2 x").toParseAs("log_(2) (x)");
320
- expect("log_bx_0").toParseAs("log_(b) (x_(0))");
321
- expect("log_x_0b").toParseAs("log_(x_(0)) (b)");
322
-
323
- expect("log_2.5x").toParseAs("log_(2.5) (x)");
324
-
325
- expect("ln ln x").toParseAs("ln(ln(x))");
326
- expect("ln x ln y").toParseAs("ln(x)*ln(y)");
327
- expect("ln x/ln y").toParseAs("ln(x)*ln(y)^(-1)");
328
-
329
- expect("\\lnx").toParseAs("ln(x)");
330
- expect("\\ln x").toParseAs("ln(x)");
331
- expect("\\ln x^y").toParseAs("ln(x^(y))");
332
- expect("\\ln xy").toParseAs("ln(x*y)");
333
- expect("\\ln x/y").toParseAs("ln(x*y^(-1))");
334
- expect("\\ln x+y").toParseAs("ln(x)+y");
335
- expect("\\ln x-y").toParseAs("ln(x)+-1*y");
336
-
337
- expect("\\logx").toParseAs("log_(10) (x)");
338
- expect("\\log x").toParseAs("log_(10) (x)");
339
- expect("\\log_2x").toParseAs("log_(2) (x)");
340
- expect("\\log _ 2 x").toParseAs("log_(2) (x)");
341
- expect("\\log_bx_0").toParseAs("log_(b) (x_(0))");
342
- expect("\\log_x_0b").toParseAs("log_(x_(0)) (b)");
343
-
344
- expect("\\log_2.5x").toParseAs("log_(2.5) (x)");
345
-
346
- expect("\\frac{\\logx}{y}").toParseAs("log_(10) (x)*y^(-1)");
347
- expect("\\frac{\\log x}{y}").toParseAs("log_(10) (x)*y^(-1)");
348
- });
349
-
350
- test("trig functions", () => {
351
- const functions = ["sin", "cos", "tan", "csc", "sec", "cot"];
352
-
353
- const inverses = _.map(functions, function (func) {
354
- return "arc" + func;
355
- });
356
-
357
- _.each(functions.concat(inverses), function (func) {
358
- expect(func + "x").toParseAs(func + "(x)");
359
- expect("\\" + func + "x").toParseAs(func + "(x)");
360
- });
361
-
362
- expect("sin^-1 x").toParseAs("arcsin(x)");
363
- expect("\\sin^-1 x").toParseAs("arcsin(x)");
364
-
365
- expect("(sinx)^2").toParseAs("sin(x)^(2)");
366
- expect("sin^2x").toParseAs("sin(x)^(2)");
367
- expect("sin^2(x)").toParseAs("sin(x)^(2)");
368
- expect("sin^2 x").toParseAs("sin(x)^(2)");
369
- expect("(sin^2x)").toParseAs("sin(x)^(2)");
370
-
371
- expect("sin xy").toParseAs("sin(x*y)");
372
- expect("sin x(y)").toParseAs("sin(x)*y");
373
- expect("sin x/y").toParseAs("sin(x*y^(-1))");
374
- expect("(sin x)/y").toParseAs("sin(x)*y^(-1)");
375
-
376
- expect("sin sin x").toParseAs("sin(sin(x))");
377
- expect("sin x sin y").toParseAs("sin(x)*sin(y)");
378
- expect("sin x/sin y").toParseAs("sin(x)*sin(y)^(-1)");
379
-
380
- expect("1/(sinx)^2").toParseAs("sin(x)^(-2)");
381
- expect("1/sin^2x").toParseAs("sin(x)^(-2)");
382
- expect("1/sin^2(x)").toParseAs("sin(x)^(-2)");
383
- expect("1/(sin^2x)").toParseAs("sin(x)^(-2)");
384
-
385
- expect("sin(theta)").toParseAs("sin(theta)");
386
- expect("\\sin(\\theta)").toParseAs("sin(theta)");
387
- });
388
-
389
- test("hyperbolic functions", () => {
390
- expect("sinh xy").toParseAs("sinh(x*y)");
391
- expect("1/(sinhx)^2").toParseAs("sinh(x)^(-2)");
392
- expect("\\sinh(\\theta)").toParseAs("sinh(theta)");
393
- });
394
-
395
- test("formulas", () => {
396
- expect("mx+b").toParseAs("m*x+b");
397
- expect("v^2/r").toParseAs("v^(2)*r^(-1)");
398
- expect("4/3pir^3").toParseAs("4/3*pi*r^(3)");
399
- expect("4/3\u03C0r^3").toParseAs("4/3*pi*r^(3)");
400
- expect("sin^2 x + cos^2 x = 1").toParseAs("sin(x)^(2)+cos(x)^(2)=1");
401
- });
402
-
403
- test("factors", () => {
404
- expect("(6x+1)(x-1)").toParseAs("(6*x+1)*(x+-1)");
405
- });
406
-
407
- test("whitespace", () => {
408
- expect("12/3").toParseAs("12/3");
409
- expect("12 /3").toParseAs("12/3");
410
- expect("12/ 3").toParseAs("12/3");
411
- expect("xy").toParseAs("x*y");
412
- expect("x y").toParseAs("x*y");
413
- });
414
-
415
- test("equations", () => {
416
- expect("y=x").toParseAs("y=x");
417
- expect("y=x^2").toParseAs("y=x^(2)");
418
- expect("1<2").toParseAs("1<2");
419
- expect("1<=2").toParseAs("1<=2");
420
- expect("1\\le2").toParseAs("1<=2");
421
- expect("2>1").toParseAs("2>1");
422
- expect("2>=1").toParseAs("2>=1");
423
- expect("2\\ge1").toParseAs("2>=1");
424
- expect("1<>2").toParseAs("1<>2");
425
- expect("1=/=2").toParseAs("1<>2");
426
- expect("1\\ne2").toParseAs("1<>2");
427
- expect("1\\neq2").toParseAs("1<>2");
428
- expect("a\u2260b").toParseAs("a<>b");
429
- expect("a\u2264b").toParseAs("a<=b");
430
- expect("a\u2265b").toParseAs("a>=b");
431
-
432
- expect("y \\le x").toParseAs("y<=x");
433
- expect("y \\leq x").toParseAs("y<=x");
434
- expect("y \\ge x").toParseAs("y>=x");
435
- expect("y \\geq x").toParseAs("y>=x");
436
- });
437
-
438
- test("function variables", () => {
439
- expect("f(x)").toParseAs("f*x");
440
- expect("f(x)").toParseAs("f(x)", {functions: ["f"]});
441
- expect("f(x+y)").toParseAs("f(x+y)", {functions: ["f"]});
442
- expect("f(x)g(x)").toParseAs("f(x)*g(x)", {functions: ["f", "g"]});
443
- expect("f(g(h(x)))").toParseAs("f(g(h(x)))", {
444
- functions: ["f", "g", "h"],
445
- });
446
-
447
- expect("f\\left(x\\right)").toParseAs("f*x");
448
- expect("f\\left(x\\right)").toParseAs("f(x)", {functions: ["f"]});
449
- expect("f\\left(x+y\\right)").toParseAs("f(x+y)", {
450
- functions: ["f"],
451
- });
452
- expect("f\\left(x\\right)g\\left(x\\right)").toParseAs("f(x)*g(x)", {
453
- functions: ["f", "g"],
454
- });
455
- expect("f\\left(g\\left(h\\left(x\\right)\\right)\\right)").toParseAs(
456
- "f(g(h(x)))",
457
- {functions: ["f", "g", "h"]},
458
- );
459
- });
460
-
461
- test("structure", () => {
462
- expect("").toParseWithStructure("Add()");
463
- expect("1.").toParseWithStructure("1");
464
- expect("1/2").toParseWithStructure("1/2");
465
- expect("1/-2").toParseWithStructure("-1/2");
466
- expect("x/-2").toParseWithStructure("Mul(Var(x),-1/2)");
467
- expect("a+b").toParseWithStructure("Add(Var(a),Var(b))");
468
- expect("a+b+c").toParseWithStructure("Add(Var(a),Var(b),Var(c))");
469
- expect("a-b").toParseWithStructure("Add(Var(a),Mul(-1,Var(b)))");
470
- expect("a-b+c").toParseWithStructure(
471
- "Add(Var(a),Mul(-1,Var(b)),Var(c))",
472
- );
473
- expect("abc").toParseWithStructure("Mul(Var(a),Var(b),Var(c))");
474
- expect("a/bc").toParseWithStructure(
475
- "Mul(Var(a),Pow(Var(b),-1),Var(c))",
476
- );
477
- expect("a*(b+c)").toParseWithStructure(
478
- "Mul(Var(a),Add(Var(b),Var(c)))",
479
- );
480
- expect("x--y").toParseWithStructure("Add(Var(x),Mul(-1,-1,Var(y)))");
481
- expect("--y").toParseWithStructure("Mul(-1,-1,Var(y))");
482
- expect("e").toParseWithStructure("Const(e)");
483
- expect("2e").toParseWithStructure("Mul(2,Const(e))");
484
- expect("2e^x").toParseWithStructure("Mul(2,Pow(Const(e),Var(x)))");
485
- expect("cdef").toParseWithStructure(
486
- "Mul(Var(c),Var(d),Const(e),Var(f))",
487
- );
488
- expect("pi").toParseWithStructure("Const(pi)");
489
- expect("pi^2").toParseWithStructure("Pow(Const(pi),2)");
490
- expect("pir").toParseWithStructure("Mul(Const(pi),Var(r))");
491
- expect("pir^2").toParseWithStructure("Mul(Const(pi),Pow(Var(r),2))");
492
- expect("y=x^2").toParseWithStructure("Eq(Var(y),=,Pow(Var(x),2))");
493
- expect("log_2x").toParseWithStructure("Log(2,Var(x))");
494
- expect("f(x+y)").toParseWithStructure("Mul(Var(f),Add(Var(x),Var(y)))");
495
- expect("f(x+y)").toParseWithStructure("Func(f,Add(Var(x),Var(y)))", {
496
- functions: ["f"],
497
- });
498
- expect("sin(theta)").toParseWithStructure("Trig(sin,Var(theta))");
499
- expect("tanh(theta)").toParseWithStructure("Trig(tanh,Var(theta))");
500
-
501
- // verify that negative signs get folded into numbers
502
- expect("-x*3").toParseWithStructure("Mul(Var(x),-3)");
503
- expect("sin -x*3").toParseWithStructure("Trig(sin,Mul(Var(x),-3))");
504
- });
505
- });