diff --git a/subprojects/library/src/api/types.api b/subprojects/library/src/api/types.api index b1b6f6919..5fbbd3ea3 100644 --- a/subprojects/library/src/api/types.api +++ b/subprojects/library/src/api/types.api @@ -457,6 +457,7 @@ public final class org/kotools/types/Zero { public static final field Companion Lorg/kotools/types/Zero$Companion; public static final field PATTERN Ljava/lang/String; public fun ()V + public fun (Ljava/lang/Object;)V public final fun compareTo (B)I public final fun compareTo (D)I public final fun compareTo (F)I diff --git a/subprojects/library/src/commonMain/kotlin/org/kotools/types/Zero.kt b/subprojects/library/src/commonMain/kotlin/org/kotools/types/Zero.kt index 06389f28a..dc06be9c4 100644 --- a/subprojects/library/src/commonMain/kotlin/org/kotools/types/Zero.kt +++ b/subprojects/library/src/commonMain/kotlin/org/kotools/types/Zero.kt @@ -43,9 +43,44 @@ public class Zero { * SAMPLE: [org.kotools.types.ZeroJavaSample.secondaryConstructor] * */ - @Suppress("ConvertSecondaryConstructorToPrimary") public constructor() + /** + * Creates an instance of [Zero] from the string representation of the + * specified [number], or throws an [IllegalArgumentException] if the string + * representation of [number] doesn't match [Zero.PATTERN]. + * + *
+ *
+ * + * Calling from Kotlin + * + * + * Here's an example of calling this constructor from Kotlin code: + * + * SAMPLE: [org.kotools.types.ZeroCommonSample.constructorAny] + *
+ * + *
+ *
+ * + * Calling from Java + * + * + * Here's an example of calling this constructor from Java code: + * + * SAMPLE: [org.kotools.types.ZeroJavaSample.constructorAny] + *
+ */ + @ExperimentalSince(KotoolsTypesVersion.Unreleased) + public constructor(number: Any) { + val regex = Regex(PATTERN) + val numberMatchesRegex: Boolean = "$number".matches(regex) + require(numberMatchesRegex) { + "'$number' is not a valid representation of zero." + } + } + // -------------------- Structural equality operations --------------------- /** diff --git a/subprojects/library/src/commonSample/kotlin/org/kotools/types/ZeroCommonSample.kt b/subprojects/library/src/commonSample/kotlin/org/kotools/types/ZeroCommonSample.kt index 7507aa041..c0e67a9b8 100644 --- a/subprojects/library/src/commonSample/kotlin/org/kotools/types/ZeroCommonSample.kt +++ b/subprojects/library/src/commonSample/kotlin/org/kotools/types/ZeroCommonSample.kt @@ -12,6 +12,18 @@ class ZeroCommonSample { Zero() } + @Test + fun constructorAny() { + val number: Any = "0.000" + val isSuccess: Boolean = try { + Zero(number) + true + } catch (exception: IllegalArgumentException) { + false + } + assertTrue(isSuccess) + } + // -------------------- Structural equality operations --------------------- @Test diff --git a/subprojects/library/src/commonTest/kotlin/org/kotools/types/ZeroTest.kt b/subprojects/library/src/commonTest/kotlin/org/kotools/types/ZeroTest.kt index 6bc68fa5c..00aa9fe61 100644 --- a/subprojects/library/src/commonTest/kotlin/org/kotools/types/ZeroTest.kt +++ b/subprojects/library/src/commonTest/kotlin/org/kotools/types/ZeroTest.kt @@ -12,6 +12,35 @@ import kotlin.test.assertTrue @OptIn(ExperimentalKotoolsTypesApi::class) class ZeroTest { + private val validNumbers: List + get() = listOf( + 0, 0.0, + "+0", "+000", "+0.000", "+000.000", // with unary plus + "-0", "-000", "-0.000", "-000.000" // with unary minus + ) + + private val invalidNumbers: List + get() = listOf( + ".0", "+.0", "-.0", // integer part missing + "0,0", "+0,0", "-0,0", // comma as decimal point + "0.", "+0.", "-0.", // decimal part missing + "hello world", "123456789" // not zero number + ) + + @Test + fun constructorAnyShouldPassWithValidNumber(): Unit = + this.validNumbers.forEach(::Zero) + + @Test + fun constructorAnyShouldFailWithInvalidNumber(): Unit = + this.invalidNumbers.forEach { + val exception: IllegalArgumentException = + assertFailsWith { Zero(it) } + val actual: String? = exception.message + val expected = "'$it' is not a valid representation of zero." + assertEquals(expected, actual) + } + // -------------------- Structural equality operations --------------------- @Test diff --git a/subprojects/library/src/jvmSample/java/org/kotools/types/ZeroJavaSample.java b/subprojects/library/src/jvmSample/java/org/kotools/types/ZeroJavaSample.java index a8aa27680..b56b73aca 100644 --- a/subprojects/library/src/jvmSample/java/org/kotools/types/ZeroJavaSample.java +++ b/subprojects/library/src/jvmSample/java/org/kotools/types/ZeroJavaSample.java @@ -10,6 +10,19 @@ void secondaryConstructor() { new Zero(); } + @Test + void constructorAny() { + final Object number = "0.000"; + boolean isSuccess; + try { + new Zero(number); + isSuccess = true; + } catch (final IllegalArgumentException exception) { + isSuccess = false; + } + Assertions.assertTrue(isSuccess); + } + // -------------------- Structural equality operations --------------------- @Test