[core] Keep integer minimum/maximum next to $ref/allOf as integers
Fixes #23445.
A minimum/maximum next to a $ref (OAS 3.1) or a single allOf is copied in DefaultCodegen with String.valueOf(bound.doubleValue()). For integers that gives 5000.0, so java/spring/kotlin-spring emit @Max(value = 5000.0), which doesn't compile, and int64 bounds above 2^53 lose digits (9007199254740993 becomes 9.007199254740992E15).
These bounds now go through the same helper as inline ones (ModelUtils.formatNumericBound, used by syncValidationProperties): an integer for integer schemas, the declared value otherwise. Same for a request body wrapped in a single allOf; a direct $ref request body with sibling bounds is rewritten to that form by the normalizer, so it's covered too.
A fractional bound on an integer schema used to be truncated toward zero (inline ones too), so minimum: 1.5 gave @Min(1) and accepted 1. It's now rounded into the allowed range: up for a minimum, down for a maximum, the other way round for an exclusive bound (minimum: 1.5 becomes 2, exclusiveMinimum: -1.5 becomes an exclusive -2). Integral bounds are unchanged.
New tests in DefaultCodegenTest, all failing on master and passing with the fix:
testIntegerBoundsNextToRefOrAllOfStayIntegers(expected: <5000> but was: <5000.0>)testIntegerBoundsNextToAllOfInRequestBody,testIntegerBoundsNextToRefInRequestBody(same)testFractionalBoundsOnIntegerSchemasAreRoundedIntoRange(expected: <2> but was: <1>)
DefaultCodegenTest, ModelUtilsTest, OpenAPINormalizerTest, ExclusiveMinMaxTest, SpringCodegenTest, KotlinSpringServerCodegenTest, JavaClientCodegenTest, AbstractJavaCodegenTest, JavaValidationArrayPrimitivesTest, DefaultGeneratorTest and the Rust/cpp-boost-beast tests that check bounds pass. No spec under src/test/resources puts a bound next to a $ref/allOf or a fractional bound on an integer schema, so samples shouldn't change; I didn't run generate-samples.sh.
PR checklist
- Read the contribution guidelines.
- Run the following to build the project and update samples (not run; no sample input is affected, see above).
I used Claude Code to write this change.
Summary by cubic
Fixes #23445 by keeping integer minimum/maximum values next to $ref or a single allOf as integers.
Previously such bounds were converted with String.valueOf(bound.doubleValue()), so 5000 became 5000.0 and Java/Spring/Kotlin generated @Max(value = 5000.0), which doesn't compile. Int64 bounds above 2^53 also lost digits. Now integer schemas get the bound as an integer, matching how inline bounds are handled in ModelUtils.syncValidationProperties. Fractional bounds on integer schemas are rounded into the allowed range (up for a minimum, down for a maximum, reversed for exclusive bounds). The same fix applies to request body parameters wrapped in a single allOf. Added regression tests.