diff --git a/plusone-validator/pom.xml b/plusone-validator/pom.xml
index c1747ee..6fcfa08 100644
--- a/plusone-validator/pom.xml
+++ b/plusone-validator/pom.xml
@@ -33,12 +33,7 @@
org.junit.jupiter
- junit-jupiter-api
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
+ junit-jupiter
test
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/ExampleCommand.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/ExampleCommand.java
new file mode 100644
index 0000000..bfb9ad2
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/ExampleCommand.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package xyz.zhouxy.plusone.example;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * 接口入参的 DTO 示例
+ */
+public class ExampleCommand {
+ private Boolean boolProperty;
+ private Integer intProperty;
+ private Long longProperty;
+ private Double doubleProperty;
+ private String stringProperty;
+ private LocalDateTime dateTimeProperty;
+ private Foo objectProperty;
+ private List stringListProperty;
+
+ public ExampleCommand() {
+ }
+
+ public ExampleCommand(Boolean boolProperty, Integer intProperty, Long longProperty, Double doubleProperty,
+ String stringProperty, LocalDateTime dateTimeProperty, Foo objectProperty,
+ List stringListProperty) {
+ this.boolProperty = boolProperty;
+ this.intProperty = intProperty;
+ this.longProperty = longProperty;
+ this.doubleProperty = doubleProperty;
+ this.stringProperty = stringProperty;
+ this.dateTimeProperty = dateTimeProperty;
+ this.objectProperty = objectProperty;
+ this.stringListProperty = stringListProperty;
+ }
+
+ public Boolean getBoolProperty() {
+ return boolProperty;
+ }
+
+ public void setBoolProperty(Boolean boolProperty) {
+ this.boolProperty = boolProperty;
+ }
+
+ public Integer getIntProperty() {
+ return intProperty;
+ }
+
+ public void setIntProperty(Integer intProperty) {
+ this.intProperty = intProperty;
+ }
+
+ public Long getLongProperty() {
+ return longProperty;
+ }
+
+ public void setLongProperty(Long longProperty) {
+ this.longProperty = longProperty;
+ }
+
+ public Double getDoubleProperty() {
+ return doubleProperty;
+ }
+
+ public void setDoubleProperty(Double doubleProperty) {
+ this.doubleProperty = doubleProperty;
+ }
+
+ public String getStringProperty() {
+ return stringProperty;
+ }
+
+ public void setStringProperty(String stringProperty) {
+ this.stringProperty = stringProperty;
+ }
+
+ public LocalDateTime getDateTimeProperty() {
+ return dateTimeProperty;
+ }
+
+ public void setDateTimeProperty(LocalDateTime dateTimeProperty) {
+ this.dateTimeProperty = dateTimeProperty;
+ }
+
+ public Foo getObjectProperty() {
+ return objectProperty;
+ }
+
+ public void setObjectProperty(Foo objectProperty) {
+ this.objectProperty = objectProperty;
+ }
+
+ public List getStringListProperty() {
+ return stringListProperty;
+ }
+
+ public void setStringListProperty(List stringListProperty) {
+ this.stringListProperty = stringListProperty;
+ }
+
+ @Override
+ public String toString() {
+ return "ExampleCommand [boolProperty=" + boolProperty + ", intProperty=" + intProperty + ", longProperty="
+ + longProperty + ", doubleProperty=" + doubleProperty + ", stringProperty=" + stringProperty
+ + ", dateTimeProperty=" + dateTimeProperty + ", objectProperty=" + objectProperty
+ + ", stringListProperty=" + stringListProperty + "]";
+ }
+}
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/Foo.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/Foo.java
new file mode 100644
index 0000000..d97cd37
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/Foo.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package xyz.zhouxy.plusone.example;
+
+public class Foo {
+ private Integer intProperty;
+ private String stringProperty;
+
+ public Foo() {
+ }
+
+ public Foo(Integer intProperty, String stringProperty) {
+ this.intProperty = intProperty;
+ this.stringProperty = stringProperty;
+ }
+
+ public Integer getIntProperty() {
+ return intProperty;
+ }
+
+ public void setIntProperty(Integer intProperty) {
+ this.intProperty = intProperty;
+ }
+
+ public String getStringProperty() {
+ return stringProperty;
+ }
+
+ public void setStringProperty(String stringProperty) {
+ this.stringProperty = stringProperty;
+ }
+
+ @Override
+ public String toString() {
+ return "Foo [intProperty=" + intProperty + ", stringProperty=" + stringProperty + "]";
+ }
+}
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/BoolPropertyValidatorTests.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/BoolPropertyValidatorTests.java
new file mode 100644
index 0000000..7018f64
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/BoolPropertyValidatorTests.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package xyz.zhouxy.plusone.example.validator;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+
+import xyz.zhouxy.plusone.example.ExampleCommand;
+import xyz.zhouxy.plusone.validator.BaseValidator;
+
+public class BoolPropertyValidatorTests {
+
+ // ================================
+ // #region - isTrueValue
+ // ================================
+
+ @Test
+ void isTrueValue_trueProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty).isTrueValue();
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue("The boolProperty should be true.");
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(() -> ExampleException.withMessage("The boolProperty should be true."));
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(property -> ExampleException.withMessage(
+ "The boolProperty should be true, but it is `%s`", property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(true);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ @Test
+ void isTrueValue_default_falseProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty).isTrueValue();
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(false);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The value must be true.", exception.getMessage());
+ }
+
+ @Test
+ void isTrueValue_message_falseProperty() {
+ final String message = "The boolProperty should be true.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(message);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(false);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isTrueValue_exceptionSupplier_falseProperty() {
+ final String message = "The boolProperty should be true.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(() -> ExampleException.withMessage(message));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(false);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isTrueValue_exceptionFunction_falseProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(property -> ExampleException.withMessage(
+ "The boolProperty should be true, but it is `%s`", property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(false);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The boolProperty should be true, but it is `false`", exception.getMessage());
+ }
+
+ @Test
+ void isTrueValue_default_nullProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty).isTrueValue();
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The value must be true.", exception.getMessage());
+ }
+
+ @Test
+ void isTrueValue_message_nullProperty() {
+ final String message = "The boolProperty should be true.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(message);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isTrueValue_exceptionSupplier_nullProperty() {
+ final String message = "The boolProperty should be true.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(() -> ExampleException.withMessage(message));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isTrueValue_exceptionFunction_nullProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isTrueValue(property -> ExampleException.withMessage(
+ "The boolProperty should be true, but it is `%s`", property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The boolProperty should be true, but it is `null`", exception.getMessage());
+ }
+
+ // ================================
+ // #endregion - isTrueValue
+ // ================================
+
+ // ================================
+ // #region - isFalseValue
+ // ================================
+
+ @Test
+ void isFalseValue_falseProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty).isFalseValue();
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue("The boolProperty should be false.");
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(() -> ExampleException.withMessage("The boolProperty should be false."));
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(property -> ExampleException.withMessage(
+ "The boolProperty should be false, but it is `%s`", property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(false);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ @Test
+ void isFalseValue_default_trueProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty).isFalseValue();
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(true);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The value must be false.", exception.getMessage());
+ }
+
+ @Test
+ void isFalseValue_message_trueProperty() {
+ final String message = "The boolProperty should be false.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(message);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(true);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isFalseValue_exceptionSupplier_trueProperty() {
+ final String message = "The boolProperty should be false.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(() -> ExampleException.withMessage(message));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(true);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isFalseValue_exceptionFunction_trueProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(property -> ExampleException.withMessage(
+ "The boolProperty should be false, but it is `%s`", property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(true);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The boolProperty should be false, but it is `true`", exception.getMessage());
+ }
+
+ @Test
+ void isFalseValue_default_nullProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty).isFalseValue();
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The value must be false.", exception.getMessage());
+ }
+
+ @Test
+ void isFalseValue_message_nullProperty() {
+ final String message = "The boolProperty should be false.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(message);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ IllegalArgumentException exception = assertThrows(
+ IllegalArgumentException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isFalseValue_exceptionSupplier_nullProperty() {
+ final String message = "The boolProperty should be false.";
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(() -> ExampleException.withMessage(message));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals(message, exception.getMessage());
+ }
+
+ @Test
+ void isFalseValue_exceptionFunction_nullProperty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForBool(ExampleCommand::getBoolProperty)
+ .isFalseValue(property -> ExampleException.withMessage(
+ "The boolProperty should be false, but it is `%s`", property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithBoolProperty(null);
+
+ ExampleException exception = assertThrows(
+ ExampleException.class,
+ () -> validator.validate(command));
+
+ assertEquals("The boolProperty should be false, but it is `null`", exception.getMessage());
+ }
+
+ // ================================
+ // #endregion - isFalseValue
+ // ================================
+
+ static ExampleCommand exampleCommandWithBoolProperty(Boolean boolProperty) {
+ ExampleCommand exampleCommand = new ExampleCommand();
+ exampleCommand.setBoolProperty(boolProperty);
+ return exampleCommand;
+ }
+}
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/CollectionPropertyValidatorTests.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/CollectionPropertyValidatorTests.java
new file mode 100644
index 0000000..6e535a8
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/CollectionPropertyValidatorTests.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package xyz.zhouxy.plusone.example.validator;
+
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.Lists;
+
+import xyz.zhouxy.plusone.example.ExampleCommand;
+import xyz.zhouxy.plusone.validator.BaseValidator;
+
+public class CollectionPropertyValidatorTests {
+
+ static final String MESSAGE_NOT_EMPTY = "The stringListProperty should not be empty.";
+ static final String MESSAGE_EMPTY = "The stringListProperty should be empty.";
+
+ // ================================
+ // #region - notEmpty
+ // ================================
+
+ @Test
+ void notEmpty_stringListIsNotEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty).notEmpty(MESSAGE_NOT_EMPTY);
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .notEmpty(() -> ExampleException.withMessage(MESSAGE_NOT_EMPTY));
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .notEmpty(strList -> ExampleException.withMessage(
+ "The stringListProperty should not be empty, but it is %s.", strList));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Lists.newArrayList("A", "B", "C"));
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ @Test
+ void notEmpty_message_stringListIsEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty).notEmpty(MESSAGE_NOT_EMPTY);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Collections.emptyList());
+
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_NOT_EMPTY, e.getMessage());
+ }
+
+ @Test
+ void notEmpty_exceptionSupplier_stringListIsEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .notEmpty(() -> ExampleException.withMessage(MESSAGE_NOT_EMPTY));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Collections.emptyList());
+
+ ExampleException e = assertThrows(ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_NOT_EMPTY, e.getMessage());
+ }
+
+ @Test
+ void notEmpty_exceptionFunction_stringListIsEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .notEmpty(strList -> ExampleException.withMessage(
+ "The stringListProperty should not be empty, but it is %s.", strList));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Collections.emptyList());
+
+ ExampleException e = assertThrows(ExampleException.class, () -> validator.validate(command));
+ assertEquals("The stringListProperty should not be empty, but it is [].", e.getMessage());
+ }
+
+ @Test
+ void notEmpty_message_stringListIsNull() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty).notEmpty(MESSAGE_NOT_EMPTY);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(null);
+
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_NOT_EMPTY, e.getMessage());
+ }
+
+ @Test
+ void notEmpty_exceptionSupplier_stringListIsNull() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .notEmpty(() -> ExampleException.withMessage(MESSAGE_NOT_EMPTY));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(null);
+
+ ExampleException e = assertThrows(ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_NOT_EMPTY, e.getMessage());
+ }
+
+ @Test
+ void notEmpty_exceptionFunction_stringListIsNull() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .notEmpty(strList -> ExampleException.withMessage(
+ "The stringListProperty should not be empty, but it is %s.", strList));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(null);
+
+ ExampleException e = assertThrows(ExampleException.class, () -> validator.validate(command));
+ assertEquals("The stringListProperty should not be empty, but it is null.", e.getMessage());
+ }
+
+ // ================================
+ // #endregion - notEmpty
+ // ================================
+
+ // ================================
+ // #region - isEmpty
+ // ================================
+
+ @Test
+ void isEmpty_stringListIsEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty).isEmpty(MESSAGE_EMPTY);
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .isEmpty(() -> ExampleException.withMessage(MESSAGE_EMPTY));
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .isEmpty(strList -> ExampleException.withMessage(
+ "The stringListProperty should be empty, but it is %s.", strList));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Collections.emptyList());
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ @Test
+ void isEmpty_stringListIsNull() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty).isEmpty(MESSAGE_EMPTY);
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .isEmpty(() -> ExampleException.withMessage(MESSAGE_EMPTY));
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .isEmpty(strList -> ExampleException.withMessage(
+ "The stringListProperty should be empty, but it is %s.", strList));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(null);
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ @Test
+ void isEmpty_message_stringListIsNotEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty).isEmpty(MESSAGE_EMPTY);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Lists.newArrayList("A", "B", "C"));
+
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_EMPTY, e.getMessage());
+ }
+
+ @Test
+ void isEmpty_exceptionSupplier_stringListIsNotEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .isEmpty(() -> ExampleException.withMessage(MESSAGE_EMPTY));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Lists.newArrayList("A", "B", "C"));
+
+ ExampleException e = assertThrows(ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_EMPTY, e.getMessage());
+ }
+
+ @Test
+ void isEmpty_exceptionFunction_stringListIsNotEmpty() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForCollection(ExampleCommand::getStringListProperty)
+ .isEmpty(strList -> ExampleException.withMessage(
+ "The stringListProperty should be empty, but it is %s.", strList));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithStringListProperty(Lists.newArrayList("A", "B", "C"));
+
+ ExampleException e = assertThrows(ExampleException.class, () -> validator.validate(command));
+ assertEquals("The stringListProperty should be empty, but it is [A, B, C].", e.getMessage());
+ }
+
+ // ================================
+ // #endregion - isEmpty
+ // ================================
+
+ static ExampleCommand exampleCommandWithStringListProperty(List property) {
+ ExampleCommand exampleCommand = new ExampleCommand();
+ exampleCommand.setStringListProperty(property);
+ return exampleCommand;
+ }
+}
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/DoublePropertyValidatorTests.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/DoublePropertyValidatorTests.java
new file mode 100644
index 0000000..685e3de
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/DoublePropertyValidatorTests.java
@@ -0,0 +1,772 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package xyz.zhouxy.plusone.example.validator;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import xyz.zhouxy.plusone.example.ExampleCommand;
+import xyz.zhouxy.plusone.validator.BaseValidator;
+
+public class DoublePropertyValidatorTests {
+
+ static final double MIN = 1.0;
+ static final double MAX = 5.0;
+
+ static final String MESSAGE_GT = "The value should be greater than " + MIN;
+ static final String MESSAGE_GE = "The value should be greater than or equal to " + MIN;
+
+ static final String MESSAGE_LT = "The value should be less than " + MAX;
+ static final String MESSAGE_LE = "The value should be less than or equal to " + MAX;
+
+ // ================================
+ // #region - gt_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN + 0.000000000000001, Double.MAX_VALUE })
+ void gt_all_validValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, MESSAGE_GT);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The doubleProperty should be greater than %s, but it is %s", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - gt_validValue
+ // ================================
+
+ // ================================
+ // #region - gt_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN, MIN - 0.000000000000001, Double.MIN_VALUE })
+ void gt_default_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than " + MIN, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN, MIN - 0.000000000000001, Double.MIN_VALUE })
+ void gt_message_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, MESSAGE_GT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN, MIN - 0.000000000000001, Double.MIN_VALUE })
+ void gt_exceptionSupplier_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN, MIN - 0.000000000000001, Double.MIN_VALUE })
+ void gt_exceptionFunction_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The doubleProperty should be greater than %s, but it is %s", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be greater than %s, but it is %s", MIN, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - gt_invalidValue
+ // ================================
+
+ // ================================
+ // #region - gt_null
+ // ================================
+
+ @Test
+ void gt_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than " + MIN, e.getMessage());
+ }
+
+ @Test
+ void gt_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, MESSAGE_GT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @Test
+ void gt_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @Test
+ void gt_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The doubleProperty should be greater than %s, but it is %s", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be greater than %s, but it is null", MIN);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - gt_null
+ // ================================
+
+ // ================================
+ // #region - ge_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN, MIN + 0.000000000000001, Double.MAX_VALUE })
+ void ge_all_validValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, MESSAGE_GE);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The doubleProperty should be greater than or equal to %s, but it is %s", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - ge_validValue
+ // ================================
+
+ // ================================
+ // #region - ge_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN - 0.000000000000001, Double.MIN_VALUE })
+ void ge_default_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than or equal to " + MIN, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN - 0.000000000000001, Double.MIN_VALUE })
+ void ge_message_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, MESSAGE_GE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN - 0.000000000000001, Double.MIN_VALUE })
+ void ge_exceptionSupplier_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MIN - 0.000000000000001, Double.MIN_VALUE })
+ void ge_exceptionFunction_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The doubleProperty should be greater than or equal to %s, but it is %s", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be greater than or equal to %s, but it is %s", MIN, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - ge_invalidValue
+ // ================================
+
+ // ================================
+ // #region - ge_null
+ // ================================
+
+ @Test
+ void ge_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than or equal to " + MIN, e.getMessage());
+ }
+
+ @Test
+ void ge_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, MESSAGE_GE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @Test
+ void ge_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @Test
+ void ge_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The doubleProperty should be greater than or equal to %s, but it is %s", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be greater than or equal to %s, but it is null", MIN);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - ge_null
+ // ================================
+
+ // ================================
+ // #region - lt_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX - 0.000000000000001, Double.MIN_VALUE })
+ void lt_all_validValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, MESSAGE_LT);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, property -> ExampleException.withMessage(
+ "The doubleProperty should be less than %s, but it is %s", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - lt_validValue
+ // ================================
+
+ // ================================
+ // #region - lt_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX, MAX + 0.000000000000001, Double.MAX_VALUE })
+ void lt_default_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than " + MAX, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX, MAX + 0.000000000000001, Double.MAX_VALUE })
+ void lt_message_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, MESSAGE_LT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX, MAX + 0.000000000000001, Double.MAX_VALUE })
+ void lt_exceptionSupplier_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX, MAX + 0.000000000000001, Double.MAX_VALUE })
+ void lt_exceptionFunction_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, property -> ExampleException.withMessage(
+ "The doubleProperty should be less than %s, but it is %s", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be less than %s, but it is %s", MAX, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - lt_invalidValue
+ // ================================
+
+ // ================================
+ // #region - lt_null
+ // ================================
+
+ @Test
+ void lt_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than " + MAX, e.getMessage());
+ }
+
+ @Test
+ void lt_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, MESSAGE_LT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @Test
+ void lt_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @Test
+ void lt_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .lt(MAX, property -> ExampleException.withMessage(
+ "The doubleProperty should be less than %s, but it is %s", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be less than %s, but it is null", MAX);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - lt_null
+ // ================================
+
+ // ================================
+ // #region - le_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX, MAX - 0.000000000000001, Double.MIN_VALUE })
+ void le_all_validValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, MESSAGE_LE);
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, () -> ExampleException.withMessage(MESSAGE_LE));
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, property -> ExampleException.withMessage(
+ "The doubleProperty should be less than or equal to %s, but it is %s", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - le_validValue
+ // ================================
+
+ // ================================
+ // #region - le_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX + 0.000000000000001, Double.MAX_VALUE })
+ void le_default_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than or equal to " + MAX, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX + 0.000000000000001, Double.MAX_VALUE })
+ void le_message_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, MESSAGE_LE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX + 0.000000000000001, Double.MAX_VALUE })
+ void le_exceptionSupplier_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, () -> ExampleException.withMessage(MESSAGE_LE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(doubles = { MAX + 0.000000000000001, Double.MAX_VALUE })
+ void le_exceptionFunction_invalidValue(double value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, property -> ExampleException.withMessage(
+ "The doubleProperty should be less than or equal to %s, but it is %s", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be less than or equal to %s, but it is %s", MAX, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - le_invalidValue
+ // ================================
+
+ // ================================
+ // #region - le_null
+ // ================================
+
+ @Test
+ void le_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than or equal to " + MAX, e.getMessage());
+ }
+
+ @Test
+ void le_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, MESSAGE_LE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @Test
+ void le_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, () -> ExampleException.withMessage(MESSAGE_LE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @Test
+ void le_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForDouble(ExampleCommand::getDoubleProperty)
+ .le(MAX, property -> ExampleException.withMessage(
+ "The doubleProperty should be less than or equal to %s, but it is %s", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithDoubleProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The doubleProperty should be less than or equal to %s, but it is null", MAX);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - le_null
+ // ================================
+
+ static ExampleCommand exampleCommandWithDoubleProperty(Double doubleProperty) {
+ ExampleCommand exampleCommand = new ExampleCommand();
+ exampleCommand.setDoubleProperty(doubleProperty);
+ return exampleCommand;
+ }
+}
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/ExampleException.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/ExampleException.java
new file mode 100644
index 0000000..b19047b
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/ExampleException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package xyz.zhouxy.plusone.example.validator;
+
+import xyz.zhouxy.plusone.commons.annotation.StaticFactoryMethod;
+
+public class ExampleException extends RuntimeException {
+
+ private ExampleException(String message) {
+ super(message);
+ }
+
+ @StaticFactoryMethod
+ public static ExampleException withMessage(String message) {
+ return new ExampleException(message);
+ }
+
+ @StaticFactoryMethod
+ public static ExampleException withMessage(String format, Object... args) {
+ return new ExampleException(String.format(format, args));
+ }
+}
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/IntPropertyValidatorTests.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/IntPropertyValidatorTests.java
new file mode 100644
index 0000000..69be9c1
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/IntPropertyValidatorTests.java
@@ -0,0 +1,771 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package xyz.zhouxy.plusone.example.validator;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import xyz.zhouxy.plusone.example.ExampleCommand;
+import xyz.zhouxy.plusone.validator.BaseValidator;
+
+public class IntPropertyValidatorTests {
+
+ static final int MIN = 0;
+ static final int MAX = 5;
+
+ static final String MESSAGE_GT = "The value should be greater than " + MIN;
+ static final String MESSAGE_GE = "The value should be greater than or equal to " + MIN;
+
+ static final String MESSAGE_LT = "The value should be less than " + MAX;
+ static final String MESSAGE_LE = "The value should be less than or equal to " + MAX;
+
+ // ================================
+ // #region - gt_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN + 1, Integer.MAX_VALUE })
+ void gt_all_validValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, MESSAGE_GT);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The intProperty should be greater than %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - gt_validValue
+ // ================================
+
+ // ================================
+ // #region - gt_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN, MIN - 1, Integer.MIN_VALUE })
+ void gt_default_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than " + MIN, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN, MIN - 1, Integer.MIN_VALUE })
+ void gt_message_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, MESSAGE_GT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN, MIN - 1, Integer.MIN_VALUE })
+ void gt_exceptionSupplier_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN, MIN - 1, Integer.MIN_VALUE })
+ void gt_exceptionFunction_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The intProperty should be greater than %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be greater than %d, but it is %d", MIN, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - gt_invalidValue
+ // ================================
+
+ // ================================
+ // #region - gt_null
+ // ================================
+
+ @Test
+ void gt_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than " + MIN, e.getMessage());
+ }
+
+ @Test
+ void gt_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, MESSAGE_GT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @Test
+ void gt_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @Test
+ void gt_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The intProperty should be greater than %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be greater than %d, but it is null", MIN);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - gt_null
+ // ================================
+
+ // ================================
+ // #region - ge_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN, MIN + 1, Integer.MAX_VALUE })
+ void ge_all_validValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, MESSAGE_GE);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The intProperty should be greater than or equal to %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - ge_validValue
+ // ================================
+
+ // ================================
+ // #region - ge_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN - 1, Integer.MIN_VALUE })
+ void ge_default_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than or equal to " + MIN, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN - 1, Integer.MIN_VALUE })
+ void ge_message_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, MESSAGE_GE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN - 1, Integer.MIN_VALUE })
+ void ge_exceptionSupplier_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MIN - 1, Integer.MIN_VALUE })
+ void ge_exceptionFunction_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The intProperty should be greater than or equal to %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be greater than or equal to %d, but it is %d", MIN, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - ge_invalidValue
+ // ================================
+
+ // ================================
+ // #region - ge_null
+ // ================================
+
+ @Test
+ void ge_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than or equal to " + MIN, e.getMessage());
+ }
+
+ @Test
+ void ge_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, MESSAGE_GE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @Test
+ void ge_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @Test
+ void ge_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The intProperty should be greater than or equal to %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be greater than or equal to %d, but it is null", MIN);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - ge_null
+ // ================================
+
+ // ================================
+ // #region - lt_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX - 1, Integer.MIN_VALUE })
+ void lt_all_validValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, MESSAGE_LT);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, property -> ExampleException.withMessage(
+ "The intProperty should be less than %d, but it is %d", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - lt_validValue
+ // ================================
+
+ // ================================
+ // #region - lt_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX, MAX + 1, Integer.MAX_VALUE })
+ void lt_default_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than " + MAX, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX, MAX + 1, Integer.MAX_VALUE })
+ void lt_message_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, MESSAGE_LT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX, MAX + 1, Integer.MAX_VALUE })
+ void lt_exceptionSupplier_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX, MAX + 1, Integer.MAX_VALUE })
+ void lt_exceptionFunction_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, property -> ExampleException.withMessage(
+ "The intProperty should be less than %d, but it is %d", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be less than %d, but it is %d", MAX, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - lt_invalidValue
+ // ================================
+
+ // ================================
+ // #region - lt_null
+ // ================================
+
+ @Test
+ void lt_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than " + MAX, e.getMessage());
+ }
+
+ @Test
+ void lt_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, MESSAGE_LT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @Test
+ void lt_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @Test
+ void lt_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .lt(MAX, property -> ExampleException.withMessage(
+ "The intProperty should be less than %d, but it is %d", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be less than %d, but it is null", MAX);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - lt_null
+ // ================================
+
+ // ================================
+ // #region - le_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX, MAX - 1, Integer.MIN_VALUE })
+ void le_all_validValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, MESSAGE_LE);
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, () -> ExampleException.withMessage(MESSAGE_LE));
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, property -> ExampleException.withMessage(
+ "The intProperty should be less than or equal to %d, but it is %d", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - le_validValue
+ // ================================
+
+ // ================================
+ // #region - le_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX + 1, Integer.MAX_VALUE })
+ void le_default_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than or equal to " + MAX, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX + 1, Integer.MAX_VALUE })
+ void le_message_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, MESSAGE_LE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX + 1, Integer.MAX_VALUE })
+ void le_exceptionSupplier_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, () -> ExampleException.withMessage(MESSAGE_LE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = { MAX + 1, Integer.MAX_VALUE })
+ void le_exceptionFunction_invalidValue(int value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, property -> ExampleException.withMessage(
+ "The intProperty should be less than or equal to %d, but it is %d", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be less than or equal to %d, but it is %d", MAX, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - le_invalidValue
+ // ================================
+
+ // ================================
+ // #region - le_null
+ // ================================
+
+ @Test
+ void le_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than or equal to " + MAX, e.getMessage());
+ }
+
+ @Test
+ void le_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, MESSAGE_LE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @Test
+ void le_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, () -> ExampleException.withMessage(MESSAGE_LE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LE, e.getMessage());
+ }
+
+ @Test
+ void le_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForInt(ExampleCommand::getIntProperty)
+ .le(MAX, property -> ExampleException.withMessage(
+ "The intProperty should be less than or equal to %d, but it is %d", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithIntProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The intProperty should be less than or equal to %d, but it is null", MAX);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - le_null
+ // ================================
+
+ static ExampleCommand exampleCommandWithIntProperty(Integer intProperty) {
+ ExampleCommand exampleCommand = new ExampleCommand();
+ exampleCommand.setIntProperty(intProperty);
+ return exampleCommand;
+ }
+}
diff --git a/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/LongPropertyValidatorTests.java b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/LongPropertyValidatorTests.java
new file mode 100644
index 0000000..86a0ea7
--- /dev/null
+++ b/plusone-validator/src/test/java/xyz/zhouxy/plusone/example/validator/LongPropertyValidatorTests.java
@@ -0,0 +1,772 @@
+/*
+ * Copyright 2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package xyz.zhouxy.plusone.example.validator;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import xyz.zhouxy.plusone.example.ExampleCommand;
+import xyz.zhouxy.plusone.validator.BaseValidator;
+
+public class LongPropertyValidatorTests {
+
+ static final long MIN = 10000000000L;
+ static final long MAX = 10000000008L;
+
+
+ static final String MESSAGE_GT = "The value should be greater than " + MIN;
+ static final String MESSAGE_GE = "The value should be greater than or equal to " + MIN;
+
+ static final String MESSAGE_LT = "The value should be less than " + MAX;
+ static final String MESSAGE_LE = "The value should be less than or equal to " + MAX;
+
+ // ================================
+ // #region - gt_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN + 1, Long.MAX_VALUE })
+ void gt_all_validValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN);
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, MESSAGE_GT);
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The longProperty should be greater than %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - gt_validValue
+ // ================================
+
+ // ================================
+ // #region - gt_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN, MIN - 1, Long.MIN_VALUE })
+ void gt_default_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than " + MIN, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN, MIN - 1, Long.MIN_VALUE })
+ void gt_message_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, MESSAGE_GT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN, MIN - 1, Long.MIN_VALUE })
+ void gt_exceptionSupplier_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN, MIN - 1, Long.MIN_VALUE })
+ void gt_exceptionFunction_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The longProperty should be greater than %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The longProperty should be greater than %d, but it is %d", MIN, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - gt_invalidValue
+ // ================================
+
+ // ================================
+ // #region - gt_null
+ // ================================
+
+ @Test
+ void gt_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than " + MIN, e.getMessage());
+ }
+
+ @Test
+ void gt_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, MESSAGE_GT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @Test
+ void gt_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, () -> ExampleException.withMessage(MESSAGE_GT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GT, e.getMessage());
+ }
+
+ @Test
+ void gt_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .gt(MIN, property -> ExampleException.withMessage(
+ "The longProperty should be greater than %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The longProperty should be greater than %d, but it is null", MIN);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - gt_null
+ // ================================
+
+ // ================================
+ // #region - ge_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN, MIN + 1, Long.MAX_VALUE })
+ void ge_all_validValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN);
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, MESSAGE_GE);
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The longProperty should be greater than or equal to %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - ge_validValue
+ // ================================
+
+ // ================================
+ // #region - ge_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN - 1, Long.MIN_VALUE })
+ void ge_default_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than or equal to " + MIN, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN - 1, Long.MIN_VALUE })
+ void ge_message_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, MESSAGE_GE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN - 1, Long.MIN_VALUE })
+ void ge_exceptionSupplier_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MIN - 1, Long.MIN_VALUE })
+ void ge_exceptionFunction_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The longProperty should be greater than or equal to %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The longProperty should be greater than or equal to %d, but it is %d", MIN, value);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - ge_invalidValue
+ // ================================
+
+ // ================================
+ // #region - ge_null
+ // ================================
+
+ @Test
+ void ge_default_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be greater than or equal to " + MIN, e.getMessage());
+ }
+
+ @Test
+ void ge_message_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, MESSAGE_GE);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @Test
+ void ge_exceptionSupplier_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, () -> ExampleException.withMessage(MESSAGE_GE));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_GE, e.getMessage());
+ }
+
+ @Test
+ void ge_exceptionFunction_null() {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .ge(MIN, property -> ExampleException.withMessage(
+ "The longProperty should be greater than or equal to %d, but it is %d", MIN, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(null);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ final String expected = String.format("The longProperty should be greater than or equal to %d, but it is null", MIN);
+ assertEquals(expected, e.getMessage());
+ }
+
+ // ================================
+ // #endregion - ge_null
+ // ================================
+
+ // ================================
+ // #region - lt_validValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(longs = { MAX - 1, Long.MIN_VALUE })
+ void lt_all_validValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .lt(MAX);
+ ruleForLong(ExampleCommand::getLongProperty)
+ .lt(MAX, MESSAGE_LT);
+ ruleForLong(ExampleCommand::getLongProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ ruleForLong(ExampleCommand::getLongProperty)
+ .lt(MAX, property -> ExampleException.withMessage(
+ "The longProperty should be less than %d, but it is %d", MAX, property));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ assertDoesNotThrow(() -> validator.validate(command));
+ }
+
+ // ================================
+ // #endregion - lt_validValue
+ // ================================
+
+ // ================================
+ // #region - lt_invalidValue
+ // ================================
+
+ @ParameterizedTest
+ @ValueSource(longs = { MAX, MAX + 1, Long.MAX_VALUE })
+ void lt_default_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .lt(MAX);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals("The value should be less than " + MAX, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MAX, MAX + 1, Long.MAX_VALUE })
+ void lt_message_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .lt(MAX, MESSAGE_LT);
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ IllegalArgumentException e = assertThrows(
+ IllegalArgumentException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MAX, MAX + 1, Long.MAX_VALUE })
+ void lt_exceptionSupplier_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator() {
+ {
+ ruleForLong(ExampleCommand::getLongProperty)
+ .lt(MAX, () -> ExampleException.withMessage(MESSAGE_LT));
+ }
+ };
+
+ ExampleCommand command = exampleCommandWithLongProperty(value);
+
+ ExampleException e = assertThrows(
+ ExampleException.class, () -> validator.validate(command));
+ assertEquals(MESSAGE_LT, e.getMessage());
+ }
+
+ @ParameterizedTest
+ @ValueSource(longs = { MAX, MAX + 1, Long.MAX_VALUE })
+ void lt_exceptionFunction_invalidValue(long value) {
+ BaseValidator validator = new BaseValidator