Skip to content

Commit

Permalink
✨ Add EmailAddress.Companion.fromStringOrNull(Any) (#635)
Browse files Browse the repository at this point in the history
Adds this function to the type in the `org.kotools.types` package, with tests, tested Kotlin and Java code samples, and documentation.
Also dumps the Application Binary Interface (ABI).
  • Loading branch information
LVMVRQUXL committed Mar 31, 2024
1 parent d2c4401 commit 6168a22
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/api/types.api
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,11 @@ public final class kotools/types/web/EmailAddress$Companion {
public final class org/kotools/types/EmailAddress {
public static final field Companion Lorg/kotools/types/EmailAddress$Companion;
public static final field PATTERN Ljava/lang/String;
public static final fun fromStringOrNull (Ljava/lang/Object;)Lorg/kotools/types/EmailAddress;
}

public final class org/kotools/types/EmailAddress$Companion {
public final fun fromStringOrNull (Ljava/lang/Object;)Lorg/kotools/types/EmailAddress;
}

public final class org/kotools/types/Zero {
Expand Down
39 changes: 39 additions & 0 deletions src/commonMain/kotlin/org/kotools/types/EmailAddress.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import kotools.types.experimental.ExperimentalKotoolsTypesApi
import kotools.types.internal.ExperimentalSince
import kotools.types.internal.InternalKotoolsTypesApi
import kotools.types.internal.KotoolsTypesVersion
import kotlin.jvm.JvmStatic

/**
* Represents an [email address](https://en.wikipedia.org/wiki/Email_address).
*
* You can use the [EmailAddress.Companion.fromStringOrNull] function for
* creating an instance of this type.
*/
@ExperimentalKotoolsTypesApi
@ExperimentalSince(KotoolsTypesVersion.Unreleased)
Expand Down Expand Up @@ -54,5 +58,40 @@ public class EmailAddress private constructor() {
* </details>
*/
public const val PATTERN: String = "^\\S+@\\S+\\.\\S+\$"

/**
* Creates an instance of [EmailAddress] from the string representation
* of the specified [value], or returns `null` if the string
* representation of [value] doesn't match the
* [default pattern][PATTERN].
*
* <br>
* <details open>
* <summary>
* <b>Calling from Kotlin</b>
* </summary>
*
* Here's an example of calling this function from Kotlin code:
*
* SAMPLE: EmailAddressCompanionKotlinSample.fromStringOrNullSample.md
* </details>
*
* <br>
* <details>
* <summary>
* <b>Calling from Java</b>
* </summary>
*
* Here's an example of calling this function from Java code:
*
* SAMPLE: EmailAddressCompanionJavaSample.fromStringOrNullSample.md
* </details>
*/
@JvmStatic
public fun fromStringOrNull(value: Any): EmailAddress? {
val string: String = value.toString()
val regex = Regex(PATTERN)
return if (string matches regex) EmailAddress() else null
}
}
}
44 changes: 44 additions & 0 deletions src/commonTest/kotlin/org/kotools/types/EmailAddressTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package org.kotools.types
import kotools.types.experimental.ExperimentalKotoolsTypesApi
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertNotNull
import kotlin.test.assertNull

@OptIn(ExperimentalKotoolsTypesApi::class)
class EmailAddressCompanionTest {
Expand All @@ -12,4 +14,46 @@ class EmailAddressCompanionTest {
val expected = "^\\S+@\\S+\\.\\S+\$"
assertEquals(expected, actual)
}

@Test
fun fromStringOrNull_Any_should_pass_with_a_valid_value() {
val value: Any = "[email protected]"
val actual: EmailAddress? = EmailAddress.fromStringOrNull(value)
assertNotNull(actual)
}

@Test
fun fromStringOrNull_Any_should_fail_with_a_missing_at_sign_in_value() {
val value: Any = "contactKotools.org"
val actual: EmailAddress? = EmailAddress.fromStringOrNull(value)
assertNull(actual)
}

@Test
fun fromStringOrNull_Any_should_fail_with_a_missing_dot_in_domain_of_value() {
val value: Any = "contact@kotoolsOrg"
val actual: EmailAddress? = EmailAddress.fromStringOrNull(value)
assertNull(actual)
}

@Test
fun fromStringOrNull_Any_should_fail_with_whitespaces_in_local_part_of_value() {
val value: Any = " cont act @kotools.org"
val actual: EmailAddress? = EmailAddress.fromStringOrNull(value)
assertNull(actual)
}

@Test
fun fromStringOrNull_Any_should_fail_with_whitespaces_in_domain_first_label_of_value() {
val value: Any = "contact@ ko tools .org"
val actual: EmailAddress? = EmailAddress.fromStringOrNull(value)
assertNull(actual)
}

@Test
fun fromStringOrNull_Any_should_fail_with_whitespaces_in_domain_second_label_of_value() {
val value: Any = "contact@kotools. or g "
val actual: EmailAddress? = EmailAddress.fromStringOrNull(value)
assertNull(actual)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,10 @@ void patternSample() {
final String pattern = EmailAddress.PATTERN;
System.out.println(pattern); // ^\S+@\S+\.\S+$
}

void fromStringOrNullSample() {
final Object value = "[email protected]";
final EmailAddress address = EmailAddress.fromStringOrNull(value);
System.out.println(address != null); // true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@ package org.kotools.types

import kotools.types.experimental.ExperimentalKotoolsTypesApi

@OptIn(ExperimentalKotoolsTypesApi::class)
internal object EmailAddressCompanionKotlinSample {
@OptIn(ExperimentalKotoolsTypesApi::class)
fun patternSample() {
val pattern: String = EmailAddress.PATTERN
println(pattern) // ^\S+@\S+\.\S+$
}

fun fromStringOrNullSample() {
val value: Any = "[email protected]"
val address: EmailAddress? = EmailAddress.fromStringOrNull(value)
println(address != null) // true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,20 @@ void patternSample_should_pass() {
final EmailAddressCompanionJavaSample sample =
new EmailAddressCompanionJavaSample();
final String actual = Assertions.assertDoesNotThrow(
() -> SystemLambda.tapSystemOut(sample::patternSample).trim()
);
() -> SystemLambda.tapSystemOut(sample::patternSample)
).trim();
final String expected = "^\\S+@\\S+\\.\\S+$";
Assertions.assertEquals(expected, actual);
}

@Test
void fromStringOrNullSample_should_pass() {
final EmailAddressCompanionJavaSample sample =
new EmailAddressCompanionJavaSample();
final String actual = Assertions.assertDoesNotThrow(
() -> SystemLambda.tapSystemOut(sample::fromStringOrNullSample)
).trim();
final String expected = "true";
Assertions.assertEquals(expected, actual);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,13 @@ class EmailAddressCompanionKotlinSampleTest {
val expected = "^\\S+@\\S+\\.\\S+\$"
assertEquals(expected, actual)
}

@Test
fun fromStringOrNullSample_should_pass() {
val actual: String = SystemLambda.tapSystemOut(
EmailAddressCompanionKotlinSample::fromStringOrNullSample
).trim()
val expected = "true"
assertEquals(expected, actual)
}
}

0 comments on commit 6168a22

Please sign in to comment.