From 052bd66fb22b11cc53f4379f53dc4f894257470b Mon Sep 17 00:00:00 2001 From: Alexander Kriegisch Date: Sun, 14 Mar 2021 10:19:21 +0700 Subject: [PATCH] Improve text matching in OutputSpec, fixing some failing Windows tests Some Java 14 text block tests failed on Windows because a StringTokenizer was used to split by LF, but the Windows line separator is CR+LF. Because a multi-line string ending with CR+LF is printed via 'System.out.println' in the test code, another CR+LF is added to the output, resulting in trailing CR+LF+CR+LF. Hence, between the two LFs, the tokenizer actually found an additional line consisting of CR (only on Windows, of course). Despite each line token actually containing a trailing CR token, that did not matter much because 'String.trim' was used everywhere before comparing values. Anyway, the improved OutputSpec uses text.trim().split("\\s*\n\\s*"), which takes care of leading/trailing whitespace both around the whole output and for each separate line. Signed-off-by: Alexander Kriegisch --- .../java/org/aspectj/testing/OutputSpec.java | 45 +++++++++---------- tests/features195/textblock/Code.java | 2 +- tests/features195/textblock/Code2.java | 2 +- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/testing/src/test/java/org/aspectj/testing/OutputSpec.java b/testing/src/test/java/org/aspectj/testing/OutputSpec.java index 8e1fd2612..9d334386a 100644 --- a/testing/src/test/java/org/aspectj/testing/OutputSpec.java +++ b/testing/src/test/java/org/aspectj/testing/OutputSpec.java @@ -11,8 +11,8 @@ * ******************************************************************/ package org.aspectj.testing; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; -import java.util.StringTokenizer; import org.aspectj.tools.ajc.AjcTestCase; import org.aspectj.util.LangUtil; @@ -63,43 +63,43 @@ public class OutputSpec { } boolean matches = false; int lineNo = 0; - StringTokenizer strTok = new StringTokenizer(output,"\n"); - if (strTok.countTokens() == expectedOutputLines.size()) { + String[] actualOutputLines = getTrimmedLines(output); + + if (actualOutputLines.length == expectedOutputLines.size()) { matches = true; - for (String line: expectedOutputLines) { - lineNo++; - String outputLine = strTok.nextToken().trim(); + for (String lineExpected : expectedOutputLines) { + String lineFound = actualOutputLines[lineNo++]; /* Avoid trying to match on ajSandbox source names that appear in messages */ - if (!outputLine.contains(line)) { + if (!lineFound.contains(lineExpected.trim())) { matches = false; break; } } } else { lineNo = -1; } if (!matches) { - createFailureMessage(output, lineNo, strTok.countTokens()); + createFailureMessage(output, lineNo, actualOutputLines.length); } } - public void unorderedMatchAgainst(String output) { - List outputFound = getOutputFound(output); - if(outputFound.size() != expectedOutputLines.size()) { - createFailureMessage(output, -1, outputFound.size()); + private void unorderedMatchAgainst(String output) { + List actualOutputLines = Arrays.asList(getTrimmedLines(output)); + int numberOfOutputLines = actualOutputLines.size(); + if(numberOfOutputLines != expectedOutputLines.size()) { + createFailureMessage(output, -1, numberOfOutputLines); return; } List expected = new ArrayList<>(expectedOutputLines); - List found = new ArrayList<>(outputFound); - for (String lineFound : outputFound) { + List found = new ArrayList<>(actualOutputLines); + for (String lineFound : actualOutputLines) { for (String lineExpected : expectedOutputLines) { - if (lineFound.contains(lineExpected)) { + if (lineFound.contains(lineExpected.trim())) { found.remove(lineFound); expected.remove(lineExpected); - continue; } } } if (!found.isEmpty() || !expected.isEmpty()) { - createFailureMessage(output,-2,outputFound.size()); + createFailureMessage(output, -2, numberOfOutputLines); } } @@ -121,13 +121,8 @@ public class OutputSpec { AjcTestCase.fail(failMessage.toString()); } - private List getOutputFound(String output) { - List found = new ArrayList<>(); - StringTokenizer strTok = new StringTokenizer(output,"\n"); - while(strTok.hasMoreTokens()) { - String outputLine = strTok.nextToken().trim(); - found.add(outputLine); - } - return found; + private String[] getTrimmedLines(String text) { + // Remove leading/trailing empty lines and leading/trailing whitespace from each line + return text.trim().split("\\s*\n\\s*"); } } diff --git a/tests/features195/textblock/Code.java b/tests/features195/textblock/Code.java index 89df1e537..5dc430872 100644 --- a/tests/features195/textblock/Code.java +++ b/tests/features195/textblock/Code.java @@ -1,9 +1,9 @@ public class Code { public static void main(String[] argv) { + // Caveat: Putting the closing '"""' on a separate line adds a line break and 'println' (not 'print'!) adds another. System.out.println(""" this is a text block """); } } - diff --git a/tests/features195/textblock/Code2.java b/tests/features195/textblock/Code2.java index f0b39e08b..7020b67a5 100644 --- a/tests/features195/textblock/Code2.java +++ b/tests/features195/textblock/Code2.java @@ -6,10 +6,10 @@ public class Code2 { aspect X { before(): execution(* Code2.main(..)) { + // Caveat: Putting the closing '"""' on a separate line adds a line break and 'println' (not 'print'!) adds another. System.out.println(""" this is a text block in advice """); } } - -- 2.39.5