diff --git a/src/net/sourceforge/plantuml/tim/Eater.java b/src/net/sourceforge/plantuml/tim/Eater.java index 6e97e651f69..9d1ca8ff732 100644 --- a/src/net/sourceforge/plantuml/tim/Eater.java +++ b/src/net/sourceforge/plantuml/tim/Eater.java @@ -79,11 +79,12 @@ final protected String eatAllToEnd() throws EaterException { } final public TValue eatExpression(TContext context, TMemory memory) throws EaterException, EaterExceptionLocated { - if (peekChar() == '{') { + char ch = peekChar(); + if (ch == '{' || ch == '[') { final String data = eatAllToEnd(); - // System.err.println("data=" + data); + // System.err.println("data=" + data); final JsonValue json = Json.parse(data); - // System.err.println("json=" + json); + // System.err.println("json=" + json); return TValue.fromJson(json); } final TokenStack tokenStack = eatTokenStack(); diff --git a/src/net/sourceforge/plantuml/tim/VariableManager.java b/src/net/sourceforge/plantuml/tim/VariableManager.java index ae29bba05f1..8f3a7bd0098 100644 --- a/src/net/sourceforge/plantuml/tim/VariableManager.java +++ b/src/net/sourceforge/plantuml/tim/VariableManager.java @@ -66,7 +66,8 @@ public int replaceVariables(String str, int i, StringBuilder result) throws Eate } else if (value.toJson().isNumber()) { result.append(value.toJson().toString()); } else { - JsonValue jsonValue = (JsonObject) value.toJson(); + JsonValue jsonValue = (value.toJson().isArray()) ? (JsonArray) value.toJson() + : (JsonObject) value.toJson(); i++; i = replaceJson(jsonValue, str, i, result) - 1; } diff --git a/test/net/sourceforge/plantuml/tim/EaterTest.java b/test/net/sourceforge/plantuml/tim/EaterTest.java new file mode 100644 index 00000000000..3dbdbe57f15 --- /dev/null +++ b/test/net/sourceforge/plantuml/tim/EaterTest.java @@ -0,0 +1,64 @@ +package net.sourceforge.plantuml.tim; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.util.Lists.newArrayList; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.Collections; +import java.util.List; + +import org.junit.jupiter.api.DisplayNameGenerator.ReplaceUnderscores; +import org.junit.jupiter.api.IndicativeSentencesGeneration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import net.sourceforge.plantuml.ErrorStatus; +import net.sourceforge.plantuml.Option; +import net.sourceforge.plantuml.Pipe; + +@IndicativeSentencesGeneration(separator = ": ", generator = ReplaceUnderscores.class) +/** + * Tests the Eater (for JSON data). + */ +class EaterTest { + + @ParameterizedTest(name = "[{index}] {1}") + @CsvSource(nullValues = "null", value = { + "'@startuml\n!$a={\"k\": \"exampleValue\"}\ntitle $a.k\na -> b\n@enduml\n' , exampleValue", + "'@startuml\n!$a=[1, 2, 3]\ntitle xx $a[2] yy\na -> a\n' , xx 3 yy", + "'@startuml\ntitle\n!foreach $i in [1, 2, 3]\nxx $i yy\n!endfor\nendtitle\na -> a\n' , xx 2 yy", + "'@startuml\ntitle\n!foreach $i in [\"a\", \"b\", \"c\"]\nxx $i yy\n!endfor\nendtitle\na -> a\n' , xx b yy", + }) + void Test_EaterTest(String input, String expected) throws Exception { + assertRenderExpectedOutput(input, expected); + } + + // TODO: to Factorize on a specific test package... + private static final String[] COMMON_OPTIONS = {"-tutxt"}; + + private String[] optionArray(String... extraOptions) { + final List list = newArrayList(COMMON_OPTIONS); + Collections.addAll(list, extraOptions); + return list.toArray(new String[0]); + } + + private String render(String diagram, String... extraOptions) throws Exception { + final Option option = new Option(optionArray(extraOptions)); + final ByteArrayInputStream bais = new ByteArrayInputStream(diagram.getBytes(UTF_8)); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + final Pipe pipe = new Pipe(option, new PrintStream(baos), bais, option.getCharset()); + pipe.managePipe(ErrorStatus.init()); + String rendered = new String(baos.toByteArray(), UTF_8); + // System.err.println(rendered); + return rendered; + } + + public void assertRenderExpectedOutput(String input, String expected) throws Exception { + String rendered = render(input); + assertThat(rendered).doesNotContain("syntax").contains(expected); + } +}