diff --git a/pkg/generator/validator.go b/pkg/generator/validator.go index a772e3e2..09ab1906 100644 --- a/pkg/generator/validator.go +++ b/pkg/generator/validator.go @@ -315,17 +315,31 @@ func (v *numericValidator) generate(out *codegen.Emitter) { } if v.multipleOf != nil { + if v.roundToInt { out.Printlnf(`if %s %s%s %% %v != 0 {`, checkPointer, pointerPrefix, value, v.valueOf(*v.multipleOf)) + out.Indent(1) + out.Printlnf(`return fmt.Errorf("field %%s: must be a multiple of %%v", "%s", %f)`, v.jsonName, *v.multipleOf) + out.Indent(-1) + out.Printlnf("}") } else { + if v.isNillable { + out.Printlnf(`if %s != nil {`, value) + } else { + out.Printlnf("{") + } + out.Indent(1) + out.Printlnf("remainder := math.Mod(%s%s, %v)", pointerPrefix, value, v.valueOf(*v.multipleOf)) out.Printlnf( - `if %s math.Abs(math.Mod(%s%s, %v)) > 1e-10 {`, checkPointer, pointerPrefix, value, v.valueOf(*v.multipleOf)) - } + `if !(math.Abs(remainder) < 1e-10 || math.Abs(remainder - %v) < 1e-10) {`, v.valueOf(*v.multipleOf)) + out.Indent(1) + out.Printlnf(`return fmt.Errorf("field %%s: must be a multiple of %%v", "%s", %f)`, v.jsonName, *v.multipleOf) + out.Indent(-1) + out.Printlnf("}") - out.Indent(1) - out.Printlnf(`return fmt.Errorf("field %%s: must be a multiple of %%v", "%s", %f)`, v.jsonName, *v.multipleOf) - out.Indent(-1) - out.Printlnf("}") + out.Indent(-1) + out.Printlnf("}") + } } nMin, nMax, nMinExclusive, nMaxExclusive := mathutils.NormalizeBounds( diff --git a/tests/data/validation/multipleOf/multipleOf.go b/tests/data/validation/multipleOf/multipleOf.go index d611316b..1ef63101 100644 --- a/tests/data/validation/multipleOf/multipleOf.go +++ b/tests/data/validation/multipleOf/multipleOf.go @@ -43,11 +43,17 @@ func (j *MultipleOf) UnmarshalJSON(b []byte) error { if plain.MyNullableInteger != nil && *plain.MyNullableInteger%2 != 0 { return fmt.Errorf("field %s: must be a multiple of %v", "myNullableInteger", 2.000000) } - if plain.MyNullableNumber != nil && math.Abs(math.Mod(*plain.MyNullableNumber, 1.2)) > 1e-10 { - return fmt.Errorf("field %s: must be a multiple of %v", "myNullableNumber", 1.200000) - } - if math.Abs(math.Mod(plain.MyNumber, 1.2)) > 1e-10 { - return fmt.Errorf("field %s: must be a multiple of %v", "myNumber", 1.200000) + if plain.MyNullableNumber != nil { + remainder := math.Mod(*plain.MyNullableNumber, 0.2) + if !(math.Abs(remainder) < 1e-10 || math.Abs(remainder-0.2) < 1e-10) { + return fmt.Errorf("field %s: must be a multiple of %v", "myNullableNumber", 0.200000) + } + } + { + remainder := math.Mod(plain.MyNumber, 0.2) + if !(math.Abs(remainder) < 1e-10 || math.Abs(remainder-0.2) < 1e-10) { + return fmt.Errorf("field %s: must be a multiple of %v", "myNumber", 0.200000) + } } *j = MultipleOf(plain) return nil diff --git a/tests/data/validation/multipleOf/multipleOf.json b/tests/data/validation/multipleOf/multipleOf.json index 1f4e99c2..cb34f2c5 100644 --- a/tests/data/validation/multipleOf/multipleOf.json +++ b/tests/data/validation/multipleOf/multipleOf.json @@ -5,7 +5,7 @@ "properties": { "myNumber": { "type": "number", - "multipleOf": 1.2 + "multipleOf": 0.2 }, "myInteger": { "type": "integer", @@ -13,7 +13,7 @@ }, "myNullableNumber": { "type": "number", - "multipleOf": 1.2 + "multipleOf": 0.2 }, "myNullableInteger": { "type": "integer", @@ -24,4 +24,4 @@ "myNumber", "myInteger" ] -} +} \ No newline at end of file diff --git a/tests/validation_test.go b/tests/validation_test.go index 8954de7c..76bf3760 100644 --- a/tests/validation_test.go +++ b/tests/validation_test.go @@ -230,6 +230,10 @@ func TestMultipleOf(t *testing.T) { desc: "no violations", data: `{"myInteger": 10, "myNumber": 2.4}`, }, + { + desc: "no violations bigger number", + data: `{"myInteger": 10, "myNumber": 482.6}`, + }, { desc: "myInt not a multiple of 2", data: `{"myInteger": 11, "myNumber": 2.4}`, @@ -238,7 +242,7 @@ func TestMultipleOf(t *testing.T) { { desc: "myNumber not a multiple of 1.2", data: `{"myInteger": 10, "myNumber": 2.5}`, - wantErr: errors.New("field myNumber: must be a multiple of 1.2"), + wantErr: errors.New("field myNumber: must be a multiple of 0.2"), }, }