Skip to content

Commit 82babe4

Browse files
authored
Merge pull request #140 from networknt/fix/#139-multiple-of-validation
Fix multipleOf validator
2 parents 706e60d + 1c6edd7 commit 82babe4

File tree

2 files changed

+93
-57
lines changed

2 files changed

+93
-57
lines changed
Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,60 @@
1-
/*
2-
* Copyright (c) 2016 Network New Technologies Inc.
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*/
16-
17-
package com.networknt.schema;
18-
19-
import com.fasterxml.jackson.databind.JsonNode;
20-
import org.slf4j.Logger;
21-
import org.slf4j.LoggerFactory;
22-
23-
import java.util.Collections;
24-
import java.util.Set;
25-
26-
public class MultipleOfValidator extends BaseJsonValidator implements JsonValidator {
27-
private static final Logger logger = LoggerFactory.getLogger(MultipleOfValidator.class);
28-
29-
private double divisor = 0;
30-
31-
public MultipleOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
32-
33-
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.MULTIPLE_OF, validationContext);
34-
if (schemaNode.isNumber()) {
35-
divisor = schemaNode.doubleValue();
36-
}
37-
38-
parseErrorCode(getValidatorType().getErrorCodeKey());
39-
}
40-
41-
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
42-
debug(logger, node, rootNode, at);
43-
44-
if (node.isNumber()) {
45-
double nodeValue = node.doubleValue();
46-
if (divisor != 0) {
47-
long multiples = Math.round(nodeValue / divisor);
48-
if (Math.abs(multiples * divisor - nodeValue) > 1e-12) {
49-
return Collections.singleton(buildValidationMessage(at, "" + divisor));
50-
}
51-
}
52-
}
53-
54-
return Collections.emptySet();
55-
}
56-
57-
}
1+
/*
2+
* Copyright (c) 2016 Network New Technologies Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.networknt.schema;
18+
19+
import com.fasterxml.jackson.databind.JsonNode;
20+
import org.slf4j.Logger;
21+
import org.slf4j.LoggerFactory;
22+
23+
import java.math.BigDecimal;
24+
import java.util.Collections;
25+
import java.util.Set;
26+
27+
public class MultipleOfValidator extends BaseJsonValidator implements JsonValidator {
28+
private static final Logger logger = LoggerFactory.getLogger(MultipleOfValidator.class);
29+
30+
private double divisor = 0;
31+
32+
public MultipleOfValidator(String schemaPath, JsonNode schemaNode, JsonSchema parentSchema, ValidationContext validationContext) {
33+
34+
super(schemaPath, schemaNode, parentSchema, ValidatorTypeCode.MULTIPLE_OF, validationContext);
35+
if (schemaNode.isNumber()) {
36+
divisor = schemaNode.doubleValue();
37+
}
38+
39+
parseErrorCode(getValidatorType().getErrorCodeKey());
40+
}
41+
42+
public Set<ValidationMessage> validate(JsonNode node, JsonNode rootNode, String at) {
43+
debug(logger, node, rootNode, at);
44+
45+
if (node.isNumber()) {
46+
double nodeValue = node.doubleValue();
47+
if (divisor != 0) {
48+
// convert to BigDecimal since double type is not accurate enough to do the division and multiple
49+
BigDecimal accurateDividend = new BigDecimal(String.valueOf(nodeValue));
50+
BigDecimal accurateDivisor = new BigDecimal(String.valueOf(divisor));
51+
if (Math.abs(accurateDividend.divideAndRemainder(accurateDivisor)[1].doubleValue()) > 1e-12) {
52+
return Collections.singleton(buildValidationMessage(at, "" + divisor));
53+
}
54+
}
55+
}
56+
57+
return Collections.emptySet();
58+
}
59+
60+
}

src/test/resources/tests/multipleOf.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,38 @@
5656
"valid": false
5757
}
5858
]
59+
},
60+
{
61+
"description": "by small number",
62+
"schema": {
63+
"multipleOf": 0.01
64+
},
65+
"tests": [
66+
{
67+
"description": "9313.7 is a multiple of 0.01",
68+
"data": 9313.7,
69+
"valid": true
70+
},
71+
{
72+
"description": "9313.9 is a multiple of 0.01",
73+
"data": 9313.9,
74+
"valid": true
75+
},
76+
{
77+
"description": "9313.8 is a multiple of 0.01",
78+
"data": 9313.8,
79+
"valid": true
80+
},
81+
{
82+
"description": "9313.8 is a multiple of 0.01",
83+
"data": -9313.8861,
84+
"valid": false
85+
},
86+
{
87+
"description": "9313.8 is a multiple of 0.01",
88+
"data": -9313.8,
89+
"valid": true
90+
}
91+
]
5992
}
6093
]

0 commit comments

Comments
 (0)