Repository: PebbleTemplates/pebble (java)

Issue:
Can not concatenate SafeString
In Pebble 1.x I used to be able to concatenate the output of a macro with the output of another macro.  Something like:

```twig
{{ macro1() + macro2() }}
```

In Pebble 2.x I can no longer do that and I think the problem is [this](https://github.com/PebbleTemplates/pebble/blob/master/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java#L39-L46) hunk of code which only checks for `String` and does not consider `SafeString`.



Pull request description:
Fixes #217: Fix regression of broken SafeString concatenation
This fix is working for me, however you may have an alternate implementation suggestion.

Patch:
diff --git a/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java b/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java
index f293f4f1..4fb5938b 100644
--- a/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java
+++ b/src/main/java/com/mitchellbosecke/pebble/utils/OperatorUtils.java
@@ -8,6 +8,8 @@
  ******************************************************************************/
 package com.mitchellbosecke.pebble.utils;
 
+import com.mitchellbosecke.pebble.extension.escaper.SafeString;
+
 import java.math.BigDecimal;
 import java.math.MathContext;
 import java.util.Collection;
@@ -39,6 +41,8 @@ public class OperatorUtils {
     public static Object add(Object op1, Object op2) {
         if (op1 instanceof String || op2 instanceof String) {
             return concatenateStrings(String.valueOf(op1), String.valueOf(op2));
+        } else if (op1 instanceof SafeString || op2 instanceof SafeString) {
+            return concatenateStrings(String.valueOf(op1), String.valueOf(op2));
         } else if (op1 instanceof List) {
             return addToList((List<?>) op1, op2);
         }


Test patch:
diff --git a/src/test/java/com/mitchellbosecke/pebble/CoreOperatorsTest.java b/src/test/java/com/mitchellbosecke/pebble/CoreOperatorsTest.java
index bb486bb4..b18e66e8 100644
--- a/src/test/java/com/mitchellbosecke/pebble/CoreOperatorsTest.java
+++ b/src/test/java/com/mitchellbosecke/pebble/CoreOperatorsTest.java
@@ -758,4 +758,26 @@ public class CoreOperatorsTest extends AbstractTest {
 
     }
 
+    /**
+     * Tests if the macro output SafeString concatenation is working.
+     */
+    @Test
+    public void testMacroSafeStringConcatenation() throws PebbleException, IOException {
+
+        PebbleEngine pebble = new PebbleEngine.Builder().loader(new StringLoader()).strictVariables(false).build();
+
+        String source = "{% macro macro1() %}Bob{% endmacro %}\n"
+                      + "{% macro macro2() %}Maria{% endmacro %}\n"
+                      + "{% macro macro3() %}John{% endmacro %}\n"
+                      + "{{ (macro1() + macro2() + macro3()) | lower }}";
+        PebbleTemplate template = pebble.getTemplate(source);
+
+        Map<String, Object> context = new HashMap<>();
+
+        Writer writer = new StringWriter();
+        template.evaluate(writer, context);
+        assertEquals("bobmariajohn", writer.toString());
+
+    }
+
 }