IfNode extends AbstractRenderableNode { @Override public void render(PebbleTemplateImpl self, Writer writer, EvaluationContextImpl context) throws IOException { boolean satisfied = false; for (Pair<Expression<?>, BodyNode> ifStatement: this.conditionsWithBodies) { Expression<?> conditionalExpression = ifStatement.getLeft(); try { Object result = conditionalExpression.evaluate(self, context); if (result != null) { if (result instanceof Boolean || result instanceof Number || result instanceof String) { satisfied = compatibleCast(result, Boolean.class); } else { throw new PebbleException( null, String.format( "Unsupported value type %s. Expected Boolean, String, Number in \"if\" statement", result.getClass().getSimpleName()), this.getLineNumber(), self.getName()); } } else if (context.isStrictVariables()) { throw new PebbleException(null, "null value given to if statement and strict variables is set to true", this.getLineNumber(), self.getName()); } } catch (RuntimeException ex) { throw new PebbleException(ex, "Wrong operand(s) type in conditional expression", this.getLineNumber(), self.getName()); } if (satisfied) { ifStatement.getRight().render(self, writer, context); break; } } if (!satisfied && this.elseBody != null) { this.elseBody.render(self, writer, context); } } IfNode(int lineNumber, List<Pair<Expression<?>, BodyNode>> conditionsWithBodies);  IfNode(int lineNumber, List<Pair<Expression<?>, BodyNode>> conditionsWithBodies,
      BodyNode elseBody); @Override void render(PebbleTemplateImpl self, Writer writer, EvaluationContextImpl context); @Override void accept(NodeVisitor visitor); List<Pair<Expression<?>, BodyNode>> getConditionsWithBodies(); BodyNode getElseBody();  }
@Test void testIfNull() throws IOException { assertEquals("no", this.render(null), "Null should be interpreted as FALSE"); }
@Test void testIfNullInStrictMode() throws IOException { assertThrows(PebbleException.class, () -> this.render(true, null)); }
@Test void testIfTrue() throws IOException { assertEquals("yes", this.render(true), "Null should be interpreted as FALSE"); }
@Test void testIfFalse() throws IOException { assertEquals("no", this.render(false), "Null should be interpreted as FALSE"); }
@Test void testIfNotZeroInteger() throws IOException { assertEquals("yes", this.render(1), "Not zero integer should be interpreted as TRUE"); }
@Test void testIfZeroInteger() throws IOException { assertEquals("no", this.render(0), "Zero integer should be interpreted as FALSE"); }
@Test void testIfNotZeroFloat() throws IOException { assertEquals("yes", this.render(1.1), "Not zero float should be interpreted as TRUE"); }
@Test void testIfZeroFloat() throws IOException { assertEquals("no", this.render(0), "Zero float should be interpreted as FALSE"); }
@Test void testIfNotEmptyString() throws IOException { assertEquals("yes", this.render("not empty string"), "Not empty string should be interpreted as TRUE"); }
@Test void testIfEmptyString() throws IOException { assertEquals("no", this.render(""), "Empty string should be interpreted as FALSE"); }