From 59e27a0aa603705032c9ef2e764113991a79d10b Mon Sep 17 00:00:00 2001 From: Stefan Bratanov Date: Sun, 22 May 2022 22:20:43 +0100 Subject: [PATCH] Add `linesOf` variants for a `Path` content (#2618) --- .../java/org/assertj/core/api/Assertions.java | 51 +++++++++- .../core/api/AssertionsForClassTypes.java | 52 +++++++++- .../org/assertj/core/api/BDDAssertions.java | 48 ++++++++++ .../org/assertj/core/api/WithAssertions.java | 48 ++++++++++ .../java/org/assertj/core/util/Files.java | 10 +- .../java/org/assertj/core/util/Paths.java | 73 ++++++++++++++ .../core/api/Assertions_linesOf_Test.java | 9 ++ .../EntryPointAssertions_linesOf_Test.java | 47 +++++++++ .../assertj/core/util/Paths_linesOf_Test.java | 96 +++++++++++++++++++ 9 files changed, 424 insertions(+), 10 deletions(-) create mode 100644 src/main/java/org/assertj/core/util/Paths.java create mode 100644 src/test/java/org/assertj/core/util/Paths_linesOf_Test.java diff --git a/src/main/java/org/assertj/core/api/Assertions.java b/src/main/java/org/assertj/core/api/Assertions.java index 71ef1b2050..4d426be100 100644 --- a/src/main/java/org/assertj/core/api/Assertions.java +++ b/src/main/java/org/assertj/core/api/Assertions.java @@ -104,6 +104,7 @@ import org.assertj.core.util.CanIgnoreReturnValue; import org.assertj.core.util.CheckReturnValue; import org.assertj.core.util.Files; +import org.assertj.core.util.Paths; import org.assertj.core.util.URLs; import org.assertj.core.util.introspection.FieldSupport; import org.assertj.core.util.introspection.Introspection; @@ -169,7 +170,7 @@ public static PredicateAssert assertThat(Predicate actual) { return AssertionsForInterfaceTypes.assertThat(actual); } - + /** * Create assertion for {@link Predicate}. *

@@ -2842,6 +2843,54 @@ public static List linesOf(File file, String charsetName) { return Files.linesOf(file, charsetName); } + /** + * Loads the text content of a file at a given path into a list of strings with the default charset, each string corresponding to a + * line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path) { + return Paths.linesOf(path, Charset.defaultCharset()); + } + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @param charset the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path, Charset charset) { + return Paths.linesOf(path, charset); + } + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. The line endings are + * either \n, \r or \r\n. + * + * @param path the path. + * @param charsetName the name of the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path, String charsetName) { + return Paths.linesOf(path, charsetName); + } + // -------------------------------------------------------------------------------------------------- // URL/Resource methods : not assertions but here to have a single entry point to all AssertJ features. // -------------------------------------------------------------------------------------------------- diff --git a/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java b/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java index eedcffc291..03d54c3869 100644 --- a/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java +++ b/src/main/java/org/assertj/core/api/AssertionsForClassTypes.java @@ -21,6 +21,7 @@ import java.net.URI; import java.net.URL; import java.nio.charset.Charset; +import java.nio.file.Path; import java.text.DateFormat; import java.time.Duration; import java.time.Instant; @@ -38,8 +39,8 @@ import java.util.OptionalInt; import java.util.OptionalLong; import java.util.concurrent.CompletableFuture; - import java.util.regex.Matcher; + import org.assertj.core.api.ThrowableAssert.ThrowingCallable; import org.assertj.core.api.filter.FilterOperator; import org.assertj.core.api.filter.Filters; @@ -60,6 +61,7 @@ import org.assertj.core.util.CanIgnoreReturnValue; import org.assertj.core.util.CheckReturnValue; import org.assertj.core.util.Files; +import org.assertj.core.util.Paths; import org.assertj.core.util.URLs; import org.assertj.core.util.introspection.FieldSupport; @@ -1652,6 +1654,54 @@ public static List linesOf(File file, String charsetName) { return Files.linesOf(file, charsetName); } + /** + * Loads the text content of a path into a list of strings with the default charset, each string corresponding to a + * line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @return the content of the file. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path) { + return Paths.linesOf(path, Charset.defaultCharset()); + } + + /** + * Loads the text content of a path into a list of strings, each string corresponding to a line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @param charset the character set to use. + * @return the content of the file. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path, Charset charset) { + return Paths.linesOf(path, charset); + } + + /** + * Loads the text content of a path into a list of strings, each string corresponding to a line. The line endings are + * either \n, \r or \r\n. + * + * @param path the path. + * @param charsetName the name of the character set to use. + * @return the content of the file. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path, String charsetName) { + return Paths.linesOf(path, charsetName); + } + // -------------------------------------------------------------------------------------------------- // URL/Resource methods : not assertions but here to have a single entry point to all AssertJ features. // -------------------------------------------------------------------------------------------------- diff --git a/src/main/java/org/assertj/core/api/BDDAssertions.java b/src/main/java/org/assertj/core/api/BDDAssertions.java index 03bbddf8d7..32284195c4 100644 --- a/src/main/java/org/assertj/core/api/BDDAssertions.java +++ b/src/main/java/org/assertj/core/api/BDDAssertions.java @@ -3338,6 +3338,54 @@ public static List linesOf(File file, String charsetName) { return Assertions.linesOf(file, charsetName); } + /** + * Loads the text content of a file at a given path into a list of strings with the default charset, each string corresponding to a + * line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path) { + return Assertions.linesOf(path, Charset.defaultCharset()); + } + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @param charset the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path, Charset charset) { + return Assertions.linesOf(path, charset); + } + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. The line endings are + * either \n, \r or \r\n. + * + * @param path the path. + * @param charsetName the name of the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + public static List linesOf(Path path, String charsetName) { + return Assertions.linesOf(path, charsetName); + } + // -------------------------------------------------------------------------------------------------- // URL/Resource methods : not assertions but here to have a single entry point to all AssertJ features. // -------------------------------------------------------------------------------------------------- diff --git a/src/main/java/org/assertj/core/api/WithAssertions.java b/src/main/java/org/assertj/core/api/WithAssertions.java index 114070b354..34441ff9bd 100644 --- a/src/main/java/org/assertj/core/api/WithAssertions.java +++ b/src/main/java/org/assertj/core/api/WithAssertions.java @@ -2067,6 +2067,54 @@ default List linesOf(final File file, final Charset charset) { return Assertions.linesOf(file, charset); } + /** + * Loads the text content of a file at a given path into a list of strings with the default charset, each string corresponding to a + * line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + default List linesOf(final Path path) { + return Assertions.linesOf(path); + } + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. The line endings are + * either \n, \r or \r\n. + * + * @param path the file. + * @param charsetName the name of the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + default List linesOf(final Path path, final String charsetName) { + return Assertions.linesOf(path, charsetName); + } + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. + * The line endings are either \n, \r or \r\n. + * + * @param path the path. + * @param charset the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + * + * @since 3.23.0 + */ + default List linesOf(final Path path, final Charset charset) { + return Assertions.linesOf(path, charset); + } + /** * Sets whether we remove elements related to AssertJ from assertion error stack trace. * diff --git a/src/main/java/org/assertj/core/util/Files.java b/src/main/java/org/assertj/core/util/Files.java index d66ab9e3be..460ec95171 100644 --- a/src/main/java/org/assertj/core/util/Files.java +++ b/src/main/java/org/assertj/core/util/Files.java @@ -288,12 +288,7 @@ public static String contentOf(File file, Charset charset) { * @throws UncheckedIOException if an I/O exception occurs. */ public static List linesOf(File file, Charset charset) { - requireNonNull(charset, "The charset should not be null"); - try { - return java.nio.file.Files.readAllLines(file.toPath(), charset); - } catch (IOException e) { - throw new UncheckedIOException("Unable to read " + file.getAbsolutePath(), e); - } + return Paths.linesOf(file.toPath(), charset); } /** @@ -307,8 +302,7 @@ public static List linesOf(File file, Charset charset) { * @throws UncheckedIOException if an I/O exception occurs. */ public static List linesOf(File file, String charsetName) { - checkArgumentCharsetIsSupported(charsetName); - return linesOf(file, Charset.forName(charsetName)); + return Paths.linesOf(file.toPath(), charsetName); } private static void checkArgumentCharsetIsSupported(String charsetName) { diff --git a/src/main/java/org/assertj/core/util/Paths.java b/src/main/java/org/assertj/core/util/Paths.java new file mode 100644 index 0000000000..4f61fe8ca5 --- /dev/null +++ b/src/main/java/org/assertj/core/util/Paths.java @@ -0,0 +1,73 @@ +/* + * Licensed 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. + * + * Copyright 2012-2022 the original author or authors. + */ +package org.assertj.core.util; + +import static java.util.Objects.requireNonNull; +import static org.assertj.core.util.Preconditions.checkArgument; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +/** + * Utility methods related to {@link Path}s. + * + * @author Stefan Bratanov + * + * @since 3.23.0 + */ +public class Paths { + + private Paths() {} + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. The line endings are + * either \n, \r or \r\n. + * + * @param path the path. + * @param charset the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + */ + public static List linesOf(Path path, Charset charset) { + requireNonNull(charset, "The charset should not be null"); + try { + return Files.readAllLines(path, charset); + } catch (IOException e) { + throw new UncheckedIOException("Unable to read " + path, e); + } + } + + /** + * Loads the text content of a file at a given path into a list of strings, each string corresponding to a line. The line endings are + * either \n, \r or \r\n. + * + * @param path the path. + * @param charsetName the name of the character set to use. + * @return the content of the file at the given path. + * @throws NullPointerException if the given charset is {@code null}. + * @throws UncheckedIOException if an I/O exception occurs. + */ + public static List linesOf(Path path, String charsetName) { + checkArgumentCharsetIsSupported(charsetName); + return linesOf(path, Charset.forName(charsetName)); + } + + private static void checkArgumentCharsetIsSupported(String charsetName) { + checkArgument(Charset.isSupported(charsetName), "Charset:<'%s'> is not supported on this system", charsetName); + } +} diff --git a/src/test/java/org/assertj/core/api/Assertions_linesOf_Test.java b/src/test/java/org/assertj/core/api/Assertions_linesOf_Test.java index 8845c5a17b..00c1277be0 100644 --- a/src/test/java/org/assertj/core/api/Assertions_linesOf_Test.java +++ b/src/test/java/org/assertj/core/api/Assertions_linesOf_Test.java @@ -18,6 +18,8 @@ import java.io.File; import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import org.junit.jupiter.api.Test; @@ -33,4 +35,11 @@ void should_read_lines_of_file_with_UTF8_charset() { assertThat(linesOf(file, StandardCharsets.UTF_8)).isEqualTo(EXPECTED_CONTENT); } + @Test + void should_read_lines_of_path_with_UTF8_charset() { + Path path = Paths.get("src", "test", "resources", "utf8.txt"); + assertThat(linesOf(path, "UTF-8")).isEqualTo(EXPECTED_CONTENT); + assertThat(linesOf(path, StandardCharsets.UTF_8)).isEqualTo(EXPECTED_CONTENT); + } + } diff --git a/src/test/java/org/assertj/core/api/EntryPointAssertions_linesOf_Test.java b/src/test/java/org/assertj/core/api/EntryPointAssertions_linesOf_Test.java index cd08e81d42..01961575bc 100644 --- a/src/test/java/org/assertj/core/api/EntryPointAssertions_linesOf_Test.java +++ b/src/test/java/org/assertj/core/api/EntryPointAssertions_linesOf_Test.java @@ -18,6 +18,8 @@ import java.io.File; import java.net.URL; import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import java.util.function.BiFunction; import java.util.function.Function; @@ -75,6 +77,51 @@ private static Stream>> fileLinesOfWithDefaultCharse return Stream.of(Assertions::linesOf, BDDAssertions::linesOf, withAssertions::linesOf); } + @ParameterizedTest + @MethodSource("pathLinesOfWithCharsetFunctions") + void should_read_path_lines_with_charset(BiFunction> linesOfWithCharsetFunction) { + // GIVEN + Path sampleFile = Paths.get("src", "test", "resources", "utf8.txt"); + // WHEN + List lines = linesOfWithCharsetFunction.apply(sampleFile, UTF_8); + // THEN + then(lines).containsExactly("A text file encoded in UTF-8, with diacritics:", "é à"); + } + + private static Stream>> pathLinesOfWithCharsetFunctions() { + return Stream.of(Assertions::linesOf, BDDAssertions::linesOf, withAssertions::linesOf); + } + + @ParameterizedTest + @MethodSource("pathLinesOfWithCharsetAsStringFunctions") + void should_read_path_lines_with_charset_as_string(BiFunction> linesOfWithCharsetFunction) { + // GIVEN + Path sampleFile = Paths.get("src", "test", "resources", "utf8.txt"); + // WHEN + List lines = linesOfWithCharsetFunction.apply(sampleFile, "UTF8"); + // THEN + then(lines).containsExactly("A text file encoded in UTF-8, with diacritics:", "é à"); + } + + private static Stream>> pathLinesOfWithCharsetAsStringFunctions() { + return Stream.of(Assertions::linesOf, BDDAssertions::linesOf, withAssertions::linesOf); + } + + @ParameterizedTest + @MethodSource("pathLinesOfWithDefaultCharsetFunctions") + void should_read_path_lines_with_default_charset(Function> linesOfWithDefaultCharsetFunction) { + // GIVEN + Path sampleFile = Paths.get("src", "test", "resources", "ascii.txt"); + // WHEN + List lines = linesOfWithDefaultCharsetFunction.apply(sampleFile); + // THEN + then(lines).containsExactly("abc"); + } + + private static Stream>> pathLinesOfWithDefaultCharsetFunctions() { + return Stream.of(Assertions::linesOf, BDDAssertions::linesOf, withAssertions::linesOf); + } + @ParameterizedTest @MethodSource("urlLinesOfWithCharsetFunctions") void should_read_url_lines_with_charset(BiFunction> linesOfWithCharsetFunction) { diff --git a/src/test/java/org/assertj/core/util/Paths_linesOf_Test.java b/src/test/java/org/assertj/core/util/Paths_linesOf_Test.java new file mode 100644 index 0000000000..60de652057 --- /dev/null +++ b/src/test/java/org/assertj/core/util/Paths_linesOf_Test.java @@ -0,0 +1,96 @@ +/* + * Licensed 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. + * + * Copyright 2012-2022 the original author or authors. + */ +package org.assertj.core.util; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; +import static org.assertj.core.api.Assertions.assertThatNullPointerException; +import static org.assertj.core.util.Lists.newArrayList; +import static org.assertj.core.util.Paths.linesOf; + +import java.io.UncheckedIOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.nio.file.Path; +import java.util.List; + +import org.junit.jupiter.api.Test; + +/** + * Tests for {@link Paths#linesOf(Path, Charset)} and {@link Paths#linesOf(Path, String)}. + * + * @author Stefan Bratanov + * @author Mateusz Haligowski + */ +class Paths_linesOf_Test { + + private static final Path RESOURCES_DIRECTORY = java.nio.file.Paths.get("src", "test", "resources"); + + private static final Path SAMPLE_UNIX_FILE = RESOURCES_DIRECTORY.resolve("utf8.txt"); + private static final Path SAMPLE_WIN_FILE = RESOURCES_DIRECTORY.resolve("utf8_win.txt"); + private static final Path SAMPLE_MAC_FILE = RESOURCES_DIRECTORY.resolve("utf8_mac.txt"); + + private static final List EXPECTED_CONTENT = newArrayList("A text file encoded in UTF-8, with diacritics:", "é à"); + public static final String UTF_8 = "UTF-8"; + + @Test + void should_throw_exception_when_charset_is_null() { + Charset charset = null; + assertThatNullPointerException().isThrownBy(() -> linesOf(SAMPLE_UNIX_FILE, charset)); + } + + @Test + void should_throw_exception_if_charset_name_does_not_exist() { + assertThatIllegalArgumentException().isThrownBy(() -> linesOf(java.nio.file.Paths.get("test"), "Klingon")); + } + + @Test + void should_throw_exception_if_path_not_found() { + Path missingFile = java.nio.file.Paths.get("missing.txt"); + assertThat(missingFile).doesNotExist(); + + assertThatExceptionOfType(UncheckedIOException.class).isThrownBy(() -> linesOf(missingFile, + Charset.defaultCharset())); + } + + @Test + void should_pass_if_unix_path_is_split_into_lines() { + assertThat(linesOf(SAMPLE_UNIX_FILE, StandardCharsets.UTF_8)).isEqualTo(EXPECTED_CONTENT); + } + + @Test + void should_pass_if_unix_path_is_split_into_lines_using_charset() { + assertThat(linesOf(SAMPLE_UNIX_FILE, UTF_8)).isEqualTo(EXPECTED_CONTENT); + } + + @Test + void should_pass_if_windows_path_is_split_into_lines() { + assertThat(linesOf(SAMPLE_WIN_FILE, StandardCharsets.UTF_8)).isEqualTo(EXPECTED_CONTENT); + } + + @Test + void should_pass_if_windows_path_is_split_into_lines_using_charset() { + assertThat(linesOf(SAMPLE_WIN_FILE, UTF_8)).isEqualTo(EXPECTED_CONTENT); + } + + @Test + void should_pass_if_mac_path_is_split_into_lines() { + assertThat(linesOf(SAMPLE_MAC_FILE, StandardCharsets.UTF_8)).isEqualTo(EXPECTED_CONTENT); + } + + @Test + void should_pass_if_mac_path_is_split_into_lines_using_charset() { + assertThat(linesOf(SAMPLE_MAC_FILE, UTF_8)).isEqualTo(EXPECTED_CONTENT); + } +}