Skip to content

Instantly share code, notes, and snippets.

@jbrains
Created October 13, 2018 19:16
Show Gist options
  • Save jbrains/a44701162b41c423e312792f94eee37e to your computer and use it in GitHub Desktop.
Save jbrains/a44701162b41c423e312792f94eee37e to your computer and use it in GitHub Desktop.

Revisions

  1. jbrains created this gist Oct 13, 2018.
    109 changes: 109 additions & 0 deletions LearnReadingLinesTest.java
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,109 @@
    package ca.jbrains.java.test;

    import ca.jbrains.java.ReaderBasedTextSource;
    import io.vavr.collection.List;
    import io.vavr.collection.Stream;
    import org.hamcrest.Description;
    import org.hamcrest.Factory;
    import org.hamcrest.Matcher;
    import org.hamcrest.TypeSafeMatcher;
    import org.junit.Assert;
    import org.junit.Test;

    import java.io.StringReader;

    import static ca.jbrains.java.test.LearnReadingLinesTest.TextParsesIntoLines.parsesInto;

    public class LearnReadingLinesTest {
    @Test
    public void readOneLineWithoutALineSeparator() throws Exception {
    Assert.assertThat(
    "this is one line of text without a line separator.",
    parsesInto(List.of(
    "this is one line of text without a line separator.")));
    }

    @Test
    public void readOneLineFromABlobOfTextEndingWithALineSeparator() throws Exception {
    Assert.assertThat(
    endWithLineSeparator("this is one line of text ending in a line separator."),
    parsesInto(List.of(
    "this is one line of text ending in a line separator.")));
    }

    @Test
    public void readMultipleLinesEndingWithSeveralEmptyLines() throws Exception {
    Assert.assertThat(new StringBuilder()
    .append(endWithLineSeparator("a non-empty line of text"))
    .append(endWithLineSeparator("a non-empty line of text"))
    .append(endWithLineSeparator("a non-empty line of text"))
    .append(endWithLineSeparator(""))
    .append(endWithLineSeparator(""))
    .append(endWithLineSeparator(""))
    .append(endWithLineSeparator(""))
    .toString(),
    parsesInto(List.of(
    "a non-empty line of text",
    "a non-empty line of text",
    "a non-empty line of text",
    "",
    "",
    "",
    "")));
    }

    @Test
    public void readNothing() throws Exception {
    Assert.assertThat("", parsesInto(List.empty()));
    }

    @Test
    public void readOnlyOneEmptyLine() throws Exception {
    Assert.assertThat(System.lineSeparator(), parsesInto(List.of("")));
    }

    // REFACTOR Maybe move to a generic text library?
    public static String endWithLineSeparator(String text) {
    return String.format("%s%s", text, System.lineSeparator());
    }

    /**
    * Matches multiline text as lines, where lines are separated
    * by {@code System.lineSeparator()}.
    */
    public static class TextParsesIntoLines extends TypeSafeMatcher<String> {
    private List<String> expectedLines;

    public TextParsesIntoLines(List<String> expectedLines) {
    this.expectedLines = expectedLines;
    }

    @Override
    protected boolean matchesSafely(String text) {
    return tokenizeAsLines(text).equals(expectedLines);
    }

    private List<String> tokenizeAsLines(String text) {
    ReaderBasedTextSource textSource = new ReaderBasedTextSource(new StringReader(text));
    Stream<String> streamOfLines = textSource.parseIntoLines();
    return List.ofAll(streamOfLines);
    }

    @Override
    protected void describeMismatchSafely(String text, Description mismatchDescription) {
    mismatchDescription.appendText("instead parses into lines ")
    .appendValueList("[", ",", "]", tokenizeAsLines(text));
    }

    @Override
    public void describeTo(Description description) {
    description.appendText("parses into lines ")
    .appendValueList("[", ",", "]", expectedLines);
    }

    @Factory
    public static Matcher<String> parsesInto(List<String> expectedLines) {
    return new TextParsesIntoLines(expectedLines);
    }
    }
    }