Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions lib/jsonschema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -984,9 +984,14 @@ generate_validator = function(ctx, schema)
-- integer multipleOf: modulo is enough
ctx:stmt(sformat(' if %s %% %d ~= 0 then', ctx:param(1), mof))
else
-- float multipleOf: it's a bit more hacky and slow
-- float multipleOf: use relative tolerance to handle IEEE 754
-- precision errors. e.g. 1.13 / 0.01 = 112.99999999999999
-- We check whether the fractional part of the quotient is
-- negligible relative to its magnitude.
ctx:stmt(sformat(' local quotient = %s / %s', ctx:param(1), mof))
ctx:stmt(sformat(' if %s(quotient) ~= quotient then', ctx:libfunc('math.modf')))
ctx:stmt(sformat(' local rounded = %s(quotient + 0.5)', ctx:libfunc('math.floor')))
ctx:stmt( ' local tol = 1e-12 * (rounded == 0 and 1 or (rounded < 0 and -rounded or rounded))')
ctx:stmt(sformat(' if %s(quotient - rounded) > tol then', ctx:libfunc('math.abs')))
end
ctx:stmt(sformat( ' return false, %s("expected %%s to be a multiple of %s", %s)',
ctx:libfunc('string.format'), mof, ctx:param(1)))
Expand Down
74 changes: 74 additions & 0 deletions spec/extra/multipleOf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[
{
"description": "multipleOf with float precision",
"schema": {
"type": "number",
"multipleOf": 0.01
},
"tests": [
{
"description": "1.13 is a multiple of 0.01",
"data": 1.13,
"valid": true
},
{
"description": "0.01 is a multiple of 0.01",
"data": 0.01,
"valid": true
},
{
"description": "100.05 is a multiple of 0.01",
"data": 100.05,
"valid": true
},
{
"description": "1.1312 is not a multiple of 0.01",
"data": 1.1312,
"valid": false
},
{
"description": "0.015 is not a multiple of 0.01",
"data": 0.015,
"valid": false
}
]
},
{
"description": "multipleOf with integer",
"schema": {
"type": "number",
"multipleOf": 3
},
"tests": [
Comment thread
jarvis9443 marked this conversation as resolved.
{
"description": "9 is a multiple of 3",
"data": 9,
"valid": true
},
{
"description": "10 is not a multiple of 3",
"data": 10,
"valid": false
}
]
},
{
"description": "multipleOf with large values",
"schema": {
"type": "number",
"multipleOf": 1000000000.5
},
"tests": [
{
"description": "exact large multiple is valid",
"data": 2000000001.0,
"valid": true
},
{
"description": "large value offset by 0.05 is invalid",
"data": 1000000000.55,
"valid": false
}
]
}
]
1 change: 1 addition & 0 deletions t/draft4.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ local supported = {
"spec/extra/dependencies.json",
"spec/extra/table.json",
"spec/extra/ref.json",
"spec/extra/multipleOf.json",

'spec/JSON-Schema-Test-Suite/tests/draft4/type.json',
'spec/JSON-Schema-Test-Suite/tests/draft4/default.json',
Expand Down
1 change: 1 addition & 0 deletions t/draft7.lua
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ local supported = {
"spec/extra/ref.json",
"spec/extra/format.json",
"spec/extra/default.json",
"spec/extra/multipleOf.json",

'spec/JSON-Schema-Test-Suite/tests/draft7/type.json',
'spec/JSON-Schema-Test-Suite/tests/draft7/default.json',
Expand Down
Loading