This is an automated email from the ASF dual-hosted git repository.

garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-validator.git


The following commit(s) were added to refs/heads/master by this push:
     new f0d0319d Add edge case tests in FloatValidatorTest and 
DoubleValidatorTest
f0d0319d is described below

commit f0d0319d7dd290e868ccf686ffacdc6701a7374b
Author: Gary Gregory <[email protected]>
AuthorDate: Thu Jun 4 07:08:28 2026 -0400

    Add edge case tests in FloatValidatorTest and DoubleValidatorTest
---
 .../validator/routines/DoubleValidatorTest.java    | 101 +++++++++++++++------
 .../validator/routines/FloatValidatorTest.java     |  86 +++++++++++-------
 2 files changed, 123 insertions(+), 64 deletions(-)

diff --git 
a/src/test/java/org/apache/commons/validator/routines/DoubleValidatorTest.java 
b/src/test/java/org/apache/commons/validator/routines/DoubleValidatorTest.java
index 813b8600..a247b1c6 100644
--- 
a/src/test/java/org/apache/commons/validator/routines/DoubleValidatorTest.java
+++ 
b/src/test/java/org/apache/commons/validator/routines/DoubleValidatorTest.java
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.validator.routines;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -35,21 +36,16 @@ class DoubleValidatorTest extends 
AbstractNumberValidatorTest {
     protected void setUp() {
         validator = new DoubleValidator(false, 0);
         strictValidator = new DoubleValidator();
-
         testPattern = "#,###.#";
-
         // testValidateMinMax()
         max = null;
         maxPlusOne = null;
         min = null;
         minMinusOne = null;
-
         // testInvalidStrict()
         invalidStrict = new String[] { null, "", "X", "X12", "12X", "1X2" };
-
         // testInvalidNotStrict()
         invalid = new String[] { null, "", "X", "X12" };
-
         // testValid()
         testNumber = Double.valueOf(1234.5);
         testZero = Double.valueOf(0);
@@ -57,16 +53,13 @@ class DoubleValidatorTest extends 
AbstractNumberValidatorTest {
         validStrictCompare = new Number[] { testZero, testNumber, testNumber };
         valid = new String[] { "0", "1234.5", "1,234.5", "1,234.5", "1234.5X" 
};
         validCompare = new Number[] { testZero, testNumber, testNumber, 
testNumber, testNumber };
-
         testStringUS = "1,234.5";
         testStringDE = "1.234,5";
-
         // Localized Pattern test
         localeValue = testStringDE;
         localePattern = "#.###,#";
         testLocale = Locale.GERMANY;
         localeExpected = testNumber;
-
     }
 
     /**
@@ -81,25 +74,75 @@ class DoubleValidatorTest extends 
AbstractNumberValidatorTest {
         final Double number19 = validator.validate("19", "#");
         final Double number20 = validator.validate("20", "#");
         final Double number21 = validator.validate("21", "#");
-
         // Test isInRange()
         assertFalse(validator.isInRange(number9, 10, 20), "isInRange() < min");
         assertTrue(validator.isInRange(number10, 10, 20), "isInRange() = min");
         assertTrue(validator.isInRange(number11, 10, 20), "isInRange() in 
range");
         assertTrue(validator.isInRange(number20, 10, 20), "isInRange() = max");
         assertFalse(validator.isInRange(number21, 10, 20), "isInRange() > 
max");
-
         // Test minValue()
         assertFalse(validator.minValue(number9, 10), "minValue() < min");
         assertTrue(validator.minValue(number10, 10), "minValue() = min");
         assertTrue(validator.minValue(number11, 10), "minValue() > min");
-
         // Test minValue()
         assertTrue(validator.maxValue(number19, 20), "maxValue() < max");
         assertTrue(validator.maxValue(number20, 20), "maxValue() = max");
         assertFalse(validator.maxValue(number21, 20), "maxValue() > max");
     }
 
+    /**
+     * Test Double Range/Min/Max with Double.NEGATIVE_INFINITY and 
Double.POSITIVE_INFINITY.
+     */
+    @Test
+    void testDoubleRangeMinMaxInfinity() {
+        final DoubleValidator validator = (DoubleValidator) strictValidator;
+        // isInRange() with NEGATIVE_INFINITY: less than any finite min
+        assertFalse(validator.isInRange(Double.NEGATIVE_INFINITY, 10, 20), 
"isInRange() NEGATIVE_INFINITY");
+        // isInRange() with POSITIVE_INFINITY: greater than any finite max
+        assertFalse(validator.isInRange(Double.POSITIVE_INFINITY, 10, 20), 
"isInRange() POSITIVE_INFINITY");
+        // minValue() with NEGATIVE_INFINITY: less than any finite min
+        assertFalse(validator.minValue(Double.NEGATIVE_INFINITY, 10), 
"minValue() NEGATIVE_INFINITY");
+        // minValue() with POSITIVE_INFINITY: greater than any finite min
+        assertTrue(validator.minValue(Double.POSITIVE_INFINITY, 10), 
"minValue() POSITIVE_INFINITY");
+        // maxValue() with NEGATIVE_INFINITY: less than any finite max
+        assertTrue(validator.maxValue(Double.NEGATIVE_INFINITY, 20), 
"maxValue() NEGATIVE_INFINITY");
+        // maxValue() with POSITIVE_INFINITY: greater than any finite max
+        assertFalse(validator.maxValue(Double.POSITIVE_INFINITY, 20), 
"maxValue() POSITIVE_INFINITY");
+    }
+
+    /**
+     * Test Double Range/Min/Max with Double.NaN. NaN comparisons always 
return false per IEEE 754.
+     */
+    @Test
+    void testDoubleRangeMinMaxNaN() {
+        final DoubleValidator validator = (DoubleValidator) strictValidator;
+        // isInRange() with NaN: NaN comparisons are always false
+        assertFalse(validator.isInRange(Double.NaN, 10, 20), "isInRange() 
NaN");
+        // minValue() with NaN: NaN >= min is always false
+        assertFalse(validator.minValue(Double.NaN, 10), "minValue() NaN");
+        // maxValue() with NaN: NaN <= max is always false
+        assertFalse(validator.maxValue(Double.NaN, 20), "maxValue() NaN");
+    }
+
+    /**
+     * Test DoubleValidator.validate(String) with Double special values. 
NumberFormat.parseObject("NaN") succeeds and returns Double.NaN, but "Infinity" 
and
+     * "-Infinity" cause a parse error and return null.
+     */
+    @Test
+    void testDoubleValidateSpecialValues() {
+        final DoubleValidator validator = DoubleValidator.getInstance();
+        // Double.NaN -> "NaN": NumberFormat parses "NaN" successfully
+        final Double nanResult = 
validator.validate(Double.toString(Double.NaN));
+        assertTrue(Double.isNaN(nanResult), "validate(\"NaN\") should return 
Double.NaN");
+        assertTrue(validator.isValid(Double.toString(Double.NaN)), 
"isValid(\"NaN\") should be true");
+        // Double.POSITIVE_INFINITY -> "Infinity": NumberFormat cannot parse 
"Infinity"
+        
assertNull(validator.validate(Double.toString(Double.POSITIVE_INFINITY)));
+        
assertFalse(validator.isValid(Double.toString(Double.POSITIVE_INFINITY)));
+        // Double.NEGATIVE_INFINITY -> "-Infinity": NumberFormat cannot parse 
"-Infinity"
+        
assertNull(validator.validate(Double.toString(Double.NEGATIVE_INFINITY)));
+        
assertFalse(validator.isValid(Double.toString(Double.NEGATIVE_INFINITY)));
+    }
+
     /**
      * Test DoubleValidator validate Methods
      */
@@ -113,24 +156,22 @@ class DoubleValidatorTest extends 
AbstractNumberValidatorTest {
         final String defaultVal = "12,345";
         final String xxxx = "XXXX";
         final Double expected = Double.valueOf(12345);
-        assertEquals(expected, 
DoubleValidator.getInstance().validate(defaultVal), "validate(A) default");
-        assertEquals(expected, 
DoubleValidator.getInstance().validate(localeVal, locale), "validate(A) 
locale");
-        assertEquals(expected, 
DoubleValidator.getInstance().validate(patternVal, pattern), "validate(A) 
pattern");
-        assertEquals(expected, 
DoubleValidator.getInstance().validate(germanPatternVal, pattern, 
Locale.GERMAN), "validate(A) both");
-
-        assertTrue(DoubleValidator.getInstance().isValid(defaultVal), 
"isValid(A) default");
-        assertTrue(DoubleValidator.getInstance().isValid(localeVal, locale), 
"isValid(A) locale");
-        assertTrue(DoubleValidator.getInstance().isValid(patternVal, pattern), 
"isValid(A) pattern");
-        assertTrue(DoubleValidator.getInstance().isValid(germanPatternVal, 
pattern, Locale.GERMAN), "isValid(A) both");
-
-        assertNull(DoubleValidator.getInstance().validate(xxxx), "validate(B) 
default");
-        assertNull(DoubleValidator.getInstance().validate(xxxx, locale), 
"validate(B) locale ");
-        assertNull(DoubleValidator.getInstance().validate(xxxx, pattern), 
"validate(B) pattern");
-        assertNull(DoubleValidator.getInstance().validate(patternVal, pattern, 
Locale.GERMAN), "validate(B) both");
-
-        assertFalse(DoubleValidator.getInstance().isValid(xxxx), "isValid(B) 
default");
-        assertFalse(DoubleValidator.getInstance().isValid(xxxx, locale), 
"isValid(B) locale");
-        assertFalse(DoubleValidator.getInstance().isValid(xxxx, pattern), 
"isValid(B) pattern");
-        assertFalse(DoubleValidator.getInstance().isValid(patternVal, pattern, 
Locale.GERMAN), "isValid(B) both");
+        final DoubleValidator validator = DoubleValidator.getInstance();
+        assertEquals(expected, validator.validate(defaultVal), "validate(A) 
default");
+        assertEquals(expected, validator.validate(localeVal, locale), 
"validate(A) locale");
+        assertEquals(expected, validator.validate(patternVal, pattern), 
"validate(A) pattern");
+        assertEquals(expected, validator.validate(germanPatternVal, pattern, 
Locale.GERMAN), "validate(A) both");
+        assertTrue(validator.isValid(defaultVal), "isValid(A) default");
+        assertTrue(validator.isValid(localeVal, locale), "isValid(A) locale");
+        assertTrue(validator.isValid(patternVal, pattern), "isValid(A) 
pattern");
+        assertTrue(validator.isValid(germanPatternVal, pattern, 
Locale.GERMAN), "isValid(A) both");
+        assertNull(validator.validate(xxxx), "validate(B) default");
+        assertNull(validator.validate(xxxx, locale), "validate(B) locale ");
+        assertNull(validator.validate(xxxx, pattern), "validate(B) pattern");
+        assertNull(validator.validate(patternVal, pattern, Locale.GERMAN), 
"validate(B) both");
+        assertFalse(validator.isValid(xxxx), "isValid(B) default");
+        assertFalse(validator.isValid(xxxx, locale), "isValid(B) locale");
+        assertFalse(validator.isValid(xxxx, pattern), "isValid(B) pattern");
+        assertFalse(validator.isValid(patternVal, pattern, Locale.GERMAN), 
"isValid(B) both");
     }
 }
diff --git 
a/src/test/java/org/apache/commons/validator/routines/FloatValidatorTest.java 
b/src/test/java/org/apache/commons/validator/routines/FloatValidatorTest.java
index 7ba5d8dd..5d515b12 100644
--- 
a/src/test/java/org/apache/commons/validator/routines/FloatValidatorTest.java
+++ 
b/src/test/java/org/apache/commons/validator/routines/FloatValidatorTest.java
@@ -14,6 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.validator.routines;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -36,21 +37,16 @@ class FloatValidatorTest extends 
AbstractNumberValidatorTest {
     protected void setUp() {
         validator = new FloatValidator(false, 0);
         strictValidator = new FloatValidator();
-
         testPattern = "#,###.#";
-
         // testValidateMinMax()
         max = Float.valueOf(Float.MAX_VALUE);
         maxPlusOne = Double.valueOf(max.doubleValue() * 10);
         min = Float.valueOf(Float.MAX_VALUE * -1);
         minMinusOne = Double.valueOf(min.doubleValue() * 10);
-
         // testInvalidStrict()
         invalidStrict = new String[] { null, "", "X", "X12", "12X", "1X2" };
-
         // testInvalidNotStrict()
         invalid = new String[] { null, "", "X", "X12" };
-
         // testValid()
         testNumber = Float.valueOf(1234.5f);
         testZero = Float.valueOf(0);
@@ -58,16 +54,13 @@ class FloatValidatorTest extends 
AbstractNumberValidatorTest {
         validStrictCompare = new Number[] { testZero, testNumber, testNumber };
         valid = new String[] { "0", "1234.5", "1,234.5", "1,234.5", "1234.5X" 
};
         validCompare = new Number[] { testZero, testNumber, testNumber, 
testNumber, testNumber };
-
         testStringUS = "1,234.5";
         testStringDE = "1.234,5";
-
         // Localized Pattern test
         localeValue = testStringDE;
         localePattern = "#.###,#";
         testLocale = Locale.GERMANY;
         localeExpected = testNumber;
-
     }
 
     /**
@@ -82,25 +75,56 @@ class FloatValidatorTest extends 
AbstractNumberValidatorTest {
         final Float number19 = validator.validate("19", "#");
         final Float number20 = validator.validate("20", "#");
         final Float number21 = validator.validate("21", "#");
-
         // Test isInRange()
         assertFalse(validator.isInRange(number9, 10, 20), "isInRange() < min");
         assertTrue(validator.isInRange(number10, 10, 20), "isInRange() = min");
         assertTrue(validator.isInRange(number11, 10, 20), "isInRange() in 
range");
         assertTrue(validator.isInRange(number20, 10, 20), "isInRange() = max");
         assertFalse(validator.isInRange(number21, 10, 20), "isInRange() > 
max");
-
         // Test minValue()
         assertFalse(validator.minValue(number9, 10), "minValue() < min");
         assertTrue(validator.minValue(number10, 10), "minValue() = min");
         assertTrue(validator.minValue(number11, 10), "minValue() > min");
-
         // Test minValue()
         assertTrue(validator.maxValue(number19, 20), "maxValue() < max");
         assertTrue(validator.maxValue(number20, 20), "maxValue() = max");
         assertFalse(validator.maxValue(number21, 20), "maxValue() > max");
     }
 
+    /**
+     * Test Float Range/Min/Max with Float.NEGATIVE_INFINITY and 
Float.POSITIVE_INFINITY.
+     */
+    @Test
+    void testFloatRangeMinMaxInfinity() {
+        final FloatValidator validator = (FloatValidator) strictValidator;
+        // isInRange() with NEGATIVE_INFINITY: less than any finite min
+        assertFalse(validator.isInRange(Float.NEGATIVE_INFINITY, 10, 20), 
"isInRange() NEGATIVE_INFINITY");
+        // isInRange() with POSITIVE_INFINITY: greater than any finite max
+        assertFalse(validator.isInRange(Float.POSITIVE_INFINITY, 10, 20), 
"isInRange() POSITIVE_INFINITY");
+        // minValue() with NEGATIVE_INFINITY: less than any finite min
+        assertFalse(validator.minValue(Float.NEGATIVE_INFINITY, 10), 
"minValue() NEGATIVE_INFINITY");
+        // minValue() with POSITIVE_INFINITY: greater than any finite min
+        assertTrue(validator.minValue(Float.POSITIVE_INFINITY, 10), 
"minValue() POSITIVE_INFINITY");
+        // maxValue() with NEGATIVE_INFINITY: less than any finite max
+        assertTrue(validator.maxValue(Float.NEGATIVE_INFINITY, 20), 
"maxValue() NEGATIVE_INFINITY");
+        // maxValue() with POSITIVE_INFINITY: greater than any finite max
+        assertFalse(validator.maxValue(Float.POSITIVE_INFINITY, 20), 
"maxValue() POSITIVE_INFINITY");
+    }
+
+    /**
+     * Test Float Range/Min/Max with Float.NaN. NaN comparisons always return 
false per IEEE 754.
+     */
+    @Test
+    void testFloatRangeMinMaxNaN() {
+        final FloatValidator validator = (FloatValidator) strictValidator;
+        // isInRange() with NaN: NaN comparisons are always false
+        assertFalse(validator.isInRange(Float.NaN, 10, 20), "isInRange() NaN");
+        // minValue() with NaN: NaN >= min is always false
+        assertFalse(validator.minValue(Float.NaN, 10), "minValue() NaN");
+        // maxValue() with NaN: NaN <= max is always false
+        assertFalse(validator.maxValue(Float.NaN, 20), "maxValue() NaN");
+    }
+
     /**
      * Test Float validation for values too small to handle. (slightly 
different from max/min which are the largest +ve/-ve
      */
@@ -108,22 +132,18 @@ class FloatValidatorTest extends 
AbstractNumberValidatorTest {
     void testFloatSmallestValues() {
         final String pattern = 
"#.#################################################################";
         final DecimalFormat fmt = new DecimalFormat(pattern);
-
         // Validate Smallest +ve value
         final Float smallestPositive = Float.valueOf(Float.MIN_VALUE);
         final String strSmallestPositive = fmt.format(smallestPositive);
         assertEquals(smallestPositive, 
FloatValidator.getInstance().validate(strSmallestPositive, pattern), "Smallest 
+ve");
-
         // Validate Smallest -ve value
         final Float smallestNegative = Float.valueOf(Float.MIN_VALUE * -1);
         final String strSmallestNegative = fmt.format(smallestNegative);
         assertEquals(smallestNegative, 
FloatValidator.getInstance().validate(strSmallestNegative, pattern), "Smallest 
-ve");
-
         // Validate Too Small +ve
         final Double tooSmallPositive = Double.valueOf((double) 
Float.MIN_VALUE / (double) 10);
         final String strTooSmallPositive = fmt.format(tooSmallPositive);
         assertFalse(FloatValidator.getInstance().isValid(strTooSmallPositive, 
pattern), "Too small +ve");
-
         // Validate Too Small -ve
         final Double tooSmallNegative = 
Double.valueOf(tooSmallPositive.doubleValue() * -1);
         final String strTooSmallNegative = fmt.format(tooSmallNegative);
@@ -143,24 +163,22 @@ class FloatValidatorTest extends 
AbstractNumberValidatorTest {
         final String defaultVal = "12,345";
         final String xxxx = "XXXX";
         final Float expected = Float.valueOf(12345);
-        assertEquals(expected, 
FloatValidator.getInstance().validate(defaultVal), "validate(A) default");
-        assertEquals(expected, 
FloatValidator.getInstance().validate(localeVal, locale), "validate(A) locale");
-        assertEquals(expected, 
FloatValidator.getInstance().validate(patternVal, pattern), "validate(A) 
pattern");
-        assertEquals(expected, 
FloatValidator.getInstance().validate(germanPatternVal, pattern, 
Locale.GERMAN), "validate(A) both");
-
-        assertTrue(FloatValidator.getInstance().isValid(defaultVal), 
"isValid(A) default");
-        assertTrue(FloatValidator.getInstance().isValid(localeVal, locale), 
"isValid(A) locale");
-        assertTrue(FloatValidator.getInstance().isValid(patternVal, pattern), 
"isValid(A) pattern");
-        assertTrue(FloatValidator.getInstance().isValid(germanPatternVal, 
pattern, Locale.GERMAN), "isValid(A) both");
-
-        assertNull(FloatValidator.getInstance().validate(xxxx), "validate(B) 
default");
-        assertNull(FloatValidator.getInstance().validate(xxxx, locale), 
"validate(B) locale ");
-        assertNull(FloatValidator.getInstance().validate(xxxx, pattern), 
"validate(B) pattern");
-        assertNull(FloatValidator.getInstance().validate(patternVal, pattern, 
Locale.GERMAN), "validate(B) both");
-
-        assertFalse(FloatValidator.getInstance().isValid(xxxx), "isValid(B) 
default");
-        assertFalse(FloatValidator.getInstance().isValid(xxxx, locale), 
"isValid(B) locale");
-        assertFalse(FloatValidator.getInstance().isValid(xxxx, pattern), 
"isValid(B) pattern");
-        assertFalse(FloatValidator.getInstance().isValid(patternVal, pattern, 
Locale.GERMAN), "isValid(B) both");
+        final FloatValidator validator = FloatValidator.getInstance();
+        assertEquals(expected, validator.validate(defaultVal), "validate(A) 
default");
+        assertEquals(expected, validator.validate(localeVal, locale), 
"validate(A) locale");
+        assertEquals(expected, validator.validate(patternVal, pattern), 
"validate(A) pattern");
+        assertEquals(expected, validator.validate(germanPatternVal, pattern, 
Locale.GERMAN), "validate(A) both");
+        assertTrue(validator.isValid(defaultVal), "isValid(A) default");
+        assertTrue(validator.isValid(localeVal, locale), "isValid(A) locale");
+        assertTrue(validator.isValid(patternVal, pattern), "isValid(A) 
pattern");
+        assertTrue(validator.isValid(germanPatternVal, pattern, 
Locale.GERMAN), "isValid(A) both");
+        assertNull(validator.validate(xxxx), "validate(B) default");
+        assertNull(validator.validate(xxxx, locale), "validate(B) locale ");
+        assertNull(validator.validate(xxxx, pattern), "validate(B) pattern");
+        assertNull(validator.validate(patternVal, pattern, Locale.GERMAN), 
"validate(B) both");
+        assertFalse(validator.isValid(xxxx), "isValid(B) default");
+        assertFalse(validator.isValid(xxxx, locale), "isValid(B) locale");
+        assertFalse(validator.isValid(xxxx, pattern), "isValid(B) pattern");
+        assertFalse(validator.isValid(patternVal, pattern, Locale.GERMAN), 
"isValid(B) both");
     }
 }

Reply via email to