| // Copyright 2015 The Bazel Authors. All Rights Reserved. | |
| // | |
| // 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. | |
| package com.google.devtools.build.lib.syntax; | |
| import static com.google.common.truth.Truth.assertThat; | |
| import static org.junit.Assert.assertThrows; | |
| import com.google.common.collect.ImmutableList; | |
| import com.google.common.collect.ImmutableMap; | |
| import com.google.devtools.build.lib.cmdline.Label; | |
| import java.util.IllegalFormatException; | |
| import java.util.LinkedHashMap; | |
| import java.util.List; | |
| import java.util.Map; | |
| import org.junit.Test; | |
| import org.junit.runner.RunWith; | |
| import org.junit.runners.JUnit4; | |
| /** | |
| * Test properties of the evaluator's datatypes and utility functions | |
| * without actually creating any parse trees. | |
| */ | |
| @RunWith(JUnit4.class) | |
| public class PrinterTest { | |
| @Test | |
| public void testPrinter() throws Exception { | |
| // Note that prettyPrintValue and printValue only differ on behaviour of | |
| // labels and strings at toplevel. | |
| assertThat(Starlark.str(createObjWithStr())).isEqualTo("<str marker>"); | |
| assertThat(Starlark.repr(createObjWithStr())).isEqualTo("<repr marker>"); | |
| assertThat(Starlark.str("foo\nbar")).isEqualTo("foo\nbar"); | |
| assertThat(Starlark.repr("foo\nbar")).isEqualTo("\"foo\\nbar\""); | |
| assertThat(Starlark.str("'")).isEqualTo("'"); | |
| assertThat(Starlark.repr("'")).isEqualTo("\"'\""); | |
| assertThat(Starlark.str("\"")).isEqualTo("\""); | |
| assertThat(Starlark.repr("\"")).isEqualTo("\"\\\"\""); | |
| assertThat(Starlark.str(3)).isEqualTo("3"); | |
| assertThat(Starlark.repr(3)).isEqualTo("3"); | |
| assertThat(Starlark.repr(Starlark.NONE)).isEqualTo("None"); | |
| assertThat(Starlark.str(Label.parseAbsolute("//x", ImmutableMap.of()))).isEqualTo("//x:x"); | |
| assertThat(Starlark.repr(Label.parseAbsolute("//x", ImmutableMap.of()))) | |
| .isEqualTo("Label(\"//x:x\")"); | |
| List<?> list = StarlarkList.of(null, "foo", "bar"); | |
| List<?> tuple = Tuple.of("foo", "bar"); | |
| assertThat(Starlark.str(Tuple.of(1, list, 3))).isEqualTo("(1, [\"foo\", \"bar\"], 3)"); | |
| assertThat(Starlark.repr(Tuple.of(1, list, 3))).isEqualTo("(1, [\"foo\", \"bar\"], 3)"); | |
| assertThat(Starlark.str(StarlarkList.of(null, 1, tuple, 3))) | |
| .isEqualTo("[1, (\"foo\", \"bar\"), 3]"); | |
| assertThat(Starlark.repr(StarlarkList.of(null, 1, tuple, 3))) | |
| .isEqualTo("[1, (\"foo\", \"bar\"), 3]"); | |
| Map<Object, Object> dict = | |
| ImmutableMap.<Object, Object>of(1, tuple, 2, list, "foo", StarlarkList.of(null)); | |
| assertThat(Starlark.str(dict)) | |
| .isEqualTo("{1: (\"foo\", \"bar\"), 2: [\"foo\", \"bar\"], \"foo\": []}"); | |
| assertThat(Starlark.repr(dict)) | |
| .isEqualTo("{1: (\"foo\", \"bar\"), 2: [\"foo\", \"bar\"], \"foo\": []}"); | |
| } | |
| private void checkFormatPositionalFails(String errorMessage, String format, Object... arguments) { | |
| IllegalFormatException e = | |
| assertThrows(IllegalFormatException.class, () -> Starlark.format(format, arguments)); | |
| assertThat(e).hasMessageThat().isEqualTo(errorMessage); | |
| } | |
| @Test | |
| public void testOutputOrderOfMap() throws Exception { | |
| Map<Object, Object> map = new LinkedHashMap<>(); | |
| map.put(5, 5); | |
| map.put(3, 3); | |
| map.put("foo", 42); | |
| map.put(7, "bar"); | |
| assertThat(Starlark.str(map)).isEqualTo("{5: 5, 3: 3, \"foo\": 42, 7: \"bar\"}"); | |
| } | |
| @Test | |
| public void testFormatPositional() throws Exception { | |
| assertThat(Starlark.formatWithList("%s %d", Tuple.of("foo", 3))).isEqualTo("foo 3"); | |
| assertThat(Starlark.format("%s %d", "foo", 3)).isEqualTo("foo 3"); | |
| assertThat(Starlark.format("%s %s %s", 1, null, 3)).isEqualTo("1 null 3"); | |
| // Note: formatToString doesn't perform scalar x -> (x) conversion; | |
| // The %-operator is responsible for that. | |
| assertThat(Starlark.formatWithList("", Tuple.of())).isEmpty(); | |
| assertThat(Starlark.format("%s", "foo")).isEqualTo("foo"); | |
| assertThat(Starlark.format("%s", 3.14159)).isEqualTo("3.14159"); | |
| checkFormatPositionalFails("not all arguments converted during string formatting", | |
| "%s", 1, 2, 3); | |
| assertThat(Starlark.format("%%%s", "foo")).isEqualTo("%foo"); | |
| checkFormatPositionalFails("not all arguments converted during string formatting", | |
| "%%s", "foo"); | |
| checkFormatPositionalFails("unsupported format character \" \" at index 1 in \"% %s\"", | |
| "% %s", "foo"); | |
| assertThat(Starlark.format("%s", StarlarkList.of(null, 1, 2, 3))).isEqualTo("[1, 2, 3]"); | |
| assertThat(Starlark.format("%s", Tuple.of(1, 2, 3))).isEqualTo("(1, 2, 3)"); | |
| assertThat(Starlark.format("%s", StarlarkList.of(null))).isEqualTo("[]"); | |
| assertThat(Starlark.format("%s", Tuple.of())).isEqualTo("()"); | |
| assertThat(Starlark.format("%% %d %r %s", 1, "2", "3")).isEqualTo("% 1 \"2\" 3"); | |
| checkFormatPositionalFails( | |
| "invalid argument \"1\" for format pattern %d", | |
| "%d", "1"); | |
| checkFormatPositionalFails("unsupported format character \".\" at index 1 in \"%.3g\"", | |
| "%.3g"); | |
| checkFormatPositionalFails("unsupported format character \".\" at index 1 in \"%.3g\"", | |
| "%.3g", 1, 2); | |
| checkFormatPositionalFails("unsupported format character \".\" at index 1 in \"%.s\"", | |
| "%.s"); | |
| } | |
| @Test | |
| public void testPrettyPrinter() throws Exception { | |
| assertThat(Printer.getPrettyPrinter().repr(ImmutableList.of(1, 2, 3)).toString()) | |
| .isEqualTo( | |
| "[\n" + | |
| " 1,\n" + | |
| " 2,\n" + | |
| " 3\n" + | |
| "]"); | |
| assertThat(Printer.getPrettyPrinter().repr(ImmutableList.<String>of()).toString()) | |
| .isEqualTo("[]"); | |
| assertThat(Printer.getPrettyPrinter().repr(ImmutableList.of("foo")).toString()) | |
| .isEqualTo("[\n \"foo\"\n]"); | |
| assertThat( | |
| Printer.getPrettyPrinter() | |
| .repr(ImmutableMap.<Object, Object>of("foo", "bar", "baz", ImmutableList.of(1, 2))) | |
| .toString()) | |
| .isEqualTo( | |
| "{\n" + | |
| " \"foo\": \"bar\",\n" + | |
| " \"baz\": [\n" + | |
| " 1,\n" + | |
| " 2\n" + | |
| " ]\n" + | |
| "}"); | |
| assertThat( | |
| Printer.getPrettyPrinter() | |
| .repr(ImmutableMap.<Object, Object>of( | |
| "foo", "bar", "empty", ImmutableList.of(), "a", "b")) | |
| .toString()) | |
| .isEqualTo( | |
| "{\n" + | |
| " \"foo\": \"bar\",\n" + | |
| " \"empty\": [],\n" + | |
| " \"a\": \"b\"\n" + | |
| "}"); | |
| } | |
| private Printer makeSimplifiedFormatPrinter() { | |
| return new Printer.BasePrinter(new StringBuilder(), /*simplifiedFormatStrings=*/ true); | |
| } | |
| @Test | |
| public void testSimplifiedDisallowsPlaceholdersBesidesPercentS() { | |
| assertThat(makeSimplifiedFormatPrinter().format("Allowed: %%").toString()) | |
| .isEqualTo("Allowed: %"); | |
| assertThat(makeSimplifiedFormatPrinter().format("Allowed: %s", "abc").toString()) | |
| .isEqualTo("Allowed: abc"); | |
| assertThrows( | |
| IllegalFormatException.class, | |
| () -> makeSimplifiedFormatPrinter().format("Disallowed: %r", "abc")); | |
| assertThrows( | |
| IllegalFormatException.class, | |
| () -> makeSimplifiedFormatPrinter().format("Disallowed: %d", 5)); | |
| } | |
| private StarlarkValue createObjWithStr() { | |
| return new StarlarkValue() { | |
| @Override | |
| public void repr(Printer printer) { | |
| printer.append("<repr marker>"); | |
| } | |
| @Override | |
| public void str(Printer printer) { | |
| printer.append("<str marker>"); | |
| } | |
| }; | |
| } | |
| } |