diff --git a/src/main/java/org/kiwiproject/base/KiwiPrimitives.java b/src/main/java/org/kiwiproject/base/KiwiPrimitives.java index ef8d7d33..bf408272 100644 --- a/src/main/java/org/kiwiproject/base/KiwiPrimitives.java +++ b/src/main/java/org/kiwiproject/base/KiwiPrimitives.java @@ -174,4 +174,51 @@ public static double tryParseDoubleOrThrow(CharSequence cs) { throw new IllegalStateException(e); } } + + /** + * Enum representing options for converting a numeric value into a boolean. + */ + public enum BooleanConversionOption { + + /** + * Convert numeric values into boolean where one represents true and zero + * represents false. No other values are allowed. + */ + ZERO_OR_ONE, + + /** + * Convert numeric values into boolean where any non-zero value + * represents true, and zero represents false. + */ + NON_ZERO_AS_TRUE + } + + /** + * Converts the given long value to a boolean. The value must be zero or one. + * + * @param value the value to convert + * @return true if the value is one, or false if zero + * @throws IllegalArgumentException if the value in the column is not zero, one, or NULL + * @see #booleanFromLong(long, BooleanConversionOption) + */ + public static boolean booleanFromLong(long value) { + return booleanFromLong(value, BooleanConversionOption.ZERO_OR_ONE); + } + + /** + * Converts the given long value to a boolean using the specified {@link BooleanConversionOption}. + * + * @param value the value to convert + * @param option how to convert the long value into a boolean + * @return true if the value is non-zero, otherwise false + */ + public static boolean booleanFromLong(long value, BooleanConversionOption option) { + return switch (option) { + case ZERO_OR_ONE -> { + checkArgument(value == 0 || value == 1, "value must be 0 or 1, but found %s", value); + yield value == 1; + } + case NON_ZERO_AS_TRUE -> value != 0; + }; + } } diff --git a/src/test/java/org/kiwiproject/base/KiwiPrimitivesTest.java b/src/test/java/org/kiwiproject/base/KiwiPrimitivesTest.java index 9272bab0..a13a828b 100644 --- a/src/test/java/org/kiwiproject/base/KiwiPrimitivesTest.java +++ b/src/test/java/org/kiwiproject/base/KiwiPrimitivesTest.java @@ -1,6 +1,7 @@ package org.kiwiproject.base; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.assertj.core.api.Assertions.assertThatIllegalStateException; import org.assertj.core.api.SoftAssertions; @@ -10,6 +11,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import org.junit.jupiter.params.provider.NullAndEmptySource; import org.junit.jupiter.params.provider.ValueSource; @@ -81,7 +83,7 @@ void shouldReturnEmptyOptional_WhenArgumentIsNotParseableToInt(String string) { class TryParseIntOrThrow { @Test - void shouldReturInt_WhenArgumentIsParseableToInt() { + void shouldReturnInt_WhenArgumentIsParseableToInt() { assertThat(KiwiPrimitives.tryParseIntOrThrow("126")).isEqualTo(126); } @@ -149,7 +151,7 @@ void shouldReturnEmptyOptional_WhenArgumentIsNotParseableToLong(String string) { class TryParseLongOrThrow { @Test - void shouldReturLong_WhenArgumentIsParseableToLong() { + void shouldReturnLong_WhenArgumentIsParseableToLong() { assertThat(KiwiPrimitives.tryParseLongOrThrow("1260000")).isEqualTo(1_260_000L); } @@ -217,7 +219,7 @@ void shouldReturnEmptyOptional_WhenArgumentIsNotParseableToDouble(String string) class TryParseDoubleOrThrow { @Test - void shouldReturDouble_WhenArgumentIsParseableToDouble() { + void shouldReturnDouble_WhenArgumentIsParseableToDouble() { assertThat(KiwiPrimitives.tryParseDoubleOrThrow("1260000.042")).isEqualTo(1_260_000.042); } @@ -238,4 +240,41 @@ void shouldThrow_WhenArgumentIsNotParseableToDouble(String string) { .withCauseExactlyInstanceOf(NumberFormatException.class); } } + + @Nested + class BooleanFromLong { + + @ParameterizedTest + @CsvSource(textBlock = """ + 1, true, + 0, false + """) + void shouldConvertLong_WithZeroOrOneConversionOption(long value, boolean expectedResult) { + assertThat(KiwiPrimitives.booleanFromLong(value)).isEqualTo(expectedResult); + } + + @ParameterizedTest + @ValueSource(longs = { -10, -5, -1, 2, 10, 42 }) + void shouldThrowIllegalArgument_WithZeroOrOneConversionOption_WhenValueIsNotZeroOrOne(long value) { + assertThatIllegalArgumentException() + .isThrownBy(() -> KiwiPrimitives.booleanFromLong(value)) + .withMessage("value must be 0 or 1, but found %d", value); + } + + @ParameterizedTest + @CsvSource(textBlock = """ + 1, ZERO_OR_ONE, true, + 1, NON_ZERO_AS_TRUE, true, + -1, NON_ZERO_AS_TRUE, true, + 2, NON_ZERO_AS_TRUE, true, + 1000, NON_ZERO_AS_TRUE, true, + 0, ZERO_OR_ONE, false + 0, NON_ZERO_AS_TRUE, false + """) + void shouldConvertLong_UsingBooleanConversionOption(long value, + KiwiPrimitives.BooleanConversionOption option, + boolean expectedResult) { + assertThat(KiwiPrimitives.booleanFromLong(value, option)).isEqualTo(expectedResult); + } + } }