From b57e0b901681539aee021698f884fd17d05bef96 Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Tue, 14 Mar 2017 23:12:45 +0100 Subject: [PATCH] Add Javadoc and more tests --- .../junit/jupiter/api/AssertLinesMatch.java | 24 +++++------ .../org/junit/jupiter/api/Assertions.java | 43 ++++++++++++++++++- .../api/AssertionsAssertLinesMatchTests.java | 33 ++++++++++++++ 3 files changed, 84 insertions(+), 16 deletions(-) diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java index e929d955e57..863a5b48997 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/AssertLinesMatch.java @@ -16,11 +16,9 @@ import static org.junit.platform.commons.util.Preconditions.condition; import static org.junit.platform.commons.util.Preconditions.notNull; +import java.util.ArrayDeque; import java.util.Deque; -import java.util.LinkedList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; /** @@ -43,7 +41,7 @@ static void assertLinesMatch(List expectedLines, List actualLine int expectedSize = expectedLines.size(); int actualSize = actualLines.size(); - // trivial case: when expecting more then actual lines available, something is wrong + // trivial case: when expecting more than actual lines available, something is wrong if (expectedSize > actualSize) { // use standard assertEquals(Object, Object, message) to let IDEs present the textual difference String expected = String.join(System.lineSeparator(), expectedLines); @@ -71,8 +69,8 @@ static void assertLinesMatch(List expectedLines, List actualLine } private static void assertLinesMatchWithFastForward(List expectedLines, List actualLines) { - Deque expectedDeque = new LinkedList<>(expectedLines); - Deque actualDeque = new LinkedList<>(actualLines); + Deque expectedDeque = new ArrayDeque<>(expectedLines); + Deque actualDeque = new ArrayDeque<>(actualLines); while (!expectedDeque.isEmpty()) { String expectedLine = expectedDeque.pop(); @@ -132,16 +130,16 @@ private static void assertLinesMatchWithFastForward(List expectedLines, } } - private static boolean isFastForwardLine(String line) { + static boolean isFastForwardLine(String line) { line = line.trim(); - return line.startsWith(">>") && line.endsWith(">>"); + return line.length() >= 4 && line.startsWith(">>") && line.endsWith(">>"); } - private static int parseFastForwardLimit(String fastForwardLine) { + static int parseFastForwardLimit(String fastForwardLine) { String text = fastForwardLine.trim().substring(2, fastForwardLine.length() - 2).trim(); try { int limit = Integer.parseInt(text); - condition(limit > 0, "fast-forward must greater than zero, it is: " + limit); + condition(limit > 0, "fast-forward limit must be greater than zero, it is: " + limit); return limit; } catch (NumberFormatException e) { @@ -149,14 +147,12 @@ private static int parseFastForwardLimit(String fastForwardLine) { } } - private static boolean matches(String expectedLine, String actualLine) { + static boolean matches(String expectedLine, String actualLine) { if (expectedLine.equals(actualLine)) { return true; } try { - Pattern pattern = Pattern.compile(expectedLine); - Matcher matcher = pattern.matcher(actualLine); - return matcher.matches(); + return actualLine.matches(expectedLine); } catch (PatternSyntaxException ignore) { return false; diff --git a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java index 653b6eb0b26..18e7e9b4332 100644 --- a/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java +++ b/junit-jupiter-api/src/main/java/org/junit/jupiter/api/Assertions.java @@ -873,8 +873,47 @@ public static void assertIterableEquals(Iterable expected, Iterable actual // --- assertLinesMatch ---------------------------------------------------- - public static void assertLinesMatch(List expected, List actual) { - AssertLinesMatch.assertLinesMatch(expected, actual); + /** + * Asserts that {@code expected} list of {@linkplain String}s matches {@code actual} + * list. + * + *

This method differs from other assertions that effectively only check {@link String#equals(Object)}, + * in that it uses the following staged match-making algorithm: + * + *

For each pair of expected and actual lines do + *

    + *
  1. check if {@code expected.equals(actual)} - if yes, continue with next pair
  2. + *
  3. otherwise treat {@code expected} as a regular expression and check via + * {@link String#matches(String)} - if yes, continue with next pair
  4. + *
  5. otherwise check if {@code expected} line is a fast-forward marker, if yes apply + * fast-forward actual lines accordingly (see below) and goto 1.
  6. + *
+ * + *

A valid fast-forward marker is an expected line that starts and ends with the literal + * {@code >>} and contains at least 4 characters. Examples: + *

    + *
  • {@code >>>>}
    {@code >> stacktrace >>}
    {@code >> single line, non Integer.parse()-able comment >>} + *
    Skip arbitrary number of actual lines, until first matching subsequent expected line is found. Any + * character between the fast-forward literals are discarded.
  • + *
  • {@code ">> 21 >>"} + *
    Skip strictly 21 lines. If they can't be skipped for any reason, an assertion error is raised.
  • + *
+ * + *

Example showing all three kinds of expected line formats: + *

{@code
+	 * │  │  │     caught: AssertionFailedError: single line fail message
+	 * >> S T A C K T R A C E >>
+	 * │  │  │   duration: [\d]+ ms
+	 * │  │  │     status: ✘ FAILED
+	 * │  └─ test() finished after [\d]+ ms\.
+	 * └─ JUnit Jupiter finished after [\d]+ ms\.
+	 * Test plan execution finished. Number of all tests: 1
+	 *
+	 * Test run finished after [\d]+ ms
+	 * }
+ */ + public static void assertLinesMatch(List expectedLines, List actualLines) { + AssertLinesMatch.assertLinesMatch(expectedLines, actualLines); } // --- assertNotEquals ----------------------------------------------------- diff --git a/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsAssertLinesMatchTests.java b/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsAssertLinesMatchTests.java index 1599ae43153..a4a5d7757e6 100644 --- a/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsAssertLinesMatchTests.java +++ b/junit-jupiter-engine/src/test/java/org/junit/jupiter/api/AssertionsAssertLinesMatchTests.java @@ -10,9 +10,13 @@ package org.junit.jupiter.api; +import static org.junit.jupiter.api.AssertLinesMatch.isFastForwardLine; +import static org.junit.jupiter.api.AssertLinesMatch.parseFastForwardLimit; +import static org.junit.jupiter.api.Assertions.assertAll; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertLinesMatch; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Arrays; import java.util.Collections; @@ -98,4 +102,33 @@ void assertLinesMatchUsingFastForwardMarkerWithTooHighLimitFails() { Error error = assertThrows(AssertionFailedError.class, () -> assertLinesMatch(expected, actual)); assertEquals("terminal fast-forward(100) error: fast-forward(2) expected", error.getMessage()); } + + @Test + void assertLinesMatchIsFastForwardLine() { + assertAll("valid fast-forward lines", // + () -> assertTrue(isFastForwardLine(">>>>")), () -> assertTrue(isFastForwardLine(">> >>")), + () -> assertTrue(isFastForwardLine(">> stacktrace >>")), + () -> assertTrue(isFastForwardLine(">> single line, non Integer.parse()-able comment >>")), + () -> assertTrue(isFastForwardLine(">>9>>")), () -> assertTrue(isFastForwardLine(">> 9 >>")), + () -> assertTrue(isFastForwardLine(">> -9 >>"))); + } + + @Test + void assertLinesMatchParseFastForwardLimit() { + assertAll("valid fast-forward limits", // + () -> assertEquals(Integer.MAX_VALUE, parseFastForwardLimit(">>>>")), + () -> assertEquals(Integer.MAX_VALUE, parseFastForwardLimit(">> >>")), + () -> assertEquals(Integer.MAX_VALUE, parseFastForwardLimit(">> stacktrace >>")), + () -> assertEquals(Integer.MAX_VALUE, parseFastForwardLimit(">> non Integer.parse()-able comment >>")), + () -> assertEquals(9, parseFastForwardLimit(">>9>>")), + () -> assertEquals(9, parseFastForwardLimit(">> 9 >>"))); + } + + @Test + void assertLinesMatchMatches() { + assertAll("valid fast-forward lines", // + () -> assertTrue(AssertLinesMatch.matches("123", "123")), + () -> assertTrue(AssertLinesMatch.matches(".*", "123")), + () -> assertTrue(AssertLinesMatch.matches("\\d+", "123"))); + } }