mirror of
https://github.com/octoleo/plantuml.git
synced 2024-11-22 21:15:09 +00:00
Fix issue with garbage after the diagram and created better tests
This commit is contained in:
parent
6849c96144
commit
0bef01372f
@ -35,11 +35,15 @@
|
|||||||
*/
|
*/
|
||||||
package net.sourceforge.plantuml;
|
package net.sourceforge.plantuml;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.sourceforge.plantuml.core.Diagram;
|
import net.sourceforge.plantuml.core.Diagram;
|
||||||
@ -51,89 +55,97 @@ import net.sourceforge.plantuml.security.SFile;
|
|||||||
public class Pipe {
|
public class Pipe {
|
||||||
|
|
||||||
private final Option option;
|
private final Option option;
|
||||||
private final InputStream is;
|
private final BufferedReader br;
|
||||||
private final PrintStream ps;
|
private final PrintStream ps;
|
||||||
private boolean closed = false;
|
|
||||||
private final String charset;
|
|
||||||
private final Stdrpt stdrpt;
|
private final Stdrpt stdrpt;
|
||||||
|
|
||||||
public Pipe(Option option, PrintStream ps, InputStream is, String charset) {
|
public Pipe(Option option, PrintStream ps, InputStream is, String charset) {
|
||||||
this.option = option;
|
this.option = option;
|
||||||
this.is = is;
|
try {
|
||||||
|
this.br = new BufferedReader(
|
||||||
|
new InputStreamReader(is, (charset != null) ? charset : Charset.defaultCharset().name()));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("Invalid charset provided", e);
|
||||||
|
}
|
||||||
this.ps = ps;
|
this.ps = ps;
|
||||||
this.charset = charset;
|
|
||||||
this.stdrpt = option.getStdrpt();
|
this.stdrpt = option.getStdrpt();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void managePipe(ErrorStatus error) throws IOException {
|
public void managePipe(ErrorStatus error) throws IOException {
|
||||||
final boolean noStdErr = option.isPipeNoStdErr();
|
final boolean noStdErr = option.isPipeNoStdErr();
|
||||||
int nb = 0;
|
|
||||||
do {
|
for(String source = readFirstDiagram(); source != null; source = readSubsequentDiagram()) {
|
||||||
final String source = readOneDiagram();
|
|
||||||
if (source == null) {
|
|
||||||
ps.flush();
|
|
||||||
if (nb == 0) {
|
|
||||||
// error.goNoData();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
nb++;
|
|
||||||
final Defines defines = option.getDefaultDefines();
|
final Defines defines = option.getDefaultDefines();
|
||||||
final SFile newCurrentDir = option.getFileDir() == null ? null : new SFile(option.getFileDir());
|
final SFile newCurrentDir = option.getFileDir() == null ? null : new SFile(option.getFileDir());
|
||||||
final SourceStringReader sourceStringReader = new SourceStringReader(defines, source, "UTF-8",
|
final SourceStringReader sourceStringReader = new SourceStringReader(defines, source, "UTF-8",
|
||||||
option.getConfig(), newCurrentDir);
|
option.getConfig(), newCurrentDir);
|
||||||
|
|
||||||
if (option.isComputeurl()) {
|
if (option.isComputeurl()) {
|
||||||
for (BlockUml s : sourceStringReader.getBlocks()) {
|
computeUrlForDiagram(sourceStringReader);
|
||||||
ps.println(s.getEncodedUrl());
|
|
||||||
}
|
|
||||||
} else if (option.isSyntax()) {
|
} else if (option.isSyntax()) {
|
||||||
final Diagram system = sourceStringReader.getBlocks().get(0).getDiagram();
|
syntaxCheckDiagram(sourceStringReader, error);
|
||||||
if (system instanceof UmlDiagram) {
|
|
||||||
error.goOk();
|
|
||||||
ps.println(((UmlDiagram) system).getUmlDiagramType().name());
|
|
||||||
ps.println(system.getDescription());
|
|
||||||
} else if (system instanceof PSystemError) {
|
|
||||||
error.goWithError();
|
|
||||||
stdrpt.printInfo(ps, (PSystemError) system);
|
|
||||||
} else {
|
|
||||||
error.goOk();
|
|
||||||
ps.println("OTHER");
|
|
||||||
ps.println(system.getDescription());
|
|
||||||
}
|
|
||||||
} else if (option.isPipeMap()) {
|
} else if (option.isPipeMap()) {
|
||||||
final String result = sourceStringReader.getCMapData(option.getImageIndex(),
|
createPipeMapForDiagram(sourceStringReader, error);
|
||||||
option.getFileFormatOption());
|
|
||||||
// https://forum.plantuml.net/10049/2019-pipemap-diagrams-containing-links-give-zero-exit-code
|
|
||||||
// We don't check errors
|
|
||||||
error.goOk();
|
|
||||||
if (result == null) {
|
|
||||||
ps.println();
|
|
||||||
} else {
|
|
||||||
ps.println(result);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
final OutputStream os = noStdErr ? new ByteArrayOutputStream() : ps;
|
generateDiagram(sourceStringReader, error, noStdErr);
|
||||||
final DiagramDescription result = sourceStringReader.outputImage(os, option.getImageIndex(),
|
|
||||||
option.getFileFormatOption());
|
|
||||||
printInfo(noStdErr ? ps : System.err, sourceStringReader);
|
|
||||||
if (result != null && "(error)".equalsIgnoreCase(result.getDescription())) {
|
|
||||||
error.goWithError();
|
|
||||||
} else {
|
|
||||||
error.goOk();
|
|
||||||
if (noStdErr) {
|
|
||||||
final ByteArrayOutputStream baos = (ByteArrayOutputStream) os;
|
|
||||||
baos.close();
|
|
||||||
ps.write(baos.toByteArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (option.getPipeDelimitor() != null) {
|
|
||||||
ps.println(option.getPipeDelimitor());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ps.flush();
|
ps.flush();
|
||||||
} while (closed == false);
|
}
|
||||||
if (nb == 0) {
|
}
|
||||||
// error.goNoData();
|
|
||||||
|
private void generateDiagram(SourceStringReader sourceStringReader, ErrorStatus error, boolean noStdErr) throws IOException {
|
||||||
|
final OutputStream os = noStdErr ? new ByteArrayOutputStream() : ps;
|
||||||
|
final DiagramDescription result = sourceStringReader.outputImage(os, option.getImageIndex(),
|
||||||
|
option.getFileFormatOption());
|
||||||
|
|
||||||
|
printInfo(noStdErr ? ps : System.err, sourceStringReader);
|
||||||
|
if (result != null && "(error)".equalsIgnoreCase(result.getDescription())) {
|
||||||
|
error.goWithError();
|
||||||
|
} else {
|
||||||
|
error.goOk();
|
||||||
|
if (noStdErr) {
|
||||||
|
final ByteArrayOutputStream baos = (ByteArrayOutputStream) os;
|
||||||
|
baos.close();
|
||||||
|
ps.write(baos.toByteArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (option.getPipeDelimitor() != null) {
|
||||||
|
ps.println(option.getPipeDelimitor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createPipeMapForDiagram(SourceStringReader sourceStringReader, ErrorStatus error) throws IOException {
|
||||||
|
final String result = sourceStringReader.getCMapData(option.getImageIndex(),
|
||||||
|
option.getFileFormatOption());
|
||||||
|
// https://forum.plantuml.net/10049/2019-pipemap-diagrams-containing-links-give-zero-exit-code
|
||||||
|
// We don't check errors
|
||||||
|
error.goOk();
|
||||||
|
if (result == null) {
|
||||||
|
ps.println();
|
||||||
|
} else {
|
||||||
|
ps.println(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeUrlForDiagram(SourceStringReader sourceStringReader) throws IOException {
|
||||||
|
for (BlockUml s : sourceStringReader.getBlocks()) {
|
||||||
|
ps.println(s.getEncodedUrl());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void syntaxCheckDiagram(SourceStringReader sourceStringReader, ErrorStatus error) {
|
||||||
|
final Diagram system = sourceStringReader.getBlocks().get(0).getDiagram();
|
||||||
|
if (system instanceof UmlDiagram) {
|
||||||
|
error.goOk();
|
||||||
|
ps.println(((UmlDiagram) system).getUmlDiagramType().name());
|
||||||
|
ps.println(system.getDescription());
|
||||||
|
} else if (system instanceof PSystemError) {
|
||||||
|
error.goWithError();
|
||||||
|
stdrpt.printInfo(ps, system);
|
||||||
|
} else {
|
||||||
|
error.goOk();
|
||||||
|
ps.println("OTHER");
|
||||||
|
ps.println(system.getDescription());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,34 +158,55 @@ public class Pipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFinished(String s) {
|
String readFirstDiagram() throws IOException {
|
||||||
return s == null || s.startsWith("@end");
|
return readSingleDiagram(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
String readOneDiagram() throws IOException {
|
String readSubsequentDiagram() throws IOException {
|
||||||
|
return readSingleDiagram(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
String readSingleDiagram(boolean unmarkedAllowed) throws IOException {
|
||||||
|
State state = State.NO_CONTENT;
|
||||||
|
String expectedEnd = null;
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
while (true) {
|
|
||||||
final String s = readOneLine();
|
String line;
|
||||||
if (s == null) {
|
while(state != State.COMPLETE && (line = br.readLine()) != null) {
|
||||||
closed = true;
|
|
||||||
} else if (s.startsWith("@@@format ")) {
|
if(line.startsWith("@@@format ")) {
|
||||||
manageFormat(s);
|
manageFormat(line);
|
||||||
} else {
|
} else {
|
||||||
sb.append(s);
|
if (state == State.NO_CONTENT && line.trim().length() > 0) {
|
||||||
sb.append(BackSlash.NEWLINE);
|
state = State.START_MARK_NOT_FOUND;
|
||||||
}
|
}
|
||||||
if (isFinished(s)) {
|
|
||||||
break;
|
if (state == State.START_MARK_NOT_FOUND && line.startsWith("@start")) {
|
||||||
|
sb.setLength(0); // discard any previous input
|
||||||
|
state = State.START_MARK_FOUND;
|
||||||
|
expectedEnd = "@end" + line.substring(6).split("^[A-Za-z]")[0];
|
||||||
|
} else if (state == State.START_MARK_FOUND && line.startsWith(expectedEnd)) {
|
||||||
|
state = State.COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state != State.NO_CONTENT) {
|
||||||
|
sb.append(line).append("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String source = sb.toString().trim();
|
|
||||||
if (sb.length() == 0) {
|
switch(state) {
|
||||||
return null;
|
case NO_CONTENT:
|
||||||
|
return null;
|
||||||
|
case START_MARK_NOT_FOUND:
|
||||||
|
return (unmarkedAllowed) ? "@startuml\n" + sb.toString() + "@enduml\n" : null;
|
||||||
|
case START_MARK_FOUND:
|
||||||
|
return sb.toString() + expectedEnd;
|
||||||
|
case COMPLETE:
|
||||||
|
return sb.toString();
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unexpected value: " + state);
|
||||||
}
|
}
|
||||||
if (source.startsWith("@start") == false) {
|
|
||||||
source = "@startuml\n" + source + "\n@enduml";
|
|
||||||
}
|
|
||||||
return source;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void manageFormat(String s) {
|
void manageFormat(String s) {
|
||||||
@ -184,27 +217,10 @@ public class Pipe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String readOneLine() throws IOException {
|
enum State {
|
||||||
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
NO_CONTENT,
|
||||||
while (true) {
|
START_MARK_NOT_FOUND,
|
||||||
final int read = is.read();
|
START_MARK_FOUND,
|
||||||
if (read == -1) {
|
COMPLETE
|
||||||
if (baos.size() == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (read != '\r' && read != '\n') {
|
|
||||||
baos.write(read);
|
|
||||||
}
|
|
||||||
if (read == '\n') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (charset == null) {
|
|
||||||
return new String(baos.toByteArray());
|
|
||||||
}
|
|
||||||
return new String(baos.toByteArray(), charset);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ 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 java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@ -154,43 +155,109 @@ class PipeTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_readOneDiagram_return_null_for_empty_input() throws IOException {
|
void should_readFirstDiagram_return_null_for_empty_input() throws IOException {
|
||||||
pipe = new Pipe(option, null, new ByteArrayInputStream(new byte[0]), UTF_8.name());
|
pipe = new Pipe(option, null, new ByteArrayInputStream(new byte[0]), UTF_8.name());
|
||||||
|
|
||||||
String actual = pipe.readOneDiagram();
|
String actual = pipe.readFirstDiagram();
|
||||||
|
|
||||||
assertThat(actual).isNull();
|
assertThat(actual).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void should_readOneDiagram_remove_carriage_returns() throws IOException {
|
void should_readFirstDiagram_decode_a_special_unicode_character_when_provided_charset_is_utf8() throws IOException {
|
||||||
pipe = new Pipe(option, null, new ByteArrayInputStream("@startuml\na\rb\r\nc\rd\re\n@enduml".getBytes(UTF_8)), UTF_8.name());
|
pipe = new Pipe(option, null, new ByteArrayInputStream("\u2620\n".getBytes(UTF_8)), UTF_8.name());
|
||||||
|
|
||||||
String actual = pipe.readOneDiagram();
|
String actual = pipe.readFirstDiagram();
|
||||||
|
|
||||||
assertThat(actual).isEqualTo("@startuml\nab\ncde\n@enduml");
|
assertThat(actual).isEqualTo("@startuml\n\u2620\n@enduml\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<InputExpected> startAndEndMarks() {
|
// The testing is relevant only if the testing VM is configured in non-UTF-8 defaultCharset()
|
||||||
LinkedList<InputExpected> linkedList = new LinkedList<>();
|
@Test
|
||||||
linkedList.add(InputExpected.of("\na\rb\r\nc\rd\re\n@enduml", "@startuml\nab\ncde\n@enduml\n@enduml"));
|
void should_readFirstDiagram_uses_current_charset_if_not_provided() throws IOException {
|
||||||
linkedList.add(InputExpected.of("\na\rb\r\nc\rd\re\n@endwhatever", "@startuml\nab\ncde\n@endwhatever\n@enduml"));
|
String input = "\u00C1"; // A acute accented. (HTML Á). Multibyte in UTF-8.
|
||||||
linkedList.add(InputExpected.of("\na\rb\r\nc\rd\re\n@enduml\n", "@startuml\nab\ncde\n@enduml\n@enduml"));
|
if(Charset.defaultCharset().newEncoder().canEncode(input)) {
|
||||||
linkedList.add(InputExpected.of("@startuml\na\rb\r\nc\rd\re\n@enduml", "@startuml\nab\ncde\n@enduml"));
|
pipe = new Pipe(option, null, new ByteArrayInputStream(input.getBytes(Charset.defaultCharset())), null);
|
||||||
linkedList.add(InputExpected.of("@startuml\na\rb\r\nc\rd\re\n@enduml\n", "@startuml\nab\ncde\n@enduml"));
|
|
||||||
linkedList.add(InputExpected.of("@startuml\na\rb\r\nc\rd\re\n@enduml\n\n", "@startuml\nab\ncde\n@enduml"));
|
String actual = pipe.readFirstDiagram();
|
||||||
linkedList.add(InputExpected.of("@startuml\na\rb\r\nc\rd\re\n@enduml\r\n\r\n", "@startuml\nab\ncde\n@enduml"));
|
|
||||||
linkedList.add(InputExpected.of("this-is-garbage\n@startuml\na\rb\r\nc\rd\re\n@enduml\nthis-is-garbage\n", "@startuml\nab\ncde\n@enduml"));
|
assertThat(actual).isEqualTo("@startuml\n\u00C1\n@enduml\n");
|
||||||
linkedList.add(InputExpected.of("@startwhatever\na\rb\r\nc\rd\re\n@endwhatever", "@startwhatever\nab\ncde\n@endwhatever"));
|
|
||||||
return linkedList;
|
} else {
|
||||||
|
// default charset can't encode Á. Ignore the test.
|
||||||
|
assertTrue(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource("startAndEndMarks")
|
@ValueSource(strings = {
|
||||||
void should_readOneDiagram_handle_correctly_start_and_end_marks(InputExpected inputExpected) throws IOException {
|
"ab\nc", // *nix, macOsX
|
||||||
|
"ab\rc", // pre-macOsX macs
|
||||||
|
"ab\r\nc", // Windows
|
||||||
|
// the case \n\r is handled as 2 new lines, thus not added
|
||||||
|
|
||||||
|
"ab\nc\n",
|
||||||
|
"ab\nc\r",
|
||||||
|
"ab\nc\r\n"
|
||||||
|
})
|
||||||
|
void should_readFirstDiagram_decode_correctly_different_line_endings(String input) throws IOException {
|
||||||
|
pipe = new Pipe(option, null, new ByteArrayInputStream(input.getBytes(UTF_8)), UTF_8.name());
|
||||||
|
|
||||||
|
String first = pipe.readFirstDiagram();
|
||||||
|
String second = pipe.readFirstDiagram();
|
||||||
|
|
||||||
|
assertThat(first).isEqualTo("@startuml\nab\nc\n@enduml\n");
|
||||||
|
assertThat(second).isEqualTo(null); // no spurious diagram afterwards
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<InputExpected> firstStartAndEndMarks() {
|
||||||
|
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"));
|
||||||
|
l.add(InputExpected.of("\nab\r\ncde\n@endwhatever", "@startuml\nab\ncde\n@endwhatever\n@enduml\n"));
|
||||||
|
l.add(InputExpected.of("\nab\r\ncde\n@enduml\n", "@startuml\nab\ncde\n@enduml\n@enduml\n"));
|
||||||
|
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"));
|
||||||
|
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", "@startuml\nab\ncde\n@enduml\n"));
|
||||||
|
l.add(InputExpected.of("@startwhatever\nab\rcde\n@endwhatever", "@startwhatever\nab\ncde\n@endwhatever\n"));
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@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());
|
pipe = new Pipe(option, null, new ByteArrayInputStream(inputExpected.getInput().getBytes(UTF_8)), UTF_8.name());
|
||||||
|
|
||||||
String actual = pipe.readOneDiagram();
|
String actual = pipe.readFirstDiagram();
|
||||||
|
|
||||||
|
assertThat(actual).isEqualTo(inputExpected.getExpected());
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<InputExpected> subsequentStartAndEndMarks() {
|
||||||
|
List<InputExpected> l = new LinkedList<>();
|
||||||
|
l.add(InputExpected.of("\nab\r\ncde", null));
|
||||||
|
l.add(InputExpected.of("\nab\r\ncde\n", null));
|
||||||
|
l.add(InputExpected.of("\nab\r\ncde\n@enduml", null));
|
||||||
|
l.add(InputExpected.of("\nab\r\ncde\n@endwhatever", null));
|
||||||
|
l.add(InputExpected.of("\nab\r\ncde\n@enduml\n", null));
|
||||||
|
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"));
|
||||||
|
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", "@startuml\nab\ncde\n@enduml\n"));
|
||||||
|
l.add(InputExpected.of("@startwhatever\nab\rcde\n@endwhatever", "@startwhatever\nab\ncde\n@endwhatever\n"));
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("subsequentStartAndEndMarks")
|
||||||
|
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());
|
||||||
|
|
||||||
|
String actual = pipe.readSubsequentDiagram();
|
||||||
|
|
||||||
assertThat(actual).isEqualTo(inputExpected.getExpected());
|
assertThat(actual).isEqualTo(inputExpected.getExpected());
|
||||||
}
|
}
|
||||||
@ -219,81 +286,8 @@ class PipeTest {
|
|||||||
assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.PNG);
|
assertThat(option.getFileFormatOption().getFileFormat()).isEqualTo(FileFormat.PNG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_readOneLine_returns_null_if_no_input() throws IOException {
|
|
||||||
pipe = new Pipe(option, null, new ByteArrayInputStream(new byte[0]), UTF_8.toString());
|
|
||||||
|
|
||||||
String result = pipe.readOneLine();
|
|
||||||
|
|
||||||
assertThat(result).isNull();
|
|
||||||
}
|
|
||||||
|
|
||||||
@ParameterizedTest
|
|
||||||
@ValueSource(strings = {"\rab\nc\n", "\ra\rb\r\nc\n", "ab\n\rc"})
|
|
||||||
void should_readOneLine_ignore_carriage_return_and_stop_at_line_feed(String input) throws IOException {
|
|
||||||
pipe = new Pipe(option, null, new ByteArrayInputStream(input.getBytes(UTF_8)), UTF_8.name());
|
|
||||||
|
|
||||||
String actual = pipe.readOneLine();
|
|
||||||
|
|
||||||
assertThat(actual).isEqualTo("ab");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_readOneLine_return_empty_string_if_line_feed_is_the_first_character() throws IOException {
|
|
||||||
pipe = new Pipe(option, null, new ByteArrayInputStream("\n".getBytes(UTF_8)), UTF_8.name());
|
|
||||||
|
|
||||||
String actual = pipe.readOneLine();
|
|
||||||
|
|
||||||
assertThat(actual).isEqualTo("");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_readOneLine_use_the_default_charset_if_not_provided() throws IOException {
|
|
||||||
pipe = new Pipe(option, null, new ByteArrayInputStream("ab\n".getBytes(Charset.defaultCharset())), null);
|
|
||||||
|
|
||||||
String actual = pipe.readOneLine();
|
|
||||||
|
|
||||||
assertThat(actual).isEqualTo("ab");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void should_readOneLine_use_provided_charset() throws IOException {
|
|
||||||
pipe = new Pipe(option, null, new ByteArrayInputStream("\u2620\n".getBytes(UTF_8)), UTF_8.name());
|
|
||||||
|
|
||||||
String actual = pipe.readOneLine();
|
|
||||||
|
|
||||||
assertThat(actual).isEqualTo("\u2620");
|
|
||||||
}
|
|
||||||
|
|
||||||
static class InputExpected {
|
|
||||||
private final String input;
|
|
||||||
private final String expected;
|
|
||||||
|
|
||||||
|
|
||||||
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 + "'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class TestCase {
|
static class TestCase {
|
||||||
|
|
||||||
private final String options;
|
private final String options;
|
||||||
private final String input;
|
private final String input;
|
||||||
private final String expectedOut;
|
private final String expectedOut;
|
||||||
@ -346,6 +340,34 @@ class PipeTest {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class InputExpected {
|
||||||
|
private final String input;
|
||||||
|
private final String expected;
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
enum Verification {
|
||||||
EXACT,
|
EXACT,
|
||||||
REGEX
|
REGEX
|
||||||
|
Loading…
Reference in New Issue
Block a user