diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2c905ec --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +# commons-lang 0.1.0 (2019-01-12) + +### Features + +* `FileCommons` utility class for I/O and filesystem handling +* `Composite` utility class for related design pattern +* `getEnclosingClasses()` method to `ReflectiveCommons` +* `singleQuote()`, `doubleQuote()` and `quote()` methods to `StringCommons` +* **tests:** Switch to JaCoCo for test reporting +* **chore:** Add `CHANGELOG` and `CODEOWNERS` files +* **build:** Add test coverage constraints +* **build:** Add `docs` and `ossrh` Maven profiles + +# commons-lang 0.0.1 (2018-08-18) + +### Features + +* `StringCommons` utility class for manipulating strings +* `ReflectiveCommons` utility class for reflection diff --git a/CHANGELOG_LATEST.md b/CHANGELOG_LATEST.md new file mode 100644 index 0000000..29b8049 --- /dev/null +++ b/CHANGELOG_LATEST.md @@ -0,0 +1,12 @@ +# commons-lang 0.1.0 + +### Features + +* `FileCommons` utility class for I/O and filesystem handling +* `Composite` utility class for related design pattern +* `getEnclosingClasses()` method to `ReflectiveCommons` +* `singleQuote()`, `doubleQuote()` and `quote()` methods to `StringCommons` +* **tests:** Switch to JaCoCo for test reporting +* **chore:** Add `CHANGELOG` and `CODEOWNERS` files +* **build:** Add test coverage constraints +* **build:** Add `docs` and `ossrh` Maven profiles diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..4152899 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @daniloarcidiacono diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8696066 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Danilo Arcidiacono + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 58556e5..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2018-2018 Danilo Arcidiacono, https://github.com/daniloarcidiacono/commons-lang - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index e69de29..857e620 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,6 @@ +[![Maven Central](https://img.shields.io/maven-central/v/io.github.daniloarcidiacono/commons-lang.svg?label=Maven%20Central)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22io.github.daniloarcidiacono%22%20a%3A%22commons-lang%22) +[![codecov](https://codecov.io/gh/daniloarcidiacono/commons-lang/branch/dev/graph/badge.svg)](https://codecov.io/gh/daniloarcidiacono/commons-lang) +[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) + +# Java language utilities + diff --git a/pom.xml b/pom.xml index c995a47..3691cd3 100644 --- a/pom.xml +++ b/pom.xml @@ -3,43 +3,39 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 + io.github.daniloarcidiacono commons-lang - 0.0.1 + 0.1.0 jar Java Language utilities Java Language utilities http://github.com/daniloarcidiacono/commons-lang + MIT License http://www.opensource.org/licenses/mit-license.php + Danilo Arcidiacono danilo.arcidiacono@gmail.com + scm:git:git@github.com:daniloarcidiacono/commons-lang.git scm:git:git@github.com:daniloarcidiacono/commons-lang.git https://github.com/daniloarcidiacono/commons-lang.git + https://github.com/daniloarcidiacono/commons-lang - - - ossrh - https://oss.sonatype.org/content/repositories/snapshots - - - ossrh - https://oss.sonatype.org/service/local/staging/deploy/maven2/ - - + UTF-8 1.8 @@ -47,15 +43,21 @@ 5.2.0 1.2.0 + 1.3.0 3.7.0 - 2.21.0 + 2.22.0 3.0.1 - 2.10.4 - 1.6 - 2.5.3 + 2.7 + 0.8.2 + + + + 0.80 + 0.50 + @@ -67,13 +69,143 @@ + org.junit.jupiter junit-jupiter-engine test + + + com.github.marschall + memoryfilesystem + ${memoryfilesystem.version} + test + + + + + docs + + + 2.10.4 + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${maven-javadoc.plugin.version} + + + attach-javadocs + + jar + + + + + + + + + + ossrh + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + 1.6.8 + 1.6 + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${maven-gpg.plugin.version} + + + sign-artifacts + verify + + sign + + + + + + + + maven-deploy-plugin + + true + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${nexus-staging-maven.plugin.version} + true + + ossrh + https://oss.sonatype.org/ + + + + + + + + deploy-to-sonatype + deploy + + deploy + + + + + + + + + + + @@ -102,21 +234,6 @@ - - - org.apache.maven.plugins - maven-javadoc-plugin - ${maven-javadoc.plugin.version} - - - attach-javadocs - - jar - - - - - maven-surefire-plugin @@ -130,28 +247,65 @@ - + - org.apache.maven.plugins - maven-release-plugin - ${maven-release.plugin.version} - - - - - org.apache.maven.plugins - maven-gpg-plugin - ${maven-gpg.plugin.version} + org.jacoco + jacoco-maven-plugin + ${jacoco.plugin.version} - sign-artifacts - verify + default-prepare-agent - sign + prepare-agent + + + default-report + + report + + + + + + default-check + + check + + + + + + CLASS + + + LINE + COVEREDRATIO + ${line.coverage.ratio} + + + BRANCH + COVEREDRATIO + ${branch.coverage.ratio} + + + + + + + + + + org.codehaus.mojo + versions-maven-plugin + ${versions-maven.plugin.version} + \ No newline at end of file diff --git a/src/main/java/io/github/daniloarcidiacono/commons/lang/FileCommons.java b/src/main/java/io/github/daniloarcidiacono/commons/lang/FileCommons.java new file mode 100644 index 0000000..6e2ff53 --- /dev/null +++ b/src/main/java/io/github/daniloarcidiacono/commons/lang/FileCommons.java @@ -0,0 +1,67 @@ +package io.github.daniloarcidiacono.commons.lang; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.Scanner; + +/** + * Miscellaneous Java file utility methods. + */ +public abstract class FileCommons { + /** + * Deletes Folder with all of its content. + * Symbolic links are NOT followed. + * @param folder path to folder which should be deleted + * @throws IOException + */ + public static void deleteFolder(final Path folder) throws IOException { + if (!Files.exists(folder) || !Files.isDirectory(folder)) { + return; + } + + // https://docs.oracle.com/javase/tutorial/essential/io/walk.html + // By default, walkFileTree does not follow symbolic links. + Files.walkFileTree(folder, new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + // TODO: Find a way to test this branch and increase the branch.coverage.ratio to 0.80 + if (exc != null) { + throw exc; + } + + Files.delete(dir); + return FileVisitResult.CONTINUE; + } + }); + } + + /** + * Reads a text file from the given path. + * @see Utils to read resource text file to String (Java) + * @param path the path to load + * @return the file content, or null if could not be loaded. + */ + public static String loadResource(final String path) { + final InputStream resourceAsStream = FileCommons.class.getClassLoader().getResourceAsStream(path); + if (resourceAsStream == null) { + return null; + } + + final Scanner scanner = new Scanner(resourceAsStream, "UTF-8").useDelimiter("\\A"); + + if (scanner.hasNext()) { + return scanner.next(); + } + + // Using scanner.next() on empty files throws NoSuchElementException + return ""; + } +} diff --git a/src/main/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommons.java b/src/main/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommons.java index 0a34dd6..a24d13e 100644 --- a/src/main/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommons.java +++ b/src/main/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommons.java @@ -8,8 +8,6 @@ /** * Miscellaneous Java Reflection utility methods. - * - * @author Danilo Arcidiacono */ public abstract class ReflectiveCommons { /** @@ -38,4 +36,21 @@ public static List getMethodsAnnotatedWith(final Class type, final Cl return methods; } + + /** + * Returns the list of the classes enclosing the specified class. + * @param clazz the starting class + * @return the list of the classes enclosing the specified class. + */ + public static List> getEnclosingClasses(final Class clazz) { + final List> enclosingClasses = new ArrayList<>(); + + Class current = clazz; + do { + enclosingClasses.add(0, current); + current = current.getEnclosingClass(); + } while (current != null); + + return enclosingClasses; + } } diff --git a/src/main/java/io/github/daniloarcidiacono/commons/lang/StringCommons.java b/src/main/java/io/github/daniloarcidiacono/commons/lang/StringCommons.java index 59434c0..d896313 100644 --- a/src/main/java/io/github/daniloarcidiacono/commons/lang/StringCommons.java +++ b/src/main/java/io/github/daniloarcidiacono/commons/lang/StringCommons.java @@ -7,8 +7,6 @@ *

This class delivers some simple functionality that should really be * provided by the core Java {@link String} and {@link StringBuilder} * classes. - * - * @author Danilo Arcidiacono */ public abstract class StringCommons { /** @@ -85,4 +83,16 @@ public static String listToString(final Iterable collection) { sb.append(" }"); return sb.toString(); } + + public static String singleQuote(final String str) { + return quote(str,"'"); + } + + public static String doubleQuote(final String str) { + return quote(str,"\""); + } + + public static String quote(final String str, final String quote) { + return quote + str + quote; + } } diff --git a/src/main/java/io/github/daniloarcidiacono/commons/lang/patterns/Composite.java b/src/main/java/io/github/daniloarcidiacono/commons/lang/patterns/Composite.java new file mode 100644 index 0000000..2284a54 --- /dev/null +++ b/src/main/java/io/github/daniloarcidiacono/commons/lang/patterns/Composite.java @@ -0,0 +1,161 @@ +package io.github.daniloarcidiacono.commons.lang.patterns; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * Base class for an object which aggregates a list of elements. + * @param type of the component + */ +public class Composite { + protected List components = new ArrayList<>(); + + public Composite() { + } + + public Composite(final Collection component) { + components.addAll(component); + } + + public Composite(final T ...component) { + Collections.addAll(components, component); + } + + public Composite add(final T component) { + components.add(component); + return this; + } + + public Composite add(final T ...component) { + Collections.addAll(components, component); + return this; + } + + /** + * Adds a component before the specified one. + *

If the specified component is not found, the component is not added. + * + * @param before the component to search for + * @param component the component to add + * @return the class instance, for chaining calls + */ + public Composite addBefore(final T before, final T component) { + final int index = components.indexOf(before); + if (index != -1) { + components.add(index, component); + } + + return this; + } + + /** + * Adds a component after the specified one. + *

If the specified component is not found, the component is not added. + * + * @param after the component to search for + * @param component the component to add + * @return the class instance, for chaining calls + */ + public Composite addAfter(final T after, final T component) { + final int index = components.indexOf(after); + if (index != -1) { + components.add(index + 1, component); + } + + return this; + } + + /** + * Multi-component variant of {@link #addBefore(Object, Object)} + * @param before the component to search for + * @param component the components to add + * @return the class instance, for chaining calls + */ + public Composite addBefore(final T before, final T ...component) { + int index = components.indexOf(before); + if (index != -1) { + for (T t : component) { + components.add(index, t); + index++; + } + } + + return this; + } + + /** + * Multi-component variant of {@link #addAfter(Object, Object)} + * @param after the component to search for + * @param component the components to add + * @return the class instance, for chaining calls + */ + public Composite addAfter(final T after, final T ...component) { + int index = components.indexOf(after); + if (index != -1) { + for (T t : component) { + components.add(index + 1, t); + index++; + } + } + + return this; + } + + /** + * Removes every component. + * @return the class instance, for chaining calls + */ + public Composite removeAll() { + components.clear(); + return this; + } + + /** + * Removes the specified component. + * @param component the component to remove. + * @return the class instance, for chaining calls + */ + public Composite remove(final T component) { + components.remove(component); + return this; + } + + /** + * Removes a set of components. + * @param component the components to remoev + * @return the class instance, for chaining calls + */ + public Composite remove(final T ...component) { + for (T t : component) { + components.remove(t); + } + + return this; + } + + /** + * Searches for the component having the specified type. + * @param clazz the return type class + * @param the return type + * @return the first component having the specified type, or null if it is not found. + */ + public U get(final Class clazz) { + for (T component : components) { + if (component != null && component.getClass().equals(clazz)) { + return (U)component; + } + } + + return null; + } + + /** + * Returns the list of components. + * @return the list of components. + */ + public List getComponents() { + return components; + } +} diff --git a/src/test/java/io/github/daniloarcidiacono/commons/lang/FileCommonsTest.java b/src/test/java/io/github/daniloarcidiacono/commons/lang/FileCommonsTest.java new file mode 100644 index 0000000..dbb0374 --- /dev/null +++ b/src/test/java/io/github/daniloarcidiacono/commons/lang/FileCommonsTest.java @@ -0,0 +1,80 @@ +package io.github.daniloarcidiacono.commons.lang; + +import com.github.marschall.memoryfilesystem.MemoryFileSystemBuilder; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.*; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * Tests for {@link FileCommons} class. + * @see jdk8u-jdk: CreateFileTree utility class + */ +class FileCommonsTest { + @Test + void deleteFolder() throws IOException { + try (final FileSystem fs = MemoryFileSystemBuilder.newEmpty().build()) { + // Try to delete a non existing folder (must do nothing) + FileCommons.deleteFolder(fs.getPath("not_existing")); + + // Create the folder that will be deleted + final Path testFolder = fs.getPath("/test"); + Files.createDirectories(testFolder); + Files.createFile(fs.getPath("/test/file1.txt")); + Files.createFile(fs.getPath("/test/file2.txt")); + Files.createFile(fs.getPath("/test/file3.txt")); + + // Create another folder + final Path otherFolder = fs.getPath("/other"); + Files.createDirectories(otherFolder); + Files.createFile(fs.getPath("/other/file1.txt")); + + // Create some symbolic links + Files.createSymbolicLink(fs.getPath("/test/file1_link.txt"), fs.getPath("/other/file1.txt")); + Files.createSymbolicLink(fs.getPath("/test/other_link"), fs.getPath("/other")); + + // Delete the folder + FileCommons.deleteFolder(testFolder); + + // Try to delete a file (must do nothing) + FileCommons.deleteFolder(fs.getPath("/other/file1.txt")); + + // https://docs.oracle.com/javase/tutorial/essential/io/walk.html + // By default, walkFileTree does not follow symbolic links. + final List paths = new ArrayList<>(); + Files.walkFileTree(fs.getPath("/"), new SimpleFileVisitor() { + @Override + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + paths.add(file.toString()); + return FileVisitResult.CONTINUE; + } + + + @Override + public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { + paths.add(dir.toString()); + return FileVisitResult.CONTINUE; + } + }); + + assertEquals( + Arrays.asList("/", "/other", "/other/file1.txt"), + paths, + "Symbolic links should not be followed" + ); + } + } + + @Test + void loadResource() { + assertEquals("test file content", FileCommons.loadResource("test.txt")); + assertEquals("", FileCommons.loadResource("test_empty.txt")); + assertEquals(null, FileCommons.loadResource("test_not_existing.txt")); + } +} \ No newline at end of file diff --git a/src/test/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommonsTest.java b/src/test/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommonsTest.java index 91d7eb7..417d3a7 100644 --- a/src/test/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommonsTest.java +++ b/src/test/java/io/github/daniloarcidiacono/commons/lang/ReflectiveCommonsTest.java @@ -4,15 +4,15 @@ import java.lang.annotation.*; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.List; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; /** * Tests for {@link ReflectiveCommons} class. - * - * @author Danilo Arcidiacono */ class ReflectiveCommonsTest { @Retention(RetentionPolicy.RUNTIME) @@ -70,4 +70,12 @@ void getMethodsAnnotatedWith() throws NoSuchMethodException { "Methods without the specified annotation are not picked" ); } + + @Test + void getEnclosingClasses() { + assertEquals( + Arrays.asList(ReflectiveCommonsTest.class, Base.class), + ReflectiveCommons.getEnclosingClasses(Base.class) + ); + } } \ No newline at end of file diff --git a/src/test/java/io/github/daniloarcidiacono/commons/lang/StringCommonsTest.java b/src/test/java/io/github/daniloarcidiacono/commons/lang/StringCommonsTest.java index 2289b1c..23ceaea 100644 --- a/src/test/java/io/github/daniloarcidiacono/commons/lang/StringCommonsTest.java +++ b/src/test/java/io/github/daniloarcidiacono/commons/lang/StringCommonsTest.java @@ -8,8 +8,6 @@ /** * Tests for {@link StringCommons} class. - * - * @author Danilo Arcidiacono */ class StringCommonsTest { @Test @@ -39,4 +37,11 @@ void listToString() { assertEquals(StringCommons.listToString(Arrays.asList( "first" )), "{ first }"); assertEquals(StringCommons.listToString(Arrays.asList( "first", "second" )), "{ first, second }"); } + + @Test + void quotes() { + assertEquals(StringCommons.singleQuote("test"), "'test'"); + assertEquals(StringCommons.doubleQuote("test"), "\"test\""); + assertEquals(StringCommons.quote("test", "*"), "*test*"); + } } \ No newline at end of file diff --git a/src/test/java/io/github/daniloarcidiacono/commons/lang/patterns/CompositeTest.java b/src/test/java/io/github/daniloarcidiacono/commons/lang/patterns/CompositeTest.java new file mode 100644 index 0000000..59020c3 --- /dev/null +++ b/src/test/java/io/github/daniloarcidiacono/commons/lang/patterns/CompositeTest.java @@ -0,0 +1,108 @@ +package io.github.daniloarcidiacono.commons.lang.patterns; + +import org.junit.jupiter.api.Test; +import java.util.Arrays; +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests for {@link Composite} class. + */ +class CompositeTest { + @Test + public void testAddBefore() { + final Composite composite = new Composite<>(); + composite.add(2); + composite.add(3); + composite.addBefore(2, 1); + composite.addBefore(1000, 10); + + assertEquals( + Arrays.asList(1, 2, 3), + composite.getComponents() + ); + + composite.addBefore(1, -3, -2, -1, 0); + composite.addBefore(1000, -3, -2, -1, 0); + + assertEquals( + Arrays.asList(-3, -2, -1, 0, 1, 2, 3), + composite.getComponents() + ); + } + + @Test + public void testAddAfter() { + final Composite composite = new Composite<>(); + composite.add(1); + composite.add(2); + composite.add(10); + composite.addAfter(2, 3); + composite.addAfter(1000, 10); + + assertEquals( + Arrays.asList(1, 2, 3, 10), + composite.getComponents() + ); + + composite.addAfter(3, 4, 5, 6, 7, 8, 9); + composite.addAfter(1000, 4, 5, 6, 7, 8, 9); + + assertEquals( + Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), + composite.getComponents() + ); + } + + @Test + public void testRemove() { + final Composite composite = new Composite<>(); + composite.add(1, 2, 3); + composite.remove(2); + + assertEquals( + Arrays.asList(1, 3), + composite.getComponents() + ); + + composite.removeAll(); + assertTrue(composite.getComponents().isEmpty()); + } + + @Test + public void testMultiRemove() { + final Composite composite = new Composite<>( + Arrays.asList(1, 2, 3, 4, 5) + ); + + composite.remove(2, 4); + assertEquals( + Arrays.asList(1, 3, 5), + composite.getComponents() + ); + } + + private static class Base { + } + + private static class DerivedA extends Base { + } + + private static class DerivedB extends Base { + } + + private static class DerivedC extends Base { + } + + @Test + public void testGet() { + final Base a = new Base(); + final Base b = new DerivedA(); + final Base c = new DerivedB(); + final Composite composite = new Composite<>(a, b, c, null); + + assertEquals(composite.get(Base.class), a); + assertEquals(composite.get(DerivedA.class), b); + assertEquals(composite.get(DerivedB.class), c); + assertEquals(composite.get(DerivedC.class), null); + } +} \ No newline at end of file diff --git a/src/test/resources/test.txt b/src/test/resources/test.txt new file mode 100644 index 0000000..2211df3 --- /dev/null +++ b/src/test/resources/test.txt @@ -0,0 +1 @@ +test file content \ No newline at end of file diff --git a/src/test/resources/test_empty.txt b/src/test/resources/test_empty.txt new file mode 100644 index 0000000..e69de29