From 9155b9757ca4f77b854416afee776306dc86f3b8 Mon Sep 17 00:00:00 2001 From: javasabr Date: Thu, 30 Oct 2025 08:58:22 +0100 Subject: [PATCH 1/8] continue updating API --- .../java/javasabr/rlib/collections/array/Array.java | 2 +- .../dictionary/MutableRefToRefDictionary.java | 3 --- .../src/main/java/javasabr/rlib/logger/api/Logger.java | 10 +++++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java index d2d76d59..ed24bafc 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java @@ -16,7 +16,7 @@ /** * @author JavaSaBr */ -public interface Array extends Iterable, Serializable, Cloneable, RandomAccess { +public interface Array extends Iterable, Serializable, Cloneable { static Array empty(Class type) { return new ImmutableArray<>(ClassUtils.unsafeCast(type)); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java index a88dba5c..5f6d7419 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java @@ -14,13 +14,10 @@ static MutableRefToRefDictionary ofTypes( return new DefaultMutableHashBasedRefToRefDictionary<>(); } - @Nullable V getOrCompute(K key, Supplier factory); - @Nullable V getOrCompute(K key, Function factory); - @Nullable V getOrCompute(K key, T arg1, Function factory); /** diff --git a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java index c439a8a0..a42775b0 100644 --- a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java +++ b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java @@ -137,11 +137,15 @@ default void debug(A arg1, B arg2, C arg3, @NonNull N3Factory print(LoggerLevel.DEBUG, arg1, arg2, arg3, factory); } + default void debug(A arg1, B arg2, C arg3, D arg4, @NonNull N4Factory factory) { + print(LoggerLevel.DEBUG, arg1, arg2, arg3, arg4, factory); + } + default void debug(A arg1, int arg2, C arg3, @NonNull N1IntN1Factory factory) { print(LoggerLevel.DEBUG, arg1, arg2, arg3, factory); } - default void debug(A arg1, int arg2, int arg3, @NonNull N1Int2Factory factory) { + default void debug(A arg1, int arg2, int arg3, @NonNull N1Int2Factory factory) { print(LoggerLevel.DEBUG, arg1, arg2, arg3, factory); } @@ -252,6 +256,10 @@ default void warning(A arg1, B arg2, @NonNull N2Factory factory) { print(LoggerLevel.WARNING, arg1, arg2, factory); } + default void warning(A arg1, int arg2, @NonNull N1IntFactory factory) { + print(LoggerLevel.WARNING, arg1, arg2, factory); + } + default void warning(A arg1, B arg2, C arg3, @NonNull N3Factory factory) { print(LoggerLevel.WARNING, arg1, arg2, arg3, factory); } From b8f84237ffdd603cf5abb454d17a338fbb90ae51 Mon Sep 17 00:00:00 2001 From: javasabr Date: Thu, 30 Oct 2025 09:37:38 +0100 Subject: [PATCH 2/8] add tests for logger api --- .../java/javasabr/rlib/logger/api/Logger.java | 60 +++++ .../javasabr/rlib/logger/api/LoggerTest.java | 227 ++++++++++++++++++ 2 files changed, 287 insertions(+) create mode 100644 rlib-logger-api/src/test/java/javasabr/rlib/logger/api/LoggerTest.java diff --git a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java index a42775b0..2d11fe9f 100644 --- a/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java +++ b/rlib-logger-api/src/main/java/javasabr/rlib/logger/api/Logger.java @@ -169,6 +169,26 @@ default void error(A arg1, B arg2, @NonNull N2Factory factory) { print(LoggerLevel.ERROR, arg1, arg2, factory); } + default void error(int arg1, int arg2, @NonNull Int2Factory factory) { + print(LoggerLevel.ERROR, arg1, arg2, factory); + } + + default void error(A arg1, int arg2, @NonNull N1IntFactory factory) { + print(LoggerLevel.ERROR, arg1, arg2, factory); + } + + default void error(A arg1, B arg2, C arg3, @NonNull N3Factory factory) { + print(LoggerLevel.ERROR, arg1, arg2, arg3, factory); + } + + default void error(A arg1, int arg2, C arg3, @NonNull N1IntN1Factory factory) { + print(LoggerLevel.ERROR, arg1, arg2, arg3, factory); + } + + default void error(A arg1, int arg2, int arg3, @NonNull N1Int2Factory factory) { + print(LoggerLevel.ERROR, arg1, arg2, arg3, factory); + } + default void error(int arg1, int arg2, C arg3, @NonNull Int2N1Factory factory) { print(LoggerLevel.ERROR, arg1, arg2, arg3, factory); } @@ -177,6 +197,10 @@ default void error(A arg1, int arg2, int arg3, D arg4, @NonNull N1Int2N1F print(LoggerLevel.ERROR, arg1, arg2, arg3, arg4, factory); } + default void error(A arg1, B arg2, C arg3, D arg4, @NonNull N4Factory factory) { + print(LoggerLevel.ERROR, arg1, arg2, arg3, arg4, factory); + } + default void error(@NonNull Throwable exception) { print(LoggerLevel.ERROR, exception); } @@ -197,6 +221,14 @@ default void info(A arg1, B arg2, @NonNull N2Factory factory) { print(LoggerLevel.INFO, arg1, arg2, factory); } + default void info(int arg1, int arg2, @NonNull Int2Factory factory) { + print(LoggerLevel.INFO, arg1, arg2, factory); + } + + default void info(A arg1, int arg2, @NonNull N1IntFactory factory) { + print(LoggerLevel.INFO, arg1, arg2, factory); + } + default void info(int arg1, B arg2, @NonNull IntN1Factory factory) { print(LoggerLevel.INFO, arg1, arg2, factory); } @@ -205,6 +237,18 @@ default void info(A arg1, B arg2, C arg3, @NonNull N3Factory print(LoggerLevel.INFO, arg1, arg2, arg3, factory); } + default void info(A arg1, int arg2, C arg3, @NonNull N1IntN1Factory factory) { + print(LoggerLevel.INFO, arg1, arg2, arg3, factory); + } + + default void info(A arg1, int arg2, int arg3, @NonNull N1Int2Factory factory) { + print(LoggerLevel.INFO, arg1, arg2, arg3, factory); + } + + default void info(A arg1, B arg2, C arg3, D arg4, @NonNull N4Factory factory) { + print(LoggerLevel.INFO, arg1, arg2, arg3, arg4, factory); + } + /** * Check of enabling the logger level. */ @@ -256,6 +300,14 @@ default void warning(A arg1, B arg2, @NonNull N2Factory factory) { print(LoggerLevel.WARNING, arg1, arg2, factory); } + default void warning(int arg1, int arg2, @NonNull Int2Factory factory) { + print(LoggerLevel.WARNING, arg1, arg2, factory); + } + + default void warning(int arg1, B arg2, @NonNull IntN1Factory factory) { + print(LoggerLevel.WARNING, arg1, arg2, factory); + } + default void warning(A arg1, int arg2, @NonNull N1IntFactory factory) { print(LoggerLevel.WARNING, arg1, arg2, factory); } @@ -264,6 +316,14 @@ default void warning(A arg1, B arg2, C arg3, @NonNull N3Factory void warning(A arg1, int arg2, C arg3, @NonNull N1IntN1Factory factory) { + print(LoggerLevel.WARNING, arg1, arg2, arg3, factory); + } + + default void warning(A arg1, int arg2, int arg3, @NonNull N1Int2Factory factory) { + print(LoggerLevel.WARNING, arg1, arg2, arg3, factory); + } + default void warning( A arg1, B arg2, diff --git a/rlib-logger-api/src/test/java/javasabr/rlib/logger/api/LoggerTest.java b/rlib-logger-api/src/test/java/javasabr/rlib/logger/api/LoggerTest.java new file mode 100644 index 00000000..d2450bc7 --- /dev/null +++ b/rlib-logger-api/src/test/java/javasabr/rlib/logger/api/LoggerTest.java @@ -0,0 +1,227 @@ +package javasabr.rlib.logger.api; + +import java.util.ArrayList; +import java.util.List; +import org.jspecify.annotations.NonNull; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +public class LoggerTest { + + @Test + @DisplayName("should print all debug methods") + void shouldPrintAllDebugMethods() { + + // given: + var messages = new ArrayList(); + var expectedMessages = List.of( + "DEBUG_msg1", + "DEBUG_msg2[str1]", + "DEBUG_msg3[13]", + "DEBUG_msg4[str2, 15]", + "DEBUG_msg5[14, str3]", + "DEBUG_msg6[22, 32]", + "DEBUG_msg7[str4, str5]", + "DEBUG_msg8[str5, str6, str7]", + "DEBUG_msg9[str8, 54, str9]", + "DEBUG_msg10[str10, 37, 76]", + "DEBUG_msg11[str11, str12, str13, str14]"); + + Logger logger = new Logger() { + + @Override + public boolean enabled(@NonNull LoggerLevel level) { + return true; + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull String message) { + messages.add(level + "_" + message); + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull Throwable exception) { + } + }; + + // when: + logger.debug("msg1"); + logger.debug("str1", "msg2[%s]"::formatted); + logger.debug(13, "msg3[%d]"::formatted); + logger.debug("str2", 15, "msg4[%s, %d]"::formatted); + logger.debug(14, "str3", "msg5[%d, %s]"::formatted); + logger.debug(22, 32, "msg6[%d, %d]"::formatted); + logger.debug("str4", "str5", "msg7[%s, %s]"::formatted); + logger.debug("str5", "str6", "str7", "msg8[%s, %s, %s]"::formatted); + logger.debug("str8", 54, "str9", "msg9[%s, %d, %s]"::formatted); + logger.debug("str10", 37, 76, "msg10[%s, %d, %d]"::formatted); + logger.debug("str11", "str12", "str13", "str14", "msg11[%s, %s, %s, %s]"::formatted); + + // then: + Assertions.assertEquals(11, messages.size()); + Assertions.assertEquals(expectedMessages, messages); + } + + @Test + @DisplayName("should print all info methods") + void shouldPrintAllInfoMethods() { + + // given: + var messages = new ArrayList(); + var expectedMessages = List.of( + "INFO_msg1", + "INFO_msg2[str1]", + "INFO_msg3[13]", + "INFO_msg4[str2, 15]", + "INFO_msg5[14, str3]", + "INFO_msg6[22, 32]", + "INFO_msg7[str4, str5]", + "INFO_msg8[str5, str6, str7]", + "INFO_msg9[str8, 54, str9]", + "INFO_msg10[str10, 37, 76]", + "INFO_msg11[str11, str12, str13, str14]"); + + Logger logger = new Logger() { + + @Override + public boolean enabled(@NonNull LoggerLevel level) { + return true; + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull String message) { + messages.add(level + "_" + message); + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull Throwable exception) { + } + }; + + // when: + logger.info("msg1"); + logger.info("str1", "msg2[%s]"::formatted); + logger.info(13, "msg3[%d]"::formatted); + logger.info("str2", 15, "msg4[%s, %d]"::formatted); + logger.info(14, "str3", "msg5[%d, %s]"::formatted); + logger.info(22, 32, "msg6[%d, %d]"::formatted); + logger.info("str4", "str5", "msg7[%s, %s]"::formatted); + logger.info("str5", "str6", "str7", "msg8[%s, %s, %s]"::formatted); + logger.info("str8", 54, "str9", "msg9[%s, %d, %s]"::formatted); + logger.info("str10", 37, 76, "msg10[%s, %d, %d]"::formatted); + logger.info("str11", "str12", "str13", "str14", "msg11[%s, %s, %s, %s]"::formatted); + + // then: + Assertions.assertEquals(11, messages.size()); + Assertions.assertEquals(expectedMessages, messages); + } + + @Test + @DisplayName("should print all warning methods") + void shouldPrintAllWarningMethods() { + + // given: + var messages = new ArrayList(); + var expectedMessages = List.of( + "WARNING_msg1", + "WARNING_msg2[str1]", + "WARNING_msg3[13]", + "WARNING_msg4[str2, 15]", + "WARNING_msg5[14, str3]", + "WARNING_msg6[22, 32]", + "WARNING_msg7[str4, str5]", + "WARNING_msg8[str5, str6, str7]", + "WARNING_msg9[str8, 54, str9]", + "WARNING_msg10[str10, 37, 76]", + "WARNING_msg11[str11, str12, str13, str14]"); + + Logger logger = new Logger() { + + @Override + public boolean enabled(@NonNull LoggerLevel level) { + return true; + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull String message) { + messages.add(level + "_" + message); + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull Throwable exception) { + } + }; + + // when: + logger.warning("msg1"); + logger.warning("str1", "msg2[%s]"::formatted); + logger.warning(13, "msg3[%d]"::formatted); + logger.warning("str2", 15, "msg4[%s, %d]"::formatted); + logger.warning(14, "str3", "msg5[%d, %s]"::formatted); + logger.warning(22, 32, "msg6[%d, %d]"::formatted); + logger.warning("str4", "str5", "msg7[%s, %s]"::formatted); + logger.warning("str5", "str6", "str7", "msg8[%s, %s, %s]"::formatted); + logger.warning("str8", 54, "str9", "msg9[%s, %d, %s]"::formatted); + logger.warning("str10", 37, 76, "msg10[%s, %d, %d]"::formatted); + logger.warning("str11", "str12", "str13", "str14", "msg11[%s, %s, %s, %s]"::formatted); + + // then: + Assertions.assertEquals(11, messages.size()); + Assertions.assertEquals(expectedMessages, messages); + } + + @Test + @DisplayName("should print all error methods") + void shouldPrintAllErrorMethods() { + + // given: + var messages = new ArrayList(); + var expectedMessages = List.of( + "ERROR_msg1", + "ERROR_msg2[str1]", + "ERROR_msg3[13]", + "ERROR_msg4[str2, 15]", + "ERROR_msg5[14, str3]", + "ERROR_msg6[22, 32]", + "ERROR_msg7[str4, str5]", + "ERROR_msg8[str5, str6, str7]", + "ERROR_msg9[str8, 54, str9]", + "ERROR_msg10[str10, 37, 76]", + "ERROR_msg11[str11, str12, str13, str14]"); + + Logger logger = new Logger() { + + @Override + public boolean enabled(@NonNull LoggerLevel level) { + return true; + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull String message) { + messages.add(level + "_" + message); + } + + @Override + public void print(@NonNull LoggerLevel level, @NonNull Throwable exception) { + } + }; + + // when: + logger.error("msg1"); + logger.error("str1", "msg2[%s]"::formatted); + logger.error(13, "msg3[%d]"::formatted); + logger.error("str2", 15, "msg4[%s, %d]"::formatted); + logger.error(14, "str3", "msg5[%d, %s]"::formatted); + logger.error(22, 32, "msg6[%d, %d]"::formatted); + logger.error("str4", "str5", "msg7[%s, %s]"::formatted); + logger.error("str5", "str6", "str7", "msg8[%s, %s, %s]"::formatted); + logger.error("str8", 54, "str9", "msg9[%s, %d, %s]"::formatted); + logger.error("str10", 37, 76, "msg10[%s, %d, %d]"::formatted); + logger.error("str11", "str12", "str13", "str14", "msg11[%s, %s, %s, %s]"::formatted); + + // then: + Assertions.assertEquals(11, messages.size()); + Assertions.assertEquals(expectedMessages, messages); + } +} From 41d9dbe905823f9a41706dfecf4841b31204928e Mon Sep 17 00:00:00 2001 From: javasabr Date: Thu, 30 Oct 2025 09:38:12 +0100 Subject: [PATCH 3/8] update version --- README.md | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7c7d77cd..8e5df243 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ repositories { } ext { - rlibVersion = "10.0.alpha5" + rlibVersion = "10.0.alpha6" } dependencies { diff --git a/build.gradle b/build.gradle index 1ce0de42..45952844 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,4 @@ -rootProject.version = "10.0.alpha5" +rootProject.version = "10.0.alpha6" group = 'javasabr.rlib' allprojects { From ea32ddba0cb550c187c27c447029e9c426d661d7 Mon Sep 17 00:00:00 2001 From: javasabr Date: Thu, 30 Oct 2025 09:59:13 +0100 Subject: [PATCH 4/8] update dictionary interfaces --- .../rlib/collections/dictionary/Dictionary.java | 1 - .../collections/dictionary/IntToRefDictionary.java | 9 ++++----- .../collections/dictionary/LongToRefDictionary.java | 11 +++++------ .../dictionary/MutableIntToRefDictionary.java | 7 ++----- .../dictionary/MutableLongToRefDictionary.java | 7 ++----- .../dictionary/MutableRefToRefDictionary.java | 4 ++-- .../collections/dictionary/RefToRefDictionary.java | 6 +++--- 7 files changed, 18 insertions(+), 27 deletions(-) diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/Dictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/Dictionary.java index d0500950..f6a12b91 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/Dictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/Dictionary.java @@ -24,7 +24,6 @@ public interface Dictionary extends Iterable { Optional getOptional(K key); - @Nullable V getOrDefault(K key, V def); > C keys(C container); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/IntToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/IntToRefDictionary.java index 98d9bf8c..71a6ea65 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/IntToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/IntToRefDictionary.java @@ -10,7 +10,7 @@ public interface IntToRefDictionary extends Dictionary { - static IntToRefEntry entry(int key, @Nullable V value) { + static IntToRefEntry entry(int key, V value) { return new SimpleIntToRefEntry<>(key, value); } @@ -18,16 +18,16 @@ static IntToRefDictionary empty() { return ImmutableHashBasedIntToRefDictionary.empty(); } - static IntToRefDictionary of(int key, @Nullable V value) { + static IntToRefDictionary of(int key, V value) { return ofEntries(entry(key, value)); } - static IntToRefDictionary of(int k1, @Nullable V v1, int k2, @Nullable V v2) { + static IntToRefDictionary of(int k1, V v1, int k2, V v2) { return ofEntries(entry(k1, v1), entry(k2, v2)); } @SafeVarargs - static IntToRefDictionary ofEntries(IntToRefEntry... entries) { + static IntToRefDictionary ofEntries(IntToRefEntry... entries) { MutableIntToRefDictionary mutable = DictionaryFactory.mutableIntToRefDictionary(); for (var entry : entries) { mutable.put(entry.key(), entry.value()); @@ -42,7 +42,6 @@ static IntToRefDictionary ofEntries(IntToRefEntry... entries) { Optional getOptional(int key); - @Nullable V getOrDefault(int key, V def); MutableIntArray keys(MutableIntArray container); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/LongToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/LongToRefDictionary.java index 3ce830b3..bb1d7fd7 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/LongToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/LongToRefDictionary.java @@ -10,24 +10,24 @@ public interface LongToRefDictionary extends Dictionary { - static LongToRefEntry entry(long key, @Nullable V value) { + static LongToRefEntry entry(long key, V value) { return new SimpleLongToRefEntry<>(key, value); } - static LongToRefDictionary empty() { + static LongToRefDictionary empty() { return ImmutableHashBasedLongToRefDictionary.empty(); } - static LongToRefDictionary of(long key, @Nullable V value) { + static LongToRefDictionary of(long key, V value) { return ofEntries(entry(key, value)); } - static LongToRefDictionary of(long k1, @Nullable V v1, long k2, @Nullable V v2) { + static LongToRefDictionary of(long k1, V v1, long k2, V v2) { return ofEntries(entry(k1, v1), entry(k2, v2)); } @SafeVarargs - static LongToRefDictionary ofEntries(LongToRefEntry... entries) { + static LongToRefDictionary ofEntries(LongToRefEntry... entries) { MutableLongToRefDictionary mutable = DictionaryFactory.mutableLongToRefDictionary(); for (var entry : entries) { mutable.put(entry.key(), entry.value()); @@ -42,7 +42,6 @@ static LongToRefDictionary ofEntries(LongToRefEntry... entries) { Optional getOptional(long key); - @Nullable V getOrDefault(long key, V def); MutableLongArray keys(MutableLongArray container); diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java index 5d6035e8..874993a8 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java @@ -13,20 +13,17 @@ static MutableIntToRefDictionary ofTypes(Class valueType) { return new DefaultMutableHashBasedIntToRefDictionary<>(); } - @Nullable V getOrCompute(int key, Supplier factory); - @Nullable V getOrCompute(int key, IntFunction factory); - @Nullable V getOrCompute(int key, T arg1, Function factory); /** * @return the previous value for the key or null. */ @Nullable - V put(int key, @Nullable V value); + V put(int key, V value); void putAll(IntToRefDictionary dictionary); @@ -35,7 +32,7 @@ static MutableIntToRefDictionary ofTypes(Class valueType) { /** * @return the optional value of the previous value for the key. */ - Optional putOptional(int key, @Nullable V value); + Optional putOptional(int key, V value); /** * @return the previous value for the key or null. diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java index ae5d38ab..b9b113bb 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java @@ -13,20 +13,17 @@ static MutableLongToRefDictionary ofTypes(Class valueType) { return new DefaultMutableHashBasedLongToRefDictionary<>(); } - @Nullable V getOrCompute(long key, Supplier factory); - @Nullable V getOrCompute(long key, LongFunction factory); - @Nullable V getOrCompute(long key, T arg1, Function factory); /** * @return the previous value for the key or null. */ @Nullable - V put(long key, @Nullable V value); + V put(long key, V value); void putAll(LongToRefDictionary dictionary); @@ -35,7 +32,7 @@ static MutableLongToRefDictionary ofTypes(Class valueType) { /** * @return the optional value of the previous value for the key. */ - Optional putOptional(long key, @Nullable V value); + Optional putOptional(long key, V value); /** * @return the previous value for the key or null. diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java index 5f6d7419..8da6d25b 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java @@ -24,7 +24,7 @@ static MutableRefToRefDictionary ofTypes( * @return the previous value for the key or null. */ @Nullable - V put(K key, @Nullable V value); + V put(K key, V value); void putAll(RefToRefDictionary dictionary); @@ -33,7 +33,7 @@ static MutableRefToRefDictionary ofTypes( /** * @return the optional value of the previous value for the key. */ - Optional putOptional(K key, @Nullable V value); + Optional putOptional(K key, V value); /** * @return the previous value for the key or null. diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java index 86bf9806..c326edd2 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java @@ -7,7 +7,7 @@ public interface RefToRefDictionary extends Dictionary { - static RefToRefEntry entry(K key, @Nullable V value) { + static RefToRefEntry entry(K key, V value) { return new SimpleRefToRefEntry<>(key, value); } @@ -15,11 +15,11 @@ static RefToRefDictionary empty() { return ImmutableHashBasedRefToRefDictionary.empty(); } - static RefToRefDictionary of(K key, @Nullable V value) { + static RefToRefDictionary of(K key, V value) { return ofEntries(entry(key, value)); } - static RefToRefDictionary of(K k1, @Nullable V v1, K k2, @Nullable V v2) { + static RefToRefDictionary of(K k1, V v1, K k2, V v2) { return ofEntries(entry(k1, v1), entry(k2, v2)); } From b1f5b83ff0c6bcfab56ec583abe0689078026f9e Mon Sep 17 00:00:00 2001 From: javasabr Date: Tue, 4 Nov 2025 19:15:33 +0100 Subject: [PATCH 5/8] update unit tests --- .../src/main/groovy/configure-java.gradle | 1 + gradle/libs.versions.toml | 9 +- .../rlib/collections/array/Array.java | 1 - .../dictionary/RefToRefDictionary.java | 1 - .../rlib/collections/array/ArrayTest.java | 77 ++++++- .../dictionary/IntToRefDictionaryTest.java | 194 ++++++++++++++++++ .../dictionary/LongToRefDictionaryTest.java | 194 ++++++++++++++++++ .../MutableIntToRefDictionaryTest.java | 142 +++++++++++++ .../MutableLongToRefDictionaryTest.java | 142 +++++++++++++ .../MutableRefToRefDictionaryTest.java | 106 ++++++---- .../dictionary/RefToRefDictionaryTest.java | 86 +++++--- .../rlib/common/tuple/IntRefTuple.java | 3 + .../rlib/common/tuple/LongRefTuple.java | 3 + 13 files changed, 893 insertions(+), 66 deletions(-) create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/IntToRefDictionaryTest.java create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/LongToRefDictionaryTest.java create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java create mode 100644 rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java create mode 100644 rlib-common/src/main/java/javasabr/rlib/common/tuple/IntRefTuple.java create mode 100644 rlib-common/src/main/java/javasabr/rlib/common/tuple/LongRefTuple.java diff --git a/buildSrc/src/main/groovy/configure-java.gradle b/buildSrc/src/main/groovy/configure-java.gradle index eb80fb22..b59eae52 100644 --- a/buildSrc/src/main/groovy/configure-java.gradle +++ b/buildSrc/src/main/groovy/configure-java.gradle @@ -57,6 +57,7 @@ dependencies { testImplementation libs.mockito.junit.jupiter testImplementation libs.junit.api testImplementation libs.junit.jupiter.params + testImplementation libs.assertj.core testCompileOnly libs.lombok testCompileOnly libs.jspecify diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index befd7903..00927cef 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,15 +10,15 @@ angus-mail = "2.0.4" # https://mvnrepository.com/artifact/org.testcontainers/testcontainers testcontainers = "1.21.3" # https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine -junit-jupiter = "5.13.4" +junit-jupiter = "6.0.1" # https://mvnrepository.com/artifact/org.projectlombok/lombok lombok = "1.18.38" # https://mvnrepository.com/artifact/org.jspecify/jspecify jspecify = "1.0.0" -# https://mvnrepository.com/artifact/org.junit.platform/junit-platform-launcher -junit-platform-launcher = "1.13.4" # https://mvnrepository.com/artifact/org.mockito/mockito-core mockito = "5.20.0" +# https://mvnrepository.com/artifact/org.assertj/assertj-core +assertj-core = "4.0.0-M1" [libraries] project-reactor-core = { module = "io.projectreactor:reactor-core", version.ref = "project-reactor" } @@ -27,7 +27,7 @@ lombok = { module = "org.projectlombok:lombok", version.ref = "lombok" } junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-jupiter" } junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit-jupiter" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit-jupiter" } -junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit-platform-launcher" } +junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit-jupiter" } slf4j-api = { module = "org.slf4j:slf4j-api", version.ref = "slf4j" } slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } slf4j-ext = { module = "org.slf4j:slf4j-ext", version.ref = "slf4j" } @@ -36,6 +36,7 @@ angus-mail = { module = "org.eclipse.angus:angus-mail", version.ref = "angus-mai testcontainers = { module = "org.testcontainers:testcontainers", version.ref = "testcontainers" } mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } +assertj-core = { module = "org.assertj:assertj-core", version.ref = "assertj-core" } [bundles] mail = ["jakarta-mail-api", "angus-mail"] \ No newline at end of file diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java index ed24bafc..99f11e95 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/array/Array.java @@ -5,7 +5,6 @@ import java.util.Iterator; import java.util.List; import java.util.Optional; -import java.util.RandomAccess; import java.util.function.Function; import java.util.stream.Stream; import javasabr.rlib.collections.array.impl.DefaultArrayIterator; diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java index c326edd2..f7c90a79 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/RefToRefDictionary.java @@ -3,7 +3,6 @@ import java.util.function.BiConsumer; import javasabr.rlib.collections.dictionary.impl.ImmutableHashBasedRefToRefDictionary; import javasabr.rlib.collections.dictionary.impl.SimpleRefToRefEntry; -import org.jspecify.annotations.Nullable; public interface RefToRefDictionary extends Dictionary { diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java index a52ee00e..e9956e6f 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/array/ArrayTest.java @@ -1,5 +1,8 @@ package javasabr.rlib.collections.array; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -69,7 +72,7 @@ void shouldCorrectlyTakeValues(Array array) { } @ParameterizedTest - @MethodSource("generateArrays") + @MethodSource("generateArraysWithDuplicates") void shouldFindElementIndex(Array array) { // when/then: Assertions.assertEquals(0, array.indexOf("First")); @@ -77,6 +80,15 @@ void shouldFindElementIndex(Array array) { Assertions.assertEquals(-1, array.indexOf("notexist")); } + @ParameterizedTest + @MethodSource("generateArraysWithDuplicates") + void shouldFindLastElementIndex(Array array) { + // when/then: + Assertions.assertEquals(4, array.lastIndexOf("First")); + Assertions.assertEquals(6, array.lastIndexOf("Third")); + Assertions.assertEquals(-1, array.lastIndexOf("notexist")); + } + @ParameterizedTest @MethodSource("generateArrays") void shouldFindElementIndexWithFunction(Array array) { @@ -113,6 +125,54 @@ void shouldCorrectlyTransformToNativeArray(Array array) { }, array.toArray(String.class)); } + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContains(Array array) { + // when/then: + assertThat(array.contains("First")).isTrue(); + assertThat(array.contains(" ")).isTrue(); + assertThat(array.contains("notexist")).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContainsAllByArray(Array array) { + // given: + Array check1 = Array.of("First"); + Array check2 = Array.of("Second", "Third"); + Array check3 = Array.of("Second", "Third", "noexist"); + // when/then: + assertThat(array.containsAll(check1)).isTrue(); + assertThat(array.containsAll(check2)).isTrue(); + assertThat(array.containsAll(check3)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContainsAllByCollection(Array array) { + // given: + List check1 = List.of("First"); + List check2 = List.of("Second", "Third"); + List check3 = List.of("Second", "Third", "noexist"); + // when/then: + assertThat(array.containsAll(check1)).isTrue(); + assertThat(array.containsAll(check2)).isTrue(); + assertThat(array.containsAll(check3)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateArrays") + void shouldCorrectlyCheckOnContainsAllByNativeArray(Array array) { + // given: + Object[] check1 = List.of("First").toArray(); + Object[] check2 = List.of("Second", "Third").toArray(); + Object[] check3 = List.of("Second", "Third", "noexist").toArray(); + // when/then: + assertThat(array.containsAll(check1)).isTrue(); + assertThat(array.containsAll(check2)).isTrue(); + assertThat(array.containsAll(check3)).isFalse(); + } + private static Stream generateArrays() { Array array = Array.of("First", "Second", "Third", " "); MutableArray mutableArray = ArrayFactory.mutableArray(String.class); @@ -127,4 +187,19 @@ private static Stream generateArrays() { Arguments.of(copyOnModifyArray), Arguments.of(stampedLockBasedArray)); } + + private static Stream generateArraysWithDuplicates() { + Array array = Array.typed(String.class, "First", "Second", "Third", " ", "First", "Second", "Third"); + MutableArray mutableArray = ArrayFactory.mutableArray(String.class); + mutableArray.addAll(array); + MutableArray copyOnModifyArray = ArrayFactory.copyOnModifyArray(String.class); + copyOnModifyArray.addAll(array); + LockableArray stampedLockBasedArray = ArrayFactory.stampedLockBasedArray(String.class); + stampedLockBasedArray.addAll(array); + return Stream.of( + Arguments.of(array), + Arguments.of(mutableArray), + Arguments.of(copyOnModifyArray), + Arguments.of(stampedLockBasedArray)); + } } diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/IntToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/IntToRefDictionaryTest.java new file mode 100644 index 00000000..0152f956 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/IntToRefDictionaryTest.java @@ -0,0 +1,194 @@ +package javasabr.rlib.collections.dictionary; + +import static javasabr.rlib.collections.dictionary.IntToRefDictionary.entry; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.collections.array.ArrayFactory; +import javasabr.rlib.collections.array.IntArray; +import javasabr.rlib.collections.array.MutableArray; +import javasabr.rlib.common.tuple.IntRefTuple; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class IntToRefDictionaryTest { + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldProvideCorrectSize(IntToRefDictionary dictionary) { + // then: + assertThat(dictionary.size()).isEqualTo(5); + assertThat(dictionary.isEmpty()).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateEmptyDictionaries") + void shouldConfirmThatDictionaryIsEmpty(IntToRefDictionary dictionary) { + // then: + assertThat(dictionary.isEmpty()).isTrue(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldFindValuesByKeys(IntToRefDictionary dictionary) { + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(3)).isEqualTo("val3"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(10)).isNull(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldFindValuesByKeysOrReturnDefault(IntToRefDictionary dictionary) { + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(10)).isNull(); + assertThat(dictionary.getOrDefault(10, "def1")).isEqualTo("def1"); + assertThat(dictionary.getOrDefault(30, "def2")).isEqualTo("def2"); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldReturnOptionalValuesByKeys(IntToRefDictionary dictionary) { + // then: + assertThat(dictionary.getOptional(1)).contains("val1"); + assertThat(dictionary.getOptional(10)).isEmpty(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldCheckContainsKeys(IntToRefDictionary dictionary) { + // then: + assertThat(dictionary.containsKey(1)).isTrue(); + assertThat(dictionary.containsKey(2)).isTrue(); + assertThat(dictionary.containsKey(5)).isTrue(); + assertThat(dictionary.containsKey(10)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldCheckContainsValues(IntToRefDictionary dictionary) { + // then: + assertThat(dictionary.containsValue("val1")).isTrue(); + assertThat(dictionary.containsValue("val3")).isTrue(); + assertThat(dictionary.containsValue("val4")).isTrue(); + assertThat(dictionary.containsValue("val10")).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldHaveExpectedKeys(IntToRefDictionary dictionary) { + // given: + var expectedArray = Array.typed(Integer.class, 1, 2, 3, 4, 5); + var expectedIntArray = IntArray.of(1, 2, 3, 4, 5); + var expectedSet = Set.copyOf(expectedArray.toList()); + + // when: + Array keys = dictionary.keys(Integer.class); + + // then: + assertThat(keys).isEqualTo(expectedArray); + + // when: + Array keys2 = dictionary.keys(MutableArray.ofType(Integer.class)); + + // then: + assertThat(keys2).isEqualTo(expectedArray); + + // when: + Set keys3 = dictionary.keys(new HashSet<>()); + + // then: + assertThat(keys3).isEqualTo(expectedSet); + + // when: + IntArray intKeys = dictionary.keys(); + + // then: + assertThat(intKeys).isEqualTo(expectedIntArray); + + // when: + intKeys = dictionary.keys(ArrayFactory.mutableIntArray()); + + // then: + assertThat(intKeys).isEqualTo(expectedIntArray); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldHaveExpectedValues(IntToRefDictionary dictionary) { + // given: + var expectedArray = Array.typed(String.class, "val1", "val2", "val3", "val4", "val5"); + var expectedSet = Set.copyOf(expectedArray.toList()); + + // when: + Array values = dictionary.values(String.class); + + // then: + assertThat(values).isEqualTo(expectedArray); + + // when: + Array values2 = dictionary.values(MutableArray.ofType(String.class)); + + // then: + assertThat(values2).isEqualTo(expectedArray); + + // when: + Set values3 = dictionary.values(new HashSet<>()); + + // then: + assertThat(values3).isEqualTo(expectedSet); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldHaveExpectedResultFromForEach(IntToRefDictionary dictionary) { + // given: + var expectedArray = Array.typed(String.class, "val1", "val2", "val3", "val4", "val5"); + var expectedPairs = Array.typed(IntRefTuple.class, + new IntRefTuple<>(1, "val1"), + new IntRefTuple<>(2, "val2"), + new IntRefTuple<>(3, "val3"), + new IntRefTuple<>(4, "val4"), + new IntRefTuple<>(5, "val5")); + + // when: + MutableArray values = MutableArray.ofType(String.class); + dictionary.forEach(values::add); + + // then: + assertThat(values).isEqualTo(expectedArray); + + // when: + MutableArray pairs = MutableArray.ofType(IntRefTuple.class); + dictionary.forEach((key, value) -> pairs.add(new IntRefTuple<>(key, value))); + + // then: + assertThat(pairs).isEqualTo(expectedPairs); + } + + private static Stream generateDictionaries() { + + IntToRefDictionary source = IntToRefDictionary.ofEntries( + entry(1, "val1"), + entry(2, "val2"), + entry(3, "val3"), + entry(4, "val4"), + entry(5, "val5")); + + return Stream.of( + Arguments.of(source), + Arguments.of(DictionaryFactory.mutableIntToRefDictionary().append(source))); + } + + private static Stream generateEmptyDictionaries() { + return Stream.of( + Arguments.of(IntToRefDictionary.empty()), + Arguments.of(DictionaryFactory.mutableIntToRefDictionary())); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/LongToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/LongToRefDictionaryTest.java new file mode 100644 index 00000000..548d36e5 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/LongToRefDictionaryTest.java @@ -0,0 +1,194 @@ +package javasabr.rlib.collections.dictionary; + +import static javasabr.rlib.collections.dictionary.LongToRefDictionary.entry; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Stream; +import javasabr.rlib.collections.array.Array; +import javasabr.rlib.collections.array.ArrayFactory; +import javasabr.rlib.collections.array.LongArray; +import javasabr.rlib.collections.array.MutableArray; +import javasabr.rlib.common.tuple.LongRefTuple; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class LongToRefDictionaryTest { + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldProvideCorrectSize(LongToRefDictionary dictionary) { + // then: + assertThat(dictionary.size()).isEqualTo(5); + assertThat(dictionary.isEmpty()).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateEmptyDictionaries") + void shouldConfirmThatDictionaryIsEmpty(LongToRefDictionary dictionary) { + // then: + assertThat(dictionary.isEmpty()).isTrue(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldFindValuesByKeys(LongToRefDictionary dictionary) { + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(3)).isEqualTo("val3"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(10)).isNull(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldFindValuesByKeysOrReturnDefault(LongToRefDictionary dictionary) { + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(10)).isNull(); + assertThat(dictionary.getOrDefault(10, "def1")).isEqualTo("def1"); + assertThat(dictionary.getOrDefault(30, "def2")).isEqualTo("def2"); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldReturnOptionalValuesByKeys(LongToRefDictionary dictionary) { + // then: + assertThat(dictionary.getOptional(1)).contains("val1"); + assertThat(dictionary.getOptional(10)).isEmpty(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldCheckContainsKeys(LongToRefDictionary dictionary) { + // then: + assertThat(dictionary.containsKey(1)).isTrue(); + assertThat(dictionary.containsKey(2)).isTrue(); + assertThat(dictionary.containsKey(5)).isTrue(); + assertThat(dictionary.containsKey(10)).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldCheckContainsValues(LongToRefDictionary dictionary) { + // then: + assertThat(dictionary.containsValue("val1")).isTrue(); + assertThat(dictionary.containsValue("val3")).isTrue(); + assertThat(dictionary.containsValue("val4")).isTrue(); + assertThat(dictionary.containsValue("val10")).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldHaveExpectedKeys(LongToRefDictionary dictionary) { + // given: + var expectedArray = Array.typed(Long.class, 1L, 2L, 3L, 4L, 5L); + var expectedLongArray = LongArray.of(1, 2, 3, 4, 5); + var expectedSet = Set.copyOf(expectedArray.toList()); + + // when: + Array keys = dictionary.keys(Long.class); + + // then: + assertThat(keys).isEqualTo(expectedArray); + + // when: + Array keys2 = dictionary.keys(MutableArray.ofType(Long.class)); + + // then: + assertThat(keys2).isEqualTo(expectedArray); + + // when: + Set keys3 = dictionary.keys(new HashSet<>()); + + // then: + assertThat(keys3).isEqualTo(expectedSet); + + // when: + LongArray longArray = dictionary.keys(); + + // then: + assertThat(longArray).isEqualTo(expectedLongArray); + + // when: + longArray = dictionary.keys(ArrayFactory.mutableLongArray()); + + // then: + assertThat(longArray).isEqualTo(expectedLongArray); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldHaveExpectedValues(LongToRefDictionary dictionary) { + // given: + var expectedArray = Array.typed(String.class, "val1", "val2", "val3", "val4", "val5"); + var expectedSet = Set.copyOf(expectedArray.toList()); + + // when: + Array values = dictionary.values(String.class); + + // then: + assertThat(values).isEqualTo(expectedArray); + + // when: + Array values2 = dictionary.values(MutableArray.ofType(String.class)); + + // then: + assertThat(values2).isEqualTo(expectedArray); + + // when: + Set values3 = dictionary.values(new HashSet<>()); + + // then: + assertThat(values3).isEqualTo(expectedSet); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldHaveExpectedResultFromForEach(LongToRefDictionary dictionary) { + // given: + var expectedArray = Array.typed(String.class, "val1", "val2", "val3", "val4", "val5"); + var expectedPairs = Array.typed(LongRefTuple.class, + new LongRefTuple<>(1, "val1"), + new LongRefTuple<>(2, "val2"), + new LongRefTuple<>(3, "val3"), + new LongRefTuple<>(4, "val4"), + new LongRefTuple<>(5, "val5")); + + // when: + MutableArray values = MutableArray.ofType(String.class); + dictionary.forEach(values::add); + + // then: + assertThat(values).isEqualTo(expectedArray); + + // when: + MutableArray pairs = MutableArray.ofType(LongRefTuple.class); + dictionary.forEach((key, value) -> pairs.add(new LongRefTuple<>(key, value))); + + // then: + assertThat(pairs).isEqualTo(expectedPairs); + } + + private static Stream generateDictionaries() { + + LongToRefDictionary source = LongToRefDictionary.ofEntries( + entry(1, "val1"), + entry(2, "val2"), + entry(3, "val3"), + entry(4, "val4"), + entry(5, "val5")); + + return Stream.of( + Arguments.of(source), + Arguments.of(DictionaryFactory.mutableLongToRefDictionary().append(source))); + } + + private static Stream generateEmptyDictionaries() { + return Stream.of( + Arguments.of(LongToRefDictionary.empty()), + Arguments.of(DictionaryFactory.mutableLongToRefDictionary())); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java new file mode 100644 index 00000000..03770569 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java @@ -0,0 +1,142 @@ +package javasabr.rlib.collections.dictionary; + +import static javasabr.rlib.collections.dictionary.IntToRefDictionary.entry; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class MutableIntToRefDictionaryTest { + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldPutNewPairs(MutableIntToRefDictionary dictionary) { + // when: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(55)).isEqualTo("val55"); + assertThat(dictionary.containsKey(1)).isTrue(); + assertThat(dictionary.containsKey(4)).isTrue(); + assertThat(dictionary.containsKey(55)).isTrue(); + assertThat(dictionary.get(10)).isNull(); + assertThat(dictionary.size()).isEqualTo(4); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldPutOptionalNewPairs(MutableIntToRefDictionary dictionary) { + // when: + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + + Optional prevForKey1 = dictionary.putOptional(1, "val1"); + Optional prevForKey55 = dictionary.putOptional(55, "val56"); + + // then: + assertThat(prevForKey1).isEmpty(); + assertThat(prevForKey55).contains("val55"); + assertThat(dictionary.get(55)).isEqualTo("val56"); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldRemoveByKeys(MutableIntToRefDictionary dictionary) { + // given: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + + // when: + String removed1 = dictionary.remove(1); + String removed2 = dictionary.remove(55); + + // then: + assertThat(removed1).isEqualTo("val1"); + assertThat(removed2).isEqualTo("val55"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(7)).isEqualTo("val7"); + assertThat(dictionary.get(1)).isNull(); + assertThat(dictionary.get(55)).isNull(); + assertThat(dictionary.containsKey(1)).isFalse(); + assertThat(dictionary.containsKey(55)).isFalse(); + assertThat(dictionary.size()).isEqualTo(2); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldRemoveOptionalByKeys(MutableIntToRefDictionary dictionary) { + // given: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + + // when: + Optional removed1 = dictionary.removeOptional(1); + Optional removed2 = dictionary.removeOptional(75); + + // then: + assertThat(removed1).contains("val1"); + assertThat(removed2).isEmpty(); + assertThat(dictionary).hasSize(3); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldCorrectlyComputeOnGet(MutableIntToRefDictionary dictionary) { + // when: + var computed1 = dictionary.getOrCompute(1, () -> "val1"); + var computed2 = dictionary.getOrCompute(4, key -> "val4"); + var computed3 = dictionary.getOrCompute(10, 5, arg1 -> "val10"); + + // then: + assertThat(computed1).isEqualTo("val1"); + assertThat(computed2).isEqualTo("val4"); + assertThat(computed3).isEqualTo("val10"); + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(10)).isEqualTo("val10"); + assertThat(dictionary.containsKey(1)).isTrue(); + assertThat(dictionary.containsKey(4)).isTrue(); + assertThat(dictionary.containsKey(10)).isTrue(); + assertThat(dictionary.size()).isEqualTo(3); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldAppendDictionary(MutableIntToRefDictionary dictionary) { + // given: + IntToRefDictionary source = IntToRefDictionary.ofEntries( + entry(1, "val1"), + entry(2, "val2"), + entry(3, "val3"), + entry(4, "val4"), + entry(5, "val5")); + + // when: + dictionary.append(source); + + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(5)).isEqualTo("val5"); + assertThat(dictionary.containsKey(3)).isTrue(); + assertThat(dictionary.containsKey(55)).isFalse(); + assertThat(dictionary.get(10)).isNull(); + assertThat(dictionary.size()).isEqualTo(5); + } + + private static Stream generateDictionaries() { + return Stream.of(Arguments.of(DictionaryFactory.mutableIntToRefDictionary())); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java new file mode 100644 index 00000000..6c866bf9 --- /dev/null +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java @@ -0,0 +1,142 @@ +package javasabr.rlib.collections.dictionary; + +import static javasabr.rlib.collections.dictionary.LongToRefDictionary.entry; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Optional; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class MutableLongToRefDictionaryTest { + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldPutNewPairs(MutableLongToRefDictionary dictionary) { + // when: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(55)).isEqualTo("val55"); + assertThat(dictionary.containsKey(1)).isTrue(); + assertThat(dictionary.containsKey(4)).isTrue(); + assertThat(dictionary.containsKey(55)).isTrue(); + assertThat(dictionary.get(10)).isNull(); + assertThat(dictionary.size()).isEqualTo(4); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldPutOptionalNewPairs(MutableLongToRefDictionary dictionary) { + // when: + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + + Optional prevForKey1 = dictionary.putOptional(1, "val1"); + Optional prevForKey55 = dictionary.putOptional(55, "val56"); + + // then: + assertThat(prevForKey1).isEmpty(); + assertThat(prevForKey55).contains("val55"); + assertThat(dictionary.get(55)).isEqualTo("val56"); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldRemoveByKeys(MutableLongToRefDictionary dictionary) { + // given: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + + // when: + String removed1 = dictionary.remove(1); + String removed2 = dictionary.remove(55); + + // then: + assertThat(removed1).isEqualTo("val1"); + assertThat(removed2).isEqualTo("val55"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(7)).isEqualTo("val7"); + assertThat(dictionary.get(1)).isNull(); + assertThat(dictionary.get(55)).isNull(); + assertThat(dictionary.containsKey(1)).isFalse(); + assertThat(dictionary.containsKey(55)).isFalse(); + assertThat(dictionary.size()).isEqualTo(2); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldRemoveOptionalByKeys(MutableLongToRefDictionary dictionary) { + // given: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + dictionary.put(7, "val7"); + dictionary.put(55, "val55"); + + // when: + Optional removed1 = dictionary.removeOptional(1); + Optional removed2 = dictionary.removeOptional(75); + + // then: + assertThat(removed1).contains("val1"); + assertThat(removed2).isEmpty(); + assertThat(dictionary).hasSize(3); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldCorrectlyComputeOnGet(MutableLongToRefDictionary dictionary) { + // when: + var computed1 = dictionary.getOrCompute(1, () -> "val1"); + var computed2 = dictionary.getOrCompute(4, key -> "val4"); + var computed3 = dictionary.getOrCompute(10, 5, arg1 -> "val10"); + + // then: + assertThat(computed1).isEqualTo("val1"); + assertThat(computed2).isEqualTo("val4"); + assertThat(computed3).isEqualTo("val10"); + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(10)).isEqualTo("val10"); + assertThat(dictionary.containsKey(1)).isTrue(); + assertThat(dictionary.containsKey(4)).isTrue(); + assertThat(dictionary.containsKey(10)).isTrue(); + assertThat(dictionary.size()).isEqualTo(3); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldAppendDictionary(MutableLongToRefDictionary dictionary) { + // given: + LongToRefDictionary source = LongToRefDictionary.ofEntries( + entry(1, "val1"), + entry(2, "val2"), + entry(3, "val3"), + entry(4, "val4"), + entry(5, "val5")); + + // when: + dictionary.append(source); + + // then: + assertThat(dictionary.get(1)).isEqualTo("val1"); + assertThat(dictionary.get(4)).isEqualTo("val4"); + assertThat(dictionary.get(5)).isEqualTo("val5"); + assertThat(dictionary.containsKey(3)).isTrue(); + assertThat(dictionary.containsKey(55)).isFalse(); + assertThat(dictionary.get(10)).isNull(); + assertThat(dictionary.size()).isEqualTo(5); + } + + private static Stream generateDictionaries() { + return Stream.of(Arguments.of(DictionaryFactory.mutableLongToRefDictionary())); + } +} diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java index bdcdbf06..62000bb0 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java @@ -1,9 +1,10 @@ package javasabr.rlib.collections.dictionary; import static javasabr.rlib.collections.dictionary.RefToRefDictionary.entry; +import static org.assertj.core.api.Assertions.assertThat; +import java.util.Optional; import java.util.stream.Stream; -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; @@ -18,16 +19,32 @@ void shouldPutNewPairs(MutableRefToRefDictionary dictionary) { dictionary.put("key4", "val4"); dictionary.put("key7", "val7"); dictionary.put("key55", "val55"); + // then: + assertThat(dictionary.get("key1")).isEqualTo("val1"); + assertThat(dictionary.get("key4")).isEqualTo("val4"); + assertThat(dictionary.get("key55")).isEqualTo("val55"); + assertThat(dictionary.containsKey("key1")).isTrue(); + assertThat(dictionary.containsKey("key4")).isTrue(); + assertThat(dictionary.containsKey("key55")).isTrue(); + assertThat(dictionary.get("key10")).isNull(); + assertThat(dictionary.size()).isEqualTo(4); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldPutOptionalNewPairs(MutableRefToRefDictionary dictionary) { + // when: + dictionary.put("key4", "val4"); + dictionary.put("key7", "val7"); + dictionary.put("key55", "val55"); + + Optional prevForKey1 = dictionary.putOptional("key1", "val1"); + Optional prevForKey55 = dictionary.putOptional("key55", "val56"); // then: - Assertions.assertEquals("val1", dictionary.get("key1")); - Assertions.assertEquals("val4", dictionary.get("key4")); - Assertions.assertEquals("val55", dictionary.get("key55")); - Assertions.assertTrue(dictionary.containsKey("key1")); - Assertions.assertTrue(dictionary.containsKey("key4")); - Assertions.assertTrue(dictionary.containsKey("key55")); - Assertions.assertNull(dictionary.get("key10")); - Assertions.assertEquals(4, dictionary.size()); + assertThat(prevForKey1).isEmpty(); + assertThat(prevForKey55).contains("val55"); + assertThat(dictionary.get("key55")).isEqualTo("val56"); } @ParameterizedTest @@ -44,15 +61,34 @@ void shouldRemoveByKeys(MutableRefToRefDictionary dictionary) { String removed2 = dictionary.remove("key55"); // then: - Assertions.assertEquals("val1", removed1); - Assertions.assertEquals("val55", removed2); - Assertions.assertEquals("val4", dictionary.get("key4")); - Assertions.assertEquals("val7", dictionary.get("key7")); - Assertions.assertNull(dictionary.get("key1")); - Assertions.assertNull(dictionary.get("key55")); - Assertions.assertFalse(dictionary.containsKey("key1")); - Assertions.assertFalse(dictionary.containsKey("key55")); - Assertions.assertEquals(2, dictionary.size()); + assertThat(removed1).isEqualTo("val1"); + assertThat(removed2).isEqualTo("val55"); + assertThat(dictionary.get("key4")).isEqualTo("val4"); + assertThat(dictionary.get("key7")).isEqualTo("val7"); + assertThat(dictionary.get("key1")).isNull(); + assertThat(dictionary.get("key55")).isNull(); + assertThat(dictionary.containsKey("key1")).isFalse(); + assertThat(dictionary.containsKey("key55")).isFalse(); + assertThat(dictionary.size()).isEqualTo(2); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldRemoveOptionalByKeys(MutableRefToRefDictionary dictionary) { + // given: + dictionary.put("key1", "val1"); + dictionary.put("key4", "val4"); + dictionary.put("key7", "val7"); + dictionary.put("key55", "val55"); + + // when: + Optional removed1 = dictionary.removeOptional("key1"); + Optional removed2 = dictionary.removeOptional("key75"); + + // then: + assertThat(removed1).contains("val1"); + assertThat(removed2).isEmpty(); + assertThat(dictionary).hasSize(3); } @ParameterizedTest @@ -64,16 +100,16 @@ void shouldCorrectlyComputeOnGet(MutableRefToRefDictionary dicti var computed3 = dictionary.getOrCompute("key10", 5, arg1 -> "val10"); // then: - Assertions.assertEquals("val1", computed1); - Assertions.assertEquals("val4", computed2); - Assertions.assertEquals("val10", computed3); - Assertions.assertEquals("val1", dictionary.get("key1")); - Assertions.assertEquals("val4", dictionary.get("key4")); - Assertions.assertEquals("val10", dictionary.get("key10")); - Assertions.assertTrue(dictionary.containsKey("key1")); - Assertions.assertTrue(dictionary.containsKey("key4")); - Assertions.assertTrue(dictionary.containsKey("key10")); - Assertions.assertEquals(3, dictionary.size()); + assertThat(computed1).isEqualTo("val1"); + assertThat(computed2).isEqualTo("val4"); + assertThat(computed3).isEqualTo("val10"); + assertThat(dictionary.get("key1")).isEqualTo("val1"); + assertThat(dictionary.get("key4")).isEqualTo("val4"); + assertThat(dictionary.get("key10")).isEqualTo("val10"); + assertThat(dictionary.containsKey("key1")).isTrue(); + assertThat(dictionary.containsKey("key4")).isTrue(); + assertThat(dictionary.containsKey("key10")).isTrue(); + assertThat(dictionary.size()).isEqualTo(3); } @ParameterizedTest @@ -91,13 +127,13 @@ void shouldAppendDictionary(MutableRefToRefDictionary dictionary dictionary.append(source); // then: - Assertions.assertEquals("val1", dictionary.get("key1")); - Assertions.assertEquals("val4", dictionary.get("key4")); - Assertions.assertEquals("val5", dictionary.get("key5")); - Assertions.assertTrue(dictionary.containsKey("key3")); - Assertions.assertFalse(dictionary.containsKey("key55")); - Assertions.assertNull(dictionary.get("key10")); - Assertions.assertEquals(5, dictionary.size()); + assertThat(dictionary.get("key1")).isEqualTo("val1"); + assertThat(dictionary.get("key4")).isEqualTo("val4"); + assertThat(dictionary.get("key5")).isEqualTo("val5"); + assertThat(dictionary.containsKey("key3")).isTrue(); + assertThat(dictionary.containsKey("key55")).isFalse(); + assertThat(dictionary.get("key10")).isNull(); + assertThat(dictionary.size()).isEqualTo(5); } private static Stream generateDictionaries() { diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/RefToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/RefToRefDictionaryTest.java index 08d99e35..15c21f00 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/RefToRefDictionaryTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/RefToRefDictionaryTest.java @@ -1,6 +1,7 @@ package javasabr.rlib.collections.dictionary; import static javasabr.rlib.collections.dictionary.RefToRefDictionary.entry; +import static org.assertj.core.api.Assertions.assertThat; import java.util.HashSet; import java.util.Set; @@ -8,47 +9,78 @@ import javasabr.rlib.collections.array.Array; import javasabr.rlib.collections.array.MutableArray; import javasabr.rlib.common.tuple.Tuple; -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; class RefToRefDictionaryTest { + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldProvideCorrectSize(RefToRefDictionary dictionary) { + // then: + assertThat(dictionary.size()).isEqualTo(5); + assertThat(dictionary.isEmpty()).isFalse(); + } + + @ParameterizedTest + @MethodSource("generateEmptyDictionaries") + void shouldConfirmThatDictionaryIsEmpty(RefToRefDictionary dictionary) { + // then: + assertThat(dictionary.isEmpty()).isTrue(); + } + @ParameterizedTest @MethodSource("generateDictionaries") void shouldFindValuesByKeys(RefToRefDictionary dictionary) { // then: - Assertions.assertEquals("val1", dictionary.get("key1")); - Assertions.assertEquals("val3", dictionary.get("key3")); - Assertions.assertEquals("val4", dictionary.get("key4")); - Assertions.assertNull(dictionary.get("key10")); + assertThat(dictionary.get("key1")).isEqualTo("val1"); + assertThat(dictionary.get("key3")).isEqualTo("val3"); + assertThat(dictionary.get("key4")).isEqualTo("val4"); + assertThat(dictionary.get("key10")).isNull(); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldFindValuesByKeysOrReturnDefault(RefToRefDictionary dictionary) { + // then: + assertThat(dictionary.get("key1")).isEqualTo("val1"); + assertThat(dictionary.get("key10")).isNull(); + assertThat(dictionary.getOrDefault("key10", "def1")).isEqualTo("def1"); + assertThat(dictionary.getOrDefault("key30", "def2")).isEqualTo("def2"); + } + + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldReturnOptionalValuesByKeys(RefToRefDictionary dictionary) { + // then: + assertThat(dictionary.getOptional("key1")).contains("val1"); + assertThat(dictionary.getOptional("key10")).isEmpty(); } @ParameterizedTest @MethodSource("generateDictionaries") void shouldCheckContainsKeys(RefToRefDictionary dictionary) { // then: - Assertions.assertTrue(dictionary.containsKey("key1")); - Assertions.assertTrue(dictionary.containsKey("key2")); - Assertions.assertTrue(dictionary.containsKey("key5")); - Assertions.assertFalse(dictionary.containsKey("key10")); + assertThat(dictionary.containsKey("key1")).isTrue(); + assertThat(dictionary.containsKey("key2")).isTrue(); + assertThat(dictionary.containsKey("key5")).isTrue(); + assertThat(dictionary.containsKey("key10")).isFalse(); } @ParameterizedTest @MethodSource("generateDictionaries") void shouldCheckContainsValues(RefToRefDictionary dictionary) { // then: - Assertions.assertTrue(dictionary.containsValue("val1")); - Assertions.assertTrue(dictionary.containsValue("val3")); - Assertions.assertTrue(dictionary.containsValue("val4")); - Assertions.assertFalse(dictionary.containsValue("val10")); + assertThat(dictionary.containsValue("val1")).isTrue(); + assertThat(dictionary.containsValue("val3")).isTrue(); + assertThat(dictionary.containsValue("val4")).isTrue(); + assertThat(dictionary.containsValue("val10")).isFalse(); } @ParameterizedTest @MethodSource("generateDictionaries") void shouldHaveExpectedKeys(RefToRefDictionary dictionary) { - // given: var expectedArray = Array.typed(String.class, "key4", "key3", "key5", "key2", "key1"); var expectedSet = Set.copyOf(expectedArray.toList()); @@ -57,25 +89,24 @@ void shouldHaveExpectedKeys(RefToRefDictionary dictionary) { Array keys = dictionary.keys(String.class); // then: - Assertions.assertEquals(expectedArray, keys); + assertThat(keys).isEqualTo(expectedArray); // when: Array keys2 = dictionary.keys(MutableArray.ofType(String.class)); // then: - Assertions.assertEquals(expectedArray, keys2); + assertThat(keys2).isEqualTo(expectedArray); // when: Set keys3 = dictionary.keys(new HashSet<>()); // then: - Assertions.assertEquals(expectedSet, keys3); + assertThat(keys3).isEqualTo(expectedSet); } @ParameterizedTest @MethodSource("generateDictionaries") void shouldHaveExpectedValues(RefToRefDictionary dictionary) { - // given: var expectedArray = Array.typed(String.class, "val4", "val3", "val5", "val2", "val1"); var expectedSet = Set.copyOf(expectedArray.toList()); @@ -84,19 +115,19 @@ void shouldHaveExpectedValues(RefToRefDictionary dictionary) { Array values = dictionary.values(String.class); // then: - Assertions.assertEquals(expectedArray, values); + assertThat(values).isEqualTo(expectedArray); // when: Array values2 = dictionary.values(MutableArray.ofType(String.class)); // then: - Assertions.assertEquals(expectedArray, values2); + assertThat(values2).isEqualTo(expectedArray); // when: - Set keys3 = dictionary.values(new HashSet<>()); + Set values3 = dictionary.values(new HashSet<>()); // then: - Assertions.assertEquals(expectedSet, keys3); + assertThat(values3).isEqualTo(expectedSet); } @ParameterizedTest @@ -117,14 +148,14 @@ void shouldHaveExpectedResultFromForEach(RefToRefDictionary dict dictionary.forEach(values::add); // then: - Assertions.assertEquals(expectedArray, values); + assertThat(values).isEqualTo(expectedArray); // when: MutableArray pairs = MutableArray.ofType(Tuple.class); dictionary.forEach((key, value) -> pairs.add(new Tuple<>(key, value))); // then: - Assertions.assertEquals(expectedPairs, pairs); + assertThat(pairs).isEqualTo(expectedPairs); } private static Stream generateDictionaries() { @@ -141,4 +172,11 @@ private static Stream generateDictionaries() { Arguments.of(DictionaryFactory.mutableRefToRefDictionary().append(source)), Arguments.of(DictionaryFactory.stampedLockBasedRefToRefDictionary().append(source))); } + + private static Stream generateEmptyDictionaries() { + return Stream.of( + Arguments.of(RefToRefDictionary.empty()), + Arguments.of(DictionaryFactory.mutableRefToRefDictionary()), + Arguments.of(DictionaryFactory.stampedLockBasedRefToRefDictionary())); + } } diff --git a/rlib-common/src/main/java/javasabr/rlib/common/tuple/IntRefTuple.java b/rlib-common/src/main/java/javasabr/rlib/common/tuple/IntRefTuple.java new file mode 100644 index 00000000..4fd7fce2 --- /dev/null +++ b/rlib-common/src/main/java/javasabr/rlib/common/tuple/IntRefTuple.java @@ -0,0 +1,3 @@ +package javasabr.rlib.common.tuple; + +public record IntRefTuple(int left, R right) {} diff --git a/rlib-common/src/main/java/javasabr/rlib/common/tuple/LongRefTuple.java b/rlib-common/src/main/java/javasabr/rlib/common/tuple/LongRefTuple.java new file mode 100644 index 00000000..766e10ca --- /dev/null +++ b/rlib-common/src/main/java/javasabr/rlib/common/tuple/LongRefTuple.java @@ -0,0 +1,3 @@ +package javasabr.rlib.common.tuple; + +public record LongRefTuple(long left, R right) {} From d73354f03f4848dfc7469b3607c3bc66bbc66dd9 Mon Sep 17 00:00:00 2001 From: javasabr Date: Tue, 4 Nov 2025 20:09:13 +0100 Subject: [PATCH 6/8] add clear() method for dictionary --- .../dictionary/MutableIntToRefDictionary.java | 2 ++ .../MutableLongToRefDictionary.java | 2 ++ .../dictionary/MutableRefToRefDictionary.java | 2 ++ ...ctLockableHashBasedRefToRefDictionary.java | 6 +++++ ...ultMutableHashBasedIntToRefDictionary.java | 6 +++++ ...ltMutableHashBasedLongToRefDictionary.java | 6 +++++ ...ultMutableHashBasedRefToRefDictionary.java | 6 +++++ .../MutableIntToRefDictionaryTest.java | 23 ++++++++++++++++++- .../MutableLongToRefDictionaryTest.java | 23 ++++++++++++++++++- .../MutableRefToRefDictionaryTest.java | 20 ++++++++++++++++ 10 files changed, 94 insertions(+), 2 deletions(-) diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java index 874993a8..caa6f304 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionary.java @@ -45,5 +45,7 @@ static MutableIntToRefDictionary ofTypes(Class valueType) { */ Optional removeOptional(int key); + void clear(); + IntToRefDictionary toReadOnly(); } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java index b9b113bb..b1b49f37 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionary.java @@ -45,5 +45,7 @@ static MutableLongToRefDictionary ofTypes(Class valueType) { */ Optional removeOptional(long key); + void clear(); + LongToRefDictionary toReadOnly(); } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java index 8da6d25b..ca6cace4 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionary.java @@ -46,5 +46,7 @@ static MutableRefToRefDictionary ofTypes( */ Optional removeOptional(K key); + void clear(); + RefToRefDictionary toReadOnly(); } diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/AbstractLockableHashBasedRefToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/AbstractLockableHashBasedRefToRefDictionary.java index a9b59ce1..c7ec8693 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/AbstractLockableHashBasedRefToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/AbstractLockableHashBasedRefToRefDictionary.java @@ -53,6 +53,12 @@ protected int decrementSize() { return size.decrementAndGet(); } + @Override + public void clear() { + Arrays.fill(entries(), null); + size.set(0); + } + @Override protected void threshold(int threshold) { this.threshold = threshold; diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedIntToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedIntToRefDictionary.java index b7081081..22650d17 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedIntToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedIntToRefDictionary.java @@ -44,6 +44,12 @@ protected int decrementSize() { return size--; } + @Override + public void clear() { + Arrays.fill(entries, null); + size = 0; + } + @Override protected void threshold(int threshold) { this.threshold = threshold; diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedLongToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedLongToRefDictionary.java index 68818fc9..621d7522 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedLongToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedLongToRefDictionary.java @@ -44,6 +44,12 @@ protected int decrementSize() { return size--; } + @Override + public void clear() { + Arrays.fill(entries, null); + size = 0; + } + @Override protected void threshold(int threshold) { this.threshold = threshold; diff --git a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedRefToRefDictionary.java b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedRefToRefDictionary.java index 3429704e..40529799 100644 --- a/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedRefToRefDictionary.java +++ b/rlib-collections/src/main/java/javasabr/rlib/collections/dictionary/impl/DefaultMutableHashBasedRefToRefDictionary.java @@ -44,6 +44,12 @@ protected int decrementSize() { return size--; } + @Override + public void clear() { + Arrays.fill(entries, null); + size = 0; + } + @Override protected void threshold(int threshold) { this.threshold = threshold; diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java index 03770569..a018f9e9 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableIntToRefDictionaryTest.java @@ -136,7 +136,28 @@ void shouldAppendDictionary(MutableIntToRefDictionary dictionary) { assertThat(dictionary.size()).isEqualTo(5); } + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldBeEmptyAfterClear(MutableIntToRefDictionary dictionary) { + // when: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + + // then: + assertThat(dictionary.isEmpty()).isFalse(); + + // when: + dictionary.clear(); + + // then: + assertThat(dictionary.isEmpty()).isTrue(); + assertThat(dictionary.get(1)).isNull(); + assertThat(dictionary.containsKey(1)).isFalse(); + } + private static Stream generateDictionaries() { - return Stream.of(Arguments.of(DictionaryFactory.mutableIntToRefDictionary())); + return Stream.of( + Arguments.of(MutableIntToRefDictionary.ofTypes(String.class)), + Arguments.of(DictionaryFactory.mutableIntToRefDictionary())); } } diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java index 6c866bf9..d26392ed 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableLongToRefDictionaryTest.java @@ -136,7 +136,28 @@ void shouldAppendDictionary(MutableLongToRefDictionary dictionary) { assertThat(dictionary.size()).isEqualTo(5); } + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldBeEmptyAfterClear(MutableLongToRefDictionary dictionary) { + // when: + dictionary.put(1, "val1"); + dictionary.put(4, "val4"); + + // then: + assertThat(dictionary.isEmpty()).isFalse(); + + // when: + dictionary.clear(); + + // then: + assertThat(dictionary.isEmpty()).isTrue(); + assertThat(dictionary.get(1)).isNull(); + assertThat(dictionary.containsKey(1)).isFalse(); + } + private static Stream generateDictionaries() { - return Stream.of(Arguments.of(DictionaryFactory.mutableLongToRefDictionary())); + return Stream.of( + Arguments.of(MutableLongToRefDictionary.ofTypes(String.class)), + Arguments.of(DictionaryFactory.mutableLongToRefDictionary())); } } diff --git a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java index 62000bb0..85bb1344 100644 --- a/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java +++ b/rlib-collections/src/test/java/javasabr/rlib/collections/dictionary/MutableRefToRefDictionaryTest.java @@ -112,6 +112,25 @@ void shouldCorrectlyComputeOnGet(MutableRefToRefDictionary dicti assertThat(dictionary.size()).isEqualTo(3); } + @ParameterizedTest + @MethodSource("generateDictionaries") + void shouldBeEmptyAfterClear(MutableRefToRefDictionary dictionary) { + // when: + dictionary.put("key1", "val1"); + dictionary.put("key4", "val4"); + + // then: + assertThat(dictionary.isEmpty()).isFalse(); + + // when: + dictionary.clear(); + + // then: + assertThat(dictionary.isEmpty()).isTrue(); + assertThat(dictionary.get("key1")).isNull(); + assertThat(dictionary.containsKey("key1")).isFalse(); + } + @ParameterizedTest @MethodSource("generateDictionaries") void shouldAppendDictionary(MutableRefToRefDictionary dictionary) { @@ -138,6 +157,7 @@ void shouldAppendDictionary(MutableRefToRefDictionary dictionary private static Stream generateDictionaries() { return Stream.of( + Arguments.of(MutableRefToRefDictionary.ofTypes(String.class, String.class)), Arguments.of(DictionaryFactory.mutableRefToRefDictionary()), Arguments.of(DictionaryFactory.stampedLockBasedRefToRefDictionary())); } From e4b33136a257b0e3de91aad45297d34bfe5a1c64 Mon Sep 17 00:00:00 2001 From: javasabr Date: Tue, 4 Nov 2025 21:14:55 +0100 Subject: [PATCH 7/8] add numbered util map for enums --- .../rlib/common/util/NumberedEnum.java | 6 ++ .../rlib/common/util/NumberedEnumMap.java | 46 +++++++++++++++ .../rlib/common/util/NumberedEnumMapTest.java | 58 +++++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnum.java create mode 100644 rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java create mode 100644 rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java diff --git a/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnum.java b/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnum.java new file mode 100644 index 00000000..32e802a1 --- /dev/null +++ b/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnum.java @@ -0,0 +1,6 @@ +package javasabr.rlib.common.util; + +public interface NumberedEnum> { + + int number(); +} diff --git a/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java b/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java new file mode 100644 index 00000000..612298dd --- /dev/null +++ b/rlib-common/src/main/java/javasabr/rlib/common/util/NumberedEnumMap.java @@ -0,0 +1,46 @@ +package javasabr.rlib.common.util; + +import java.util.stream.Stream; +import lombok.CustomLog; +import org.jspecify.annotations.Nullable; + +@CustomLog +public class NumberedEnumMap & NumberedEnum> { + + T[] values; + + public NumberedEnumMap(Class enumClass) { + + T[] enumConstants = enumClass.getEnumConstants(); + int maxIndex = Stream + .of(enumConstants) + .mapToInt(NumberedEnum::number) + .max() + .orElse(0); + + T[] indexedConstants = ArrayUtils.create(enumClass, maxIndex + 1); + for (T enumConstant : enumConstants) { + indexedConstants[enumConstant.number()] = enumConstant; + } + + values = indexedConstants; + } + + @Nullable + public T resolve(int number) { + try { + return values[number]; + } catch (IndexOutOfBoundsException e) { + log.warning(e.getMessage()); + return null; + } + } + + public T require(int number) { + T constant = resolve(number); + if (constant == null) { + throw new IllegalArgumentException("Unknown enum constant for number:" + number); + } + return constant; + } +} diff --git a/rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java b/rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java new file mode 100644 index 00000000..35b79730 --- /dev/null +++ b/rlib-common/src/test/java/javasabr/rlib/common/util/NumberedEnumMapTest.java @@ -0,0 +1,58 @@ +package javasabr.rlib.common.util; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import org.jspecify.annotations.NonNull; +import org.junit.jupiter.api.Test; + +class NumberedEnumMapTest { + + public enum TestEnum implements NumberedEnum<@NonNull TestEnum> { + CONSTANT1(4), + CONSTANT2(13), + CONSTANT3(9), + CONSTANT4(25), + CONSTANT5(1); + + private static final NumberedEnumMap MAP = new NumberedEnumMap<>(TestEnum.class); + + private final int number; + + TestEnum(int number) { + this.number = number; + } + + @Override + public int number() { + return number; + } + } + + @Test + void shouldResolveEnumByNumber() { + // when\then: + assertThat(TestEnum.MAP.resolve(4)).isEqualTo(TestEnum.CONSTANT1); + assertThat(TestEnum.MAP.resolve(13)).isEqualTo(TestEnum.CONSTANT2); + assertThat(TestEnum.MAP.resolve(9)).isEqualTo(TestEnum.CONSTANT3); + assertThat(TestEnum.MAP.resolve(25)).isEqualTo(TestEnum.CONSTANT4); + assertThat(TestEnum.MAP.resolve(900)).isNull(); + assertThat(TestEnum.MAP.resolve(-50)).isNull(); + assertThat(TestEnum.MAP.resolve(24)).isNull(); + } + + @Test + void shouldRequireEnumByNumber() { + // when\then: + assertThat(TestEnum.MAP.require(4)).isEqualTo(TestEnum.CONSTANT1); + assertThat(TestEnum.MAP.require(13)).isEqualTo(TestEnum.CONSTANT2); + assertThat(TestEnum.MAP.require(9)).isEqualTo(TestEnum.CONSTANT3); + assertThat(TestEnum.MAP.require(25)).isEqualTo(TestEnum.CONSTANT4); + assertThatThrownBy(() -> TestEnum.MAP.require(900)) + .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> TestEnum.MAP.require(-50)) + .isInstanceOf(IllegalArgumentException.class); + assertThatThrownBy(() -> TestEnum.MAP.require(24)) + .isInstanceOf(IllegalArgumentException.class); + } +} From 8e249bdd9e7f60ade43d8b3c5618b6b5e303cbc9 Mon Sep 17 00:00:00 2001 From: javasabr Date: Wed, 5 Nov 2025 18:59:28 +0100 Subject: [PATCH 8/8] small updates --- README.md | 12 ++--- .../rlib/mail/sender/MailSenderConfig.java | 2 +- .../mail/sender/impl/JavaxMailSender.java | 48 +++++++------------ 3 files changed, 23 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 8e5df243..b1e40da9 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ dependencies { ### Fake SMTP Server ```java + var container = new FakeSMTPTestContainer() .withSmtpPassword("pwd") .withSmtpUser("test_user"); @@ -92,19 +93,15 @@ LoggerLevel.DEBUG.setEnabled(true); logger.debug("Simple message"); logger.debug(5, (val) -> "Lazy message with 5: " + val); +logger.debug(5, "Lazy message with 5:%d"::formated); logger.debug(5, 10D, (val1, val2) -> "Lazy message with 5: " + val1 + " and 10: " + val2); -logger.debug("", "Message with a string owner."); -logger.debug("", 5, (val) -> "Lazy message with 5: " + val); -logger.debug("", 5, 10D, (val1, val2) -> "Lazy message with 5: " + val1 + " and 10: " + val2); +logger.debug(5, 10D, "Lazy message with 5:%d and 10:%d"::formatted); // global disable debug level LoggerLevel.DEBUG.setEnabled(false); // local enable debug level only for this logger instance logger.setEnabled(LoggerLevel.DEBUG, true); - -// show debug message -logger.debug("Showed"); ``` ### Mail Sender @@ -132,10 +129,9 @@ var javaxConfig = JavaxMailSender.JavaxMailSenderConfig var sender = new JavaxMailSender(config, javaxConfig); sender.send("to@test.com","Test Subject","Content"); - sender .sendAsync("to@test.com","Test Subject","Content") - .thenAccept(aVoid ->System.out.println("done!")); + .thenAccept(aVoid -> System.out.println("done!")); ``` ### Network API diff --git a/rlib-mail/src/main/java/javasabr/rlib/mail/sender/MailSenderConfig.java b/rlib-mail/src/main/java/javasabr/rlib/mail/sender/MailSenderConfig.java index 79135665..37446a70 100644 --- a/rlib-mail/src/main/java/javasabr/rlib/mail/sender/MailSenderConfig.java +++ b/rlib-mail/src/main/java/javasabr/rlib/mail/sender/MailSenderConfig.java @@ -16,5 +16,5 @@ public class MailSenderConfig { private String from; private boolean useAuth; - private boolean enableTtls; + private boolean enableTls; } diff --git a/rlib-mail/src/main/java/javasabr/rlib/mail/sender/impl/JavaxMailSender.java b/rlib-mail/src/main/java/javasabr/rlib/mail/sender/impl/JavaxMailSender.java index 72666dea..d430d62b 100644 --- a/rlib-mail/src/main/java/javasabr/rlib/mail/sender/impl/JavaxMailSender.java +++ b/rlib-mail/src/main/java/javasabr/rlib/mail/sender/impl/JavaxMailSender.java @@ -20,26 +20,22 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import javasabr.rlib.logger.api.Logger; -import javasabr.rlib.logger.api.LoggerManager; import javasabr.rlib.mail.sender.MailSender; import javasabr.rlib.mail.sender.MailSenderConfig; import javasabr.rlib.mail.sender.exception.UncheckedMessagingException; import lombok.Builder; +import lombok.CustomLog; import lombok.Getter; +@CustomLog public class JavaxMailSender implements MailSender { - private static final Logger LOGGER = LoggerManager.getLogger(JavaxMailSender.class); - @Getter @Builder public static class JavaxMailSenderConfig { - private int executorMinThreads; private int executorMaxThreads; private int executorKeepAlive; - private Executor executor; } @@ -48,13 +44,12 @@ public static class JavaxMailSenderConfig { private final InternetAddress from; public JavaxMailSender(MailSenderConfig config) { - this(config, - JavaxMailSenderConfig - .builder() - .executorKeepAlive(60) - .executorMinThreads(1) - .executorMaxThreads(2) - .build()); + this(config, JavaxMailSenderConfig + .builder() + .executorKeepAlive(60) + .executorMinThreads(1) + .executorMaxThreads(2) + .build()); } public JavaxMailSender(MailSenderConfig config, JavaxMailSenderConfig javaxConfig) { @@ -64,7 +59,7 @@ public JavaxMailSender(MailSenderConfig config, JavaxMailSenderConfig javaxConfi prop.put("mail.smtp.host", config.getHost()); prop.put("mail.smtp.port", String.valueOf(config.getPort())); - if (config.isEnableTtls()) { + if (config.isEnableTls()) { prop.put("mail.smtp.socketFactory.port", String.valueOf(config.getPort())); prop.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); prop.put("mail.smtp.starttls.enable", "true"); @@ -82,18 +77,17 @@ protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); - try { this.from = new InternetAddress(config.getFrom()); } catch (AddressException e) { throw new RuntimeException(e); } - LOGGER.info("Initialized javax mail sender with settings:"); - LOGGER.info("User : " + username); - LOGGER.info("From : " + config.getFrom()); - LOGGER.info("Server : " + config.getHost() + ":" + config.getPort()); - LOGGER.info("Using SSL : " + config.isEnableTtls()); + log.info("Initialized javax mail sender with settings:"); + log.info(username, "User:[%s]"::formatted); + log.info(config.getFrom(), "From:[%s]"::formatted); + log.info(config.getHost(), config.getPort(), "Server:[%s:%d]"::formatted); + log.info(config.isEnableTls(), "Using SSL:[%s]"::formatted); if (javaxConfig.getExecutor() != null) { this.executor = javaxConfig.getExecutor(); @@ -111,24 +105,18 @@ protected PasswordAuthentication getPasswordAuthentication() { @Override public void send(String email, String subject, String content) { - try { - - var message = new MimeMessage(session); - message.setFrom(from); - message.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(email)); - message.setSubject(subject, StandardCharsets.UTF_8.name()); - var mimeBodyPart = new MimeBodyPart(); mimeBodyPart.setContent(content, "text/html; charset=UTF-8"); - var multipart = new MimeMultipart(); multipart.addBodyPart(mimeBodyPart); + var message = new MimeMessage(session); + message.setFrom(from); + message.setRecipients(MimeMessage.RecipientType.TO, InternetAddress.parse(email)); + message.setSubject(subject, StandardCharsets.UTF_8.name()); message.setContent(multipart); - Transport.send(message); - } catch (MessagingException e) { throw new UncheckedMessagingException(e); }