Repository: PebbleTemplates/pebble
Pull request #399 (2018-09-04 10:46:45)

Make ternary if operator more tolerant to argument type


Patch:
diff --git a/pebble/src/main/java/com/mitchellbosecke/pebble/node/expression/TernaryExpression.java b/pebble/src/main/java/com/mitchellbosecke/pebble/node/expression/TernaryExpression.java
index d97b997b..e5a4ea7b 100644
--- a/pebble/src/main/java/com/mitchellbosecke/pebble/node/expression/TernaryExpression.java
+++ b/pebble/src/main/java/com/mitchellbosecke/pebble/node/expression/TernaryExpression.java
@@ -12,6 +12,8 @@ import com.mitchellbosecke.pebble.extension.NodeVisitor;
 import com.mitchellbosecke.pebble.template.EvaluationContextImpl;
 import com.mitchellbosecke.pebble.template.PebbleTemplateImpl;
 
+import static com.mitchellbosecke.pebble.utils.TypeUtils.compatibleCast;
+
 public class TernaryExpression implements Expression<Object> {
 
   private final Expression<Boolean> expression1;
@@ -32,8 +34,9 @@ public class TernaryExpression implements Expression<Object> {
 
   @Override
   public Object evaluate(PebbleTemplateImpl self, EvaluationContextImpl context) {
-    if (this.expression1.evaluate(self, context) != null && this.expression1
-        .evaluate(self, context)) {
+    Object evaluatedExpression1 = this.expression1.evaluate(self, context);
+    if (evaluatedExpression1 != null
+            && compatibleCast(evaluatedExpression1, Boolean.class)) {
       return this.expression2.evaluate(self, context);
     } else {
       return this.expression3.evaluate(self, context);
diff --git a/pebble/src/main/java/com/mitchellbosecke/pebble/utils/TypeUtils.java b/pebble/src/main/java/com/mitchellbosecke/pebble/utils/TypeUtils.java
index 94315951..1f53023a 100644
--- a/pebble/src/main/java/com/mitchellbosecke/pebble/utils/TypeUtils.java
+++ b/pebble/src/main/java/com/mitchellbosecke/pebble/utils/TypeUtils.java
@@ -59,7 +59,7 @@ public class TypeUtils {
         return (T) new Date(number.longValue());
       }
       if (type == Boolean.class) {
-        return (T) (Boolean) (number.intValue() != 0);
+        return (T) (Boolean) (number.doubleValue() != 0.0);
       }
     }
     if (value instanceof String) {


Test patch:
diff --git a/pebble/src/test/java/com/mitchellbosecke/pebble/TernaryExpressionTest.java b/pebble/src/test/java/com/mitchellbosecke/pebble/TernaryExpressionTest.java
index d37f4bab..ff759677 100644
--- a/pebble/src/test/java/com/mitchellbosecke/pebble/TernaryExpressionTest.java
+++ b/pebble/src/test/java/com/mitchellbosecke/pebble/TernaryExpressionTest.java
@@ -279,4 +279,75 @@ public class TernaryExpressionTest {
     assertEquals("true", writer.toString());
   }
 
+  @Test
+  public void testTernaryIntTrue() throws IOException {
+    PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
+        .strictVariables(false).build();
+
+    PebbleTemplate template = pebble.getTemplate(
+            "{{ 1 ? 'true' : 'false' }}");
+    StringWriter writer = new StringWriter();
+    template.evaluate(writer);
+    assertEquals("true", writer.toString());
+  }
+
+  @Test
+  public void testTernaryIntFalse() throws IOException {
+    PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
+        .strictVariables(false).build();
+
+    PebbleTemplate template = pebble.getTemplate(
+            "{{ 0 ? 'true' : 'false' }}");
+    StringWriter writer = new StringWriter();
+    template.evaluate(writer);
+    assertEquals("false", writer.toString());
+  }
+
+  @Test
+  public void testTernaryStringTrue() throws IOException {
+    PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
+        .strictVariables(false).build();
+
+    PebbleTemplate template = pebble.getTemplate(
+            "{{ 'not empty' ? 'true' : 'false' }}");
+    StringWriter writer = new StringWriter();
+    template.evaluate(writer);
+    assertEquals("true", writer.toString());
+  }
+
+  @Test
+  public void testTernaryStringFalse() throws IOException {
+    PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
+        .strictVariables(false).build();
+
+    PebbleTemplate template = pebble.getTemplate(
+            "{{ '' ? 'true' : 'false' }}");
+    StringWriter writer = new StringWriter();
+    template.evaluate(writer);
+    assertEquals("false", writer.toString());
+  }
+
+  @Test
+  public void testTernaryDecimalTrue() throws IOException {
+    PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
+        .strictVariables(false).build();
+
+    PebbleTemplate template = pebble.getTemplate(
+            "{{ 0.000001 ? 'true' : 'false' }}");
+    StringWriter writer = new StringWriter();
+    template.evaluate(writer);
+    assertEquals("true", writer.toString());
+  }
+
+  @Test
+  public void testTernaryDecimalFalse() throws IOException {
+    PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader())
+        .strictVariables(false).build();
+
+    PebbleTemplate template = pebble.getTemplate(
+            "{{ 0.00000 ? 'true' : 'false' }}");
+    StringWriter writer = new StringWriter();
+    template.evaluate(writer);
+    assertEquals("false", writer.toString());
+  }
 }