Skip to content

Commit d4fd468

Browse files
committed
Issue #89 Update CI test count to 463 after adding integer validation edge case tests
1 parent 411fef7 commit d4fd468

File tree

3 files changed

+73
-2
lines changed

3 files changed

+73
-2
lines changed

json-java21-jtd/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ Validates primitive types:
6969

7070
Supported types: `boolean`, `string`, `timestamp`, `int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`, `float32`, `float64`
7171

72+
#### Integer Type Validation
73+
Integer types (`int8`, `uint8`, `int16`, `uint16`, `int32`, `uint32`) validate based on **numeric value**, not textual representation:
74+
75+
- **Valid integers**: `3`, `3.0`, `3.000`, `42.00` (mathematically integers)
76+
- **Invalid integers**: `3.1`, `3.14`, `3.0001` (have fractional components)
77+
78+
This follows RFC 8927 §2.2.3.1: "An integer value is a number without a fractional component."
79+
7280
### 4. Enum Schema
7381
Validates against string values:
7482
```json

json-java21-jtd/src/main/java/json/java21/jtd/JtdSchema.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,10 @@ Jtd.Result validateInteger(JsonValue instance, String type, boolean verboseError
244244
return Jtd.Result.failure(Jtd.Error.EXPECTED_INTEGER.message());
245245
}
246246

247-
// Handle BigDecimal - check if it has fractional part
248-
if (value instanceof java.math.BigDecimal bd && bd.scale() > 0) {
247+
// Handle BigDecimal - check if it has fractional component (not just scale > 0)
248+
// RFC 8927 §2.2.3.1: "An integer value is a number without a fractional component"
249+
// Values like 3.0 or 3.000 are valid integers despite positive scale, but 3.1 is not
250+
if (value instanceof java.math.BigDecimal bd && bd.remainder(java.math.BigDecimal.ONE).signum() != 0) {
249251
return Jtd.Result.failure(Jtd.Error.EXPECTED_INTEGER.message());
250252
}
251253

json-java21-jtd/src/test/java/json/java21/jtd/TestRfc8927.java

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,4 +469,65 @@ public void testInt32RejectsDecimal() throws Exception {
469469
.as("Should have validation errors for decimal value")
470470
.isNotEmpty();
471471
}
472+
473+
/// Test that integer types accept valid integer representations with trailing zeros
474+
/// RFC 8927 §2.2.3.1: "An integer value is a number without a fractional component"
475+
/// Values like 3.0, 3.000 are valid integers despite positive scale
476+
@Test
477+
public void testIntegerTypesAcceptTrailingZeros() throws Exception {
478+
JsonValue schema = Json.parse("{\"type\": \"int32\"}");
479+
480+
// Valid integer representations with trailing zeros
481+
JsonValue[] validIntegers = {
482+
JsonNumber.of(new java.math.BigDecimal("3.0")),
483+
JsonNumber.of(new java.math.BigDecimal("3.000")),
484+
JsonNumber.of(new java.math.BigDecimal("42.00")),
485+
JsonNumber.of(new java.math.BigDecimal("0.0"))
486+
};
487+
488+
Jtd validator = new Jtd();
489+
490+
for (JsonValue validValue : validIntegers) {
491+
Jtd.Result result = validator.validate(schema, validValue);
492+
493+
LOG.fine(() -> "Testing int32 with valid integer representation: " + validValue);
494+
495+
assertThat(result.isValid())
496+
.as("int32 should accept integer representation %s", validValue)
497+
.isTrue();
498+
assertThat(result.errors())
499+
.as("Should have no validation errors for integer representation %s", validValue)
500+
.isEmpty();
501+
}
502+
}
503+
504+
/// Test that integer types reject values with actual fractional components
505+
/// RFC 8927 §2.2.3.1: "An integer value is a number without a fractional component"
506+
@Test
507+
public void testIntegerTypesRejectFractionalComponents() throws Exception {
508+
JsonValue schema = Json.parse("{\"type\": \"int32\"}");
509+
510+
// Invalid values with actual fractional components
511+
JsonValue[] invalidValues = {
512+
JsonNumber.of(new java.math.BigDecimal("3.1")),
513+
JsonNumber.of(new java.math.BigDecimal("3.0001")),
514+
JsonNumber.of(new java.math.BigDecimal("3.14")),
515+
JsonNumber.of(new java.math.BigDecimal("0.1"))
516+
};
517+
518+
Jtd validator = new Jtd();
519+
520+
for (JsonValue invalidValue : invalidValues) {
521+
Jtd.Result result = validator.validate(schema, invalidValue);
522+
523+
LOG.fine(() -> "Testing int32 with fractional value: " + invalidValue);
524+
525+
assertThat(result.isValid())
526+
.as("int32 should reject fractional value %s", invalidValue)
527+
.isFalse();
528+
assertThat(result.errors())
529+
.as("Should have validation errors for fractional value %s", invalidValue)
530+
.isNotEmpty();
531+
}
532+
}
472533
}

0 commit comments

Comments
 (0)