diff --git a/src/main/java/org/kiwiproject/base/KiwiPreconditions.java b/src/main/java/org/kiwiproject/base/KiwiPreconditions.java index 4fda8684..36e6748c 100644 --- a/src/main/java/org/kiwiproject/base/KiwiPreconditions.java +++ b/src/main/java/org/kiwiproject/base/KiwiPreconditions.java @@ -11,8 +11,10 @@ import com.google.common.base.Preconditions; import lombok.SneakyThrows; import lombok.experimental.UtilityClass; +import org.kiwiproject.collect.KiwiMaps; import java.util.Collection; +import java.util.Map; import java.util.function.IntSupplier; import java.util.function.Supplier; @@ -255,12 +257,6 @@ public static void checkArgumentIsNull(T reference, String errorMessageTempl } } - private static IllegalArgumentException newIllegalArgumentException(String errorMessageTemplate, - Object... errorMessageArgs) { - var errorMessage = format(errorMessageTemplate, errorMessageArgs); - return new IllegalArgumentException(errorMessage); - } - /** * Ensures that the string passed as a parameter to the calling method is not null, empty or blank, throwing * an {@link IllegalArgumentException} if it is null, empty, or blank. @@ -335,6 +331,107 @@ public static void checkArgumentIsBlank(String string, String errorMessageTempla } } + /** + * Ensures that the collection passed as a parameter to the calling method is not null or empty. + * Throws an {@link IllegalArgumentException} if the collection is null or empty. + * + * @param collection a collection, possibly null + * @param the type of object in the collection + */ + public static void checkArgumentNotEmpty(Collection collection) { + Preconditions.checkArgument(isNotNullOrEmpty(collection)); + } + + /** + * Ensures that the collection passed as a parameter to the calling method is not null or empty. + * Throws an {@link IllegalArgumentException} if the collection is null or empty. + * + * @param collection a collection, possibly null + * @param errorMessage the error message for the exception + * @param the type of object in the collection + */ + public static void checkArgumentNotEmpty(Collection collection, String errorMessage) { + Preconditions.checkArgument(isNotNullOrEmpty(collection), errorMessage); + } + + /** + * Ensures that the collection passed as a parameter to the calling method is not null or empty. + * Throws an {@link IllegalArgumentException} if the collection is null or empty. + * + * @param collection a collection, possibly null + * @param errorMessageTemplate a template for the exception message should the check fail, according to how + * {@link KiwiStrings#format(String, Object...)} handles placeholders + * @param errorMessageArgs the arguments to be substituted into the message template. Arguments + * are converted to Strings using {@link String#valueOf(Object)}. + * @param the type of object in the collection + */ + public static void checkArgumentNotEmpty(Collection collection, + String errorMessageTemplate, + Object... errorMessageArgs) { + if (isNullOrEmpty(collection)) { + throw newIllegalArgumentException(errorMessageTemplate, errorMessageArgs); + } + } + + private static boolean isNotNullOrEmpty(Collection collection) { + return !isNullOrEmpty(collection); + } + + private static boolean isNullOrEmpty(Collection collection) { + return isNull(collection) || collection.isEmpty(); + } + + /** + * Ensures that the map passed as a parameter to the calling method is not null or empty. + * Throws an {@link IllegalArgumentException} if the map is null or empty. + * + * @param map a map, possibly null + * @param the type of keys in the map + * @param the type of values in the map + */ + public static void checkArgumentNotEmpty(Map map) { + Preconditions.checkArgument(KiwiMaps.isNotNullOrEmpty(map)); + } + + /** + * Ensures that the map passed as a parameter to the calling method is not null or empty. + * Throws an {@link IllegalArgumentException} if the map is null or empty. + * + * @param map a map, possibly null + * @param errorMessage the error message for the exception + * @param the type of keys in the map + * @param the type of values in the map + */ + public static void checkArgumentNotEmpty(Map map, String errorMessage) { + Preconditions.checkArgument(KiwiMaps.isNotNullOrEmpty(map), errorMessage); + } + + /** + * Ensures that the map passed as a parameter to the calling method is not null or empty. + * Throws an {@link IllegalArgumentException} if the map is null or empty. + * + * @param map a map, possibly null + * @param errorMessageTemplate a template for the exception message should the check fail, according to how + * {@link KiwiStrings#format(String, Object...)} handles placeholders + * @param errorMessageArgs the arguments to be substituted into the message template. Arguments + * are converted to Strings using {@link String#valueOf(Object)}. + * @param the type of keys in the map + * @param the type of values in the map + */ + public static void checkArgumentNotEmpty(Map map, + String errorMessageTemplate, + Object... errorMessageArgs) { + if (KiwiMaps.isNullOrEmpty(map)) { + throw newIllegalArgumentException(errorMessageTemplate, errorMessageArgs); + } + } + + private static IllegalArgumentException newIllegalArgumentException(String errorMessageTemplate, + Object... errorMessageArgs) { + var errorMessage = format(errorMessageTemplate, errorMessageArgs); + return new IllegalArgumentException(errorMessage); + } + /** * Ensures that a collection of items has an even count, throwing an {@link IllegalArgumentException} if * items is null or there is an odd number of items. diff --git a/src/test/java/org/kiwiproject/base/KiwiPreconditionsTest.java b/src/test/java/org/kiwiproject/base/KiwiPreconditionsTest.java index b1671f75..4d3cbaaa 100644 --- a/src/test/java/org/kiwiproject/base/KiwiPreconditionsTest.java +++ b/src/test/java/org/kiwiproject/base/KiwiPreconditionsTest.java @@ -22,11 +22,15 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ArgumentsSource; +import org.junit.jupiter.params.provider.NullAndEmptySource; import org.junit.jupiter.params.provider.ValueSource; import org.kiwiproject.util.BlankStringArgumentsProvider; import java.math.BigInteger; import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; @DisplayName("KiwiPreconditions") @ExtendWith(SoftAssertionsExtension.class) @@ -312,6 +316,158 @@ void shouldThrowIllegalArgument_WhenArgumentIsNotBlank() { } } + @Nested + class CheckCollectionArgumentNotEmpty { + + @Nested + class WithNoMessage { + + @Test + void shouldNotThrow_WhenArgumentIsNotEmpty() { + assertThatCode(() -> KiwiPreconditions.checkArgumentNotEmpty(List.of(1))) + .doesNotThrowAnyException(); + + assertThatCode(() -> KiwiPreconditions.checkArgumentNotEmpty(Set.of(42))) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenListArgument_IsNullOrEmpty(List list) { + assertThatIllegalArgumentException() + .isThrownBy(() -> KiwiPreconditions.checkArgumentNotEmpty(list)); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenSetArgument_IsNullOrEmpty(Set set) { + assertThatIllegalArgumentException() + .isThrownBy(() -> KiwiPreconditions.checkArgumentNotEmpty(set)); + } + } + + @Nested + class WithMessage { + + @Test + void shouldNotThrow_WhenArgumentIsNotEmpty() { + assertThatCode(() -> KiwiPreconditions.checkArgumentNotEmpty(List.of(1), "invalid list")) + .doesNotThrowAnyException(); + + assertThatCode(() -> KiwiPreconditions.checkArgumentNotEmpty(Set.of(42), "invalid set")) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenListArgument_IsNullOrEmpty(List list) { + assertThatIllegalArgumentException() + .isThrownBy(() -> KiwiPreconditions.checkArgumentNotEmpty(list, "invalid list")) + .withMessage("invalid list"); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenSetArgument_IsNullOrEmpty(Set set) { + assertThatIllegalArgumentException() + .isThrownBy(() -> KiwiPreconditions.checkArgumentNotEmpty(set, "invalid set")) + .withMessage("invalid set"); + } + } + + @Nested + class WithMessageTemplate { + + @Test + void shouldNotThrow_WhenArgumentIsNotEmpty() { + assertThatCode(() -> + KiwiPreconditions.checkArgumentNotEmpty(List.of(1), "bad {} map", "foo")) + .doesNotThrowAnyException(); + + assertThatCode(() -> + KiwiPreconditions.checkArgumentNotEmpty(Set.of(42), "bad {} set", "bar")) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenListArgument_IsNullOrEmpty(List list) { + assertThatIllegalArgumentException() + .isThrownBy(() -> + KiwiPreconditions.checkArgumentNotEmpty(list, "bad {} list", "bar")) + .withMessage("bad bar list"); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenSetArgument_IsNullOrEmpty(Set set) { + assertThatIllegalArgumentException() + .isThrownBy(() -> + KiwiPreconditions.checkArgumentNotEmpty(set, "bad {} set", "foo")) + .withMessage("bad foo set"); + } + } + } + + @Nested + class CheckMapArgumentNotEmpty { + + @Nested + class WithNoMessage { + + @Test + void shouldNotThrow_WhenArgumentIsNotEmpty() { + assertThatCode(() -> KiwiPreconditions.checkArgumentNotEmpty(Map.of("k1", "v1"))) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenArgument_IsNullOrEmpty(Map map) { + assertThatIllegalArgumentException() + .isThrownBy(() -> KiwiPreconditions.checkArgumentNotEmpty(map)); + } + } + + @Nested + class WithMessage { + + @Test + void shouldNotThrow_WhenArgumentIsNotEmpty() { + assertThatCode(() -> + KiwiPreconditions.checkArgumentNotEmpty(Map.of("k1", "v1"), "invalid map")) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenArgument_IsNullOrEmpty(Map map) { + assertThatIllegalArgumentException() + .isThrownBy(() -> KiwiPreconditions.checkArgumentNotEmpty(map, "invalid map")); + } + } + + @Nested + class WithMessageTemplate { + + @Test + void shouldNotThrow_WhenArgumentIsNotEmpty() { + assertThatCode(() -> + KiwiPreconditions.checkArgumentNotEmpty(Map.of("k1", "v1"), "invalid {} {} map", "foo", "bar")) + .doesNotThrowAnyException(); + } + + @ParameterizedTest + @NullAndEmptySource + void shouldThrowWhenArgument_IsNullOrEmpty(Map map) { + assertThatIllegalArgumentException() + .isThrownBy(() -> + KiwiPreconditions.checkArgumentNotEmpty(map, "invalid {} {} map", "foo", "bar")) + .withMessage("invalid foo bar map"); + } + } + } + @SuppressWarnings("unused") static class SomeCheckedException extends Exception {