summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/parser.ts8
-rw-r--r--tests/calc.spec.ts11
-rw-r--r--tests/parser.spec.ts57
3 files changed, 69 insertions, 7 deletions
diff --git a/src/parser.ts b/src/parser.ts
index c2aa30f..81f7a9e 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -119,14 +119,10 @@ const precedence = (op: BinOp) =>
const binOpWithFixitySwitchity = (op: BinOp, left: Expr, right: Expr) =>
match(right, {
BinOp: binOp => {
- if (precedence(op) > precedence(binOp.op)) {
+ if (precedence(op) >= precedence(binOp.op)) {
return Expr.BinOp({
op: binOp.op,
- left: Expr.BinOp({
- op,
- left: left,
- right: binOp.left,
- }),
+ left: binOpWithFixitySwitchity(op, left, binOp.left),
right: binOp.right,
})
}
diff --git a/tests/calc.spec.ts b/tests/calc.spec.ts
index a4e11cd..421a82a 100644
--- a/tests/calc.spec.ts
+++ b/tests/calc.spec.ts
@@ -12,7 +12,7 @@ describe('calc', () => {
addClass: jest.fn(),
removeClass: jest.fn(),
delay: jest.fn(),
- jsEval: jest.fn(),
+ jsEval: jest.fn(eval),
loadCssx: jest.fn(),
getVariable: jest.fn(variables),
updateVariable: jest.fn(),
@@ -37,6 +37,15 @@ describe('calc', () => {
['calc(var(--test-8rem))', EvalValue.Number(128)],
['calc(var(--test-1))', EvalValue.Number(0)], // Var not found
['calc(5px * var(--test-8rem)/2 + 1)', EvalValue.Number(321)],
+ ['calc(js-eval("2 * 5"))', EvalValue.Number(10)],
+ ['calc(9 * js-eval("2 * 5")/2 - 6)', EvalValue.Number(39)],
+ ['calc(30 - 5 - 3)', EvalValue.Number(22)],
+ ['calc(30 / 5 / 3)', EvalValue.Number(2)],
+ ['calc(360 * 6/2 - 90 + 30)', EvalValue.Number(1020)],
+ [
+ 'calc(360 * js-eval("18 / 3")/2 - 90 + (3 * js-eval("2 * 5")))',
+ EvalValue.Number(1020),
+ ],
])('when given "%s"', (expr, expected) => {
it('should evaluate the result of math', async () => {
const evalValue = await evalExpr(parseExpr(expr), actions)
diff --git a/tests/parser.spec.ts b/tests/parser.spec.ts
index 16480e6..6e8431d 100644
--- a/tests/parser.spec.ts
+++ b/tests/parser.spec.ts
@@ -285,5 +285,62 @@ describe('parser', () => {
}),
])
})
+
+ it('preserves order of operations (same operator)', () => {
+ expect(parse(`calc(30 - 5 - 3)`)).toEqual([
+ Expr.Call({
+ name: 'calc',
+ args: [
+ Expr.BinOp({
+ op: '-',
+ left: Expr.BinOp({
+ op: '-',
+ left: Expr.LiteralNumber({ value: 30, unit: '' }),
+ right: Expr.LiteralNumber({ value: 5, unit: '' }),
+ }),
+ right: Expr.LiteralNumber({ value: 3, unit: '' }),
+ }),
+ ],
+ }),
+ ])
+ })
+
+ it('preserves order of operations (different operators, same precedance)', () => {
+ expect(parse(`calc(30 + 5 - 3)`)).toEqual([
+ Expr.Call({
+ name: 'calc',
+ args: [
+ Expr.BinOp({
+ op: '-',
+ left: Expr.BinOp({
+ op: '+',
+ left: Expr.LiteralNumber({ value: 30, unit: '' }),
+ right: Expr.LiteralNumber({ value: 5, unit: '' }),
+ }),
+ right: Expr.LiteralNumber({ value: 3, unit: '' }),
+ }),
+ ],
+ }),
+ ])
+ })
+
+ it('preserves order of operations (different operators, different precedance)', () => {
+ expect(parse(`calc(30 / 5 * 3)`)).toEqual([
+ Expr.Call({
+ name: 'calc',
+ args: [
+ Expr.BinOp({
+ op: '*',
+ left: Expr.BinOp({
+ op: '/',
+ left: Expr.LiteralNumber({ value: 30, unit: '' }),
+ right: Expr.LiteralNumber({ value: 5, unit: '' }),
+ }),
+ right: Expr.LiteralNumber({ value: 3, unit: '' }),
+ }),
+ ],
+ }),
+ ])
+ })
})
})