diff --git a/fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/generator/ArbitraryGeneratorContext.java b/fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/generator/ArbitraryGeneratorContext.java index 69ae5f7ce..bdb84fb85 100644 --- a/fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/generator/ArbitraryGeneratorContext.java +++ b/fixture-monkey-api/src/main/java/com/navercorp/fixturemonkey/api/generator/ArbitraryGeneratorContext.java @@ -18,12 +18,16 @@ package com.navercorp.fixturemonkey.api.generator; +import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toMap; import java.lang.annotation.Annotation; +import java.lang.annotation.Repeatable; import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; diff --git a/fixture-monkey-jakarta-validation/src/main/java/com/navercorp/fixturemonkey/jakarta/validation/introspector/JakartaValidationConstraintGenerator.java b/fixture-monkey-jakarta-validation/src/main/java/com/navercorp/fixturemonkey/jakarta/validation/introspector/JakartaValidationConstraintGenerator.java index cdbc76a86..a17086f03 100644 --- a/fixture-monkey-jakarta-validation/src/main/java/com/navercorp/fixturemonkey/jakarta/validation/introspector/JakartaValidationConstraintGenerator.java +++ b/fixture-monkey-jakarta-validation/src/main/java/com/navercorp/fixturemonkey/jakarta/validation/introspector/JakartaValidationConstraintGenerator.java @@ -292,178 +292,128 @@ public JavaIntegerConstraint generateIntegerConstraint(ArbitraryGeneratorContext @Override @Nullable public JavaDecimalConstraint generateDecimalConstraint(ArbitraryGeneratorContext context) { - BigDecimal positiveMin = null; - Boolean positiveMinInclusive = null; - BigDecimal positiveMax = null; - Boolean positiveMaxInclusive = null; - BigDecimal negativeMin = null; - Boolean negativeMinInclusive = null; - BigDecimal negativeMax = null; - boolean negativeMaxInclusive = false; + BigDecimal min = null; + Boolean minInclusive = null; + BigDecimal max = null; + Boolean maxInclusive = null; Integer scale = null; - Optional digits = context.findAnnotation(Digits.class); - if (digits.isPresent()) { - BigDecimal value = BigDecimal.ONE; - int integer = digits.get().integer(); - if (integer > 1) { - value = BigDecimal.TEN.pow(integer - 1); - } - positiveMax = value.multiply(BigDecimal.TEN).subtract(BigDecimal.ONE); - positiveMin = value; - negativeMax = positiveMin.negate(); - negativeMin = positiveMax.negate(); - positiveMinInclusive = false; - negativeMinInclusive = false; - scale = digits.get().fraction(); - } - Optional minAnnotation = context.findAnnotation(Min.class); if (minAnnotation.isPresent()) { - BigDecimal minValue = minAnnotation.map(Min::value).map(BigDecimal::valueOf).get(); - if (minValue.compareTo(BigDecimal.ZERO) >= 0) { - if (positiveMin == null) { - positiveMin = minValue; - } else { - positiveMin = positiveMin.min(minValue); - } - negativeMax = null; - negativeMin = null; - } else { - if (negativeMin == null) { - negativeMin = minValue; - } else { - negativeMin = negativeMin.min(minValue); - } - negativeMinInclusive = true; - } + min = BigDecimal.valueOf(minAnnotation.get().value()); + minInclusive = true; } Optional decimalMinAnnotation = context.findAnnotation(DecimalMin.class); if (decimalMinAnnotation.isPresent()) { - BigDecimal decimalMin = new BigDecimal( - decimalMinAnnotation - .get() - .value() - ); + BigDecimal newMin = new BigDecimal(decimalMinAnnotation.get().value()); - if (decimalMin.compareTo(BigDecimal.ZERO) >= 0) { - if (positiveMin == null) { - positiveMin = decimalMin; - } else { - positiveMin = positiveMin.min(decimalMin); - } - if (!decimalMinAnnotation.map(DecimalMin::inclusive).get()) { - positiveMinInclusive = false; - } - negativeMax = null; - negativeMin = null; - } else { - if (negativeMin == null) { - negativeMin = decimalMin; - } else { - negativeMin = negativeMin.min(negativeMin); - } - if (!decimalMinAnnotation.map(DecimalMin::inclusive).get()) { - negativeMinInclusive = false; - } + if (min == null || newMin.compareTo(min) > 0 + || (newMin.compareTo(min) == 0 && !decimalMinAnnotation.get().inclusive())) { + + min = newMin; + minInclusive = decimalMinAnnotation.get().inclusive(); } } Optional maxAnnotation = context.findAnnotation(Max.class); if (maxAnnotation.isPresent()) { - BigDecimal maxValue = maxAnnotation.map(Max::value).map(BigDecimal::valueOf).get(); - if (maxValue.compareTo(BigDecimal.ZERO) > 0) { - if (positiveMax == null) { - positiveMax = maxValue; - } else { - positiveMax = positiveMax.max(maxValue); - } - } else { - if (negativeMax == null) { - negativeMax = maxValue; - } else { - negativeMax = negativeMax.max(maxValue); - } - } + max = BigDecimal.valueOf(maxAnnotation.get().value()); + maxInclusive = true; } Optional decimalMaxAnnotation = context.findAnnotation(DecimalMax.class); if (decimalMaxAnnotation.isPresent()) { - BigDecimal decimalMax = new BigDecimal( - decimalMaxAnnotation - .get() - .value() - ); + BigDecimal newMax = new BigDecimal(decimalMaxAnnotation.get().value()); - if (decimalMax.compareTo(BigDecimal.ZERO) > 0) { - if (positiveMax == null) { - positiveMax = decimalMax; - } else { - positiveMax = positiveMax.max(decimalMax); - } - positiveMaxInclusive = decimalMaxAnnotation.map(DecimalMax::inclusive).get(); - } else { - if (negativeMax == null) { - negativeMax = decimalMax; - } else { - negativeMax = negativeMax.max(decimalMax); - } - negativeMaxInclusive = decimalMaxAnnotation.map(DecimalMax::inclusive).get(); + if (max == null || newMax.compareTo(max) < 0 + || (newMax.compareTo(max) == 0 && !decimalMaxAnnotation.get().inclusive())) { + + max = newMax; + maxInclusive = decimalMaxAnnotation.get().inclusive(); } + } - if (!decimalMaxAnnotation.map(DecimalMax::inclusive).get()) { - positiveMaxInclusive = false; + if (context.findAnnotation(Positive.class).isPresent()) { + if (min == null || BigDecimal.ZERO.compareTo(min) > 0 + || (BigDecimal.ZERO.compareTo(min) == 0 && minInclusive)) { + min = BigDecimal.ZERO; + minInclusive = false; } + } - if (positiveMax == null) { - positiveMax = decimalMax; - } else if (positiveMax.compareTo(decimalMax) > 0) { - positiveMax = decimalMax; + if (context.findAnnotation(PositiveOrZero.class).isPresent()) { + if (min == null || BigDecimal.ZERO.compareTo(min) > 0) { + min = BigDecimal.ZERO; + minInclusive = true; } } if (context.findAnnotation(Negative.class).isPresent()) { - if (negativeMax == null || negativeMax.compareTo(BigDecimal.ZERO) > 0) { - negativeMax = BigDecimal.ZERO; - negativeMaxInclusive = false; + if (max == null || BigDecimal.ZERO.compareTo(max) < 0 + || (BigDecimal.ZERO.compareTo(max) == 0 && maxInclusive)) { + max = BigDecimal.ZERO; + maxInclusive = false; } } if (context.findAnnotation(NegativeOrZero.class).isPresent()) { - if (negativeMax == null || negativeMax.compareTo(BigDecimal.ZERO) > 0) { - negativeMax = BigDecimal.ZERO; - negativeMaxInclusive = true; + if (max == null || BigDecimal.ZERO.compareTo(max) < 0) { + max = BigDecimal.ZERO; + maxInclusive = true; } } - if (context.findAnnotation(Positive.class).isPresent()) { - if (positiveMin == null || positiveMin.compareTo(BigDecimal.ZERO) < 0) { - positiveMin = BigDecimal.ZERO; - positiveMinInclusive = false; + Optional digitsAnn = context.findAnnotation(Digits.class); + if (digitsAnn.isPresent()) { + Digits digits = digitsAnn.get(); + int integerDigits = digits.integer(); + int fractionDigits = digits.fraction(); + + StringBuilder maxBuilder = new StringBuilder(); + for (int i = 0; i < integerDigits; i++) { + maxBuilder.append('9'); } - } + if (fractionDigits > 0) { + maxBuilder.append('.'); + for (int i = 0; i < fractionDigits; i++) { + maxBuilder.append('9'); + } + } + BigDecimal digitsMax = new BigDecimal(maxBuilder.toString()); + BigDecimal digitsMin = digitsMax.negate(); - if (context.findAnnotation(PositiveOrZero.class).isPresent()) { - if (positiveMin == null || positiveMin.compareTo(BigDecimal.ZERO) < 0) { - positiveMin = BigDecimal.ZERO; - positiveMinInclusive = true; + if (max == null || digitsMax.compareTo(max) < 0) { + max = digitsMax; + maxInclusive = true; + } + if (min == null || digitsMin.compareTo(min) > 0) { + min = digitsMin; + minInclusive = true; } + + scale = digits.fraction(); } - if (positiveMin == null && positiveMax == null && negativeMin == null && negativeMax == null && scale == null) { + if (min == null && max == null) { return null; } + boolean isPositiveMin = min != null && min.compareTo(BigDecimal.ZERO) >= 0; + boolean isPositiveMax = max != null && max.compareTo(BigDecimal.ZERO) >= 0; + boolean isNegativeMin = min != null && min.compareTo(BigDecimal.ZERO) < 0; + boolean isNegativeMax = max != null && max.compareTo(BigDecimal.ZERO) < 0; + return new JavaDecimalConstraint( - positiveMin, - positiveMinInclusive, - positiveMax, - positiveMaxInclusive, - negativeMin, - negativeMinInclusive, - negativeMax, - negativeMaxInclusive, + isPositiveMin ? min : null, + isPositiveMin ? minInclusive : null, + isPositiveMax ? max : null, + isPositiveMax ? maxInclusive : null, + + isNegativeMin ? min : null, + isNegativeMin ? minInclusive : null, + isNegativeMax ? max : null, + isNegativeMax ? maxInclusive : null, scale ); } diff --git a/fixture-monkey-javax-validation/src/main/java/com/navercorp/fixturemonkey/javax/validation/introspector/JavaxValidationConstraintGenerator.java b/fixture-monkey-javax-validation/src/main/java/com/navercorp/fixturemonkey/javax/validation/introspector/JavaxValidationConstraintGenerator.java index 289267ad7..c14a867bc 100644 --- a/fixture-monkey-javax-validation/src/main/java/com/navercorp/fixturemonkey/javax/validation/introspector/JavaxValidationConstraintGenerator.java +++ b/fixture-monkey-javax-validation/src/main/java/com/navercorp/fixturemonkey/javax/validation/introspector/JavaxValidationConstraintGenerator.java @@ -291,178 +291,128 @@ public JavaIntegerConstraint generateIntegerConstraint(ArbitraryGeneratorContext @Override @Nullable public JavaDecimalConstraint generateDecimalConstraint(ArbitraryGeneratorContext context) { - BigDecimal positiveMin = null; - Boolean positiveMinInclusive = null; - BigDecimal positiveMax = null; - Boolean positiveMaxInclusive = null; - BigDecimal negativeMin = null; - Boolean negativeMinInclusive = null; - BigDecimal negativeMax = null; - boolean negativeMaxInclusive = false; + BigDecimal min = null; + Boolean minInclusive = null; + BigDecimal max = null; + Boolean maxInclusive = null; Integer scale = null; - Optional digits = context.findAnnotation(Digits.class); - if (digits.isPresent()) { - BigDecimal value = BigDecimal.ONE; - int integer = digits.get().integer(); - if (integer > 1) { - value = BigDecimal.TEN.pow(integer - 1); - } - positiveMax = value.multiply(BigDecimal.TEN).subtract(BigDecimal.ONE); - positiveMin = value; - negativeMax = positiveMin.negate(); - negativeMin = positiveMax.negate(); - positiveMinInclusive = false; - negativeMinInclusive = false; - scale = digits.get().fraction(); - } - Optional minAnnotation = context.findAnnotation(Min.class); if (minAnnotation.isPresent()) { - BigDecimal minValue = minAnnotation.map(Min::value).map(BigDecimal::valueOf).get(); - if (minValue.compareTo(BigDecimal.ZERO) >= 0) { - if (positiveMin == null) { - positiveMin = minValue; - } else { - positiveMin = positiveMin.min(minValue); - } - negativeMax = null; - negativeMin = null; - } else { - if (negativeMin == null) { - negativeMin = minValue; - } else { - negativeMin = negativeMin.min(minValue); - } - negativeMinInclusive = true; - } + min = BigDecimal.valueOf(minAnnotation.get().value()); + minInclusive = true; } Optional decimalMinAnnotation = context.findAnnotation(DecimalMin.class); if (decimalMinAnnotation.isPresent()) { - BigDecimal decimalMin = new BigDecimal( - decimalMinAnnotation - .get() - .value() - ); + BigDecimal newMin = new BigDecimal(decimalMinAnnotation.get().value()); - if (decimalMin.compareTo(BigDecimal.ZERO) >= 0) { - if (positiveMin == null) { - positiveMin = decimalMin; - } else { - positiveMin = positiveMin.min(decimalMin); - } - if (!decimalMinAnnotation.map(DecimalMin::inclusive).get()) { - positiveMinInclusive = false; - } - negativeMax = null; - negativeMin = null; - } else { - if (negativeMin == null) { - negativeMin = decimalMin; - } else { - negativeMin = negativeMin.min(negativeMin); - } - if (!decimalMinAnnotation.map(DecimalMin::inclusive).get()) { - negativeMinInclusive = false; - } + if (min == null || newMin.compareTo(min) > 0 + || (newMin.compareTo(min) == 0 && !decimalMinAnnotation.get().inclusive())) { + + min = newMin; + minInclusive = decimalMinAnnotation.get().inclusive(); } } Optional maxAnnotation = context.findAnnotation(Max.class); if (maxAnnotation.isPresent()) { - BigDecimal maxValue = maxAnnotation.map(Max::value).map(BigDecimal::valueOf).get(); - if (maxValue.compareTo(BigDecimal.ZERO) > 0) { - if (positiveMax == null) { - positiveMax = maxValue; - } else { - positiveMax = positiveMax.max(maxValue); - } - } else { - if (negativeMax == null) { - negativeMax = maxValue; - } else { - negativeMax = negativeMax.max(maxValue); - } - } + max = BigDecimal.valueOf(maxAnnotation.get().value()); + maxInclusive = true; } Optional decimalMaxAnnotation = context.findAnnotation(DecimalMax.class); if (decimalMaxAnnotation.isPresent()) { - BigDecimal decimalMax = new BigDecimal( - decimalMaxAnnotation - .get() - .value() - ); + BigDecimal newMax = new BigDecimal(decimalMaxAnnotation.get().value()); - if (decimalMax.compareTo(BigDecimal.ZERO) > 0) { - if (positiveMax == null) { - positiveMax = decimalMax; - } else { - positiveMax = positiveMax.max(decimalMax); - } - positiveMaxInclusive = decimalMaxAnnotation.map(DecimalMax::inclusive).get(); - } else { - if (negativeMax == null) { - negativeMax = decimalMax; - } else { - negativeMax = negativeMax.max(decimalMax); - } - negativeMaxInclusive = decimalMaxAnnotation.map(DecimalMax::inclusive).get(); + if (max == null || newMax.compareTo(max) < 0 + || (newMax.compareTo(max) == 0 && !decimalMaxAnnotation.get().inclusive())) { + + max = newMax; + maxInclusive = decimalMaxAnnotation.get().inclusive(); } + } - if (!decimalMaxAnnotation.map(DecimalMax::inclusive).get()) { - positiveMaxInclusive = false; + if (context.findAnnotation(Positive.class).isPresent()) { + if (min == null || BigDecimal.ZERO.compareTo(min) > 0 + || (BigDecimal.ZERO.compareTo(min) == 0 && minInclusive)) { + min = BigDecimal.ZERO; + minInclusive = false; } + } - if (positiveMax == null) { - positiveMax = decimalMax; - } else if (positiveMax.compareTo(decimalMax) > 0) { - positiveMax = decimalMax; + if (context.findAnnotation(PositiveOrZero.class).isPresent()) { + if (min == null || BigDecimal.ZERO.compareTo(min) > 0) { + min = BigDecimal.ZERO; + minInclusive = true; } } if (context.findAnnotation(Negative.class).isPresent()) { - if (negativeMax == null || negativeMax.compareTo(BigDecimal.ZERO) > 0) { - negativeMax = BigDecimal.ZERO; - negativeMaxInclusive = false; + if (max == null || BigDecimal.ZERO.compareTo(max) < 0 + || (BigDecimal.ZERO.compareTo(max) == 0 && maxInclusive)) { + max = BigDecimal.ZERO; + maxInclusive = false; } } if (context.findAnnotation(NegativeOrZero.class).isPresent()) { - if (negativeMax == null || negativeMax.compareTo(BigDecimal.ZERO) > 0) { - negativeMax = BigDecimal.ZERO; - negativeMaxInclusive = true; + if (max == null || BigDecimal.ZERO.compareTo(max) < 0) { + max = BigDecimal.ZERO; + maxInclusive = true; } } - if (context.findAnnotation(Positive.class).isPresent()) { - if (positiveMin == null || positiveMin.compareTo(BigDecimal.ZERO) < 0) { - positiveMin = BigDecimal.ZERO; - positiveMinInclusive = false; + Optional digitsAnn = context.findAnnotation(Digits.class); + if (digitsAnn.isPresent()) { + Digits digits = digitsAnn.get(); + int integerDigits = digits.integer(); + int fractionDigits = digits.fraction(); + + StringBuilder maxBuilder = new StringBuilder(); + for (int i = 0; i < integerDigits; i++) { + maxBuilder.append('9'); } - } + if (fractionDigits > 0) { + maxBuilder.append('.'); + for (int i = 0; i < fractionDigits; i++) { + maxBuilder.append('9'); + } + } + BigDecimal digitsMax = new BigDecimal(maxBuilder.toString()); + BigDecimal digitsMin = digitsMax.negate(); - if (context.findAnnotation(PositiveOrZero.class).isPresent()) { - if (positiveMin == null || positiveMin.compareTo(BigDecimal.ZERO) < 0) { - positiveMin = BigDecimal.ZERO; - positiveMinInclusive = true; + if (max == null || digitsMax.compareTo(max) < 0) { + max = digitsMax; + maxInclusive = true; + } + if (min == null || digitsMin.compareTo(min) > 0) { + min = digitsMin; + minInclusive = true; } + + scale = digits.fraction(); } - if (positiveMin == null && positiveMax == null && negativeMin == null && negativeMax == null && scale == null) { + if (min == null && max == null) { return null; } + boolean isPositiveMin = min != null && min.compareTo(BigDecimal.ZERO) >= 0; + boolean isPositiveMax = max != null && max.compareTo(BigDecimal.ZERO) >= 0; + boolean isNegativeMin = min != null && min.compareTo(BigDecimal.ZERO) < 0; + boolean isNegativeMax = max != null && max.compareTo(BigDecimal.ZERO) < 0; + return new JavaDecimalConstraint( - positiveMin, - positiveMinInclusive, - positiveMax, - positiveMaxInclusive, - negativeMin, - negativeMinInclusive, - negativeMax, - negativeMaxInclusive, + isPositiveMin ? min : null, + isPositiveMin ? minInclusive : null, + isPositiveMax ? max : null, + isPositiveMax ? maxInclusive : null, + + isNegativeMin ? min : null, + isNegativeMin ? minInclusive : null, + isNegativeMax ? max : null, + isNegativeMax ? maxInclusive : null, scale ); }