You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2019/01/26 17:29:05 UTC

[freemarker] branch 2.3-gae updated: The "boolean_format" configuration setting now can be set to "c". Then ${aBoolean} will behave as ${aBoolean?c}. This should be only used if you are generating output for non-human (computer) consumption only. If your output has pieces for human audience too, it's still recommended to use ${aBoolean?c} where true/false is needed, and either not set the "boolean_format" at all, or set it to something that's appropriate for everyday uses (like "yes, no").

This is an automated email from the ASF dual-hosted git repository.

ddekany pushed a commit to branch 2.3-gae
in repository https://gitbox.apache.org/repos/asf/freemarker.git


The following commit(s) were added to refs/heads/2.3-gae by this push:
     new becf252  The "boolean_format" configuration setting now can be set to "c". Then ${aBoolean} will behave as ${aBoolean?c}. This should be only used if you are generating output for non-human (computer) consumption only. If your output has pieces for human audience too, it's still recommended to use ${aBoolean?c} where true/false is needed, and either not set the "boolean_format" at all, or set it to something that's appropriate for everyday uses (like "yes,no").
becf252 is described below

commit becf25290b422eb5306a5dbba4bb87261c35253e
Author: ddekany <dd...@apache.org>
AuthorDate: Sat Jan 26 17:37:29 2019 +0100

    The "boolean_format" configuration setting now can be set to "c". Then ${aBoolean} will behave as ${aBoolean?c}. This should be only used if you are generating output for non-human (computer) consumption only. If your output has pieces for human audience too, it's still recommended to use ${aBoolean?c} where true/false is needed, and either not set the "boolean_format" at all, or set it to something that's appropriate for everyday uses (like "yes,no").
---
 src/main/java/freemarker/core/Configurable.java    | 66 ++++++++++++-------
 src/main/java/freemarker/core/MiscUtil.java        |  2 +-
 src/manual/en_US/book.xml                          | 77 ++++++++++++++++------
 .../freemarker/template/ConfigurationTest.java     | 18 +++++
 .../templatesuite/templates/boolean-formatting.ftl |  9 ++-
 .../templatesuite/templates/sequence-builtins.ftl  | 39 +++++------
 .../templates/string-builtins-regexps.ftl          | 55 ++++++++--------
 .../templatesuite/templates/string-builtins2.ftl   | 23 +++----
 8 files changed, 183 insertions(+), 106 deletions(-)

diff --git a/src/main/java/freemarker/core/Configurable.java b/src/main/java/freemarker/core/Configurable.java
index 70f2dfa..27e5285 100644
--- a/src/main/java/freemarker/core/Configurable.java
+++ b/src/main/java/freemarker/core/Configurable.java
@@ -81,7 +81,8 @@ import freemarker.template.utility.StringUtil;
  */
 public class Configurable {
     static final String C_TRUE_FALSE = "true,false";
-    
+    static final String C_FORMAT_STRING = "c";
+
     private static final String NULL = "null";
     private static final String DEFAULT = "default";
     private static final String DEFAULT_2_3_0 = "default_2_3_0";
@@ -963,39 +964,46 @@ public class Configurable {
     }
     
     /**
-     * The string value for the boolean {@code true} and {@code false} values, intended for human audience (not for a
-     * computer language), separated with comma. For example, {@code "yes,no"}. Note that white-space is significant,
-     * so {@code "yes, no"} is WRONG (unless you want that leading space before "no").
+     * The string value for the boolean {@code true} and {@code false} values, usually intended for human consumption
+     * (not for a computer language), separated with comma. For example, {@code "yes,no"}. Note that white-space is
+     * significant, so {@code "yes, no"} is WRONG (unless you want that leading space before "no"). Because the proper
+     * way of formatting booleans depends on the context too much, it's probably the best to leave this setting on its
+     * default, which will enforce explicit formatting, like <code>${aBoolean?string('on', 'off')}</code>.
      * 
      * <p>For backward compatibility the default is {@code "true,false"}, but using that value is denied for automatic
-     * boolean-to-string conversion (like <code>${myBoolean}</code> will fail with it), only {@code myBool?string} will
-     * allow it, which is deprecated since FreeMarker 2.3.20.
+     * boolean-to-string conversion, like <code>${myBoolean}</code> will fail with it. If you generate the piece of
+     * output for "computer audience" as opposed to "human audience", then you should write
+     * <code>${myBoolean?c}</code>, which will print {@code true} or {@code false}. If you really want to always
+     * format for computer audience, then it's might be reasonable to set this setting to {@code c}.
      * 
      * <p>Note that automatic boolean-to-string conversion only exists since FreeMarker 2.3.20. Earlier this setting
      * only influenced the result of {@code myBool?string}. 
      */
     public void setBooleanFormat(String booleanFormat) {
         NullArgumentException.check("booleanFormat", booleanFormat);
-        
-        int commaIdx = booleanFormat.indexOf(',');
-        if (commaIdx == -1) {
-            throw new IllegalArgumentException(
-                    "Setting value must be a string that contains two comma-separated values for true and false, " +
-                    "respectively.");
-        }
-        
-        this.booleanFormat = booleanFormat; 
-        properties.setProperty(BOOLEAN_FORMAT_KEY, booleanFormat);
-        
+
         if (booleanFormat.equals(C_TRUE_FALSE)) {
             // C_TRUE_FALSE is the default for BC, but it's not a good default for human audience formatting, so we
             // pretend that it wasn't set.
             trueStringValue = null; 
             falseStringValue = null;
+        } else if (booleanFormat.equals(C_FORMAT_STRING)) {
+            trueStringValue = MiscUtil.C_TRUE;
+            falseStringValue = MiscUtil.C_FALSE;
         } else {
-            trueStringValue = booleanFormat.substring(0, commaIdx); 
+            int commaIdx = booleanFormat.indexOf(',');
+            if (commaIdx == -1) {
+                throw new IllegalArgumentException(
+                        "Setting value must be a string that contains two comma-separated values for true and false, " +
+                                "or it must be \"" + C_FORMAT_STRING + "\", but it was " +
+                                StringUtil.jQuote(booleanFormat) + ".");
+            }
+            trueStringValue = booleanFormat.substring(0, commaIdx);
             falseStringValue = booleanFormat.substring(commaIdx + 1);
         }
+
+        this.booleanFormat = booleanFormat;
+        properties.setProperty(BOOLEAN_FORMAT_KEY, booleanFormat);
     }
     
     /**
@@ -1045,15 +1053,23 @@ public class Configurable {
                 "Can't convert boolean to string automatically, because the \"", BOOLEAN_FORMAT_KEY ,"\" setting was ",
                 new _DelayedJQuote(getBooleanFormat()), 
                 (getBooleanFormat().equals(C_TRUE_FALSE)
-                    ? ", which is the legacy default computer-language format, and hence isn't accepted."
+                    ? ", which is the legacy deprecated default, and we treat it as if no format was set. "
+                            + "This is the default configuration; you should provide the format explicitly for each "
+                            + "place where you print a boolean."
                     : ".")
                 ).tips(
-                     "If you just want \"true\"/\"false\" result as you are generting computer-language output, "
-                     + "use \"?c\", like ${myBool?c}.",
-                     "You can write myBool?string('yes', 'no') and like to specify boolean formatting in place.",
-                     new Object[] {
-                         "If you need the same two values on most places, the programmers should set the \"",
-                         BOOLEAN_FORMAT_KEY ,"\" setting to something like \"yes,no\"." }
+                     "Write something like myBool?string('yes', 'no') to specify boolean formatting in place.",
+                    new Object[]{
+                        "If you want \"true\"/\"false\" result as you are generating computer-language output "
+                                + "(not for direct human consumption), then use \"?c\", like ${myBool?c}. (If you "
+                                + "always generate computer-language output, then it's might be reasonable to set "
+                                + "the \"", BOOLEAN_FORMAT_KEY, "\" setting to \"c\" instead.)",
+                    },
+                    new Object[] {
+                        "If you need the same two values on most places, the programmers can set the \"",
+                        BOOLEAN_FORMAT_KEY ,"\" setting to something like \"yes,no\". However, then it will be easy to "
+                                + "unwillingly format booleans like that."
+                    }
                  );
     }
 
diff --git a/src/main/java/freemarker/core/MiscUtil.java b/src/main/java/freemarker/core/MiscUtil.java
index ccd0dd9..770e394 100644
--- a/src/main/java/freemarker/core/MiscUtil.java
+++ b/src/main/java/freemarker/core/MiscUtil.java
@@ -35,7 +35,7 @@ class MiscUtil {
 
     static final String C_FALSE = "false";
     static final String C_TRUE = "true";
-    
+
     /**
      * Returns the map entries in source code order of the Expression values.
      */
diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml
index 161b52c..d82d089 100644
--- a/src/manual/en_US/book.xml
+++ b/src/manual/en_US/book.xml
@@ -15979,7 +15979,8 @@ Extended decimal format: 10<emphasis>_</emphasis>00<emphasis>3</emphasis></progr
                 </tr>
 
                 <tr>
-                  <td><literal>multiplier</literal></td>
+                  <td><literal>multiplier</literal> (was
+                  <literal>multipier</literal> before 2.3.29)</td>
 
                   <td>The number will be shown after multiplied with this
                   integer number.</td>
@@ -16721,10 +16722,18 @@ Tue, Apr 8, '03
           <quote>computer language</quote> as opposed to for human audience.
           The result will be <literal>"true"</literal> or
           <literal>"false"</literal>, regardless of the
-          <literal>boolean_format</literal> setting. When generating
-          JavaScript and such, this should be used, as otherwise changing the
-          <literal>boolean_format</literal> can break the generated
-          computer-language output.</para>
+          <literal>boolean_format</literal> configuration setting, as that
+          setting is meant to specify the format for human consumption. When
+          generating boolean literals for JavaScript and such, this should be
+          used.</para>
+
+          <para>If you only generate output that's computer language and isn't
+          read by end-users, you may want to set the
+          <literal>boolean_format</literal> configuration setting to
+          <literal>c</literal> (since FreeMarker 2.3.29), in which case
+          <literal>${<replaceable>aBoolean</replaceable>}</literal> will have
+          the same output as
+          <literal>${<replaceable>aBoolean</replaceable>?c}</literal>.</para>
 
           <para>Note that this built-in <link linkend="ref_builtin_c">also
           works on strings</link>.</para>
@@ -26752,14 +26761,14 @@ End book</programlisting>
           </question>
 
           <answer>
-            <para>Unlike numbers, booleans has no commonly accepted format,
-            not even a common format within the same page. Like when you show
-            on a HTML page if a product is washable, you will hardly want to
-            show for the visitor "Washable: true", but rather "Washable: yes".
-            So we force the template author (by <literal>${washable}</literal>
-            causing error) to find out with his human knowledge how the
-            boolean value should be shown at the given place. The common way
-            of formatting a boolean is like <literal>${washable?string("yes",
+            <para><literal>${<replaceable>...</replaceable>}</literal> meant
+            to format values for human consumption, and unlike numbers,
+            booleans has no commonly accepted format
+            (<literal>true</literal>/<literal>false</literal> is common in
+            computer languages, but you rarely use it outside that). The
+            proper format depends quite much on the context, therefore,
+            usually the template author should decide the proper format for
+            each case, like <literal>${washable?string("yes",
             "no")}</literal>, <literal>${caching?string("Enabled",
             "Disabled")}</literal>, <literal>${heating?string("on",
             "off")}</literal>, etc.</para>
@@ -26771,14 +26780,24 @@ End book</programlisting>
               <listitem>
                 <para>When printing boolean to generate computer language
                 output, and hence you want
-                <literal>true</literal>/<literal>false</literal>, use
-                <literal>${<replaceable>someBoolean</replaceable>?c}</literal>.
-                (This requires at least FreeMarker 2.3.20. Before that, the
-                common practice was writing
-                <literal>${<replaceable>someBoolean</replaceable>?string}</literal>,
-                however that's dangerous because its output depends on the
-                current boolean format setting, whose default is
-                <literal>"true"</literal>/<literal>"false"</literal>.)</para>
+                <literal>true</literal>/<literal>false</literal>. In such case
+                use <literal>${<replaceable>someBoolean</replaceable><link
+                linkend="ref_builtin_c_boolean">?c</link>}</literal> (requires
+                FreeMarker 2.3.20). If you never generate for human
+                consumption, only for computer language output, you might want
+                to set <literal>boolean_format</literal> to
+                <literal>c</literal> (available since FreeMarker 2.3.29), and
+                then <literal>${<replaceable>aBoolean</replaceable>}</literal>
+                will behave as
+                <literal>${<replaceable>aBoolean</replaceable>?c}</literal>.</para>
+
+                <para>Before 2.3.20, if you really can't upgrade FreeMarker,
+                try if
+                <literal>${<replaceable>someBoolean</replaceable>?string}</literal>.
+                By default that prints
+                <literal>true</literal>/<literal>false</literal>. Then somehow
+                try to ensure that <literal>boolean_format</literal> won't be
+                changed later by someone, breaking your output.</para>
               </listitem>
 
               <listitem>
@@ -27928,6 +27947,22 @@ TemplateModel x = env.getVariable("x");  // get variable x</programlisting>
             </listitem>
 
             <listitem>
+              <para>The <literal>boolean_format</literal> configuration
+              setting now can be set to <literal>"c"</literal>. Then
+              <literal>${<replaceable>aBoolean</replaceable>}</literal> will
+              behave as
+              <literal>${<replaceable>aBoolean</replaceable>?c}</literal>.
+              This should be only used if you are generating output for
+              non-human (computer) consumption only. If your output has pieces
+              for human audience too, it's still recommended to use
+              <literal>${<replaceable>aBoolean</replaceable>?c}</literal>
+              where <literal>true</literal>/<literal>false</literal> output is
+              needed, and either not set the <literal>boolean_format</literal>
+              at all, or set it to something that's appropriate for everyday
+              uses (like <literal>"yes,no"</literal>).</para>
+            </listitem>
+
+            <listitem>
               <para>Added
               <literal>TemplateModelUtils.wrapAsHashUnion(ObjectWrapper,
               List&lt;?&gt;)</literal> and
diff --git a/src/test/java/freemarker/template/ConfigurationTest.java b/src/test/java/freemarker/template/ConfigurationTest.java
index cd71ca1..3cf8c8b 100644
--- a/src/test/java/freemarker/template/ConfigurationTest.java
+++ b/src/test/java/freemarker/template/ConfigurationTest.java
@@ -1417,6 +1417,24 @@ public class ConfigurationTest extends TestCase {
     }
 
     @Test
+    public void testSetBooleanFormat() throws Exception {
+        Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
+
+        cfg.setBooleanFormat("yes,no");
+        assertOutputEquals("yes no", new Template(null, "${true} ${false}", cfg));
+
+        cfg.setBooleanFormat("c");
+        assertOutputEquals("true false", new Template(null, "${true} ${false}", cfg));
+
+        try {
+            cfg.setBooleanFormat("yes no");
+            fail();
+        } catch (IllegalArgumentException e) {
+            assertThat(e.getMessage(), containsString("comma"));
+        }
+    }
+
+    @Test
     public void testSetTabSize() throws Exception {
         Configuration cfg = new Configuration(Configuration.VERSION_2_3_0);
         
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/boolean-formatting.ftl b/src/test/resources/freemarker/test/templatesuite/templates/boolean-formatting.ftl
index 9d6c742..e77d3bf 100644
--- a/src/test/resources/freemarker/test/templatesuite/templates/boolean-formatting.ftl
+++ b/src/test/resources/freemarker/test/templatesuite/templates/boolean-formatting.ftl
@@ -16,7 +16,7 @@
   specific language governing permissions and limitations
   under the License.
 -->
-<#assign suppress>
+<@noOutput>
 <@assertFails message="true,false">${true}</@>
 <@assertFails message="true,false">${false}</@>
 <@assertFails message="true,false">${"" + true}</@>
@@ -31,6 +31,11 @@
 <@assertEquals expected="f" actual=false?string('t', 'f') />
 <#setting boolean_format = 'true,false'>
 <@assertFails message="true,false">${true}</@>
+<#setting boolean_format = 'c'>
+<@assertEquals expected="true" actual=true?string />
+<@assertEquals expected="false" actual=false?string />
+<@assertEquals expected="true" actual="${true}" />
+<@assertEquals expected="false" actual="${false}" />
 
 <#setting boolean_format = 'ja,nein'>
 <@assertEquals expected="ja" actual="" + true />
@@ -58,7 +63,7 @@
 <@assertEquals actual=123?upper_case expected="123" />
 <@assertEquals actual=true?upper_case expected="Y" />
 
-</#assign>
+</...@noOutput>
 <#escape x as x?upper_case>
 <#assign x = true>${x} ${true} ${true?string}
 <#assign x = false>${x} ${false} ${false?string}
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl b/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl
index e21bc2d..7b76501 100644
--- a/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl
+++ b/src/test/resources/freemarker/test/templatesuite/templates/sequence-builtins.ftl
@@ -19,6 +19,7 @@
 <@noOutput>
 <#setting locale="en_US">
 <#setting number_format="0.#########">
+<#setting boolean_format="c">
 
 <#assign ls = []?sort>
 <#list ls as i>
@@ -67,7 +68,7 @@ Boolean order:
         false,
         true]>
 <#list x?sort as i>
-- ${i?string}
+- ${i}
 </#list>
 
 
@@ -135,25 +136,25 @@ Contains:
 <#macro test></#macro>
 <#assign x = [1, "2", true, [1,2,3], {"a":1}, test, '1992-02-21'?date('yyyy-MM-dd')]>
 True:
-${x?seq_contains(1.0)?string}
-${x?seq_contains("2")?string}
-${x?seq_contains(true)?string}
-${x?seq_contains('1992-02-21'?date('yyyy-MM-dd'))?string}
-${abcSet?seq_contains("a")?string}
-${abcSet?seq_contains("b")?string}
-${abcSet?seq_contains("c")?string}
+${x?seq_contains(1.0)}
+${x?seq_contains("2")}
+${x?seq_contains(true)}
+${x?seq_contains('1992-02-21'?date('yyyy-MM-dd'))}
+${abcSet?seq_contains("a")}
+${abcSet?seq_contains("b")}
+${abcSet?seq_contains("c")}
 
 False:
-${x?seq_contains("1")?string}
-${x?seq_contains(2)?string}
-${x?seq_contains(false)?string}
-${x?seq_contains('1992-02-22'?date('yyyy-MM-dd'))?string}
-${abcSet?seq_contains("A")?string}
-${abcSet?seq_contains(1)?string}
-${abcSet?seq_contains(true)?string}
+${x?seq_contains("1")}
+${x?seq_contains(2)}
+${x?seq_contains(false)}
+${x?seq_contains('1992-02-22'?date('yyyy-MM-dd'))}
+${abcSet?seq_contains("A")}
+${abcSet?seq_contains(1)}
+${abcSet?seq_contains(true)}
 
 <#assign x = []>
-False: ${x?seq_contains(1)?string}
+False: ${x?seq_contains(1)}
 
 Index_of:
 ---------
@@ -285,12 +286,12 @@ seq_last_index_of "c":
 Sequence builtins ignoring nulls
 --------------------------------
 
-true = ${listWithNull?seq_contains('c')?string}
+true = ${listWithNull?seq_contains('c')}
 2 = ${listWithNull?seq_index_of('c')}
 0 = ${listWithNull?seq_last_index_of('a')}
 
 These should throw exception, but for BC they don't:
-false = ${listWithNull?seq_contains(noSuchVar)?string}
+false = ${listWithNull?seq_contains(noSuchVar)}
 -1 = ${listWithNull?seq_index_of(noSuchVar)}
 -1 = ${listWithNull?seq_last_index_of(noSuchVar)}
 
@@ -301,7 +302,7 @@ Sequence built-ins failing on date-type mismatch
 <@assertEquals actual=x?seq_index_of('foo') expected=1 />
 <@assertEquals actual=x?seq_index_of('1992-02-21'?date('yyyy-MM-dd')) expected=0 />
 <@assertFails message="dates of different types">
-  0 = ${x?seq_index_of('1992-02-21 00:00:00'?datetime('yyyy-MM-dd HH:mm:ss'))}
+  ${x?seq_index_of('1992-02-21 00:00:00'?datetime('yyyy-MM-dd HH:mm:ss'))}
 </@>
 
 Chunk
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl b/src/test/resources/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl
index 81c0b8f..ad27270 100644
--- a/src/test/resources/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl
+++ b/src/test/resources/freemarker/test/templatesuite/templates/string-builtins-regexps.ftl
@@ -16,31 +16,32 @@
   specific language governing permissions and limitations
   under the License.
 -->
-${"test"?matches('test')?string} == true
-${"test"?matches('test', '')?string} == true
-
-${"TEST"?matches('test')?string} == false
-${"TEST"?matches('test', 'i')?string} == true
-
-${"test\nfoo"?matches('.*^foo')?string} == false
-${"test\nfoo"?matches(r'.*\n^foo', 'm')?string} == true
-
-${"test\nfoo"?matches('test.foo')?string} == false
-${"test\nfoo"?matches('test.foo', 's')?string} == true
-
-${"test\nFoo"?matches('.*foo', 's')?string} == false
-${"test\nFoo"?matches('.*foo', 'i')?string} == false
-${"test\nFoo"?matches('.*foo', 'im')?string} == false
-${"test\nFoo"?matches('.*foo', 'si')?string} == true
-${"test\nFoo"?matches('.*foo', 'is')?string} == true
-${"test\nFoo"?matches('.*foo', 'mis')?string} == true
-
-${"test\nFoo"?matches('.*\n^foo', 'm')?string} == false
-${"test\nFoo"?matches('.*\n^foo', 'i')?string} == false
-${"test\nFoo"?matches('.*\n^foo', 'im')?string} == true
-${"test\nFoo"?matches('.*\n^foo', 'mi')?string} == true
-${"test\nFoo"?matches('.*^foo', 'ism')?string} == true
-${"test\nFoo"?matches('.*^foo', 'smi')?string} == true
+<#setting boolean_format="c">
+${"test"?matches('test')} == true
+${"test"?matches('test', '')} == true
+
+${"TEST"?matches('test')} == false
+${"TEST"?matches('test', 'i')} == true
+
+${"test\nfoo"?matches('.*^foo')} == false
+${"test\nfoo"?matches(r'.*\n^foo', 'm')} == true
+
+${"test\nfoo"?matches('test.foo')} == false
+${"test\nfoo"?matches('test.foo', 's')} == true
+
+${"test\nFoo"?matches('.*foo', 's')} == false
+${"test\nFoo"?matches('.*foo', 'i')} == false
+${"test\nFoo"?matches('.*foo', 'im')} == false
+${"test\nFoo"?matches('.*foo', 'si')} == true
+${"test\nFoo"?matches('.*foo', 'is')} == true
+${"test\nFoo"?matches('.*foo', 'mis')} == true
+
+${"test\nFoo"?matches('.*\n^foo', 'm')} == false
+${"test\nFoo"?matches('.*\n^foo', 'i')} == false
+${"test\nFoo"?matches('.*\n^foo', 'im')} == true
+${"test\nFoo"?matches('.*\n^foo', 'mi')} == true
+${"test\nFoo"?matches('.*^foo', 'ism')} == true
+${"test\nFoo"?matches('.*^foo', 'smi')} == true
 <#setting boolean_format="True,False">
 <@assert test=false?matches('[eslaF]+') />
 <@assert test='False'?matches('[eslaF]+') />
@@ -89,12 +90,12 @@ Lower c-word with follower in the same line:
 </#list>
 
 <#attempt>
-  Ignored but logged in 2.3: ${s?matches('broken', 'I')?string} == False
+  Ignored but logged in 2.3: ${s?matches('broken', 'I')} == False
 <#recover>
   Fails in 2.4
 </#attempt>
 <#attempt>
-  Ignored but logged in 2.3: ${s?matches('broken', 'f')?string} == False
+  Ignored but logged in 2.3: ${s?matches('broken', 'f')} == False
 <#recover>
   Fails in 2.4
 </#attempt>
diff --git a/src/test/resources/freemarker/test/templatesuite/templates/string-builtins2.ftl b/src/test/resources/freemarker/test/templatesuite/templates/string-builtins2.ftl
index c9294fa..6e0f018 100644
--- a/src/test/resources/freemarker/test/templatesuite/templates/string-builtins2.ftl
+++ b/src/test/resources/freemarker/test/templatesuite/templates/string-builtins2.ftl
@@ -16,6 +16,7 @@
   specific language governing permissions and limitations
   under the License.
 -->
+<#setting boolean_format="c">
 --
 <#assign s = "abbcdbb">
 ${s?index_of("bb")} = 1
@@ -26,19 +27,19 @@ ${s?last_index_of("bb")} = 5
 ${s?last_index_of("bb", 4)} = 1
 ${s?last_index_of("")} = ${s?length}
 --
-${s?starts_with("abb")?string} = true
-${s?starts_with("bb")?string} = false
-${s?starts_with("")?string} = true
+${s?starts_with("abb")} = true
+${s?starts_with("bb")} = false
+${s?starts_with("")} = true
 --
-${s?ends_with("dbb")?string} = true
-${s?ends_with("cbb")?string} = false
-${s?ends_with("")?string} = true
+${s?ends_with("dbb")} = true
+${s?ends_with("cbb")} = false
+${s?ends_with("")} = true
 --
-${s?contains("abb")?string} = true
-${s?contains("bcd")?string} = true
-${s?contains("dbb")?string} = true
-${s?contains("bbx")?string} = false
-${s?contains("")?string} = true
+${s?contains("abb")} = true
+${s?contains("bcd")} = true
+${s?contains("dbb")} = true
+${s?contains("bbx")} = false
+${s?contains("")} = true
 --
 [${s?chop_linebreak}] = [abbcdbb]
 [${"qwe\n"?chop_linebreak}] = [qwe]