diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index eff639302..74a2aa1d9 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -57,7 +57,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@4dd16135b69a43b6c8efb853346f8437d92d3c93 # 3.26.6 + uses: github/codeql-action/init@294a9d92911152fe08befb9ec03e240add280cb3 # 3.26.8 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -68,7 +68,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@4dd16135b69a43b6c8efb853346f8437d92d3c93 # 3.26.6 + uses: github/codeql-action/autobuild@294a9d92911152fe08befb9ec03e240add280cb3 # 3.26.8 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -82,4 +82,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@4dd16135b69a43b6c8efb853346f8437d92d3c93 # 3.26.6 + uses: github/codeql-action/analyze@294a9d92911152fe08befb9ec03e240add280cb3 # 3.26.8 diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 000000000..0748cf09a --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,31 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +name: 'Dependency Review' +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: 'Checkout Repository' + uses: actions/checkout@v4 + - name: 'Dependency Review' + uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index a63b56364..972862ffb 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -64,6 +64,6 @@ jobs: retention-days: 5 - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@4dd16135b69a43b6c8efb853346f8437d92d3c93 # 3.26.6 + uses: github/codeql-action/upload-sarif@294a9d92911152fe08befb9ec03e240add280cb3 # 3.26.8 with: sarif_file: results.sarif diff --git a/pom.xml b/pom.xml index bc4e9e3e4..d8ac381c5 100644 --- a/pom.xml +++ b/pom.xml @@ -206,6 +206,7 @@ ${checkstyle.config.file} false ${checkstyle.suppress.file} + true diff --git a/src/main/java/org/apache/commons/csv/CSVParser.java b/src/main/java/org/apache/commons/csv/CSVParser.java index 471a43c12..a2bc23070 100644 --- a/src/main/java/org/apache/commons/csv/CSVParser.java +++ b/src/main/java/org/apache/commons/csv/CSVParser.java @@ -72,7 +72,7 @@ * For those who like fluent APIs, parsers can be created using {@link CSVFormat#parse(java.io.Reader)} as a shortcut: *

*
- * for(CSVRecord record : CSVFormat.EXCEL.parse(in)) {
+ * for (CSVRecord record : CSVFormat.EXCEL.parse(in)) {
  *     ...
  * }
  * 
diff --git a/src/main/java/org/apache/commons/csv/ExtendedBufferedReader.java b/src/main/java/org/apache/commons/csv/ExtendedBufferedReader.java index 82e16562c..18c922a50 100644 --- a/src/main/java/org/apache/commons/csv/ExtendedBufferedReader.java +++ b/src/main/java/org/apache/commons/csv/ExtendedBufferedReader.java @@ -56,22 +56,6 @@ final class ExtendedBufferedReader extends UnsynchronizedBufferedReader { super(reader); } - @Override - public void mark(final int readAheadLimit) throws IOException { - lineNumberMark = lineNumber; - lastCharMark = lastChar; - positionMark = position; - super.mark(readAheadLimit); - } - - @Override - public void reset() throws IOException { - lineNumber = lineNumberMark; - lastChar = lastCharMark; - position = positionMark; - super.reset(); - } - /** * Closes the stream. * @@ -85,6 +69,18 @@ public void close() throws IOException { super.close(); } + /** + * Returns the last character that was read as an integer (0 to 65535). This will be the last character returned by + * any of the read methods. This will not include a character read using the {@link #peek()} method. If no + * character has been read then this will return {@link Constants#UNDEFINED}. If the end of the stream was reached + * on the last read then this will return {@link IOUtils#EOF}. + * + * @return the last character that was read + */ + int getLastChar() { + return lastChar; + } + /** * Returns the current line number * @@ -98,18 +94,6 @@ long getLineNumber() { return lineNumber + 1; // Allow for counter being incremented only at EOL } - /** - * Returns the last character that was read as an integer (0 to 65535). This will be the last character returned by - * any of the read methods. This will not include a character read using the {@link #peek()} method. If no - * character has been read then this will return {@link Constants#UNDEFINED}. If the end of the stream was reached - * on the last read then this will return {@link IOUtils#EOF}. - * - * @return the last character that was read - */ - int getLastChar() { - return lastChar; - } - /** * Gets the character position in the reader. * @@ -119,6 +103,14 @@ long getPosition() { return this.position; } + @Override + public void mark(final int readAheadLimit) throws IOException { + lineNumberMark = lineNumber; + lastCharMark = lastChar; + positionMark = position; + super.mark(readAheadLimit); + } + @Override public int read() throws IOException { final int current = super.read(); @@ -190,4 +182,12 @@ public String readLine() throws IOException { return buffer.toString(); } + @Override + public void reset() throws IOException { + lineNumber = lineNumberMark; + lastChar = lastCharMark; + position = positionMark; + super.reset(); + } + } diff --git a/src/main/java/org/apache/commons/csv/Lexer.java b/src/main/java/org/apache/commons/csv/Lexer.java index b25ade052..6d9c8a485 100644 --- a/src/main/java/org/apache/commons/csv/Lexer.java +++ b/src/main/java/org/apache/commons/csv/Lexer.java @@ -63,6 +63,26 @@ final class Lexer implements Closeable { this.escapeDelimiterBuf = new char[2 * delimiter.length - 1]; } + /** + * Appends the next escaped character to the token's content. + * + * @param token the current token + * @throws IOException on stream access error + * @throws CSVException Thrown on invalid input. + */ + private void appendNextEscapedCharacterToToken(final Token token) throws IOException { + if (isEscapeDelimiter()) { + token.content.append(delimiter); + } else { + final int unescaped = readEscape(); + if (unescaped == EOF) { // unexpected char after escape + token.content.append((char) escape).append((char) reader.getLastChar()); + } else { + token.content.append((char) unescaped); + } + } + } + /** * Closes resources. * @@ -190,10 +210,6 @@ boolean isStartOfLine(final int ch) { return ch == Constants.LF || ch == Constants.CR || ch == Constants.UNDEFINED; } - private int nullToDisabled(final Character c) { - return c == null ? Constants.UNDEFINED : c.charValue(); // Explicit unboxing - } - /** * Returns the next token. *

@@ -279,6 +295,10 @@ Token nextToken(final Token token) throws IOException { return token; } + private int nullToDisabled(final Character c) { + return c == null ? Constants.UNDEFINED : c.charValue(); // Explicit unboxing + } + /** * Parses an encapsulated token. *

@@ -408,26 +428,6 @@ private Token parseSimpleToken(final Token token, int ch) throws IOException { return token; } - /** - * Appends the next escaped character to the token's content. - * - * @param token the current token - * @throws IOException on stream access error - * @throws CSVException Thrown on invalid input. - */ - private void appendNextEscapedCharacterToToken(final Token token) throws IOException { - if (isEscapeDelimiter()) { - token.content.append(delimiter); - } else { - final int unescaped = readEscape(); - if (unescaped == EOF) { // unexpected char after escape - token.content.append((char) escape).append((char) reader.getLastChar()); - } else { - token.content.append((char) unescaped); - } - } - } - /** * Greedily accepts \n, \r and \r\n This checker consumes silently the second control-character... * diff --git a/src/test/java/org/apache/commons/csv/CSVBenchmark.java b/src/test/java/org/apache/commons/csv/CSVBenchmark.java index 4a146a0a9..a3cdd33f9 100644 --- a/src/test/java/org/apache/commons/csv/CSVBenchmark.java +++ b/src/test/java/org/apache/commons/csv/CSVBenchmark.java @@ -28,10 +28,6 @@ import java.util.concurrent.TimeUnit; import java.util.zip.GZIPInputStream; -import com.generationjava.io.CsvReader; -import com.opencsv.CSVParserBuilder; -import com.opencsv.CSVReaderBuilder; - import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.openjdk.jmh.annotations.Benchmark; @@ -49,6 +45,10 @@ import org.supercsv.io.CsvListReader; import org.supercsv.prefs.CsvPreference; +import com.generationjava.io.CsvReader; +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReaderBuilder; + @BenchmarkMode(Mode.AverageTime) @Fork(value = 1, jvmArgs = {"-server", "-Xms1024M", "-Xmx1024M"}) @Threads(1) diff --git a/src/test/java/org/apache/commons/csv/CSVDuplicateHeaderTest.java b/src/test/java/org/apache/commons/csv/CSVDuplicateHeaderTest.java index 9eae51b05..dfca5765b 100644 --- a/src/test/java/org/apache/commons/csv/CSVDuplicateHeaderTest.java +++ b/src/test/java/org/apache/commons/csv/CSVDuplicateHeaderTest.java @@ -307,25 +307,24 @@ public void testCSVParser(final DuplicateHeaderMode duplicateHeaderMode, final boolean allowMissingColumnNames, final boolean ignoreHeaderCase, final String[] headers, - final boolean valid) throws IOException { - final CSVFormat format = - CSVFormat.DEFAULT.builder() - .setDuplicateHeaderMode(duplicateHeaderMode) - .setAllowMissingColumnNames(allowMissingColumnNames) - .setIgnoreHeaderCase(ignoreHeaderCase) - .setNullString("NULL") - .setHeader() - .build(); + final boolean valid) throws IOException { + // @formatter:off + final CSVFormat format = CSVFormat.DEFAULT.builder() + .setDuplicateHeaderMode(duplicateHeaderMode) + .setAllowMissingColumnNames(allowMissingColumnNames) + .setIgnoreHeaderCase(ignoreHeaderCase) + .setNullString("NULL") + .setHeader() + .build(); + // @formatter:on final String input = Arrays.stream(headers) .map(s -> s == null ? format.getNullString() : s) .collect(Collectors.joining(format.getDelimiterString())); + // @formatter:off if (valid) { - try(CSVParser parser = CSVParser.parse(input, format)) { + try (CSVParser parser = CSVParser.parse(input, format)) { // Parser ignores null headers - final List expected = - Arrays.stream(headers) - .filter(s -> s != null) - .collect(Collectors.toList()); + final List expected = Arrays.stream(headers).filter(s -> s != null).collect(Collectors.toList()); Assertions.assertEquals(expected, parser.getHeaderNames(), "HeaderNames"); } } else { diff --git a/src/test/java/org/apache/commons/csv/CSVFormatTest.java b/src/test/java/org/apache/commons/csv/CSVFormatTest.java index 939935eeb..ff806b82e 100644 --- a/src/test/java/org/apache/commons/csv/CSVFormatTest.java +++ b/src/test/java/org/apache/commons/csv/CSVFormatTest.java @@ -715,11 +715,21 @@ public void testFormatThrowsNullPointerException() { @Test public void testFormatToString() { - final CSVFormat format = CSVFormat.RFC4180.withEscape('?').withDelimiter(',').withQuoteMode(QuoteMode.MINIMAL).withRecordSeparator(CRLF).withQuote('"') - .withNullString("").withIgnoreHeaderCase(true).withHeaderComments("This is HeaderComments").withHeader("col1", "col2", "col3"); + // @formatter:off + final CSVFormat format = CSVFormat.RFC4180 + .withEscape('?') + .withDelimiter(',') + .withQuoteMode(QuoteMode.MINIMAL) + .withRecordSeparator(CRLF) + .withQuote('"') + .withNullString("") + .withIgnoreHeaderCase(true) + .withHeaderComments("This is HeaderComments") + .withHeader("col1", "col2", "col3"); + // @formatter:on assertEquals( - "Delimiter=<,> Escape= QuoteChar=<\"> QuoteMode= NullString=<> RecordSeparator=<" + CRLF - + "> IgnoreHeaderCase:ignored SkipHeaderRecord:false HeaderComments:[This is HeaderComments] Header:[col1, col2, col3]", + "Delimiter=<,> Escape= QuoteChar=<\"> QuoteMode= NullString=<> RecordSeparator=<" + CRLF + + "> IgnoreHeaderCase:ignored SkipHeaderRecord:false HeaderComments:[This is HeaderComments] Header:[col1, col2, col3]", format.toString()); } @@ -960,12 +970,14 @@ public void testQuoteCharSameAsDelimiterThrowsException_Deprecated() { @Test public void testQuoteModeNoneShouldReturnMeaningfulExceptionMessage() { - final Exception exception = assertThrows(IllegalArgumentException.class, () -> { + final Exception exception = assertThrows(IllegalArgumentException.class, () -> + // @formatter:off CSVFormat.DEFAULT.builder() .setHeader("Col1", "Col2", "Col3", "Col4") .setQuoteMode(QuoteMode.NONE) - .build(); - }); + .build() + // @formatter:on + ); final String actualMessage = exception.getMessage(); final String expectedMessage = "Quote mode set to NONE but no escape character is set"; assertEquals(expectedMessage, actualMessage); diff --git a/src/test/java/org/apache/commons/csv/CSVParserTest.java b/src/test/java/org/apache/commons/csv/CSVParserTest.java index 4cbbf8e5b..6a0637301 100644 --- a/src/test/java/org/apache/commons/csv/CSVParserTest.java +++ b/src/test/java/org/apache/commons/csv/CSVParserTest.java @@ -23,11 +23,11 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; import java.io.File; import java.io.IOException; @@ -64,9 +64,8 @@ /** * CSVParserTest * - * The test are organized in three different sections: The 'setter/getter' section, the lexer section and finally the - * parser section. In case a test fails, you should follow a top-down approach for fixing a potential bug (its likely - * that the parser itself fails if the lexer has problems...). + * The test are organized in three different sections: The 'setter/getter' section, the lexer section and finally the parser section. In case a test fails, you + * should follow a top-down approach for fixing a potential bug (its likely that the parser itself fails if the lexer has problems...). */ public class CSVParserTest { @@ -74,18 +73,18 @@ public class CSVParserTest { private static final String UTF_8_NAME = UTF_8.name(); - private static final String CSV_INPUT = "a,b,c,d\n" + " a , b , 1 2 \n" + "\"foo baar\", b,\n" + private static final String CSV_INPUT = "a,b,c,d\n" + " a , b , 1 2 \n" + "\"foo baar\", b,\n" + // + " \"foo\n,,\n\"\",,\n\\\"\",d,e\n"; - + " \"foo\n,,\n\"\",,\n\"\"\",d,e\n"; // changed to use standard CSV escaping + " \"foo\n,,\n\"\",,\n\"\"\",d,e\n"; // changed to use standard CSV escaping private static final String CSV_INPUT_1 = "a,b,c,d"; private static final String CSV_INPUT_2 = "a,b,1 2"; - private static final String[][] RESULT = {{"a", "b", "c", "d"}, {"a", "b", "1 2"}, {"foo baar", "b", ""}, {"foo\n,,\n\",,\n\"", "d", "e"}}; + private static final String[][] RESULT = { { "a", "b", "c", "d" }, { "a", "b", "1 2" }, { "foo baar", "b", "" }, { "foo\n,,\n\",,\n\"", "d", "e" } }; // CSV with no header comments - static private final String CSV_INPUT_NO_COMMENT = "A,B"+CRLF+"1,2"+CRLF; + static private final String CSV_INPUT_NO_COMMENT = "A,B" + CRLF + "1,2" + CRLF; // CSV with a header comment static private final String CSV_INPUT_HEADER_COMMENT = "# header comment" + CRLF + "A,B" + CRLF + "1,2" + CRLF; @@ -94,23 +93,28 @@ public class CSVParserTest { static private final String CSV_INPUT_HEADER_TRAILER_COMMENT = "# header comment" + CRLF + "A,B" + CRLF + "1,2" + CRLF + "# comment"; // CSV with a multi-line header and trailer comment - static private final String CSV_INPUT_MULTILINE_HEADER_TRAILER_COMMENT = "# multi-line" + CRLF + "# header comment" + CRLF + "A,B" + CRLF + "1,2" + CRLF + "# multi-line" + CRLF + "# comment"; + static private final String CSV_INPUT_MULTILINE_HEADER_TRAILER_COMMENT = "# multi-line" + CRLF + "# header comment" + CRLF + "A,B" + CRLF + "1,2" + CRLF + + "# multi-line" + CRLF + "# comment"; // Format with auto-detected header static private final CSVFormat FORMAT_AUTO_HEADER = CSVFormat.Builder.create(CSVFormat.DEFAULT).setCommentMarker('#').setHeader().build(); // Format with explicit header + // @formatter:off static private final CSVFormat FORMAT_EXPLICIT_HEADER = CSVFormat.Builder.create(CSVFormat.DEFAULT) .setSkipHeaderRecord(true) .setCommentMarker('#') .setHeader("A", "B") .build(); + // @formatter:on // Format with explicit header that does not skip the header line + // @formatter:off CSVFormat FORMAT_EXPLICIT_HEADER_NOSKIP = CSVFormat.Builder.create(CSVFormat.DEFAULT) .setCommentMarker('#') .setHeader("A", "B") .build(); + // @formatter:on @SuppressWarnings("resource") // caller releases private BOMInputStream createBOMInputStream(final String resource) throws IOException { @@ -131,22 +135,22 @@ private void parseFully(final CSVParser parser) { @Test public void testBackslashEscaping() throws IOException { - // To avoid confusion over the need for escaping chars in java code, // We will test with a forward slash as the escape char, and a single // quote as the encapsulator. - final String code = "one,two,three\n" // 0 - + "'',''\n" // 1) empty encapsulators - + "/',/'\n" // 2) single encapsulators - + "'/'','/''\n" // 3) single encapsulators encapsulated via escape - + "'''',''''\n" // 4) single encapsulators encapsulated via doubling - + "/,,/,\n" // 5) separator escaped - + "//,//\n" // 6) escape escaped - + "'//','//'\n" // 7) escape escaped in encapsulation - + " 8 , \"quoted \"\" /\" // string\" \n" // don't eat spaces - + "9, /\n \n" // escaped newline - + ""; + // @formatter:off + final String code = "one,two,three\n" + // 0 + "'',''\n" + // 1) empty encapsulators + "/',/'\n" + // 2) single encapsulators + "'/'','/''\n" + // 3) single encapsulators encapsulated via escape + "'''',''''\n" + // 4) single encapsulators encapsulated via doubling + "/,,/,\n" + // 5) separator escaped + "//,//\n" + // 6) escape escaped + "'//','//'\n" + // 7) escape escaped in encapsulation + " 8 , \"quoted \"\" /\" // string\" \n" + // don't eat spaces + "9, /\n \n" + // escaped newline + ""; final String[][] res = {{"one", "two", "three"}, // 0 {"", ""}, // 1 {"'", "'"}, // 2 @@ -155,40 +159,35 @@ public void testBackslashEscaping() throws IOException { {",", ","}, // 5 {"/", "/"}, // 6 {"/", "/"}, // 7 - {" 8 ", " \"quoted \"\" /\" / string\" "}, {"9", " \n "},}; - + {" 8 ", " \"quoted \"\" /\" / string\" "}, {"9", " \n "} }; + // @formatter:on final CSVFormat format = CSVFormat.newFormat(',').withQuote('\'').withRecordSeparator(CRLF).withEscape('/').withIgnoreEmptyLines(); - try (final CSVParser parser = CSVParser.parse(code, format)) { final List records = parser.getRecords(); assertFalse(records.isEmpty()); - Utils.compare("Records do not match expected result", res, records); } } @Test public void testBackslashEscaping2() throws IOException { - // To avoid confusion over the need for escaping chars in java code, // We will test with a forward slash as the escape char, and a single // quote as the encapsulator. - - final String code = "" + " , , \n" // 1) - + " \t , , \n" // 2) - + " // , /, , /,\n" // 3) - + ""; + // @formatter:off + final String code = "" + " , , \n" + // 1) + " \t , , \n" + // 2) + " // , /, , /,\n" + // 3) + ""; final String[][] res = {{" ", " ", " "}, // 1 {" \t ", " ", " "}, // 2 {" / ", " , ", " ,"}, // 3 }; - + // @formatter:on final CSVFormat format = CSVFormat.newFormat(',').withRecordSeparator(CRLF).withEscape('/').withIgnoreEmptyLines(); - try (final CSVParser parser = CSVParser.parse(code, format)) { final List records = parser.getRecords(); assertFalse(records.isEmpty()); - Utils.compare("", res, records); } } @@ -196,13 +195,16 @@ public void testBackslashEscaping2() throws IOException { @Test @Disabled public void testBackslashEscapingOld() throws IOException { - final String code = "one,two,three\n" + "on\\\"e,two\n" + "on\"e,two\n" + "one,\"tw\\\"o\"\n" + "one,\"t\\,wo\"\n" + "one,two,\"th,ree\"\n" - + "\"a\\\\\"\n" + "a\\,b\n" + "\"a\\\\,b\""; - final String[][] res = {{"one", "two", "three"}, {"on\\\"e", "two"}, {"on\"e", "two"}, {"one", "tw\"o"}, {"one", "t\\,wo"}, // backslash in quotes only - // escapes a delimiter (",") - {"one", "two", "th,ree"}, {"a\\\\"}, // backslash in quotes only escapes a delimiter (",") - {"a\\", "b"}, // a backslash must be returned - {"a\\\\,b"} // backslash in quotes only escapes a delimiter (",") + final String code = "one,two,three\n" + "on\\\"e,two\n" + "on\"e,two\n" + "one,\"tw\\\"o\"\n" + "one,\"t\\,wo\"\n" + "one,two,\"th,ree\"\n" + + "\"a\\\\\"\n" + "a\\,b\n" + "\"a\\\\,b\""; + final String[][] res = { { "one", "two", "three" }, { "on\\\"e", "two" }, { "on\"e", "two" }, { "one", "tw\"o" }, { "one", "t\\,wo" }, // backslash in + // quotes only + // escapes a + // delimiter + // (",") + { "one", "two", "th,ree" }, { "a\\\\" }, // backslash in quotes only escapes a delimiter (",") + { "a\\", "b" }, // a backslash must be returned + { "a\\\\,b" } // backslash in quotes only escapes a delimiter (",") }; try (final CSVParser parser = CSVParser.parse(code, CSVFormat.DEFAULT)) { final List records = parser.getRecords(); @@ -226,7 +228,7 @@ public void testBOM() throws IOException { @Test public void testBOMInputStreamParserWithInputStream() throws IOException { try (final BOMInputStream inputStream = createBOMInputStream("org/apache/commons/csv/CSVFileParser/bom.csv"); - final CSVParser parser = CSVParser.parse(inputStream, UTF_8, CSVFormat.EXCEL.withHeader())) { + final CSVParser parser = CSVParser.parse(inputStream, UTF_8, CSVFormat.EXCEL.withHeader())) { parser.forEach(record -> assertNotNull(record.get("Date"))); } } @@ -234,7 +236,7 @@ public void testBOMInputStreamParserWithInputStream() throws IOException { @Test public void testBOMInputStreamParserWithReader() throws IOException { try (final Reader reader = new InputStreamReader(createBOMInputStream("org/apache/commons/csv/CSVFileParser/bom.csv"), UTF_8_NAME); - final CSVParser parser = new CSVParser(reader, CSVFormat.EXCEL.withHeader())) { + final CSVParser parser = new CSVParser(reader, CSVFormat.EXCEL.withHeader())) { parser.forEach(record -> assertNotNull(record.get("Date"))); } } @@ -242,7 +244,7 @@ public void testBOMInputStreamParserWithReader() throws IOException { @Test public void testBOMInputStreamParseWithReader() throws IOException { try (final Reader reader = new InputStreamReader(createBOMInputStream("org/apache/commons/csv/CSVFileParser/bom.csv"), UTF_8_NAME); - final CSVParser parser = CSVParser.parse(reader, CSVFormat.EXCEL.withHeader())) { + final CSVParser parser = CSVParser.parse(reader, CSVFormat.EXCEL.withHeader())) { parser.forEach(record -> assertNotNull(record.get("Date"))); } } @@ -402,28 +404,25 @@ public void testCSV57() throws Exception { @Test public void testDefaultFormat() throws IOException { - final String code = "" + "a,b#\n" // 1) - + "\"\n\",\" \",#\n" // 2) - + "#,\"\"\n" // 3) - + "# Final comment\n"// 4) + // @formatter:off + final String code = "" + "a,b#\n" + // 1) + "\"\n\",\" \",#\n" + // 2) + "#,\"\"\n" + // 3) + "# Final comment\n" // 4) ; - final String[][] res = {{"a", "b#"}, {"\n", " ", "#"}, {"#", ""}, {"# Final comment"}}; - + // @formatter:on + final String[][] res = { { "a", "b#" }, { "\n", " ", "#" }, { "#", "" }, { "# Final comment" } }; CSVFormat format = CSVFormat.DEFAULT; assertFalse(format.isCommentMarkerSet()); - final String[][] res_comments = {{"a", "b#"}, {"\n", " ", "#"},}; - + final String[][] res_comments = { { "a", "b#" }, { "\n", " ", "#" } }; try (final CSVParser parser = CSVParser.parse(code, format)) { final List records = parser.getRecords(); assertFalse(records.isEmpty()); - Utils.compare("Failed to parse without comments", res, records); - format = CSVFormat.DEFAULT.withCommentMarker('#'); } try (final CSVParser parser = CSVParser.parse(code, format)) { final List records = parser.getRecords(); - Utils.compare("Failed to parse with comments", res_comments, records); } } @@ -438,13 +437,13 @@ public void testDuplicateHeadersAllowedByDefault() throws Exception { @Test public void testDuplicateHeadersNotAllowed() { assertThrows(IllegalArgumentException.class, - () -> CSVParser.parse("a,b,a\n1,2,3\nx,y,z", CSVFormat.DEFAULT.withHeader().withAllowDuplicateHeaderNames(false))); + () -> CSVParser.parse("a,b,a\n1,2,3\nx,y,z", CSVFormat.DEFAULT.withHeader().withAllowDuplicateHeaderNames(false))); } @Test public void testEmptyFile() throws Exception { try (final CSVParser parser = CSVParser.parse(Paths.get("src/test/resources/org/apache/commons/csv/empty.txt"), StandardCharsets.UTF_8, - CSVFormat.DEFAULT)) { + CSVFormat.DEFAULT)) { assertNull(parser.nextRecord()); } } @@ -459,8 +458,8 @@ public void testEmptyFileHeaderParsing() throws Exception { @Test public void testEmptyLineBehaviorCSV() throws Exception { - final String[] codes = {"hello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n"}; - final String[][] res = {{"hello", ""} // CSV format ignores empty lines + final String[] codes = { "hello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n" }; + final String[][] res = { { "hello", "" } // CSV format ignores empty lines }; for (final String code : codes) { try (final CSVParser parser = CSVParser.parse(code, CSVFormat.DEFAULT)) { @@ -476,9 +475,9 @@ public void testEmptyLineBehaviorCSV() throws Exception { @Test public void testEmptyLineBehaviorExcel() throws Exception { - final String[] codes = {"hello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n"}; - final String[][] res = {{"hello", ""}, {""}, // Excel format does not ignore empty lines - {""}}; + final String[] codes = { "hello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n" }; + final String[][] res = { { "hello", "" }, { "" }, // Excel format does not ignore empty lines + { "" } }; for (final String code : codes) { try (final CSVParser parser = CSVParser.parse(code, CSVFormat.EXCEL)) { final List records = parser.getRecords(); @@ -500,10 +499,10 @@ public void testEmptyString() throws Exception { @Test public void testEndOfFileBehaviorCSV() throws Exception { - final String[] codes = {"hello,\r\n\r\nworld,\r\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\r\n", "hello,\r\n\r\nworld,\"\"", - "hello,\r\n\r\nworld,\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\n", "hello,\r\n\r\nworld,\"\""}; - final String[][] res = {{"hello", ""}, // CSV format ignores empty lines - {"world", ""}}; + final String[] codes = { "hello,\r\n\r\nworld,\r\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\r\n", "hello,\r\n\r\nworld,\"\"", + "hello,\r\n\r\nworld,\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\n", "hello,\r\n\r\nworld,\"\"" }; + final String[][] res = { { "hello", "" }, // CSV format ignores empty lines + { "world", "" } }; for (final String code : codes) { try (final CSVParser parser = CSVParser.parse(code, CSVFormat.DEFAULT)) { final List records = parser.getRecords(); @@ -518,10 +517,10 @@ public void testEndOfFileBehaviorCSV() throws Exception { @Test public void testEndOfFileBehaviorExcel() throws Exception { - final String[] codes = {"hello,\r\n\r\nworld,\r\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\r\n", "hello,\r\n\r\nworld,\"\"", - "hello,\r\n\r\nworld,\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\n", "hello,\r\n\r\nworld,\"\""}; - final String[][] res = {{"hello", ""}, {""}, // Excel format does not ignore empty lines - {"world", ""}}; + final String[] codes = { "hello,\r\n\r\nworld,\r\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\r\n", "hello,\r\n\r\nworld,\"\"", + "hello,\r\n\r\nworld,\n", "hello,\r\n\r\nworld,", "hello,\r\n\r\nworld,\"\"\n", "hello,\r\n\r\nworld,\"\"" }; + final String[][] res = { { "hello", "" }, { "" }, // Excel format does not ignore empty lines + { "world", "" } }; for (final String code : codes) { try (final CSVParser parser = CSVParser.parse(code, CSVFormat.EXCEL)) { @@ -538,8 +537,8 @@ public void testEndOfFileBehaviorExcel() throws Exception { @Test public void testExcelFormat1() throws IOException { final String code = "value1,value2,value3,value4\r\na,b,c,d\r\n x,,," + "\r\n\r\n\"\"\"hello\"\"\",\" \"\"world\"\"\",\"abc\ndef\",\r\n"; - final String[][] res = {{"value1", "value2", "value3", "value4"}, {"a", "b", "c", "d"}, {" x", "", "", ""}, {""}, - {"\"hello\"", " \"world\"", "abc\ndef", ""}}; + final String[][] res = { { "value1", "value2", "value3", "value4" }, { "a", "b", "c", "d" }, { " x", "", "", "" }, { "" }, + { "\"hello\"", " \"world\"", "abc\ndef", "" } }; try (final CSVParser parser = CSVParser.parse(code, CSVFormat.EXCEL)) { final List records = parser.getRecords(); assertEquals(res.length, records.size()); @@ -553,7 +552,7 @@ public void testExcelFormat1() throws IOException { @Test public void testExcelFormat2() throws Exception { final String code = "foo,baar\r\n\r\nhello,\r\n\r\nworld,\r\n"; - final String[][] res = {{"foo", "baar"}, {""}, {"hello", ""}, {""}, {"world", ""}}; + final String[][] res = { { "foo", "baar" }, { "" }, { "hello", "" }, { "" }, { "world", "" } }; try (final CSVParser parser = CSVParser.parse(code, CSVFormat.EXCEL)) { final List records = parser.getRecords(); assertEquals(res.length, records.size()); @@ -611,15 +610,16 @@ public void testFirstEndOfLineLf() throws IOException { @Test public void testForEach() throws Exception { - try (final Reader in = new StringReader("a,b,c\n1,2,3\nx,y,z"); final CSVParser parser = CSVFormat.DEFAULT.parse(in)) { + try (final Reader in = new StringReader("a,b,c\n1,2,3\nx,y,z"); + final CSVParser parser = CSVFormat.DEFAULT.parse(in)) { final List records = new ArrayList<>(); for (final CSVRecord record : parser) { records.add(record); } assertEquals(3, records.size()); - assertArrayEquals(new String[] {"a", "b", "c"}, records.get(0).values()); - assertArrayEquals(new String[] {"1", "2", "3"}, records.get(1).values()); - assertArrayEquals(new String[] {"x", "y", "z"}, records.get(2).values()); + assertArrayEquals(new String[] { "a", "b", "c" }, records.get(0).values()); + assertArrayEquals(new String[] { "1", "2", "3" }, records.get(1).values()); + assertArrayEquals(new String[] { "x", "y", "z" }, records.get(2).values()); } } @@ -659,7 +659,7 @@ public void testGetHeaderComment_HeaderTrailerComment() throws IOException { parser.getRecords(); // Expect a header comment assertTrue(parser.hasHeaderComment()); - assertEquals("multi-line"+LF+"header comment", parser.getHeaderComment()); + assertEquals("multi-line" + LF + "header comment", parser.getHeaderComment()); } } @@ -782,7 +782,8 @@ public void testGetOneLine() throws IOException { @Test public void testGetOneLineOneParser() throws IOException { final CSVFormat format = CSVFormat.DEFAULT; - try (final PipedWriter writer = new PipedWriter(); final CSVParser parser = new CSVParser(new PipedReader(writer), format)) { + try (final PipedWriter writer = new PipedWriter(); + final CSVParser parser = new CSVParser(new PipedReader(writer), format)) { writer.append(CSV_INPUT_1); writer.append(format.getRecordSeparator()); final CSVRecord record1 = parser.nextRecord(); @@ -842,7 +843,7 @@ public void testGetRecordsFromBrokenInputStream() throws IOException { @Test public void testGetRecordWithMultiLineValues() throws Exception { try (final CSVParser parser = CSVParser.parse("\"a\r\n1\",\"a\r\n2\"" + CRLF + "\"b\r\n1\",\"b\r\n2\"" + CRLF + "\"c\r\n1\",\"c\r\n2\"", - CSVFormat.DEFAULT.withRecordSeparator(CRLF))) { + CSVFormat.DEFAULT.withRecordSeparator(CRLF))) { CSVRecord record; assertEquals(0, parser.getRecordNumber()); assertEquals(0, parser.getCurrentLineNumber()); @@ -923,7 +924,7 @@ public void testGetTrailerComment_MultilineComment() throws IOException { try (CSVParser parser = CSVParser.parse(CSV_INPUT_MULTILINE_HEADER_TRAILER_COMMENT, FORMAT_AUTO_HEADER)) { parser.getRecords(); assertTrue(parser.hasTrailerComment()); - assertEquals("multi-line"+LF+"comment", parser.getTrailerComment()); + assertEquals("multi-line" + LF + "comment", parser.getTrailerComment()); } } @@ -949,10 +950,8 @@ public void testHeader() throws Exception { @Test public void testHeaderComment() throws Exception { final Reader in = new StringReader("# comment\na,b,c\n1,2,3\nx,y,z"); - try (final CSVParser parser = CSVFormat.DEFAULT.withCommentMarker('#').withHeader().parse(in)) { final Iterator records = parser.iterator(); - for (int i = 0; i < 2; i++) { assertTrue(records.hasNext()); final CSVRecord record = records.next(); @@ -960,7 +959,6 @@ public void testHeaderComment() throws Exception { assertEquals(record.get(1), record.get("b")); assertEquals(record.get(2), record.get("c")); } - assertFalse(records.hasNext()); } } @@ -968,17 +966,14 @@ public void testHeaderComment() throws Exception { @Test public void testHeaderMissing() throws Exception { final Reader in = new StringReader("a,,c\n1,2,3\nx,y,z"); - try (final CSVParser parser = CSVFormat.DEFAULT.withHeader().withAllowMissingColumnNames().parse(in)) { final Iterator records = parser.iterator(); - for (int i = 0; i < 2; i++) { assertTrue(records.hasNext()); final CSVRecord record = records.next(); assertEquals(record.get(0), record.get("a")); assertEquals(record.get(2), record.get("c")); } - assertFalse(records.hasNext()); } } @@ -994,7 +989,7 @@ public void testHeaderMissingWithNull() throws Exception { @Test public void testHeadersMissing() throws Exception { try (final Reader in = new StringReader("a,,c,,e\n1,2,3,4,5\nv,w,x,y,z"); - final CSVParser parser = CSVFormat.DEFAULT.withHeader().withAllowMissingColumnNames().parse(in)) { + final CSVParser parser = CSVFormat.DEFAULT.withHeader().withAllowMissingColumnNames().parse(in)) { parser.iterator(); } } @@ -1034,7 +1029,8 @@ public void testIgnoreCaseHeaderMapping() throws Exception { assertEquals("1", record.get("one")); assertEquals("2", record.get("two")); assertEquals("3", record.get("THREE")); - }} + } + } @Test public void testIgnoreEmptyLines() throws IOException { @@ -1055,10 +1051,8 @@ public void testInvalidFormat() { @Test public void testIterator() throws Exception { final Reader in = new StringReader("a,b,c\n1,2,3\nx,y,z"); - try (final CSVParser parser = CSVFormat.DEFAULT.parse(in)) { final Iterator iterator = parser.iterator(); - assertTrue(iterator.hasNext()); assertThrows(UnsupportedOperationException.class, iterator::remove); assertArrayEquals(new String[] { "a", "b", "c" }, iterator.next().values()); @@ -1068,17 +1062,15 @@ public void testIterator() throws Exception { assertTrue(iterator.hasNext()); assertArrayEquals(new String[] { "x", "y", "z" }, iterator.next().values()); assertFalse(iterator.hasNext()); - assertThrows(NoSuchElementException.class, iterator::next); - }} + } + } @Test public void testIteratorSequenceBreaking() throws IOException { final String fiveRows = "1\n2\n3\n4\n5\n"; - // Iterator hasNext() shouldn't break sequence try (CSVParser parser = CSVFormat.DEFAULT.parse(new StringReader(fiveRows))) { - final Iterator iter = parser.iterator(); int recordNumber = 0; while (iter.hasNext()) { @@ -1096,7 +1088,6 @@ public void testIteratorSequenceBreaking() throws IOException { assertEquals(String.valueOf(recordNumber), record.get(0)); } } - // Consecutive enhanced for loops shouldn't break sequence try (CSVParser parser = CSVFormat.DEFAULT.parse(new StringReader(fiveRows))) { int recordNumber = 0; @@ -1112,7 +1103,6 @@ public void testIteratorSequenceBreaking() throws IOException { assertEquals(String.valueOf(recordNumber), record.get(0)); } } - // Consecutive enhanced for loops with hasNext() peeking shouldn't break sequence try (CSVParser parser = CSVFormat.DEFAULT.parse(new StringReader(fiveRows))) { int recordNumber = 0; @@ -1146,7 +1136,6 @@ public void testMappedButNotSetAsOutlook2007ContactExport() throws Exception { try (final CSVParser parser = CSVFormat.DEFAULT.withHeader("A", "B", "C").withSkipHeaderRecord().parse(in)) { final Iterator records = parser.iterator(); CSVRecord record; - // 1st record record = records.next(); assertTrue(record.isMapped("A")); @@ -1158,7 +1147,6 @@ record = records.next(); assertEquals("1", record.get("A")); assertEquals("2", record.get("B")); assertFalse(record.isConsistent()); - // 2nd record record = records.next(); assertTrue(record.isMapped("A")); @@ -1171,7 +1159,7 @@ record = records.next(); assertEquals("y", record.get("B")); assertEquals("z", record.get("C")); assertTrue(record.isConsistent()); - + // end assertFalse(records.hasNext()); } } @@ -1455,7 +1443,8 @@ public void testRepeatedHeadersAreReturnedInCSVRecordHeaderNames() throws IOExce @SuppressWarnings("resource") final CSVParser recordParser = record.getParser(); assertEquals(Arrays.asList("header1", "header2", "header1"), recordParser.getHeaderNames()); - }} + } + } @Test public void testRoundtrip() throws Exception { @@ -1491,7 +1480,8 @@ public void testSkipHeaderOverrideDuplicateHeaders() throws Exception { assertEquals("1", record.get("X")); assertEquals("2", record.get("Y")); assertEquals("3", record.get("Z")); - }} + } + } @Test public void testSkipSetAltHeaders() throws Exception { @@ -1520,9 +1510,9 @@ public void testSkipSetHeader() throws Exception { @Test @Disabled public void testStartWithEmptyLinesThenHeaders() throws Exception { - final String[] codes = {"\r\n\r\n\r\nhello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n"}; - final String[][] res = {{"hello", ""}, {""}, // Excel format does not ignore empty lines - {""}}; + final String[] codes = { "\r\n\r\n\r\nhello,\r\n\r\n\r\n", "hello,\n\n\n", "hello,\"\"\r\n\r\n\r\n", "hello,\"\"\n\n\n" }; + final String[][] res = { { "hello", "" }, { "" }, // Excel format does not ignore empty lines + { "" } }; for (final String code : codes) { try (final CSVParser parser = CSVParser.parse(code, CSVFormat.EXCEL)) { final List records = parser.getRecords(); @@ -1544,7 +1534,8 @@ public void testStream() throws Exception { assertArrayEquals(new String[] { "a", "b", "c" }, list.get(0).values()); assertArrayEquals(new String[] { "1", "2", "3" }, list.get(1).values()); assertArrayEquals(new String[] { "x", "y", "z" }, list.get(2).values()); - }} + } + } @Test public void testThrowExceptionWithLineAndPosition() throws IOException { @@ -1587,7 +1578,8 @@ public void testTrim() throws Exception { assertEquals("2", record.get("Y")); assertEquals("3", record.get("Z")); assertEquals(3, record.size()); - }} + } + } private void validateLineNumbers(final String lineSeparator) throws IOException { try (final CSVParser parser = CSVParser.parse("a" + lineSeparator + "b" + lineSeparator + "c", CSVFormat.DEFAULT.withRecordSeparator(lineSeparator))) { @@ -1626,7 +1618,7 @@ private void validateRecordNumbers(final String lineSeparator) throws IOExceptio private void validateRecordPosition(final String lineSeparator) throws IOException { final String nl = lineSeparator; // used as linebreak in values for better distinction final String code = "a,b,c" + lineSeparator + "1,2,3" + lineSeparator + - // to see if recordPosition correctly points to the enclosing quote + // to see if recordPosition correctly points to the enclosing quote "'A" + nl + "A','B" + nl + "B',CC" + lineSeparator + // unicode test... not very relevant while operating on strings instead of bytes, but for // completeness... diff --git a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java index d4bff61ee..ce938073b 100644 --- a/src/test/java/org/apache/commons/csv/CSVPrinterTest.java +++ b/src/test/java/org/apache/commons/csv/CSVPrinterTest.java @@ -314,8 +314,8 @@ public void testCRComment() throws IOException { try (final CSVPrinter printer = new CSVPrinter(sw, CSVFormat.DEFAULT.withCommentMarker('#'))) { printer.print(value); printer.printComment("This is a comment\r\non multiple lines\rthis is next comment\r"); - assertEquals("abc" + recordSeparator + "# This is a comment" + recordSeparator + "# on multiple lines" + recordSeparator + "# this is next comment" - + recordSeparator + "# " + recordSeparator, sw.toString()); + assertEquals("abc" + recordSeparator + "# This is a comment" + recordSeparator + "# on multiple lines" + recordSeparator + + "# this is next comment" + recordSeparator + "# " + recordSeparator, sw.toString()); } } @@ -729,8 +729,8 @@ public void testJdbcPrinter() throws IOException, ClassNotFoundException, SQLExc } } final String csv = sw.toString(); - assertEquals("1,r1,\"long text 1\",\"YmluYXJ5IGRhdGEgMQ==\r\n\"" + recordSeparator + "2,r2,\"" + longText2 + "\",\"YmluYXJ5IGRhdGEgMg==\r\n\"" - + recordSeparator, csv); + assertEquals("1,r1,\"long text 1\",\"YmluYXJ5IGRhdGEgMQ==\r\n\"" + recordSeparator + "2,r2,\"" + longText2 + "\",\"YmluYXJ5IGRhdGEgMg==\r\n\"" + + recordSeparator, csv); // Round trip the data try (StringReader reader = new StringReader(csv); final CSVParser csvParser = csvFormat.parse(reader)) { @@ -1349,11 +1349,12 @@ public void testPrint() throws IOException { @Test public void testPrintCSVParser() throws IOException { - final String code = "a1,b1\n" // 1) - + "a2,b2\n" // 2) - + "a3,b3\n" // 3) - + "a4,b4\n"// 4) - ; + // @formatter:off + final String code = "a1,b1\n" + // 1) + "a2,b2\n" + // 2) + "a3,b3\n" + // 3) + "a4,b4\n"; // 4) + // @formatter:on final String[][] res = { { "a1", "b1" }, { "a2", "b2" }, { "a3", "b3" }, { "a4", "b4" } }; final CSVFormat format = CSVFormat.DEFAULT; final StringWriter sw = new StringWriter(); @@ -1370,11 +1371,12 @@ public void testPrintCSVParser() throws IOException { @Test public void testPrintCSVRecord() throws IOException { - final String code = "a1,b1\n" // 1) - + "a2,b2\n" // 2) - + "a3,b3\n" // 3) - + "a4,b4\n"// 4) - ; + // @formatter:off + final String code = "a1,b1\n" + // 1) + "a2,b2\n" + // 2) + "a3,b3\n" + // 3) + "a4,b4\n"; // 4) + // @formatter:on final String[][] res = { { "a1", "b1" }, { "a2", "b2" }, { "a3", "b3" }, { "a4", "b4" } }; final CSVFormat format = CSVFormat.DEFAULT; final StringWriter sw = new StringWriter(); @@ -1393,11 +1395,12 @@ public void testPrintCSVRecord() throws IOException { @Test public void testPrintCSVRecords() throws IOException { - final String code = "a1,b1\n" // 1) - + "a2,b2\n" // 2) - + "a3,b3\n" // 3) - + "a4,b4\n"// 4) - ; + // @formatter:off + final String code = "a1,b1\n" + // 1) + "a2,b2\n" + // 2) + "a3,b3\n" + // 3) + "a4,b4\n"; // 4) + // @formatter:on final String[][] res = { { "a1", "b1" }, { "a2", "b2" }, { "a3", "b3" }, { "a4", "b4" } }; final CSVFormat format = CSVFormat.DEFAULT; final StringWriter sw = new StringWriter(); @@ -1506,8 +1509,8 @@ public void testPrintOnePositiveInteger() throws IOException { * Test to target the use of {@link IOUtils#copy(java.io.Reader, Appendable)} which directly buffers the value from the Reader to the Appendable. * *

- * Requires the format to have no quote or escape character, value to be a {@link Reader Reader} and the output MUST NOT be a - * {@link Writer Writer} but some other Appendable. + * Requires the format to have no quote or escape character, value to be a {@link Reader Reader} and the output MUST NOT be a {@link Writer Writer} + * but some other Appendable. *

* * @throws IOException Not expected to happen @@ -1527,8 +1530,7 @@ public void testPrintReaderWithoutQuoteToAppendable() throws IOException { * Test to target the use of {@link IOUtils#copyLarge(java.io.Reader, Writer)} which directly buffers the value from the Reader to the Writer. * *

- * Requires the format to have no quote or escape character, value to be a {@link Reader Reader} and the output MUST be a - * {@link Writer Writer}. + * Requires the format to have no quote or escape character, value to be a {@link Reader Reader} and the output MUST be a {@link Writer Writer}. *

* * @throws IOException Not expected to happen @@ -1546,11 +1548,12 @@ public void testPrintReaderWithoutQuoteToWriter() throws IOException { @Test public void testPrintRecordStream() throws IOException { - final String code = "a1,b1\n" // 1) - + "a2,b2\n" // 2) - + "a3,b3\n" // 3) - + "a4,b4\n"// 4) - ; + // @formatter:off + final String code = "a1,b1\n" + // 1) + "a2,b2\n" + // 2) + "a3,b3\n" + // 3) + "a4,b4\n"; // 4) + // @formatter:on final String[][] res = { { "a1", "b1" }, { "a2", "b2" }, { "a3", "b3" }, { "a4", "b4" } }; final CSVFormat format = CSVFormat.DEFAULT; final StringWriter sw = new StringWriter(); diff --git a/src/test/java/org/apache/commons/csv/PerformanceTest.java b/src/test/java/org/apache/commons/csv/PerformanceTest.java index 415d9be95..100ac84ef 100644 --- a/src/test/java/org/apache/commons/csv/PerformanceTest.java +++ b/src/test/java/org/apache/commons/csv/PerformanceTest.java @@ -53,28 +53,28 @@ private interface CSVParserFactory { private static final class Stats { final int count; final int fields; + Stats(final int c, final int f) { count = c; fields = f; } } - private static final String[] PROPERTY_NAMES = { - "java.version", // Java Runtime Environment version - "java.vendor", // Java Runtime Environment vendor + private static final String[] PROPERTY_NAMES = { "java.version", // Java Runtime Environment version + "java.vendor", // Java Runtime Environment vendor // "java.vm.specification.version", // Java Virtual Machine specification version // "java.vm.specification.vendor", // Java Virtual Machine specification vendor // "java.vm.specification.name", // Java Virtual Machine specification name - "java.vm.version", // Java Virtual Machine implementation version + "java.vm.version", // Java Virtual Machine implementation version // "java.vm.vendor", // Java Virtual Machine implementation vendor - "java.vm.name", // Java Virtual Machine implementation name + "java.vm.name", // Java Virtual Machine implementation name // "java.specification.version", // Java Runtime Environment specification version // "java.specification.vendor", // Java Runtime Environment specification vendor // "java.specification.name", // Java Runtime Environment specification name - "os.name", // Operating system name - "os.arch", // Operating system architecture - "os.version", // Operating system version + "os.name", // Operating system name + "os.arch", // Operating system architecture + "os.version", // Operating system version }; private static int max = 11; // skip first test @@ -112,18 +112,16 @@ private static Stats iterate(final Iterable iterable) { return new Stats(count, fields); } - public static void main(final String [] args) throws Exception { + public static void main(final String[] args) throws Exception { if (BIG_FILE.exists()) { System.out.printf("Found test fixture %s: %,d bytes.%n", BIG_FILE, BIG_FILE.length()); } else { - System.out.println("Decompressing test fixture to: " + BIG_FILE + "..."); - try ( - final InputStream input = new GZIPInputStream( - PerformanceTest.class.getClassLoader().getResourceAsStream(TEST_RESRC)); - final OutputStream output = new FileOutputStream(BIG_FILE)) { - IOUtils.copy(input, output); - System.out.println(String.format("Decompressed test fixture %s: %,d bytes.", BIG_FILE, BIG_FILE.length())); - } + System.out.println("Decompressing test fixture to: " + BIG_FILE + "..."); + try (final InputStream input = new GZIPInputStream(PerformanceTest.class.getClassLoader().getResourceAsStream(TEST_RESRC)); + final OutputStream output = new FileOutputStream(BIG_FILE)) { + IOUtils.copy(input, output); + System.out.println(String.format("Decompressed test fixture %s: %,d bytes.", BIG_FILE, BIG_FILE.length())); + } } final int argc = args.length; if (argc > 0) { @@ -195,7 +193,7 @@ private static Stats readAll(final BufferedReader in, final boolean split) throw } // calculate and show average - private static void show(){ + private static void show() { if (num > 1) { long tot = 0; for (int i = 1; i < num; i++) { // skip first test @@ -341,5 +339,5 @@ private static void testReadBigFile(final boolean split) throws Exception { } show(); } +} -} \ No newline at end of file diff --git a/src/test/java/org/apache/commons/csv/Utils.java b/src/test/java/org/apache/commons/csv/Utils.java index d585669a7..23ff79b60 100644 --- a/src/test/java/org/apache/commons/csv/Utils.java +++ b/src/test/java/org/apache/commons/csv/Utils.java @@ -6,7 +6,7 @@ * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, diff --git a/src/test/java/org/apache/commons/csv/issues/JiraCsv148Test.java b/src/test/java/org/apache/commons/csv/issues/JiraCsv148Test.java index 315d2bf73..62cd33b2c 100644 --- a/src/test/java/org/apache/commons/csv/issues/JiraCsv148Test.java +++ b/src/test/java/org/apache/commons/csv/issues/JiraCsv148Test.java @@ -33,18 +33,16 @@ public void testWithIgnoreSurroundingSpacesEmpty() { .build(); // @formatter:on assertEquals( - "\"\",\" \",\" Single space on the left\",\"Single space on the right \"," - + "\" Single spaces on both sides \",\" Multiple spaces on the left\"," - + "\"Multiple spaces on the right \",\" Multiple spaces on both sides \"", - format.format("", " ", " Single space on the left", "Single space on the right ", - " Single spaces on both sides ", " Multiple spaces on the left", "Multiple spaces on the right ", - " Multiple spaces on both sides ")); + "\"\",\" \",\" Single space on the left\",\"Single space on the right \"," + + "\" Single spaces on both sides \",\" Multiple spaces on the left\"," + + "\"Multiple spaces on the right \",\" Multiple spaces on both sides \"", + format.format("", " ", " Single space on the left", "Single space on the right ", " Single spaces on both sides ", + " Multiple spaces on the left", "Multiple spaces on the right ", " Multiple spaces on both sides ")); } /** - * The difference between withTrim()and withIgnoreSurroundingSpace(): difference: withTrim() can remove the leading - * and trailing spaces and newlines in quotation marks, while withIgnoreSurroundingSpace() cannot The same point: - * you can remove the leading and trailing spaces, tabs and other symbols. + * The difference between withTrim()and withIgnoreSurroundingSpace(): difference: withTrim() can remove the leading and trailing spaces and newlines in + * quotation marks, while withIgnoreSurroundingSpace() cannot The same point: you can remove the leading and trailing spaces, tabs and other symbols. */ @Test public void testWithTrimEmpty() { @@ -55,11 +53,9 @@ public void testWithTrimEmpty() { .build(); // @formatter:on assertEquals( - "\"\",\"\",\"Single space on the left\",\"Single space on the right\"," - + "\"Single spaces on both sides\",\"Multiple spaces on the left\"," - + "\"Multiple spaces on the right\",\"Multiple spaces on both sides\"", - format.format("", " ", " Single space on the left", "Single space on the right ", - " Single spaces on both sides ", " Multiple spaces on the left", "Multiple spaces on the right ", - " Multiple spaces on both sides ")); + "\"\",\"\",\"Single space on the left\",\"Single space on the right\"," + "\"Single spaces on both sides\",\"Multiple spaces on the left\"," + + "\"Multiple spaces on the right\",\"Multiple spaces on both sides\"", + format.format("", " ", " Single space on the left", "Single space on the right ", " Single spaces on both sides ", + " Multiple spaces on the left", "Multiple spaces on the right ", " Multiple spaces on both sides ")); } } diff --git a/src/test/java/org/apache/commons/csv/issues/JiraCsv150Test.java b/src/test/java/org/apache/commons/csv/issues/JiraCsv150Test.java index c4575ceec..1ede9f239 100644 --- a/src/test/java/org/apache/commons/csv/issues/JiraCsv150Test.java +++ b/src/test/java/org/apache/commons/csv/issues/JiraCsv150Test.java @@ -23,7 +23,6 @@ import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; public class JiraCsv150Test { diff --git a/src/test/java/org/apache/commons/csv/issues/JiraCsv206Test.java b/src/test/java/org/apache/commons/csv/issues/JiraCsv206Test.java index 3d0a4fb4c..8693c36ff 100644 --- a/src/test/java/org/apache/commons/csv/issues/JiraCsv206Test.java +++ b/src/test/java/org/apache/commons/csv/issues/JiraCsv206Test.java @@ -49,8 +49,12 @@ record = iterator.next(); assertEquals("123 Main St.", record.get(2)); } // Write with multiple character delimiter - final String outString = "# Change delimiter to [I]\r\n" + "first name[I]last name[I]address\r\n" - + "John[I]Smith[I]123 Main St."; + // @formatter:off + final String outString = + "# Change delimiter to [I]\r\n" + + "first name[I]last name[I]address\r\n" + + "John[I]Smith[I]123 Main St."; + // @formatter:on final String comment = "Change delimiter to [I]"; // @formatter:off final CSVFormat format = CSVFormat.EXCEL.builder() diff --git a/src/test/java/org/apache/commons/csv/issues/JiraCsv265Test.java b/src/test/java/org/apache/commons/csv/issues/JiraCsv265Test.java index f62b86658..ac5f851d6 100644 --- a/src/test/java/org/apache/commons/csv/issues/JiraCsv265Test.java +++ b/src/test/java/org/apache/commons/csv/issues/JiraCsv265Test.java @@ -36,13 +36,14 @@ public class JiraCsv265Test { @Test public void testCharacterPositionWithComments() throws IOException { // @formatter:off - final String csv = "# Comment1\n" - + "Header1,Header2\n" - + "# Comment2\n" - + "Value1,Value2\n" - + "# Comment3\n" - + "Value3,Value4\n" - + "# Comment4\n"; + final String csv = + "# Comment1\n" + + "Header1,Header2\n" + + "# Comment2\n" + + "Value1,Value2\n" + + "# Comment3\n" + + "Value3,Value4\n" + + "# Comment4\n"; final CSVFormat csvFormat = CSVFormat.DEFAULT.builder() .setCommentMarker('#') .setHeader() @@ -61,15 +62,16 @@ public void testCharacterPositionWithComments() throws IOException { @Test public void testCharacterPositionWithCommentsSpanningMultipleLines() throws IOException { // @formatter:off - final String csv = "# Comment1\n" - + "# Comment2\n" - + "Header1,Header2\n" - + "# Comment3\n" - + "# Comment4\n" - + "Value1,Value2\n" - + "# Comment5\n" - + "# Comment6\n" - + "Value3,Value4"; + final String csv = + "# Comment1\n" + + "# Comment2\n" + + "Header1,Header2\n" + + "# Comment3\n" + + "# Comment4\n" + + "Value1,Value2\n" + + "# Comment5\n" + + "# Comment6\n" + + "Value3,Value4"; final CSVFormat csvFormat = CSVFormat.DEFAULT.builder() .setCommentMarker('#') .setHeader() diff --git a/src/test/java/org/apache/commons/csv/issues/JiraCsv271Test.java b/src/test/java/org/apache/commons/csv/issues/JiraCsv271Test.java index 6150a7668..c7e03492e 100644 --- a/src/test/java/org/apache/commons/csv/issues/JiraCsv271Test.java +++ b/src/test/java/org/apache/commons/csv/issues/JiraCsv271Test.java @@ -35,7 +35,7 @@ public void testJiraCsv271_withArray() throws IOException { final StringWriter stringWriter = new StringWriter(); try (CSVPrinter printer = new CSVPrinter(stringWriter, csvFormat)) { printer.print("a"); - printer.printRecord("b","c"); + printer.printRecord("b", "c"); } assertEquals("a,b,c\r\n", stringWriter.toString()); } @@ -46,7 +46,7 @@ public void testJiraCsv271_withList() throws IOException { final StringWriter stringWriter = new StringWriter(); try (CSVPrinter printer = new CSVPrinter(stringWriter, csvFormat)) { printer.print("a"); - printer.printRecord(Arrays.asList("b","c")); + printer.printRecord(Arrays.asList("b", "c")); } assertEquals("a,b,c\r\n", stringWriter.toString()); } diff --git a/src/test/java/org/apache/commons/csv/issues/JiraCsv288Test.java b/src/test/java/org/apache/commons/csv/issues/JiraCsv288Test.java index 37209e7af..4d5307e9b 100644 --- a/src/test/java/org/apache/commons/csv/issues/JiraCsv288Test.java +++ b/src/test/java/org/apache/commons/csv/issues/JiraCsv288Test.java @@ -211,4 +211,4 @@ public void testParseWithTwoCharDelimiterEndsWithDelimiter() throws Exception { } } } -} \ No newline at end of file +} diff --git a/src/test/java/org/apache/commons/csv/perf/PerformanceTest.java b/src/test/java/org/apache/commons/csv/perf/PerformanceTest.java index e8a3aa57c..ba9ef4991 100644 --- a/src/test/java/org/apache/commons/csv/perf/PerformanceTest.java +++ b/src/test/java/org/apache/commons/csv/perf/PerformanceTest.java @@ -134,4 +134,4 @@ public void testReadBigFile() throws Exception { } println(String.format("Best time out of %,d is %,d milliseconds.", this.max, bestTime)); } -} \ No newline at end of file +}