From e7fb81821ff07338a6aa5e09d9d209d8efe8d94e Mon Sep 17 00:00:00 2001 From: Alex Gyoshev Date: Thu, 12 Oct 2017 10:55:59 +0300 Subject: [PATCH] Fix subtraction expressions closes #38 --- src/__tests__/index.js | 21 +++++++++++++++++++++ src/lib/reducer.js | 30 ++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/__tests__/index.js b/src/__tests__/index.js index 2437f69..1937587 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -303,3 +303,24 @@ test( 'calc(500px/2px)', 'Cannot divide by "px", number expected' ) + +test( + 'should reduce substraction from zero', + testFixture, + 'calc( 0 - 10px)', + '-10px' +) + +test( + 'should reduce subtracted expression from zero', + testFixture, + 'calc( 0 - calc(1px + 1em) )', + 'calc(-1px + -1em)' +) + +test( + 'should reduce nested expression', + testFixture, + 'calc( (1em - calc( 10px + 1em)) / 2)', + '-5px' +) diff --git a/src/lib/reducer.js b/src/lib/reducer.js index 2c69be5..f13b98c 100644 --- a/src/lib/reducer.js +++ b/src/lib/reducer.js @@ -62,6 +62,20 @@ function convertMathExpression(node, precision) { return node } +function flip(operator) { + return operator === '+' ? '-' : '+' +} + +function flipValue(node) { + if (isValueType(node.type)) + node.value = -node.value + else if (node.type == 'MathExpression') { + node.left = flipValue(node.left) + node.right = flipValue(node.right) + } + return node +} + function reduceAddSubExpression(node, precision) { const {left, right, operator: op} = node @@ -77,6 +91,10 @@ function reduceAddSubExpression(node, precision) { if (left.value === 0 && op === "+") return right + // 0 - something => -something + if (left.value === 0 && op === "-") + return flipValue(right) + // value + value // value - value if (left.type === right.type && isValueType(left.type)) { @@ -115,13 +133,13 @@ function reduceAddSubExpression(node, precision) { } // value + (something + value) => (value + value) + something // value + (something - value) => (value - value) + something - // value - (something + value) => (value + value) - something - // value - (something - value) => (value - value) - something + // value - (something + value) => (value - value) - something + // value - (something - value) => (value + value) - something else if (left.type === right.right.type) { node = Object.assign({ }, node) node.left = reduce({ type: 'MathExpression', - operator: right.operator, + operator: op === '-' ? flip(right.operator) : right.operator, left: left, right: right.right }, precision) @@ -183,7 +201,7 @@ function reduceAddSubExpression(node, precision) { return node } -function reduceDivisionExpression(node) { +function reduceDivisionExpression(node, precision) { if (!isValueType(node.right.type)) return node @@ -201,7 +219,7 @@ function reduceDivisionExpression(node) { ) { node.left.left.value /= node.right.value node.left.right.value /= node.right.value - return node.left + return reduce(node.left, precision) } return node } @@ -255,7 +273,7 @@ function reduceMathExpression(node, precision) { case "-": return reduceAddSubExpression(node, precision) case "/": - return reduceDivisionExpression(node) + return reduceDivisionExpression(node, precision) case "*": return reduceMultiplicationExpression(node) }