package org.rapidoid.render; /* * #%L * rapidoid-render * %% * Copyright (C) 2014 - 2017 Nikolche Mihajlovski and contributors * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import org.junit.Test; import org.rapidoid.annotation.Authors; import org.rapidoid.annotation.Since; import org.rapidoid.u.U; @Authors("Nikolche Mihajlovski") @Since("5.1.0") public class RenderTest extends AbstractRenderTest { private final static Object[] VALUES = {"abc", 123, 3.14, true, false, U.list(), U.set(1, 2), U.map(1, "one", "two", 2)}; private final static Object[] TRUE_VALUES = {"abc", 0, 123, 3.14, true, U.list("a", true, false), U.set(false, 2), U.map(1, "one", "two", 2)}; private final static Object[] FALSE_VALUES = {"", null, false, U.set(), U.list(), U.map()}; private static final String IF_TEMPLATE = "{{?x}}[${x}]{{/x}}"; private static final String IF_NOT_TEMPLATE = "{{^x}}[${x}]{{/x}}"; private static final String IF_NOT_TEMPLATE2 = "{{!x}}[${x}]{{/x}}"; @Test public void testPrint() { for (Object x : VALUES) { eq(Render.template("${.}").model(x), "" + x); } } @Test public void testPrintUnescaped() { for (Object x : VALUES) { eq(Render.template("${.}").model(x), "" + x); } } @Test public void testIf() { for (Object x : TRUE_VALUES) { eq(Render.template(IF_TEMPLATE).model(U.map("x", x)), "[" + view(x) + "]"); } for (Object x : FALSE_VALUES) { eq(Render.template(IF_TEMPLATE).model(U.map("x", x)), ""); } } @Test public void testIfNot() { for (Object x : FALSE_VALUES) { eq(Render.template(IF_NOT_TEMPLATE).model(U.map("x", x)), "[" + view(x) + "]"); } for (Object x : TRUE_VALUES) { eq(Render.template(IF_NOT_TEMPLATE).model(U.map("x", x)), ""); } } @Test public void testIfNot2() { for (Object x : FALSE_VALUES) { eq(Render.template(IF_NOT_TEMPLATE2).model(U.map("x", x)), "[" + view(x) + "]"); } for (Object x : TRUE_VALUES) { eq(Render.template(IF_NOT_TEMPLATE2).model(U.map("x", x)), ""); } } @Test public void testIteration() { eq(Render.template("{{#.}}(${length}){{/.}}").model(U.list("aaa", "bb")), "(3)(2)"); } @Test public void testScopes() { eq(Render.template("${x}").multiModel(U.map("x", 1), U.map("x", 2)), "2"); eq(Render.template("${x}").multiModel(U.map("x", 1), U.map("y", 2)), "1"); eq(Render.template("${y}").multiModel(U.map("x", 1), U.map("y", 2)), "2"); eq(Render.template("${z}").multiModel(U.map("x", 1), U.map("y", 2)), view(null)); } @Test public void testEscaping() { String s = "a\r\n\tb"; String t = "<p id=\"foo\"><b ng-click=\"f(1, 'x', 2);\">abc</b></p>"; String t2 = "<p id="foo"><b ng-click="f(1, 'x', 2);">abc</b></p>"; eq(Render.template("${.}").model(s), s); eq(Render.template("@{.}").model(s), s); eq(Render.template("${.}").model(t), t2); eq(Render.template("@{.}").model(t), t); } @Test public void testUTF8() { eq(Render.template("Штрк-X-123").model(U.map()), "Штрк-X-123"); eq(Render.template("абвгд-${x}-foo").model(U.map("x", "чачача")), "абвгд-чачача-foo"); // 2-byte UTF-8 encoding eq(Render.template("${x}:ш:${x}").model(U.map("x", "ч")), "ч:ш:ч"); // 3-byte UTF-8 encoding eq(Render.template("${y}:€€:${y}").model(U.map("y", "€")), "€:€€:€"); } @Test public void testUTF8Surrogates() { String a = "\uD852\uDF62"; String b = "\uD852\uDF63"; eq(a.length(), 2); eq(b.length(), 2); // 4-byte (surrogate) UTF-8 encoding eq(Render.template("${x}:" + a + ":${x}").model(U.map("x", b)), b + ":" + a + ":" + b); // mix of 2-byte, 3-byte and 4-byte (surrogate) UTF-8 encoding eq(Render.template("шш€f€€\uD852\uDF62:${x}").model(U.map("x", "4€шf3\uD852\uDF63")), "шш€f€€\uD852\uDF62:4€шf3\uD852\uDF63"); } @Test public void testUTF8MalformedSurrogates() { String missing = "\uD852"; // [high] eq(Render.template("${x}:" + missing + ":${x}").model(U.map("x", missing)), "?:?:?"); String wrongOrder = "\uDF62\uD852"; // [low, high] eq(Render.template("${x}:" + wrongOrder + ":${x}").model(U.map("x", wrongOrder)), "??:??:??"); } private String view(Object x) { return U.or(x, "N/A").toString(); } }