Skip to content

Commit

Permalink
✨ Add EmailAddress(String) constructor (#635)
Browse files Browse the repository at this point in the history
  • Loading branch information
LVMVRQUXL committed Apr 18, 2024
1 parent 13d1341 commit 9b6dc1e
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 2 deletions.
2 changes: 1 addition & 1 deletion subprojects/library/src/api/types.api
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ 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 synthetic fun <init> (Ljava/lang/String;Lkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Ljava/lang/String;)V
public final fun equals (Ljava/lang/Object;)Z
public static final fun fromString (Ljava/lang/Object;)Lorg/kotools/types/EmailAddress;
public static final fun fromString (Ljava/lang/Object;Ljava/lang/Object;)Lorg/kotools/types/EmailAddress;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,43 @@ private const val FINAL_WARNING: String = "RedundantModalityModifier"
* You can use the [EmailAddress.Companion.fromString] or the
* [EmailAddress.Companion.fromStringOrNull] functions for creating an instance
* of this type.
*
* @constructor Creates an instance of [EmailAddress] with the specified value,
* or throws an [IllegalArgumentException] if the value doesn't match the
* [default pattern][EmailAddress.Companion.PATTERN].
*
* <br>
* <details open>
* <summary>
* <b>Calling from Kotlin</b>
* </summary>
*
* Here's an example of calling this constructor from Kotlin code:
*
* SAMPLE: EmailAddressKotlinSample.constructorString.md
* </details>
*
* <br>
* <details>
* <summary>
* <b>Calling from Java</b>
* </summary>
*
* Here's an example of calling this constructor from Java code:
*
* SAMPLE: EmailAddressJavaSample.constructorString.md
* </details>
*/
@ExperimentalKotoolsTypesApi
@ExperimentalSince(KotoolsTypesVersion.Unreleased)
public class EmailAddress private constructor(private val value: String) {
public class EmailAddress(private val value: String) {
init {
val regex = Regex(PATTERN)
require(this.value matches regex) {
InvalidEmailAddress(this.value, PATTERN)
}
}

// -------------------- Structural equality operations ---------------------

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,52 @@ private object Values {

@OptIn(ExperimentalKotoolsTypesApi::class)
class EmailAddressTest {
@Test
fun constructor_should_pass_with_valid_value() {
val value: String = Values.VALID
EmailAddress(value)
}

@Test
fun constructor_should_fail_with_a_missing_at_sign_in_value() {
val value: String = Values.MISSING_AT_SIGN
this.constructor_String_failingTest(value)
}

@Test
fun constructor_should_fail_with_a_missing_dot_in_domain_of_value() {
val value: String = Values.MISSING_DOMAIN_DOT
this.constructor_String_failingTest(value)
}

@Test
fun constructor_should_fail_with_whitespaces_in_local_part_of_value() {
val value: String = Values.WHITESPACES_IN_LOCAL_PART
this.constructor_String_failingTest(value)
}

@Test
fun constructor_should_fail_with_whitespaces_in_domain_first_label_of_value() {
val value: String = Values.WHITESPACES_IN_DOMAIN_FIRST_LABEL
this.constructor_String_failingTest(value)
}

@Test
fun constructor_should_fail_with_whitespaces_in_domain_second_label_of_value() {
val value: String = Values.WHITESPACES_IN_DOMAIN_SECOND_LABEL
this.constructor_String_failingTest(value)
}

private fun constructor_String_failingTest(value: String) {
val exception: IllegalArgumentException = assertFailsWith {
EmailAddress(value)
}
val actual: String? = exception.message
val expected: String = InvalidEmailAddress(value, EmailAddress.PATTERN)
.toString()
assertEquals(expected, actual)
}

@Test
fun structural_equality_should_pass_with_the_same_instance() {
val first: EmailAddress = EmailAddress.fromString(Values.VALID)
Expand Down
11 changes: 11 additions & 0 deletions subprojects/samples/src/main/java/EmailAddressJavaSample.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package org.kotools.types;

class EmailAddressJavaSample {
void constructorString() {
boolean isSuccess;
try {
new EmailAddress("[email protected]"); // TABS: 1
isSuccess = true; // TABS: 1
} catch (IllegalArgumentException exception) {
isSuccess = false; // TABS: 1
}
System.out.println(isSuccess); // true
} // END

void equals_override() {
final Object value = "[email protected]";
final EmailAddress first = EmailAddress.fromString(value);
Expand Down
10 changes: 10 additions & 0 deletions subprojects/samples/src/main/kotlin/EmailAddressKotlinSample.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ import kotools.types.experimental.ExperimentalKotoolsTypesApi

@OptIn(ExperimentalKotoolsTypesApi::class)
internal object EmailAddressKotlinSample {
fun constructorString() {
val isSuccess: Boolean = try {
EmailAddress("[email protected]") // TABS: 1
true // TABS: 1
} catch (exception: IllegalArgumentException) {
false // TABS: 1
}
println(isSuccess) // true
} // END

@Suppress("FunctionName")
fun equals_override() {
val value: Any = "[email protected]"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
class EmailAddressJavaSampleTest {
private final EmailAddressJavaSample sample = new EmailAddressJavaSample();

@Test
void constructor_String_should_pass() {
Assert.printsTrue(sample::constructorString);
}

@Test
void equals_override_should_pass() {
Assert.printsTrue(sample::equals_override);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ package org.kotools.types
import kotlin.test.Test

class EmailAddressKotlinSampleTest {
@Test
fun `constructor(String) should pass`() {
assertPrintsTrue(EmailAddressKotlinSample::constructorString)
}

@Test
fun `equals(nullable Any) should pass`(): Unit =
assertPrintsTrue(EmailAddressKotlinSample::equals_override)
Expand Down

0 comments on commit 9b6dc1e

Please sign in to comment.