diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c507849 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +target +.idea diff --git a/build.sbt b/build.sbt index 873ee7f..7f219ea 100644 --- a/build.sbt +++ b/build.sbt @@ -6,21 +6,21 @@ maintainer := "oggioni.walter@gmail.com" version := "1.0" resolvers += Resolver.mavenLocal +resolvers in ThisBuild += Resolver.jcenterRepo git.useGitDescribe := true crossPaths := false autoScalaLibrary := false -libraryDependencies += "org.projectlombok" % "lombok" % "1.18.8" % Provided +libraryDependencies += "org.projectlombok" % "lombok" % Versions.lombok % Provided -libraryDependencies += "org.slf4j" % "slf4j-api" % "1.7.28" +libraryDependencies += "org.slf4j" % "slf4j-api" % Versions.slf4j -libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test -libraryDependencies += "org.apache.logging.log4j" % "log4j-core" % "2.12.1" % Test -libraryDependencies += "org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.12.1" % Test +libraryDependencies += "net.aichler" % "jupiter-interface" % JupiterKeys.jupiterVersion.value % Test +libraryDependencies += "org.junit.jupiter" % "junit-jupiter-params" % JupiterKeys.junitJupiterVersion.value % Test -javacOptions in (Compile, compile) ++= Seq("-source", "1.8", "-target", "1.8") +javacOptions in (Compile, compile) ++= Seq("--release", "8") Compile / packageBin / packageOptions += Package.ManifestAttributes("Automatic-Module-Name" -> "net.woggioni.jwo") diff --git a/project/build.properties b/project/build.properties index ea6d47b..08e4d79 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.1 +sbt.version=1.4.1 diff --git a/project/build.scala b/project/build.scala new file mode 100644 index 0000000..60dc8bb --- /dev/null +++ b/project/build.scala @@ -0,0 +1,5 @@ +object Versions { + val slf4j = "1.7.30" + val log4j = "2.13.2" + val lombok = "1.18.16" +} \ No newline at end of file diff --git a/project/plugins.sbt b/project/plugins.sbt index feec9a3..92d50ae 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,8 @@ +resolvers += Resolver.jcenterRepo addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0") addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "0.9.3") addSbtPlugin("de.heikoseeberger" % "sbt-header" % "4.1.0") +addSbtPlugin("net.aichler" % "sbt-jupiter-interface" % "0.8.4-SNAPSHOT") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.6") addSbtPlugin("com.thoughtworks.sbt" % "delombokjavadoc" % "1.0.0+66-8fbcf18c") diff --git a/src/main/java/net/woggioni/jwo/JWO.java b/src/main/java/net/woggioni/jwo/JWO.java index f26b051..0313cc1 100644 --- a/src/main/java/net/woggioni/jwo/JWO.java +++ b/src/main/java/net/woggioni/jwo/JWO.java @@ -384,4 +384,13 @@ public class JWO { new Tuple2<>(fileName.substring(0, index), fileName.substring(index))); } } + + public static T dynamicCast(U obj, Class cls) { + if(obj == null) return null; + else if(cls.isInstance(obj.getClass())) { + return (T) obj; + } else { + return null; + } + } } diff --git a/src/main/java/net/woggioni/jwo/cache/LruCache.java b/src/main/java/net/woggioni/jwo/cache/LruCache.java new file mode 100644 index 0000000..36bbd34 --- /dev/null +++ b/src/main/java/net/woggioni/jwo/cache/LruCache.java @@ -0,0 +1,297 @@ +package net.woggioni.jwo.cache; + +import lombok.Getter; +import net.woggioni.jwo.Chronometer; +import net.woggioni.jwo.CollectionUtils; + +import java.util.*; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Stream; + +public class LruCache implements Map { + private final Map linkedHashMap; + private final Object mtx; + private final int maxSize; + private final Function loader; + private final Map fallback; + + @Getter + private Stats stats = new Stats(); + + private final Chronometer chronometer = new Chronometer(); + + public LruCache(int maxSize) { + this(maxSize, false); + } + + public LruCache(int maxSize, boolean threadSafe) { + this(maxSize, threadSafe, null, null); + } + + public LruCache(int maxSize, boolean threadSafe, Function loader) { + this(maxSize, threadSafe, loader, null); + } + + public LruCache(int maxSize, boolean threadSafe, Function loader, Map fallback) { + this.linkedHashMap = new LinkedHashMap<>(); + this.mtx = threadSafe ? linkedHashMap : null; + this.maxSize = maxSize; + if (loader != null) { + if(fallback == null) { + this.loader = (K key) -> { + this.stats.miss++; + return loader.apply(key); + }; + } else { + this.loader = (K key) -> { + this.stats.miss++; + V value = fallback.get(key); + if (value == null) { + return loader.apply(key); + } else { + return value; + } + }; + } + } else { + this.loader = null; + } + this.fallback = fallback; + } + + private T withMutex(Supplier supplier) { + if(mtx != null) { + synchronized (mtx) { + return supplier.get(); + } + } else { + return supplier.get(); + } + } + + @Override + public int size() { + if(fallback == null) { + return withMutex(linkedHashMap::size); + } else { + return withMutex(fallback::size); + } + } + + @Override + public boolean isEmpty() { + return withMutex(linkedHashMap::isEmpty); + } + + @Override + public boolean containsKey(Object key) { + K k; + try { + k = (K) key; + } catch (ClassCastException cce) { + return false; + } + return withMutex(() -> { + boolean result = linkedHashMap.containsKey(key); + if(!result && fallback != null) { + result = fallback.containsKey(key); + } + return result; + }); + } + + @Override + public boolean containsValue(Object value) { + return withMutex(() -> { + boolean result = linkedHashMap.containsValue(value); + if(!result && fallback != null) { + result = fallback.containsValue(value); + } + return result; + }); + } + + private V getOrFallback(K key) { + V value = linkedHashMap.get(key); + if(value == null) { + stats.miss++; + if (fallback != null) { + value = fallback.get(key); + if (value != null) { + linkedHashMap.put(key, value); + } + } + } + return value; + } + + @Override + public V get(Object key) { + K k; + try { + k = (K) key; + } catch (ClassCastException cce) { + return null; + } + return withMutex(() -> { + stats.calls++; + if (loader != null) { + try { + chronometer.reset(); + V result = getOrFallback(k); + if (result == null) { + V newValue; + if ((newValue = loader.apply(k)) != null) { + put(k, newValue); + return newValue; + } + } + stats.loadingTime += chronometer.elapsed(); + return result; + } catch (Exception e) { + stats.exceptions++; + throw e; + } + } else { + return getOrFallback(k); + } + }); + } + + @Override + public V put(K k, V v) { + return withMutex(() -> { + if (linkedHashMap.size() == maxSize) { + Iterator> it = linkedHashMap.entrySet().iterator(); + if (it.hasNext()) { + Map.Entry entry = it.next(); + remove(entry.getKey()); + stats.evictions++; + } + } + if(fallback != null) { + fallback.put(k, v); + } + linkedHashMap.put(k, v); + return v; + }); + } + + @Override + public V remove(Object key) { + return withMutex( () -> { + if(fallback != null) { + V result = fallback.remove(key); + if(result != null) { + linkedHashMap.remove(key); + } + return result; + } else { + return linkedHashMap.remove(key); + } + }); + } + + @Override + public void putAll(Map map) { + for (Map.Entry entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + @Override + public void clear() { + withMutex(() -> { + linkedHashMap.clear(); + if(fallback != null) { + fallback.clear(); + } + return null; + }); + } + + @Override + public Set keySet() { + return withMutex(() -> { + if(fallback == null) { + return linkedHashMap.keySet(); + } else { + return Stream.concat( + linkedHashMap.keySet().stream(), fallback.keySet().stream() + ).collect(CollectionUtils.toUnmodifiableSet()); + } + }); + } + + @Override + public Collection values() { + return withMutex(() -> { + if(fallback == null) { + return linkedHashMap.values(); + } else { + return Stream.concat( + linkedHashMap.values().stream(), fallback.values().stream() + ).collect(CollectionUtils.toUnmodifiableList()); + } + }); + } + + @Override + public Set> entrySet() { + return withMutex(() -> { + if(fallback == null) { + return linkedHashMap.entrySet(); + } else { + return Stream.concat( + linkedHashMap.entrySet().stream(), fallback.entrySet().stream() + ).collect(CollectionUtils.toUnmodifiableSet()); + } + }); + } + + public Stats resetStats() { + return withMutex(() -> { + stats = new Stats(); + return stats; + }); + } + + @Getter + public class Stats { + + private int miss; + + private int calls; + + private int exceptions; + + private int evictions; + + private long loadingTime; + + public int getSize() { + return LruCache.this.size(); + } + + public float getHitRate() { + return (calls - miss) / (float) calls; + } + + public float getAverageLoadingTime(Chronometer.UnitOfMeasure unitOfMeasure) { + return (float) stats.loadingTime / calls / unitOfMeasure.nanoseconds_size; + } + + public float getTotalLoadingTime(Chronometer.UnitOfMeasure unitOfMeasure) { + return (float) stats.loadingTime / unitOfMeasure.nanoseconds_size; + } + + public float getAverageLoadingTime() { + return getAverageLoadingTime(Chronometer.UnitOfMeasure.SECONDS); + } + + public float getTotalLoadingTime() { + return getAverageLoadingTime(Chronometer.UnitOfMeasure.SECONDS); + } + } +} \ No newline at end of file diff --git a/src/test/java/net/woggioni/jwo/JWOTest.java b/src/test/java/net/woggioni/jwo/JWOTest.java index 287cceb..d218a83 100644 --- a/src/test/java/net/woggioni/jwo/JWOTest.java +++ b/src/test/java/net/woggioni/jwo/JWOTest.java @@ -1,8 +1,9 @@ package net.woggioni.jwo; import lombok.SneakyThrows; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; import java.io.*; import java.util.*; @@ -20,22 +21,24 @@ public class JWOTest { if (n > 3) return Optional.of(n); else return Optional.empty(); }).collect(Collectors.toList()); - Assert.assertEquals(Collections.singletonList(4), l); + Assertions.assertEquals(Collections.singletonList(4), l); } @Test public void optional2StreamTest() { Integer integer = 3; Optional s = Optional.of(integer); - JWO.optional2Stream(s).forEach(n -> Assert.assertEquals(integer, n)); + JWO.optional2Stream(s).forEach(n -> Assertions.assertEquals(integer, n)); s = Optional.empty(); - JWO.optional2Stream(s).forEach(n -> Assert.fail()); + JWO.optional2Stream(s).forEach(n -> Assertions.fail( + "Stream should have been empty and this piece of code never executed") + ); } @Test @SneakyThrows public void testRenderTemplate() { - Map valuesMap = new HashMap(); + Map valuesMap = new HashMap<>(); valuesMap.put("author", "John Doe"); valuesMap.put("date", "2020-03-25 16:22"); valuesMap.put("adjective", "simple"); @@ -43,18 +46,18 @@ public class JWOTest { try (Reader reader = new InputStreamReader( JWOTest.class.getResourceAsStream("/render_template_test.txt"))) { String rendered = JWO.renderTemplate(reader, valuesMap); - Assert.assertEquals(expected, rendered); + Assertions.assertEquals(expected, rendered); } try (Reader reader = new InputStreamReader( JWOTest.class.getResourceAsStream("/render_template_test.txt"))) { String rendered = JWO.renderTemplate(JWO.readAll(reader), valuesMap); - Assert.assertEquals(expected, rendered); + Assertions.assertEquals(expected, rendered); } } public static String renderTemplateNaive(String template, Map valuesMap){ - StringBuffer formatter = new StringBuffer(template); + StringBuilder formatter = new StringBuilder(template); Object absent = new Object(); Matcher matcher = Pattern.compile("\\$\\{(\\w+)}").matcher(template); diff --git a/src/test/java/net/woggioni/jwo/Leb128Test.java b/src/test/java/net/woggioni/jwo/Leb128Test.java index 4f70042..f9423de 100644 --- a/src/test/java/net/woggioni/jwo/Leb128Test.java +++ b/src/test/java/net/woggioni/jwo/Leb128Test.java @@ -1,8 +1,8 @@ package net.woggioni.jwo; import lombok.SneakyThrows; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -21,7 +21,7 @@ public class Leb128Test { byte[] bytes = baos.toByteArray(); Leb128.Leb128Decoder decoder = new Leb128.Leb128Decoder(new ByteArrayInputStream(bytes)); - numbers.forEach(n -> Assert.assertEquals((long) n, decoder.decode())); + numbers.forEach(n -> Assertions.assertEquals((long) n, decoder.decode())); } @Test @@ -36,14 +36,14 @@ public class Leb128Test { byte[] bytes = baos.toByteArray(); Leb128.Leb128Decoder decoder = new Leb128.Leb128Decoder(new ByteArrayInputStream(bytes)); - numbers.forEach(n -> Assert.assertEquals(n, decoder.decodeDouble(), 0.0)); + numbers.forEach(n -> Assertions.assertEquals(n, decoder.decodeDouble(), 0.0)); } @Test public void reverseTest() { long n = 101325; - Assert.assertEquals(n, Leb128.reverse(Leb128.reverse(n))); + Assertions.assertEquals(n, Leb128.reverse(Leb128.reverse(n))); } @Test @@ -55,7 +55,7 @@ public class Leb128Test { try(ByteArrayOutputStream os = new ByteArrayOutputStream()) { Leb128.encode(os, reverse); byte[] bytes = os.toByteArray(); - Assert.assertEquals(3, bytes.length); + Assertions.assertEquals(3, bytes.length); } } } diff --git a/src/test/java/net/woggioni/jwo/cache/LruCacheTest.java b/src/test/java/net/woggioni/jwo/cache/LruCacheTest.java new file mode 100644 index 0000000..12e12df --- /dev/null +++ b/src/test/java/net/woggioni/jwo/cache/LruCacheTest.java @@ -0,0 +1,178 @@ +package net.woggioni.jwo.cache; + +import lombok.EqualsAndHashCode; +import lombok.SneakyThrows; +import net.woggioni.jwo.JWO; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.Serializable; +import java.security.MessageDigest; +import java.util.*; +import java.util.function.Function; + +@EqualsAndHashCode +class RandomObject implements Serializable { + @EqualsAndHashCode.Include + UUID uuid = UUID.randomUUID(); + + String name = uuid.toString(); + + String md5 = md5(name); + + String md5half1 = md5.substring(0, 16); + + String md5half2 = md5.substring(16); + + @SneakyThrows + private String md5(String source) { + MessageDigest md = MessageDigest.getInstance("MD5"); + md.update(source.getBytes()); + byte[] digest = md.digest(); + return JWO.bytesToHex(digest); + } +} + +public class LruCacheTest { + + private static final int CACHE_MAX_SIZE = 50; + private static final int NUMBER_OF_ENTRIES = 100; + + int loaderInvocations = 0; + List objects; + + LruCache lruCache; + + @AfterEach + public void teardown() { + lruCache.clear(); + } + + @Test + public void cacheWithoutFallbackAndLoader() { + lruCache = new LruCache<>(CACHE_MAX_SIZE, true); + objects = new ArrayList<>(); + for (int i = 0; i < NUMBER_OF_ENTRIES; i++) { + RandomObject randomObject = new RandomObject(); + lruCache.put(randomObject.name, randomObject); + objects.add(randomObject); + } + + //Since NUMBER_OF_ENTRIES > CACHE_MAX_SIZE the cache size should have reached its maximum + Assertions.assertEquals(CACHE_MAX_SIZE, lruCache.size()); + + // The cache should not contain any of the first NUMBER_OF_ENTRIES - CACHE_MAX_SIZE elements (they should have been evicted) + objects.stream().limit(NUMBER_OF_ENTRIES - CACHE_MAX_SIZE) + .forEach(value -> Assertions.assertFalse(lruCache.containsKey(value.name))); + + // The cache should contain all the CACHE_MAX_SIZE elements that were last inserted + objects.stream().skip(CACHE_MAX_SIZE) + .peek(value -> Assertions.assertTrue(lruCache.containsKey(value.name))) + .forEach(value -> Assertions.assertEquals(value, lruCache.get(value.name))); + + //Removing the first inserted element should be a no-op since it should have been already evicted + RandomObject randomObject = objects.get(0); + Assertions.assertNull(lruCache.remove(randomObject.name)); + Assertions.assertFalse(lruCache.containsKey(randomObject.name)); + Assertions.assertEquals(CACHE_MAX_SIZE, lruCache.size()); + + //Removing the last inserted element should return it and decrease the cache size by 1 + randomObject = objects.get(objects.size() - 1); + Assertions.assertEquals(randomObject, lruCache.remove(randomObject.name)); + Assertions.assertFalse(lruCache.containsKey(randomObject.name)); + Assertions.assertEquals(CACHE_MAX_SIZE - 1, lruCache.size()); + + //Clearing the cache should reduce its size to 0 + lruCache.clear(); + Assertions.assertEquals(0, lruCache.size()); + } + + @Test + public void cacheWithFallback() { + Map fallback = new HashMap<>(); + lruCache = new LruCache<>(CACHE_MAX_SIZE, true, null, fallback); + objects = new ArrayList<>(); + for (int i = 0; i < NUMBER_OF_ENTRIES; i++) { + RandomObject randomObject = new RandomObject(); + fallback.put(randomObject.name, randomObject); + objects.add(randomObject); + } + + //The cache should contain all the elements that were inserted in the fallback map + objects.forEach(value -> Assertions.assertTrue(lruCache.containsKey(value.name))); + + //The cache size should be equal to the number of inserted elements + Assertions.assertEquals(NUMBER_OF_ENTRIES, lruCache.size()); + + //Removing the first inserted element should return it and decrease the cache size by 1 + RandomObject randomObject = objects.get(0); + Assertions.assertEquals(randomObject, lruCache.remove(randomObject.name)); + Assertions.assertFalse(lruCache.containsKey(randomObject.name)); + Assertions.assertEquals(NUMBER_OF_ENTRIES - 1, lruCache.size()); + + //Clearing the cache should reduce its size to 0 + lruCache.clear(); + Assertions.assertEquals(0, lruCache.size()); + } + + @Test + public void cacheWithLoader() { + Function loader = key -> { + loaderInvocations++; + return objects.stream().filter(o -> Objects.equals(key, o.name)).findFirst().get(); + }; + lruCache = new LruCache<>(CACHE_MAX_SIZE, true, loader); + LruCache.Stats stats = lruCache.getStats(); + objects = new ArrayList<>(); + for (int i = 0; i < NUMBER_OF_ENTRIES; i++) { + RandomObject randomObject = new RandomObject(); + objects.add(randomObject); + lruCache.put(randomObject.name, randomObject); + } + + //Since NUMBER_OF_ENTRIES > CACHE_MAX_SIZE the cache size should have reached its maximum + Assertions.assertEquals(CACHE_MAX_SIZE, lruCache.size()); + + int evictionsAfterLoad = stats.getEvictions(); + int loaderInvocations = this.loaderInvocations; + // The cache should contain all the CACHE_MAX_SIZE elements that were last inserted without loading any with the loader + objects.stream().skip(CACHE_MAX_SIZE) + .peek(value -> Assertions.assertTrue(lruCache.containsKey(value.name))) + .forEach(value -> Assertions.assertEquals(value, lruCache.get(value.name))); + // Since the entries were already present in the cache, no new invocation of the loader should have been performed, + // nor any new eviction should have occurred + Assertions.assertEquals(evictionsAfterLoad, stats.getEvictions()); + Assertions.assertEquals(loaderInvocations, this.loaderInvocations); + + // The cache should not contain any of the first NUMBER_OF_ENTRIES - CACHE_MAX_SIZE elements + int evictedElements = NUMBER_OF_ENTRIES - CACHE_MAX_SIZE; + objects.stream().limit(evictedElements) + .forEach(value -> Assertions.assertFalse(lruCache.containsKey(value.name))); + + // Calling "get" for entries that were not present in the cache, should trigger a new invocation of the loader + // for each of them, and, since the cache was full, an equal number of evictions should occurr + evictionsAfterLoad = stats.getEvictions(); + loaderInvocations = this.loaderInvocations; + objects.stream().limit(evictedElements) + .forEach(value -> lruCache.get(value.name)); + Assertions.assertEquals(evictionsAfterLoad + evictedElements, stats.getEvictions()); + Assertions.assertEquals(loaderInvocations + evictedElements, this.loaderInvocations); + + //Removing the last inserted element should be a no-op since it should have been already evicted + RandomObject randomObject = objects.get(objects.size() - 1); + Assertions.assertNull(lruCache.remove(randomObject.name)); + Assertions.assertFalse(lruCache.containsKey(randomObject.name)); + Assertions.assertEquals(CACHE_MAX_SIZE, lruCache.size()); + + //Removing the first inserted element should return it and decrease the cache size by 1 + randomObject = objects.get(0); + Assertions.assertEquals(randomObject, lruCache.remove(randomObject.name)); + Assertions.assertFalse(lruCache.containsKey(randomObject.name)); + Assertions.assertEquals(CACHE_MAX_SIZE - 1, lruCache.size()); + + //Clearing the cache should reduce its size to 0 + lruCache.clear(); + Assertions.assertEquals(0, lruCache.size()); + } +} \ No newline at end of file diff --git a/src/test/java/net/woggioni/jwo/compression/CompressionOutputStreamTest.java b/src/test/java/net/woggioni/jwo/compression/CompressionOutputStreamTest.java index e06765f..ae21f74 100644 --- a/src/test/java/net/woggioni/jwo/compression/CompressionOutputStreamTest.java +++ b/src/test/java/net/woggioni/jwo/compression/CompressionOutputStreamTest.java @@ -1,38 +1,31 @@ package net.woggioni.jwo.compression; -import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import net.woggioni.jwo.JWO; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import java.io.*; import java.security.DigestInputStream; import java.security.MessageDigest; import java.util.Arrays; -import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; -@RequiredArgsConstructor -@RunWith(Parameterized.class) public class CompressionOutputStreamTest { - @Parameterized.Parameters(name = "Format {0}, level {1}") - public static Iterable data() { + private static Stream testParameters() { return Arrays.stream(CompressionFormat.values()) .filter(format -> JWO.which(format.executable).isPresent()) - .flatMap(v -> IntStream.of(1, 3, 5, 7, 9).mapToObj(l -> new Object[]{v, l})) - .collect(Collectors.toList()); + .flatMap(v -> IntStream.of(1, 3, 5, 7, 9).mapToObj(l -> Arguments.of(v, l))); } - private final CompressionFormat compressionFormat; - private final int level; - - @Test @SneakyThrows - public void test() { + @ParameterizedTest + @MethodSource("testParameters") + public void test(CompressionFormat compressionFormat, int level) { MessageDigest inputDigest = MessageDigest.getInstance("MD5"); byte[] compressed; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); @@ -55,6 +48,6 @@ public class CompressionOutputStreamTest { byte[] buffer = new byte[1024]; while(is.read(buffer, 0, buffer.length) >= 0) {} } - Assert.assertArrayEquals(inputDigest.digest(), outputDigest.digest()); + Assertions.assertArrayEquals(inputDigest.digest(), outputDigest.digest()); } } diff --git a/src/test/java/net/woggioni/jwo/io/CircularBufferTest.java b/src/test/java/net/woggioni/jwo/io/CircularBufferTest.java index 278d70a..861e69d 100644 --- a/src/test/java/net/woggioni/jwo/io/CircularBufferTest.java +++ b/src/test/java/net/woggioni/jwo/io/CircularBufferTest.java @@ -1,9 +1,8 @@ package net.woggioni.jwo.io; import lombok.SneakyThrows; -import net.woggioni.jwo.io.CircularBuffer; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import java.io.InputStream; import java.io.InputStreamReader; @@ -28,10 +27,8 @@ public class CircularBufferTest { } else { char c = (char) b; outputDigest.update((byte) b); - System.out.print(c); } } - System.out.println(); - Assert.assertArrayEquals(streamDigest.digest(), outputDigest.digest()); + Assertions.assertArrayEquals(streamDigest.digest(), outputDigest.digest()); } } diff --git a/src/test/java/net/woggioni/jwo/tree/TreeWalkerTest.java b/src/test/java/net/woggioni/jwo/tree/TreeWalkerTest.java index 7a70f0c..04160b9 100644 --- a/src/test/java/net/woggioni/jwo/tree/TreeWalkerTest.java +++ b/src/test/java/net/woggioni/jwo/tree/TreeWalkerTest.java @@ -3,8 +3,8 @@ package net.woggioni.jwo.tree; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.woggioni.jwo.tuple.Tuple2; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import java.util.*; import java.util.function.Function; @@ -60,24 +60,24 @@ public class TreeWalkerTest { TreeNodeVisitor nodeVisitor = new TreeNodeVisitor() { @Override public VisitOutcome visitPre(List> stackContextList) { - Assert.assertTrue(it_pre.hasNext()); - Assert.assertEquals(it_pre.next(), + Assertions.assertTrue(it_pre.hasNext()); + Assertions.assertEquals(it_pre.next(), stackContextList.get(stackContextList.size() - 1).getNode().getId()); return VisitOutcome.CONTINUE; } @Override public void visitPost(List> stackContextList) { - Assert.assertTrue(it_post.hasNext()); - Assert.assertEquals(it_post.next(), + Assertions.assertTrue(it_post.hasNext()); + Assertions.assertEquals(it_post.next(), stackContextList.get(stackContextList.size() - 1).getNode().getId()); } }; TreeWalker walker = new TreeWalker<>(nodeVisitor); walker.walk(testNodeMap.get(1)); - Assert.assertFalse(it_pre.hasNext()); - Assert.assertFalse(it_post.hasNext()); + Assertions.assertFalse(it_pre.hasNext()); + Assertions.assertFalse(it_post.hasNext()); } @Test @@ -88,9 +88,9 @@ public class TreeWalkerTest { TreeNodeVisitor linkVisitor = new TreeNodeVisitor() { @Override public VisitOutcome visitPre(List> nodePath) { - Assert.assertTrue(it.hasNext()); + Assertions.assertTrue(it.hasNext()); Integer id = nodePath.get(nodePath.size() - 1).getNode().getId(); - Assert.assertEquals(it.next(), id); + Assertions.assertEquals(it.next(), id); if(Objects.equals(4, nodePath.get(nodePath.size() - 1).getNode().getId())) { return VisitOutcome.SKIP; } else { @@ -101,6 +101,6 @@ public class TreeWalkerTest { TreeWalker walker = new TreeWalker<>(linkVisitor); walker.walk(testNodeMap.get(1)); - Assert.assertFalse(it.hasNext()); + Assertions.assertFalse(it.hasNext()); } }