diff --git a/src/main/java/it/aboutbits/springboot/toolbox/type/EmailAddress.java b/src/main/java/it/aboutbits/springboot/toolbox/type/EmailAddress.java
new file mode 100644
index 0000000..4c2869b
--- /dev/null
+++ b/src/main/java/it/aboutbits/springboot/toolbox/type/EmailAddress.java
@@ -0,0 +1,37 @@
+package it.aboutbits.springboot.toolbox.type;
+
+import it.aboutbits.springboot.toolbox.validation.util.EmailAddressValidator;
+import lombok.NonNull;
+
+/**
+ * A record representing an email address, validated and stored in lowercase.
+ *
+ * The EmailAddress record ensures that the provided email address string
+ * is in a valid format and automatically converts it to lowercase for
+ * consistent internal representation. It implements the Comparable
+ * interface to allow comparison between different email addresses.
+ *
+ *
+ * @param value the email address string
+ * @throws IllegalArgumentException if the provided email address is not in a valid format
+ */
+public record EmailAddress(String value) implements Comparable {
+ public EmailAddress(String value) {
+ if (value == null || EmailAddressValidator.isNotValid(value)) {
+ throw new IllegalArgumentException("Value is not a valid email address: " + value);
+ }
+
+ this.value = value.toLowerCase();
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ @Override
+ public int compareTo(@NonNull EmailAddress o) {
+ return value().compareTo(o.value());
+ }
+}
diff --git a/src/main/java/it/aboutbits/springboot/toolbox/type/Iban.java b/src/main/java/it/aboutbits/springboot/toolbox/type/Iban.java
new file mode 100644
index 0000000..0098da5
--- /dev/null
+++ b/src/main/java/it/aboutbits/springboot/toolbox/type/Iban.java
@@ -0,0 +1,48 @@
+package it.aboutbits.springboot.toolbox.type;
+
+import it.aboutbits.springboot.toolbox.validation.util.IbanValidator;
+import lombok.NonNull;
+
+import java.util.Optional;
+
+/**
+ * The {@code Iban} class represents an International Bank Account Number (IBAN) and provides functionality for validation
+ * and comparison of IBANs. It ensures the valid format of the IBAN according to predefined rules.
+ *
+ * @param value the IBAN value, which must be a valid and non-null string
+ */
+public record Iban(String value) implements Comparable {
+ public Iban(String value) {
+ if (value == null || IbanValidator.isNotValid(value.toUpperCase())) {
+ throw new IllegalArgumentException("Value is not a valid IBAN: " + value);
+ }
+
+ this.value = value.toUpperCase();
+ }
+
+ @NonNull
+ @Override
+ public String toString() {
+ return value;
+ }
+
+ /**
+ * Retrieves the ABI (Bank Branch Code) if the IBAN belongs to an Italian bank.
+ *
+ * @return An {@code Optional} containing the ABI value if the IBAN is Italian, or an empty {@code Optional} otherwise.
+ */
+ @NonNull
+ public Optional getAbiIfItalian() {
+ var iban = value();
+
+ if (!iban.startsWith("IT")) {
+ return Optional.empty();
+ }
+ return Optional.of(iban.substring(5, 10));
+ }
+
+ @Override
+ public int compareTo(@NonNull Iban o) {
+ return value().compareTo(o.value());
+ }
+}
diff --git a/src/main/java/it/aboutbits/springboot/toolbox/type/ScaledBigDecimal.java b/src/main/java/it/aboutbits/springboot/toolbox/type/ScaledBigDecimal.java
new file mode 100644
index 0000000..3ffc5ec
--- /dev/null
+++ b/src/main/java/it/aboutbits/springboot/toolbox/type/ScaledBigDecimal.java
@@ -0,0 +1,231 @@
+package it.aboutbits.springboot.toolbox.type;
+
+import lombok.NonNull;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.MathContext;
+import java.math.RoundingMode;
+
+/**
+ * A record that represents a scaled BigDecimal with a fixed MathContext.
+ * This class provides various constructors for creating instances with different numerical types.
+ * It also provides a set of arithmetic operations that return new instances with the appropriate scale and rounding.
+ */
+public record ScaledBigDecimal(
+ @NonNull BigDecimal value
+) implements Comparable {
+ private static final MathContext MATH_CONTEXT = new MathContext(15, RoundingMode.HALF_UP);
+
+ public static final ScaledBigDecimal ZERO = new ScaledBigDecimal(0);
+ public static final ScaledBigDecimal ONE = new ScaledBigDecimal(1);
+ public static final ScaledBigDecimal TWO = new ScaledBigDecimal(2);
+ public static final ScaledBigDecimal TEN = new ScaledBigDecimal(10);
+
+ public ScaledBigDecimal(@NonNull BigDecimal value) {
+ this.value = value.setScale(MATH_CONTEXT.getPrecision(), MATH_CONTEXT.getRoundingMode());
+ }
+
+ public ScaledBigDecimal(int value) {
+ this(new BigDecimal(value, MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(@NonNull Integer value) {
+ this(new BigDecimal(value, MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(@NonNull BigInteger value) {
+ this(new BigDecimal(value, MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(long value) {
+ this(new BigDecimal(value, MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(@NonNull Long value) {
+ this(new BigDecimal(value, MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(float value) {
+ this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(@NonNull Float value) {
+ this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(double value) {
+ this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(@NonNull Double value) {
+ this(new BigDecimal(String.valueOf(value), MATH_CONTEXT));
+ }
+
+ public ScaledBigDecimal(@NonNull String value) {
+ this(new BigDecimal(value, MATH_CONTEXT));
+ }
+
+ public static ScaledBigDecimal valueOf(int value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(@NonNull Integer value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(@NonNull BigInteger value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(long value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(@NonNull Long value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(float value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(@NonNull Float value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(double value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(@NonNull Double value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ public static ScaledBigDecimal valueOf(@NonNull String value) {
+ return new ScaledBigDecimal(value);
+ }
+
+ @NonNull
+ public ScaledBigDecimal add(@NonNull ScaledBigDecimal other) {
+ return new ScaledBigDecimal(this.value().add(other.value()));
+ }
+
+ @NonNull
+ public ScaledBigDecimal subtract(@NonNull ScaledBigDecimal other) {
+ return new ScaledBigDecimal(this.value().subtract(other.value()));
+ }
+
+ @NonNull
+ public ScaledBigDecimal multiply(@NonNull ScaledBigDecimal other) {
+ return new ScaledBigDecimal(this.value().multiply(other.value()));
+ }
+
+ @NonNull
+ public ScaledBigDecimal divide(@NonNull ScaledBigDecimal other) {
+ return new ScaledBigDecimal(this.value().divide(other.value(), MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal add(@NonNull BigDecimal other) {
+ return new ScaledBigDecimal(this.value().add(other));
+ }
+
+ @NonNull
+ public ScaledBigDecimal subtract(@NonNull BigDecimal other) {
+ return new ScaledBigDecimal(this.value().subtract(other));
+ }
+
+ @NonNull
+ public ScaledBigDecimal multiply(@NonNull BigDecimal other) {
+ return new ScaledBigDecimal(this.value().multiply(other));
+ }
+
+ @NonNull
+ public ScaledBigDecimal divide(@NonNull BigDecimal other) {
+ return new ScaledBigDecimal(this.value().divide(other, MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal remainder(@NonNull ScaledBigDecimal divisor) {
+ return new ScaledBigDecimal(this.value().remainder(divisor.value(), MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal remainder(@NonNull BigDecimal divisor) {
+ return new ScaledBigDecimal(this.value().remainder(divisor, MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal sqrt() {
+ return new ScaledBigDecimal(this.value().sqrt(MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal pow(int n) {
+ return new ScaledBigDecimal(this.value().pow(n, MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal abs() {
+ return new ScaledBigDecimal(this.value().abs(MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal negate() {
+ return new ScaledBigDecimal(this.value().negate(MATH_CONTEXT));
+ }
+
+ @NonNull
+ public ScaledBigDecimal min(@NonNull ScaledBigDecimal val) {
+ return new ScaledBigDecimal(this.value().min(val.value()));
+ }
+
+ @NonNull
+ public ScaledBigDecimal min(@NonNull BigDecimal val) {
+ return new ScaledBigDecimal(this.value().min(val));
+ }
+
+ @NonNull
+ public ScaledBigDecimal max(@NonNull ScaledBigDecimal val) {
+ return new ScaledBigDecimal(this.value().max(val.value()));
+ }
+
+ @NonNull
+ public ScaledBigDecimal max(@NonNull BigDecimal val) {
+ return new ScaledBigDecimal(this.value().max(val));
+ }
+
+ @NonNull
+ public BigDecimal toBigDecimal(int scale) {
+ return this.value().setScale(scale, RoundingMode.HALF_UP);
+ }
+
+ @NonNull
+ public ScaledBigDecimal roundToScale(int scale) {
+ return new ScaledBigDecimal(this.value().setScale(scale, RoundingMode.HALF_UP));
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+
+ if (o instanceof ScaledBigDecimal other) {
+ return this.value().compareTo(other.value()) == 0;
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return value().hashCode();
+ }
+
+ @Override
+ public int compareTo(@NonNull ScaledBigDecimal o) {
+ return this.value().compareTo(o.value());
+ }
+}
diff --git a/src/main/java/it/aboutbits/springboot/toolbox/validation/util/EmailAddressValidator.java b/src/main/java/it/aboutbits/springboot/toolbox/validation/util/EmailAddressValidator.java
new file mode 100644
index 0000000..62ed128
--- /dev/null
+++ b/src/main/java/it/aboutbits/springboot/toolbox/validation/util/EmailAddressValidator.java
@@ -0,0 +1,27 @@
+package it.aboutbits.springboot.toolbox.validation.util;
+
+import org.apache.commons.validator.routines.EmailValidator;
+
+public final class EmailAddressValidator {
+ private static final EmailValidator EMAIL_VALIDATOR = EmailValidator.getInstance();
+
+ private EmailAddressValidator() {
+ }
+
+ /**
+ * Validates if the provided email address is in a proper format.
+ *
+ * @param email the email address to validate
+ * @return true if the email address is valid, false otherwise
+ */
+ public static boolean isValid(String email) {
+ if (email == null) {
+ return false;
+ }
+ return EMAIL_VALIDATOR.isValid(email);
+ }
+
+ public static boolean isNotValid(String email) {
+ return !isValid(email);
+ }
+}
diff --git a/src/main/java/it/aboutbits/springboot/toolbox/validation/util/IbanValidator.java b/src/main/java/it/aboutbits/springboot/toolbox/validation/util/IbanValidator.java
new file mode 100644
index 0000000..b3de1a1
--- /dev/null
+++ b/src/main/java/it/aboutbits/springboot/toolbox/validation/util/IbanValidator.java
@@ -0,0 +1,27 @@
+package it.aboutbits.springboot.toolbox.validation.util;
+
+import org.apache.commons.validator.routines.IBANValidator;
+
+public final class IbanValidator {
+ private static final IBANValidator IBAN_VALIDATOR = new IBANValidator();
+
+ private IbanValidator() {
+ }
+
+ /**
+ * Validates whether the given IBAN (International Bank Account Number) is valid according to predefined rules.
+ *
+ * @param iban the IBAN to be validated
+ * @return true if the IBAN is valid, false otherwise
+ */
+ public static boolean isValid(String iban) {
+ if (iban == null) {
+ return false;
+ }
+ return IBAN_VALIDATOR.isValid(iban);
+ }
+
+ public static boolean isNotValid(String iban) {
+ return !isValid(iban);
+ }
+}
diff --git a/src/test/java/it/aboutbits/springboot/toolbox/type/EmailAddressTest.java b/src/test/java/it/aboutbits/springboot/toolbox/type/EmailAddressTest.java
new file mode 100644
index 0000000..bbed40e
--- /dev/null
+++ b/src/test/java/it/aboutbits/springboot/toolbox/type/EmailAddressTest.java
@@ -0,0 +1,82 @@
+package it.aboutbits.springboot.toolbox.type;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+
+class EmailAddressTest {
+ @Nested
+ class Constructor {
+ @ParameterizedTest
+ @ValueSource(strings = {"egon@aboutbits.it", "hans.mueller@aboutbits.it", "peterP_pansky@aboutbits.it"})
+ void validValues_shouldSucceed(String value) {
+ assertThatCode(
+ () -> new EmailAddress(value)
+ ).doesNotThrowAnyException();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"", " ", " ", "\t", "\r", "\n", "sepp", "x@ y", "@aboutbits.it", "hans mueller@aboutbits.it", "peter@pansky@aboutbits.it"})
+ void invalidValues_shouldFail(String value) {
+ assertThatIllegalArgumentException().isThrownBy(
+ () -> new EmailAddress(value)
+ );
+ }
+
+ @Test
+ void null_shouldFail() {
+ assertThatIllegalArgumentException().isThrownBy(
+ () -> new EmailAddress(null)
+ );
+ }
+ }
+
+ @Nested
+ class ToStringAndValue {
+ @Test
+ void shouldAlwaysReturnTheSameValue() {
+ var emailAddress = new EmailAddress("someValue@aboutbits.it");
+
+ assertThat(emailAddress.value()).isEqualTo(emailAddress.toString());
+ }
+
+ @Test
+ void shouldReturnLowercaseValue() {
+ var emailAddress = new EmailAddress("someValue@aboutbits.it");
+
+ assertThat(emailAddress.value()).isEqualTo("somevalue@aboutbits.it");
+ }
+ }
+
+ @Nested
+ class CompareTo {
+ @Test
+ void shouldCompareToReturnNegativeWhenInputValueIsGreater() {
+ var emailAddress1 = new EmailAddress("abc@aboutbits.it");
+ var emailAddress2 = new EmailAddress("xyz@aboutbits.it");
+
+ assertThat(emailAddress1.compareTo(emailAddress2)).isNegative();
+ }
+
+ @Test
+ void shouldCompareToReturnPositiveWhenInputValueIsLesser() {
+ var emailAddress1 = new EmailAddress("xyz@aboutbits.it");
+ var emailAddress2 = new EmailAddress("abc@aboutbits.it");
+
+ assertThat(emailAddress1.compareTo(emailAddress2)).isPositive();
+ }
+
+ @Test
+ void shouldCompareToReturnZeroWhenInputValuesAreEqual() {
+ var emailAddress1 = new EmailAddress("abc@aboutbits.it");
+ var emailAddress2 = new EmailAddress("abc@aboutbits.it");
+
+ assertThat(emailAddress1).isEqualByComparingTo(emailAddress2);
+ }
+ }
+}
diff --git a/src/test/java/it/aboutbits/springboot/toolbox/type/IbanTest.java b/src/test/java/it/aboutbits/springboot/toolbox/type/IbanTest.java
new file mode 100644
index 0000000..3b9fe55
--- /dev/null
+++ b/src/test/java/it/aboutbits/springboot/toolbox/type/IbanTest.java
@@ -0,0 +1,82 @@
+package it.aboutbits.springboot.toolbox.type;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+
+class IbanTest {
+ @Nested
+ class Constructor {
+ @ParameterizedTest
+ @ValueSource(strings = {"NL08INGB3330533676", "HR3425000097537651489", "IT37G0300203280237914848919", "AT705400073311799347", "DE60500105175378199617"})
+ void validValues_shouldSucceed(String value) {
+ assertThatCode(
+ () -> new Iban(value)
+ ).doesNotThrowAnyException();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"IT60X0542811101000000123450", "some-wrong-stuff", "", " ", " ", "\t", "\r", "\n"})
+ void invalidValues_shouldFail(String value) {
+ assertThatIllegalArgumentException().isThrownBy(
+ () -> new Iban(value)
+ );
+ }
+
+ @Test
+ void null_shouldFail() {
+ assertThatIllegalArgumentException().isThrownBy(
+ () -> new Iban(null)
+ );
+ }
+ }
+
+ @Nested
+ class ToStringAndValue {
+ @Test
+ void shouldAlwaysReturnTheSameValue() {
+ var emailAddress = new Iban("HR3425000097537651489");
+
+ assertThat(emailAddress.value()).isEqualTo(emailAddress.toString());
+ }
+
+ @Test
+ void shouldReturnUppercaseValue() {
+ var emailAddress = new Iban("hr3425000097537651489");
+
+ assertThat(emailAddress.value()).isEqualTo("HR3425000097537651489");
+ }
+ }
+
+ @Nested
+ class CompareTo {
+ @Test
+ void shouldCompareToReturnNegativeWhenInputValueIsGreater() {
+ var iban1 = new Iban("HR3425000097537651489");
+ var iban2 = new Iban("NL08INGB3330533676");
+
+ assertThat(iban1.compareTo(iban2)).isNegative();
+ }
+
+ @Test
+ void shouldCompareToReturnPositiveWhenInputValueIsLesser() {
+ var iban1 = new Iban("NL08INGB3330533676");
+ var iban2 = new Iban("HR3425000097537651489");
+
+ assertThat(iban1.compareTo(iban2)).isPositive();
+ }
+
+ @Test
+ void shouldCompareToReturnZeroWhenInputValuesAreEqual() {
+ var iban1 = new Iban("HR3425000097537651489");
+ var iban2 = new Iban("HR3425000097537651489");
+
+ assertThat(iban1).isEqualByComparingTo(iban2);
+ }
+ }
+}
diff --git a/src/test/java/it/aboutbits/springboot/toolbox/validation/util/EmailAddressValidatorTest.java b/src/test/java/it/aboutbits/springboot/toolbox/validation/util/EmailAddressValidatorTest.java
new file mode 100644
index 0000000..3e3a189
--- /dev/null
+++ b/src/test/java/it/aboutbits/springboot/toolbox/validation/util/EmailAddressValidatorTest.java
@@ -0,0 +1,62 @@
+package it.aboutbits.springboot.toolbox.validation.util;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class EmailAddressValidatorTest {
+ @Nested
+ class IsValid {
+ @ParameterizedTest
+ @ValueSource(strings = {"egon@aboutbits.it", "hans.mueller@aboutbits.it", "peterP_pansky@aboutbits.it"})
+ void validValues_shouldSucceed(String value) {
+ assertThat(
+ EmailAddressValidator.isValid(value)
+ ).isTrue();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"", " ", " ", "\t", "\r", "\n", "sepp", "x@ y", "@aboutbits.it", "hans mueller@aboutbits.it", "peter@pansky@aboutbits.it"})
+ void invalidValues_shouldFail(String value) {
+ assertThat(
+ EmailAddressValidator.isValid(value)
+ ).isFalse();
+ }
+
+ @Test
+ void null_shouldFail() {
+ assertThat(
+ EmailAddressValidator.isValid(null)
+ ).isFalse();
+ }
+ }
+
+ @Nested
+ class IsNotValid {
+ @ParameterizedTest
+ @ValueSource(strings = {"egon@aboutbits.it", "hans.mueller@aboutbits.it", "peterP_pansky@aboutbits.it"})
+ void validValues_shouldSucceed(String value) {
+ assertThat(
+ EmailAddressValidator.isNotValid(value)
+ ).isFalse();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"", " ", " ", "\t", "\r", "\n", "sepp", "x@ y", "@aboutbits.it", "hans mueller@aboutbits.it", "peter@pansky@aboutbits.it"})
+ void invalidValues_shouldFail(String value) {
+ assertThat(
+ EmailAddressValidator.isNotValid(value)
+ ).isTrue();
+ }
+
+ @Test
+ void null_shouldFail() {
+ assertThat(
+ EmailAddressValidator.isNotValid(null)
+ ).isTrue();
+ }
+ }
+}
diff --git a/src/test/java/it/aboutbits/springboot/toolbox/validation/util/IbanValidatorTest.java b/src/test/java/it/aboutbits/springboot/toolbox/validation/util/IbanValidatorTest.java
new file mode 100644
index 0000000..d70ea11
--- /dev/null
+++ b/src/test/java/it/aboutbits/springboot/toolbox/validation/util/IbanValidatorTest.java
@@ -0,0 +1,62 @@
+package it.aboutbits.springboot.toolbox.validation.util;
+
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class IbanValidatorTest {
+ @Nested
+ class IsValid {
+ @ParameterizedTest
+ @ValueSource(strings = {"NL08INGB3330533676", "HR3425000097537651489", "IT37G0300203280237914848919", "AT705400073311799347", "DE60500105175378199617"})
+ void validValues_shouldSucceed(String value) {
+ assertThat(
+ IbanValidator.isValid(value)
+ ).isTrue();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"IT60X0542811101000000123450", "some-wrong-stuff", "", " ", " ", "\t", "\r", "\n"})
+ void invalidValues_shouldFail(String value) {
+ assertThat(
+ IbanValidator.isValid(value)
+ ).isFalse();
+ }
+
+ @Test
+ void null_shouldFail() {
+ assertThat(
+ IbanValidator.isValid(null)
+ ).isFalse();
+ }
+ }
+
+ @Nested
+ class IsNotValid {
+ @ParameterizedTest
+ @ValueSource(strings = {"NL08INGB3330533676", "HR3425000097537651489", "IT37G0300203280237914848919", "AT705400073311799347", "DE60500105175378199617"})
+ void validValues_shouldSucceed(String value) {
+ assertThat(
+ IbanValidator.isNotValid(value)
+ ).isFalse();
+ }
+
+ @ParameterizedTest
+ @ValueSource(strings = {"IT60X0542811101000000123450", "some-wrong-stuff", "", " ", " ", "\t", "\r", "\n"})
+ void invalidValues_shouldFail(String value) {
+ assertThat(
+ IbanValidator.isNotValid(value)
+ ).isTrue();
+ }
+
+ @Test
+ void null_shouldFail() {
+ assertThat(
+ IbanValidator.isNotValid(null)
+ ).isTrue();
+ }
+ }
+}