-
Notifications
You must be signed in to change notification settings - Fork 77
Add support for date, time, and date-time validators #118
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
Changes from all commits
fe9f0c9
4802423
0aec188
696b2dd
67ef451
c01e38c
a7f6c82
991b653
a47ad74
5d4edf7
4ddf0a4
9ff0b2a
c21d826
0fb8929
29e2b15
4637ac1
cb1085f
e31ef51
cdb44c4
8f962f8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
/.build/ | ||
/.swiftpm/ | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import Foundation | ||
|
||
func validateDateTime(_ context: Context, _ value: Any) -> AnySequence<ValidationError> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While testing some of the examples from rfc3339 (https://tools.ietf.org/html/rfc3339#section-5.8), appears this isn't behaving as expected with leap seconds, the test below seems to fail. import XCTest
import JSONSchema
class DateTimeFormatTests: XCTestCase {
func testDateTimeWithLeapSecond() throws {
let schema: [String: Any] = [
"$schema": "https://json-schema.org/draft/2020-12/schema",
"format": "date-time",
]
let result = try validate("1990-12-31T23:59:60Z", schema: schema)
XCTAssertTrue(result.valid)
}
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @kylef I'm a bit confused about this one as it's called out as invalid in the jsonschema.org tests repo - see https://github.com/json-schema-org/JSON-Schema-Test-Suite/blob/6bc53e60c3de5d2e2ab15a84bcd3a79ca12c66a9/tests/draft2020-12/optional/format/date-time.json#L28 This seems to be at odds with the spec though:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting, unsure if that's test is trying to disallow a leap second or instead there being 31 days in February. We can try to clarify that in the tests suite. Started with json-schema-org/JSON-Schema-Test-Suite#481 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The leap second would need to be at the end of the day. |
||
if let date = value as? String { | ||
if let regularExpression = try? NSRegularExpression(pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}", options: .caseInsensitive) { | ||
kylef marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let range = NSRange(location: 0, length: date.utf16.count) | ||
let result = regularExpression.matches(in: date, options: [], range: range) | ||
if result.isEmpty { | ||
return AnySequence([ | ||
ValidationError( | ||
"'\(date)' is not a valid RFC 3339 formatted date.", | ||
instanceLocation: context.instanceLocation, | ||
keywordLocation: context.keywordLocation | ||
) | ||
]) | ||
} | ||
} | ||
|
||
let rfc3339DateTimeFormatter = DateFormatter() | ||
|
||
rfc3339DateTimeFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ" | ||
if rfc3339DateTimeFormatter.date(from: date) != nil { | ||
return AnySequence(EmptyCollection()) | ||
} | ||
|
||
rfc3339DateTimeFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ" | ||
if rfc3339DateTimeFormatter.date(from: date) != nil { | ||
return AnySequence(EmptyCollection()) | ||
} | ||
|
||
rfc3339DateTimeFormatter.dateFormat = "yyyy-MM-dd't'HH:mm:ss.SSS'z'" | ||
if rfc3339DateTimeFormatter.date(from: date) != nil { | ||
return AnySequence(EmptyCollection()) | ||
} | ||
|
||
return AnySequence([ | ||
ValidationError( | ||
"'\(date)' is not a valid RFC 3339 formatted date-time.", | ||
instanceLocation: context.instanceLocation, | ||
keywordLocation: context.keywordLocation | ||
) | ||
]) | ||
} | ||
|
||
return AnySequence(EmptyCollection()) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import XCTest | ||
@testable import JSONSchema | ||
|
||
|
||
class TimeFormatTests: XCTestCase { | ||
func testTimeWithoutSecondFraction() throws { | ||
let schema: [String: Any] = [ | ||
"$schema": "https://json-schema.org/draft/2020-12/schema", | ||
"format": "time", | ||
] | ||
|
||
let result = try validate("23:59:50Z", schema: schema) | ||
|
||
XCTAssertTrue(result.valid) | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.