-
-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added openApi spec formats #22
Conversation
Pull Request Test Coverage Report for Build 711580351
💛 - Coveralls |
I think coveralls has a quirck: is says 6 lines lost coverage, but looking at my output it says:
87 is within compareDate Happy to have a look at that as well, but I'd rather not mix it with this PR ;-) Kind regards, |
tests/extras/format.json
Outdated
"valid": false | ||
}, | ||
{ | ||
"description": "2**32 fails", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the test should be that 231 also fails, 232 - 1 succeeds
src/formats.ts
Outdated
// byte: https://github.com/miguelmota/is-base64 | ||
byte: /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/gm, | ||
// signed 32 bit integer | ||
int32: validateInteger(32), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should be defined as:
{
type: "number",
validateInteger(32),
}
otherwise that would be applied to strings (they should not be) and would not be applied to numbers (they should be)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it to work using:
{
type: "number",
validate: validateInteger(32)
}
The problem that I have now is that the test on a non-numerical value ("x"
) now returns true instead of false ?!?
Can I just safely remove that test ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to fail on non-numeric value the schema should have type: "number"
, format on its own should not fail non-numbers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is the general approach of JSON Schema that type should be explicit in the schema, it is never implied by anything else. Even your old definition would pass {}
for example on that test, unless there is type in the schema.
@@ -62,6 +69,21 @@ export const fullFormats: DefinedFormats = { | |||
"json-pointer-uri-fragment": /^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i, | |||
// relative JSON-pointer: http://tools.ietf.org/html/draft-luff-relative-json-pointer-00 | |||
"relative-json-pointer": /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/, | |||
// the following formats are used by the openapi specification: https://spec.openapis.org/oas/v3.0.0#data-types |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v3.1.0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/formats.ts
Outdated
// C-type float | ||
float: validateNumber(128), | ||
// C-type double | ||
double: validateNumber(1024), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be defined as {type: "number", validate: isFinite}
, although type: "number"
would do it already, so maybe just true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a javascript perspective yes, but if you validate them before export then a receiver using C will see a difference between floats and doubles. This was the only test I found to check the difference between floats and doubles.
We can set it to true, but it might come back to haunt us ;-)
src/formats.ts
Outdated
const max = Number(BigInt(2) ** BigInt(bits - 1)) | ||
const min = max * -1 | ||
|
||
return (value) => max >= value && min <= value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strictly ">" I think (although the limit is slightly lower I think)...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is where it becomes a bit of a challenge
Javascript integers go up to 2^53 hence the BigInt type
Ideally AJV would use BigInt for all its integer handling, however BigInt only plays nice with other BigInts :-(
(e.g. 2*BigInt(2)
fails BigInt(2)*BigInt(2)
succeeds.
So either we stick to basic javascript integers and skip the whole BigInt stuff of we need to come up with something clever ..
src/formats.ts
Outdated
// signed 64 bit integer | ||
int64: validateInteger(64), | ||
// C-type float | ||
float: validateNumber(128), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly, float can be constrained by hardcoded IEEE 754 limits (as 2**128 is not precise anyway and would cause run-time conversions)...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will need to read up a bit on this ;-)
We might be making our lives a bit too complex ;-) float and double should just be "number", no smart arithmic on when something is a double or not The float, double, int32 and int64 labels would then just be hints to developers, just like password and binary. What do you think ? Kind regards, |
Sorry for the delay.
I am ok with that. Options are:
I suggest Also ok to hardcode the limits for float as a single precision number.
agreed re int64 (In JS it would limit it to 2^53, but anything above is not really integer |
I have reworked the implementation of float, double, int32 and int64 Since I can't specify:
and we still want to block strings I had to use a function that returns true. On the testing I found a weird thing, if I add this test:
To any of the numeric formats, the test returns Hans |
No Schema You might want to say that format: double should apply to both number and correctly formatted string, but I don't think it's correct - in JSON Schema data type is never implied by other keywords, it is not applied by any string format (for example any number is valid against Hope it makes some sense :) |
OK, I have fixed the tests to use {"format": "double", "type": "number"}. Kind regards, |
thank you! |
As discussed in #9 I added formats for:
As defined in the OpenAPI specification at https://spec.openapis.org/oas/v3.0.0#data-types
Kind regards,
Hans