Skip to content

Commit

Permalink
Fix operator precendence #290
Browse files Browse the repository at this point in the history
  • Loading branch information
ebussieres committed May 1, 2018
1 parent cd3a821 commit 9cd7583
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
- Fixed security issue which allowed to execute shell command (by having access to Java's Class object) (#329)
- Throw ParserException when endBlock not found (#308)
- For tag : add enumeration support (#292)
- Fix operator precedence (#290)

## v2.4.0 (2017-06-04)
- Add arrays support for iterable test (#254)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,51 @@
******************************************************************************/
package com.mitchellbosecke.pebble.extension.core;

import com.mitchellbosecke.pebble.extension.*;
import com.mitchellbosecke.pebble.node.expression.*;
import com.mitchellbosecke.pebble.operator.*;
import com.mitchellbosecke.pebble.tokenParser.*;
import com.mitchellbosecke.pebble.extension.AbstractExtension;
import com.mitchellbosecke.pebble.extension.Filter;
import com.mitchellbosecke.pebble.extension.Function;
import com.mitchellbosecke.pebble.extension.NodeVisitorFactory;
import com.mitchellbosecke.pebble.extension.Test;
import com.mitchellbosecke.pebble.node.expression.AddExpression;
import com.mitchellbosecke.pebble.node.expression.AndExpression;
import com.mitchellbosecke.pebble.node.expression.ConcatenateExpression;
import com.mitchellbosecke.pebble.node.expression.ContainsExpression;
import com.mitchellbosecke.pebble.node.expression.DivideExpression;
import com.mitchellbosecke.pebble.node.expression.EqualsExpression;
import com.mitchellbosecke.pebble.node.expression.FilterExpression;
import com.mitchellbosecke.pebble.node.expression.GreaterThanEqualsExpression;
import com.mitchellbosecke.pebble.node.expression.GreaterThanExpression;
import com.mitchellbosecke.pebble.node.expression.LessThanEqualsExpression;
import com.mitchellbosecke.pebble.node.expression.LessThanExpression;
import com.mitchellbosecke.pebble.node.expression.ModulusExpression;
import com.mitchellbosecke.pebble.node.expression.MultiplyExpression;
import com.mitchellbosecke.pebble.node.expression.NegativeTestExpression;
import com.mitchellbosecke.pebble.node.expression.NotEqualsExpression;
import com.mitchellbosecke.pebble.node.expression.OrExpression;
import com.mitchellbosecke.pebble.node.expression.PositiveTestExpression;
import com.mitchellbosecke.pebble.node.expression.RangeExpression;
import com.mitchellbosecke.pebble.node.expression.SubtractExpression;
import com.mitchellbosecke.pebble.node.expression.UnaryMinusExpression;
import com.mitchellbosecke.pebble.node.expression.UnaryNotExpression;
import com.mitchellbosecke.pebble.node.expression.UnaryPlusExpression;
import com.mitchellbosecke.pebble.operator.Associativity;
import com.mitchellbosecke.pebble.operator.BinaryOperator;
import com.mitchellbosecke.pebble.operator.BinaryOperatorImpl;
import com.mitchellbosecke.pebble.operator.UnaryOperator;
import com.mitchellbosecke.pebble.operator.UnaryOperatorImpl;
import com.mitchellbosecke.pebble.tokenParser.BlockTokenParser;
import com.mitchellbosecke.pebble.tokenParser.CacheTokenParser;
import com.mitchellbosecke.pebble.tokenParser.ExtendsTokenParser;
import com.mitchellbosecke.pebble.tokenParser.FilterTokenParser;
import com.mitchellbosecke.pebble.tokenParser.FlushTokenParser;
import com.mitchellbosecke.pebble.tokenParser.ForTokenParser;
import com.mitchellbosecke.pebble.tokenParser.IfTokenParser;
import com.mitchellbosecke.pebble.tokenParser.ImportTokenParser;
import com.mitchellbosecke.pebble.tokenParser.IncludeTokenParser;
import com.mitchellbosecke.pebble.tokenParser.MacroTokenParser;
import com.mitchellbosecke.pebble.tokenParser.ParallelTokenParser;
import com.mitchellbosecke.pebble.tokenParser.SetTokenParser;
import com.mitchellbosecke.pebble.tokenParser.TokenParser;

import java.util.ArrayList;
import java.util.HashMap;
Expand Down Expand Up @@ -43,7 +84,7 @@ public List<TokenParser> getTokenParsers() {
@Override
public List<UnaryOperator> getUnaryOperators() {
ArrayList<UnaryOperator> operators = new ArrayList<>();
operators.add(new UnaryOperatorImpl("not", 5, UnaryNotExpression.class));
operators.add(new UnaryOperatorImpl("not", 10, UnaryNotExpression.class));
operators.add(new UnaryOperatorImpl("+", 500, UnaryPlusExpression.class));
operators.add(new UnaryOperatorImpl("-", 500, UnaryMinusExpression.class));
return operators;
Expand All @@ -52,8 +93,8 @@ public List<UnaryOperator> getUnaryOperators() {
@Override
public List<BinaryOperator> getBinaryOperators() {
ArrayList<BinaryOperator> operators = new ArrayList<>();
operators.add(new BinaryOperatorImpl("or", 10, OrExpression.class, Associativity.LEFT));
operators.add(new BinaryOperatorImpl("and", 15, AndExpression.class, Associativity.LEFT));
operators.add(new BinaryOperatorImpl("or", 1, OrExpression.class, Associativity.LEFT));
operators.add(new BinaryOperatorImpl("and", 5, AndExpression.class, Associativity.LEFT));
operators.add(new BinaryOperatorImpl("is", 20, PositiveTestExpression.class, Associativity.LEFT));
operators.add(new BinaryOperatorImpl("is not", 20, NegativeTestExpression.class, Associativity.LEFT));
operators.add(new BinaryOperatorImpl("contains", 20, ContainsExpression.class, Associativity.LEFT));
Expand Down
42 changes: 35 additions & 7 deletions src/test/java/com/mitchellbosecke/pebble/CoreOperatorsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
******************************************************************************/
package com.mitchellbosecke.pebble;

import static org.junit.Assert.assertEquals;
import com.mitchellbosecke.pebble.error.PebbleException;
import com.mitchellbosecke.pebble.loader.StringLoader;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import com.mitchellbosecke.pebble.utils.Pair;

import org.junit.Test;

import java.io.IOException;
import java.io.StringWriter;
Expand All @@ -21,12 +26,7 @@
import java.util.List;
import java.util.Map;

import org.junit.Test;

import com.mitchellbosecke.pebble.error.PebbleException;
import com.mitchellbosecke.pebble.loader.StringLoader;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import com.mitchellbosecke.pebble.utils.Pair;
import static org.junit.Assert.assertEquals;

public class CoreOperatorsTest extends AbstractTest {

Expand Down Expand Up @@ -221,6 +221,34 @@ public void testLogicOperatorOnAttributes() throws PebbleException, IOException
assertEquals("noyes", writer.toString());
}

@Test
public void testNotOperatorPrecedence() throws IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader()).strictVariables(false).build();

String source = "{% if not item.falsy and not item.truthy %}This should not be displayed{% else %}All's good{% endif %}";
PebbleTemplate template = pebble.getTemplate(source);
Map<String, Object> context = new HashMap<>();
context.put("item", new Item());

Writer writer = new StringWriter();
template.evaluate(writer, context);
assertEquals("All's good", writer.toString());
}

@Test
public void testNotOperatorWithParenthesisPrecedence() throws IOException {
PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader()).strictVariables(false).build();

String source = "{% if (not item.falsy) and (not item.truthy) %}This should not be displayed{% else %}All's good{% endif %}";
PebbleTemplate template = pebble.getTemplate(source);
Map<String, Object> context = new HashMap<>();
context.put("item", new Item());

Writer writer = new StringWriter();
template.evaluate(writer, context);
assertEquals("All's good", writer.toString());
}

@Test
public void testTernary() throws PebbleException, IOException {

Expand Down

0 comments on commit 9cd7583

Please sign in to comment.