1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-12-22 10:59:01 +00:00

Remove \r when running PipeTest on Windows

This commit is contained in:
Arnaud Roques 2021-07-30 18:43:10 +02:00
parent 19822a5539
commit fd920b7d52

View File

@ -1,6 +1,5 @@
package net.sourceforge.plantuml; package net.sourceforge.plantuml;
import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
@ -20,356 +19,393 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.ValueSource;
class PipeTest { class PipeTest {
ByteArrayOutputStream baos; ByteArrayOutputStream baos;
ErrorStatus errorStatus; ErrorStatus errorStatus;
Option option; Option option;
Pipe pipe; Pipe pipe;
PrintStream ps; PrintStream ps;
@BeforeEach @BeforeEach
void setup() { void setup() {
errorStatus = ErrorStatus.init(); errorStatus = ErrorStatus.init();
baos = new ByteArrayOutputStream(); baos = new ByteArrayOutputStream();
option = new Option(); option = new Option();
ps = new PrintStream(baos); ps = new PrintStream(baos);
pipe = new Pipe(option, ps, new ByteArrayInputStream(new byte[0]), UTF_8.toString()); pipe = new Pipe(option, ps, new ByteArrayInputStream(new byte[0]), UTF_8.toString());
} }
@Test @Test
void should_managePipe_set_as_no_error_for_empty_input() throws IOException { void should_managePipe_set_as_no_error_for_empty_input() throws IOException {
pipe = new Pipe(option, ps, new ByteArrayInputStream(new byte[0]), UTF_8.name()); pipe = new Pipe(option, ps, new ByteArrayInputStream(new byte[0]), UTF_8.name());
pipe.managePipe(errorStatus); pipe.managePipe(errorStatus);
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) { try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
softly.assertThat(errorStatus.hasError()).isFalse(); softly.assertThat(errorStatus.hasError()).isFalse();
softly.assertThat(errorStatus.isNoData()).isTrue(); softly.assertThat(errorStatus.isNoData()).isTrue();
softly.assertThat(baos.toByteArray()).isEmpty(); softly.assertThat(baos.toByteArray()).isEmpty();
} }
} }
static List<TestCase> managePipeTestCases() {
static List<TestCase> managePipeTestCases() { LinkedList<TestCase> l = new LinkedList<>();
LinkedList<TestCase> l = new LinkedList<>();
l.add(TestCase.of("", "", "", Verification.EXACT, false, true));
l.add(TestCase.of("", "", "", Verification.EXACT, false, true));
// ok render
// ok render l.add(TestCase.of("", "a->b", "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, false,
l.add(TestCase.of("", "a->b", "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, false, false)); false));
l.add(TestCase.of("", "@startuml\na->b\n@enduml", "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, false, false)); l.add(TestCase.of("", "@startuml\na->b\n@enduml", "(?s).*PNG.*Generated by http://plantuml.com.*",
l.add(TestCase.of("", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n", "(?s).*(PNG.*Generated by http://plantuml.com.*){2}", Verification.REGEX, false, false)); Verification.REGEX, false, false));
l.add(TestCase.of("", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n",
// bad data "(?s).*(PNG.*Generated by http://plantuml.com.*){2}", Verification.REGEX, false, false));
l.add(TestCase.of("", "a", "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, true, false));
l.add(TestCase.of("", "@startuml\na\n@enduml\n", "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, true, false)); // bad data
l.add(TestCase.of("", "@startuml\na\n@enduml\n@startuml\na\n@enduml\n", "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, true, false)); l.add(TestCase.of("", "a", "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, true, false));
l.add(TestCase.of("", "@startuml\na\n@enduml\n", "(?s).*PNG.*Generated by http://plantuml.com.*",
// ignore garbage before; after; before&between&after diagrams Verification.REGEX, true, false));
l.add(TestCase.of("", "this-is-garbage\n@startuml\na->b\n@enduml", "(?s).*(PNG.*Generated by http://plantuml.com.*){1}", Verification.REGEX, false, false)); l.add(TestCase.of("", "@startuml\na\n@enduml\n@startuml\na\n@enduml\n",
l.add(TestCase.of("", "@startuml\na->b\n@enduml\nthis-is-garbage", "(?s).*(PNG.*Generated by http://plantuml.com.*){1}", Verification.REGEX, false, false)); "(?s).*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, true, false));
l.add(TestCase.of("", "this-is-garbage\n@startuml\na->b\n@enduml\nthis-is-garbage\n@startuml\na->b\n@enduml\nthis-is-garbage", "(?s).*(PNG.*Generated by http://plantuml.com.*){2}", Verification.REGEX, false, false));
// ignore garbage before; after; before&between&after diagrams
// ignore other diagram start tags when still not closed (but fails to generate) l.add(TestCase.of("", "this-is-garbage\n@startuml\na->b\n@enduml",
l.add(TestCase.of("", "@startuml\na->b\n@startgantt\n@enduml\n", "(?s).*(PNG.*Generated by http://plantuml.com.*){1}", Verification.REGEX, true, false)); "(?s).*(PNG.*Generated by http://plantuml.com.*){1}", Verification.REGEX, false, false));
l.add(TestCase.of("", "@startuml\na->b\n@enduml\nthis-is-garbage",
// manage @@@format svg "(?s).*(PNG.*Generated by http://plantuml.com.*){1}", Verification.REGEX, false, false));
l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml", "(?s).*<\\?xml.*<svg.*</svg>", Verification.REGEX, false, false)); l.add(TestCase.of("",
l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml\n@startuml\n@@@format svg\na->b\n@enduml", "(?s).*(<\\?xml.*<svg.*</svg>.*){2}", Verification.REGEX, false, false)); "this-is-garbage\n@startuml\na->b\n@enduml\nthis-is-garbage\n@startuml\na->b\n@enduml\nthis-is-garbage",
"(?s).*(PNG.*Generated by http://plantuml.com.*){2}", Verification.REGEX, false, false));
// mixed formats
l.add(TestCase.of("", "@startuml\n@@@format png\na->b\n@enduml\n@startuml\n@@@format svg\na->b\n@enduml", "(?s).*PNG.*Generated by http://plantuml.com.*<\\?xml.*<svg.*</svg>", Verification.REGEX, false, false)); // ignore other diagram start tags when still not closed (but fails to generate)
l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml\n@startuml\n@@@format png\na->b\n@enduml", "(?s).*<\\?xml.*<svg.*</svg>.*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, false, false)); l.add(TestCase.of("", "@startuml\na->b\n@startgantt\n@enduml\n",
"(?s).*(PNG.*Generated by http://plantuml.com.*){1}", Verification.REGEX, true, false));
// pipe delimitor
l.add(TestCase.of("-pipedelimitor PIPE-DELIMITOR", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n", "(?s).*(PNG.*Generated by http://plantuml.com.*PIPE-DELIMITOR.*){2}", Verification.REGEX, false, false)); // manage @@@format svg
l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml", "(?s).*<\\?xml.*<svg.*</svg>",
// if format is set in first diagram and not in the second, it will be used in both (Possibly incorrect: preseved from old behaviour) Verification.REGEX, false, false));
l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml\n@startuml\na->b\n@enduml", "(?s).*(<\\?xml.*<svg.*</svg>.*){2}", Verification.REGEX, false, false)); l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml\n@startuml\n@@@format svg\na->b\n@enduml",
"(?s).*(<\\?xml.*<svg.*</svg>.*){2}", Verification.REGEX, false, false));
// ok computeurl
l.add(TestCase.of("-computeurl", "@startuml\na->b\n@enduml", "IzIrIm80\n", Verification.EXACT, false, true)); // mixed formats
l.add(TestCase.of("-computeurl", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n", "IzIrIm80\nIzIrI-9AqhLB1W00\n", Verification.EXACT,false, true)); l.add(TestCase.of("", "@startuml\n@@@format png\na->b\n@enduml\n@startuml\n@@@format svg\na->b\n@enduml",
"(?s).*PNG.*Generated by http://plantuml.com.*<\\?xml.*<svg.*</svg>", Verification.REGEX, false,
// ok encodeurl false));
l.add(TestCase.of("-encodeurl", "@startuml\na->b\n@enduml", "IzIrIm80\n", Verification.EXACT,false, true)); l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml\n@startuml\n@@@format png\na->b\n@enduml",
l.add(TestCase.of("-encodeurl", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n", "IzIrIm80\nIzIrI-9AqhLB1W00\n", Verification.EXACT, false, true)); "(?s).*<\\?xml.*<svg.*</svg>.*PNG.*Generated by http://plantuml.com.*", Verification.REGEX, false,
false));
// valid syntax
l.add(TestCase.of("-syntax", "@startuml\na->b\n@enduml", "SEQUENCE\n(2 participants)\n", Verification.EXACT, false, false)); // pipe delimitor
l.add(TestCase.of("-syntax", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n", "SEQUENCE\n(2 participants)\nSEQUENCE\n(3 participants)\n", Verification.EXACT, false, false)); l.add(TestCase.of("-pipedelimitor PIPE-DELIMITOR", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n",
l.add(TestCase.of("-syntax", "@startgantt\n[a] lasts 1 day\n@endgantt", "OTHER\n(Project)\n", Verification.EXACT, false, false)); "(?s).*(PNG.*Generated by http://plantuml.com.*PIPE-DELIMITOR.*){2}", Verification.REGEX, false,
false));
// invalid syntax
l.add(TestCase.of("-syntax", "@startuml\na\n@enduml", "ERROR\n1\nSyntax Error?\n", Verification.EXACT, true, false)); // if format is set in first diagram and not in the second, it will be used in
l.add(TestCase.of("-syntax", "@startuml\na\n@enduml\n@startuml\na\n@enduml", "ERROR\n1\nSyntax Error?\nERROR\n1\nSyntax Error?\n", Verification.EXACT, true, false)); // both (Possibly incorrect: preseved from old behaviour)
l.add(TestCase.of("-syntax", "@startuml\na->b\n@enduml\n@startuml\na\n@enduml", "SEQUENCE\n(2 participants)\nERROR\n1\nSyntax Error?\n", Verification.EXACT, true, false)); l.add(TestCase.of("", "@startuml\n@@@format svg\na->b\n@enduml\n@startuml\na->b\n@enduml",
l.add(TestCase.of("-syntax", "@startuml\na\n@enduml\n@startuml\na->b\n@enduml", "ERROR\n1\nSyntax Error?\nSEQUENCE\n(2 participants)\n", Verification.EXACT, true, false)); "(?s).*(<\\?xml.*<svg.*</svg>.*){2}", Verification.REGEX, false, false));
// pipemap (using regexp to allow any coords so that it doesn't fail on different systems) // ok computeurl
l.add(TestCase.of("-pipemap", "@startuml\na->b: [[http://a.com]] c\n@enduml", l.add(TestCase.of("-computeurl", "@startuml\na->b\n@enduml", "IzIrIm80\n", Verification.EXACT, false, true));
"<map id=\"plantuml_map\" name=\"plantuml_map\">\n" + l.add(TestCase.of("-computeurl", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n",
"<area shape=\"rect\" id=\"id1\" href=\"http://a.com\" title=\"http://a.com\" alt=\"\" coords=\"[0-9]+,[0-9]+,[0-9]+,[0-9]+\"/>\n" + "IzIrIm80\nIzIrI-9AqhLB1W00\n", Verification.EXACT, false, true));
"</map>\n\n",
Verification.REGEX, false, false)); // ok encodeurl
l.add(TestCase.of("-pipemap", "@startuml\na->b: [[http://a.com]] c\n@enduml\n@startuml\nc->d: [[http://c.com]] e\n@enduml", l.add(TestCase.of("-encodeurl", "@startuml\na->b\n@enduml", "IzIrIm80\n", Verification.EXACT, false, true));
"<map id=\"plantuml_map\" name=\"plantuml_map\">\n" + l.add(TestCase.of("-encodeurl", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n",
"<area shape=\"rect\" id=\"id1\" href=\"http://a.com\" title=\"http://a.com\" alt=\"\" coords=\"[0-9]+,[0-9]+,[0-9]+,[0-9]+\"/>\n" + "IzIrIm80\nIzIrI-9AqhLB1W00\n", Verification.EXACT, false, true));
"</map>\n\n" +
"<map id=\"plantuml_map\" name=\"plantuml_map\">\n" + // valid syntax
"<area shape=\"rect\" id=\"id1\" href=\"http://c.com\" title=\"http://c.com\" alt=\"\" coords=\"[0-9]+,[0-9]+,[0-9]+,[0-9]+\"/>\n" + l.add(TestCase.of("-syntax", "@startuml\na->b\n@enduml", "SEQUENCE\n(2 participants)\n", Verification.EXACT,
"</map>\n\n", false, false));
Verification.REGEX, false, false)); l.add(TestCase.of("-syntax", "@startuml\na->b\n@enduml\n@startuml\na->b\nb->c\n@enduml\n",
"SEQUENCE\n(2 participants)\nSEQUENCE\n(3 participants)\n", Verification.EXACT, false, false));
// no links/invalid input => no pipemap to output (no error as of https://forum.plantuml.net/10049/2019-pipemap-diagrams-containing-links-give-zero-exit-code ) l.add(TestCase.of("-syntax", "@startgantt\n[a] lasts 1 day\n@endgantt", "OTHER\n(Project)\n",
l.add(TestCase.of("-pipemap", "@startuml\na->b\n@enduml", "\n", Verification.EXACT, false, false)); Verification.EXACT, false, false));
l.add(TestCase.of("-pipemap", "@startuml\na\n@enduml", "\n", Verification.EXACT, false, false));
// invalid syntax
return l; l.add(TestCase.of("-syntax", "@startuml\na\n@enduml", "ERROR\n1\nSyntax Error?\n", Verification.EXACT, true,
} false));
@ParameterizedTest l.add(TestCase.of("-syntax", "@startuml\na\n@enduml\n@startuml\na\n@enduml",
@MethodSource("managePipeTestCases") "ERROR\n1\nSyntax Error?\nERROR\n1\nSyntax Error?\n", Verification.EXACT, true, false));
void should_managePipe_manage_success_cases_correctly(TestCase testCase) throws IOException, InterruptedException { l.add(TestCase.of("-syntax", "@startuml\na->b\n@enduml\n@startuml\na\n@enduml",
option = new Option(testCase.getOptions().split(" ")); "SEQUENCE\n(2 participants)\nERROR\n1\nSyntax Error?\n", Verification.EXACT, true, false));
pipe = new Pipe(option, ps, new ByteArrayInputStream(testCase.getInput().getBytes(UTF_8)), UTF_8.name()); l.add(TestCase.of("-syntax", "@startuml\na\n@enduml\n@startuml\na->b\n@enduml",
"ERROR\n1\nSyntax Error?\nSEQUENCE\n(2 participants)\n", Verification.EXACT, true, false));
pipe.managePipe(errorStatus);
// pipemap (using regexp to allow any coords so that it doesn't fail on
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) { // different systems)
softly.assertThat(errorStatus.hasError()).isEqualTo(testCase.isExpectedHasErrors()); l.add(TestCase.of("-pipemap", "@startuml\na->b: [[http://a.com]] c\n@enduml",
softly.assertThat(errorStatus.isNoData()).isEqualTo(testCase.isExpectedIsNoData()); "<map id=\"plantuml_map\" name=\"plantuml_map\">\n"
switch(testCase.getExpectedOutVerification()) { + "<area shape=\"rect\" id=\"id1\" href=\"http://a.com\" title=\"http://a.com\" alt=\"\" coords=\"[0-9]+,[0-9]+,[0-9]+,[0-9]+\"/>\n"
case EXACT: + "</map>\n\n",
softly.assertThat(new String(baos.toByteArray(), UTF_8)).isEqualTo(testCase.getExpectedOut()); Verification.REGEX, false, false));
break; l.add(TestCase.of("-pipemap",
"@startuml\na->b: [[http://a.com]] c\n@enduml\n@startuml\nc->d: [[http://c.com]] e\n@enduml",
case REGEX: "<map id=\"plantuml_map\" name=\"plantuml_map\">\n"
softly.assertThat(new String(baos.toByteArray(), UTF_8)).matches(testCase.getExpectedOut()); + "<area shape=\"rect\" id=\"id1\" href=\"http://a.com\" title=\"http://a.com\" alt=\"\" coords=\"[0-9]+,[0-9]+,[0-9]+,[0-9]+\"/>\n"
break; + "</map>\n\n" + "<map id=\"plantuml_map\" name=\"plantuml_map\">\n"
} + "<area shape=\"rect\" id=\"id1\" href=\"http://c.com\" title=\"http://c.com\" alt=\"\" coords=\"[0-9]+,[0-9]+,[0-9]+,[0-9]+\"/>\n"
} + "</map>\n\n",
} Verification.REGEX, false, false));
@Test // no links/invalid input => no pipemap to output (no error as of
void should_readFirstDiagram_return_null_for_empty_input() throws IOException { // https://forum.plantuml.net/10049/2019-pipemap-diagrams-containing-links-give-zero-exit-code
pipe = new Pipe(option, null, new ByteArrayInputStream(new byte[0]), UTF_8.name()); // )
l.add(TestCase.of("-pipemap", "@startuml\na->b\n@enduml", "\n", Verification.EXACT, false, false));
String actual = pipe.readFirstDiagram(); l.add(TestCase.of("-pipemap", "@startuml\na\n@enduml", "\n", Verification.EXACT, false, false));
assertThat(actual).isNull(); return l;
} }
@Test @ParameterizedTest
void should_readFirstDiagram_decode_a_special_unicode_character_when_provided_charset_is_utf8() throws IOException { @MethodSource("managePipeTestCases")
pipe = new Pipe(option, null, new ByteArrayInputStream("\u2620\n".getBytes(UTF_8)), UTF_8.name()); void should_managePipe_manage_success_cases_correctly(TestCase testCase) throws IOException, InterruptedException {
option = new Option(testCase.getOptions().split(" "));
String actual = pipe.readFirstDiagram(); pipe = new Pipe(option, ps, new ByteArrayInputStream(testCase.getInput().getBytes(UTF_8)), UTF_8.name());
assertThat(actual).isEqualTo("@startuml\n\u2620\n@enduml\n"); pipe.managePipe(errorStatus);
}
try (AutoCloseableSoftAssertions softly = new AutoCloseableSoftAssertions()) {
// The testing is relevant only if the testing VM is configured in non-UTF-8 defaultCharset() softly.assertThat(errorStatus.hasError()).isEqualTo(testCase.isExpectedHasErrors());
@Test softly.assertThat(errorStatus.isNoData()).isEqualTo(testCase.isExpectedIsNoData());
void should_readFirstDiagram_uses_current_charset_if_not_provided() throws IOException { testCase.getExpectedOutVerification().assertOk(softly, baos, testCase.getExpectedOut());
String input = "\u00C1"; // A acute accented. (HTML &Aacute;). Multibyte in UTF-8. }
if(Charset.defaultCharset().newEncoder().canEncode(input)) { }
pipe = new Pipe(option, null, new ByteArrayInputStream(input.getBytes(Charset.defaultCharset())), null);
@Test
String actual = pipe.readFirstDiagram(); void should_readFirstDiagram_return_null_for_empty_input() throws IOException {
pipe = new Pipe(option, null, new ByteArrayInputStream(new byte[0]), UTF_8.name());
assertThat(actual).isEqualTo("@startuml\n\u00C1\n@enduml\n");
String actual = pipe.readFirstDiagram();
} else {
// default charset can't encode &Aacute;. Ignore the test. assertThat(actual).isNull();
assertTrue(true); }
}
} @Test
void should_readFirstDiagram_decode_a_special_unicode_character_when_provided_charset_is_utf8() throws IOException {
@ParameterizedTest pipe = new Pipe(option, null, new ByteArrayInputStream("\u2620\n".getBytes(UTF_8)), UTF_8.name());
@ValueSource(strings = {
"ab\nc", // *nix, macOsX String actual = pipe.readFirstDiagram();
"ab\rc", // pre-macOsX macs
"ab\r\nc", // Windows assertThat(actual).isEqualTo("@startuml\n\u2620\n@enduml\n");
// the case \n\r is handled as 2 new lines, thus not added }
"ab\nc\n", // The testing is relevant only if the testing VM is configured in non-UTF-8
"ab\nc\r", // defaultCharset()
"ab\nc\r\n" @Test
}) void should_readFirstDiagram_uses_current_charset_if_not_provided() throws IOException {
void should_readFirstDiagram_decode_correctly_different_line_endings(String input) throws IOException { String input = "\u00C1"; // A acute accented. (HTML &Aacute;). Multibyte in UTF-8.
pipe = new Pipe(option, null, new ByteArrayInputStream(input.getBytes(UTF_8)), UTF_8.name()); if (Charset.defaultCharset().newEncoder().canEncode(input)) {
pipe = new Pipe(option, null, new ByteArrayInputStream(input.getBytes(Charset.defaultCharset())), null);
String first = pipe.readFirstDiagram();
String second = pipe.readFirstDiagram(); String actual = pipe.readFirstDiagram();
assertThat(first).isEqualTo("@startuml\nab\nc\n@enduml\n"); assertThat(actual).isEqualTo("@startuml\n\u00C1\n@enduml\n");
assertThat(second).isEqualTo(null); // no spurious diagram afterwards
} } else {
// default charset can't encode &Aacute;. Ignore the test.
static List<InputExpected> firstStartAndEndMarks() { assertTrue(true);
List<InputExpected> l = new LinkedList<>(); }
l.add(InputExpected.of("\nab\r\ncde", "@startuml\nab\ncde\n@enduml\n")); }
l.add(InputExpected.of("\nab\r\ncde\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("\nab\r\ncde\n@enduml", "@startuml\nab\ncde\n@enduml\n@enduml\n")); @ParameterizedTest
l.add(InputExpected.of("\nab\r\ncde\n@endwhatever", "@startuml\nab\ncde\n@endwhatever\n@enduml\n")); @ValueSource(strings = { "ab\nc", // *nix, macOsX
l.add(InputExpected.of("\nab\r\ncde\n@enduml\n", "@startuml\nab\ncde\n@enduml\n@enduml\n")); "ab\rc", // pre-macOsX macs
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml", "@startuml\nab\ncde\n@enduml\n")); "ab\r\nc", // Windows
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n", "@startuml\nab\ncde\n@enduml\n")); // the case \n\r is handled as 2 new lines, thus not added
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\r\n\r\n", "@startuml\nab\ncde\n@enduml\n")); "ab\nc\n", "ab\nc\r", "ab\nc\r\n" })
l.add(InputExpected.of("this-is-garbage\n@startuml\nab\rcde\n@enduml\nthis-is-garbage\n", "@startuml\nab\ncde\n@enduml\n")); void should_readFirstDiagram_decode_correctly_different_line_endings(String input) throws IOException {
l.add(InputExpected.of("@startwhatever\nab\rcde\n@endwhatever", "@startwhatever\nab\ncde\n@endwhatever\n")); pipe = new Pipe(option, null, new ByteArrayInputStream(input.getBytes(UTF_8)), UTF_8.name());
return l;
} String first = pipe.readFirstDiagram();
String second = pipe.readFirstDiagram();
@ParameterizedTest
@MethodSource("firstStartAndEndMarks") assertThat(first).isEqualTo("@startuml\nab\nc\n@enduml\n");
void should_readFirstDiagram_handle_correctly_start_and_end_marks(InputExpected inputExpected) throws IOException { assertThat(second).isEqualTo(null); // no spurious diagram afterwards
pipe = new Pipe(option, null, new ByteArrayInputStream(inputExpected.getInput().getBytes(UTF_8)), UTF_8.name()); }
String actual = pipe.readFirstDiagram(); static List<InputExpected> firstStartAndEndMarks() {
List<InputExpected> l = new LinkedList<>();
assertThat(actual).isEqualTo(inputExpected.getExpected()); l.add(InputExpected.of("\nab\r\ncde", "@startuml\nab\ncde\n@enduml\n"));
} l.add(InputExpected.of("\nab\r\ncde\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("\nab\r\ncde\n@enduml", "@startuml\nab\ncde\n@enduml\n@enduml\n"));
static List<InputExpected> subsequentStartAndEndMarks() { l.add(InputExpected.of("\nab\r\ncde\n@endwhatever", "@startuml\nab\ncde\n@endwhatever\n@enduml\n"));
List<InputExpected> l = new LinkedList<>(); l.add(InputExpected.of("\nab\r\ncde\n@enduml\n", "@startuml\nab\ncde\n@enduml\n@enduml\n"));
l.add(InputExpected.of("\nab\r\ncde", null)); l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("\nab\r\ncde\n", null)); l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("\nab\r\ncde\n@enduml", null)); l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("\nab\r\ncde\n@endwhatever", null)); l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\r\n\r\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("\nab\r\ncde\n@enduml\n", null)); l.add(InputExpected.of("this-is-garbage\n@startuml\nab\rcde\n@enduml\nthis-is-garbage\n",
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml", "@startuml\nab\ncde\n@enduml\n")); "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n", "@startuml\nab\ncde\n@enduml\n")); l.add(InputExpected.of("@startwhatever\nab\rcde\n@endwhatever", "@startwhatever\nab\ncde\n@endwhatever\n"));
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n\n", "@startuml\nab\ncde\n@enduml\n")); return l;
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\r\n\r\n", "@startuml\nab\ncde\n@enduml\n")); }
l.add(InputExpected.of("this-is-garbage\n@startuml\nab\rcde\n@enduml\nthis-is-garbage\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("@startwhatever\nab\rcde\n@endwhatever", "@startwhatever\nab\ncde\n@endwhatever\n")); @ParameterizedTest
return l; @MethodSource("firstStartAndEndMarks")
} void should_readFirstDiagram_handle_correctly_start_and_end_marks(InputExpected inputExpected) throws IOException {
pipe = new Pipe(option, null, new ByteArrayInputStream(inputExpected.getInput().getBytes(UTF_8)), UTF_8.name());
@ParameterizedTest
@MethodSource("subsequentStartAndEndMarks") String actual = pipe.readFirstDiagram();
void should_readSubsequentDiagram_handle_correctly_start_and_end_marks(InputExpected inputExpected) throws IOException {
pipe = new Pipe(option, null, new ByteArrayInputStream(inputExpected.getInput().getBytes(UTF_8)), UTF_8.name()); assertThat(actual).isEqualTo(inputExpected.getExpected());
}
String actual = pipe.readSubsequentDiagram();
static List<InputExpected> subsequentStartAndEndMarks() {
assertThat(actual).isEqualTo(inputExpected.getExpected()); List<InputExpected> l = new LinkedList<>();
} l.add(InputExpected.of("\nab\r\ncde", null));
l.add(InputExpected.of("\nab\r\ncde\n", null));
@ParameterizedTest l.add(InputExpected.of("\nab\r\ncde\n@enduml", null));
@ValueSource(strings = {"@@@format png", "png", "@@@format png <deadbeef>"}) l.add(InputExpected.of("\nab\r\ncde\n@endwhatever", null));
void should_manageFormat_handle_png(String valid) { l.add(InputExpected.of("\nab\r\ncde\n@enduml\n", null));
pipe.manageFormat(valid); l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n", "@startuml\nab\ncde\n@enduml\n"));
assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.PNG); l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\n\n", "@startuml\nab\ncde\n@enduml\n"));
} l.add(InputExpected.of("@startuml\nab\r\ncde\n@enduml\r\n\r\n", "@startuml\nab\ncde\n@enduml\n"));
l.add(InputExpected.of("this-is-garbage\n@startuml\nab\rcde\n@enduml\nthis-is-garbage\n",
@ParameterizedTest "@startuml\nab\ncde\n@enduml\n"));
@ValueSource(strings = {"@@@format svg", "svg", "@@@format svg <deadbeef>"}) l.add(InputExpected.of("@startwhatever\nab\rcde\n@endwhatever", "@startwhatever\nab\ncde\n@endwhatever\n"));
void should_manageFormat_handle_svg(String valid) { return l;
pipe.manageFormat(valid); }
assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.SVG); @ParameterizedTest
} @MethodSource("subsequentStartAndEndMarks")
void should_readSubsequentDiagram_handle_correctly_start_and_end_marks(InputExpected inputExpected)
@ParameterizedTest throws IOException {
@ValueSource(strings = {"@@@format invalid", "invalid", "@@@format invalid <deadbeef>"}) pipe = new Pipe(option, null, new ByteArrayInputStream(inputExpected.getInput().getBytes(UTF_8)), UTF_8.name());
void should_manageFormat_ignore_any_other_value_and_keep_default_value_as_file_format_option(String valid) {
pipe.manageFormat(valid); String actual = pipe.readSubsequentDiagram();
assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.PNG); assertThat(actual).isEqualTo(inputExpected.getExpected());
} }
static class TestCase { @ParameterizedTest
@ValueSource(strings = { "@@@format png", "png", "@@@format png <deadbeef>" })
private final String options; void should_manageFormat_handle_png(String valid) {
private final String input; pipe.manageFormat(valid);
private final String expectedOut;
private final Verification expectedOutVerification; assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.PNG);
private final boolean expectedHasErrors; }
private final boolean expectedIsNoData;
@ParameterizedTest
@ValueSource(strings = { "@@@format svg", "svg", "@@@format svg <deadbeef>" })
public TestCase(String options, String input, String expectedOut, Verification expectedOutVerification, boolean expectedHasErrors, boolean expectedIsNoData) { void should_manageFormat_handle_svg(String valid) {
this.options = options; pipe.manageFormat(valid);
this.input = input;
this.expectedOut = expectedOut; assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.SVG);
this.expectedOutVerification = expectedOutVerification; }
this.expectedHasErrors = expectedHasErrors;
this.expectedIsNoData = expectedIsNoData; @ParameterizedTest
} @ValueSource(strings = { "@@@format invalid", "invalid", "@@@format invalid <deadbeef>" })
void should_manageFormat_ignore_any_other_value_and_keep_default_value_as_file_format_option(String valid) {
public static TestCase of(String option, String input, String expectedOut, Verification expectedOutVerification, boolean expectedHasErrors, boolean expectedIsNoData) { pipe.manageFormat(valid);
return new TestCase(option, input, expectedOut, expectedOutVerification, expectedHasErrors, expectedIsNoData);
} assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.PNG);
}
public String getOptions() {
return options; static class TestCase {
}
private final String options;
public String getInput() { private final String input;
return input; private final String expectedOut;
} private final Verification expectedOutVerification;
private final boolean expectedHasErrors;
public String getExpectedOut() { private final boolean expectedIsNoData;
return expectedOut;
} public TestCase(String options, String input, String expectedOut, Verification expectedOutVerification,
boolean expectedHasErrors, boolean expectedIsNoData) {
public Verification getExpectedOutVerification() { this.options = options;
return expectedOutVerification; this.input = input;
} this.expectedOut = expectedOut;
this.expectedOutVerification = expectedOutVerification;
public boolean isExpectedHasErrors() { this.expectedHasErrors = expectedHasErrors;
return expectedHasErrors; this.expectedIsNoData = expectedIsNoData;
} }
public boolean isExpectedIsNoData() { public static TestCase of(String option, String input, String expectedOut, Verification expectedOutVerification,
return expectedIsNoData; boolean expectedHasErrors, boolean expectedIsNoData) {
} return new TestCase(option, input, expectedOut, expectedOutVerification, expectedHasErrors,
expectedIsNoData);
@Override }
public String toString() {
return "o:'" + options + "', i:'" + input + "', e-out='" + expectedOut + "', e-err='" + expectedHasErrors + "', e-nodata='" + expectedIsNoData + "'"; public String getOptions() {
} return options;
}
}
public String getInput() {
static class InputExpected { return input;
private final String input; }
private final String expected;
public String getExpectedOut() {
return expectedOut;
public InputExpected(String input, String expected) { }
this.input = input;
this.expected = expected; public Verification getExpectedOutVerification() {
} return expectedOutVerification;
}
public static InputExpected of(String input, String expected) {
return new InputExpected(input, expected); public boolean isExpectedHasErrors() {
} return expectedHasErrors;
}
public String getInput() {
return input; public boolean isExpectedIsNoData() {
} return expectedIsNoData;
}
public String getExpected() {
return expected; @Override
} public String toString() {
return "o:'" + options + "', i:'" + input + "', e-out='" + expectedOut + "', e-err='" + expectedHasErrors
@Override + "', e-nodata='" + expectedIsNoData + "'";
public String toString() { }
return "i:'" + input + "', e='" + expected + "'";
} }
}
static class InputExpected {
enum Verification { private final String input;
EXACT, private final String expected;
REGEX
} public InputExpected(String input, String expected) {
this.input = input;
this.expected = expected;
}
public static InputExpected of(String input, String expected) {
return new InputExpected(input, expected);
}
public String getInput() {
return input;
}
public String getExpected() {
return expected;
}
@Override
public String toString() {
return "i:'" + input + "', e='" + expected + "'";
}
}
enum Verification {
EXACT, REGEX;
void assertOk(AutoCloseableSoftAssertions softly, ByteArrayOutputStream baos, String expectedOut) {
final String result = new String(baos.toByteArray(), UTF_8).replaceAll("\r", "");
switch (this) {
case EXACT:
softly.assertThat(result).isEqualTo(expectedOut);
break;
case REGEX:
softly.assertThat(result).matches(expectedOut);
break;
}
}
}
} }