Skip to content

Commit 50e0e47

Browse files
committed
port #409 to the OAS 3.0 module
1 parent a21615e commit 50e0e47

File tree

3 files changed

+100
-28
lines changed

3 files changed

+100
-28
lines changed

Sources/OpenAPIKit30/Schema Object/JSONSchema.swift

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,6 +1762,9 @@ extension JSONSchema: Decodable {
17621762
}
17631763

17641764
self = schema
1765+
1766+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
1767+
self.vendorExtensions = try Self.decodeVenderExtensions(from: decoder)
17651768
return
17661769
}
17671770

@@ -1775,6 +1778,9 @@ extension JSONSchema: Decodable {
17751778
}
17761779

17771780
self = schema
1781+
1782+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
1783+
self.vendorExtensions = try Self.decodeVenderExtensions(from: decoder)
17781784
return
17791785
}
17801786

@@ -1788,6 +1794,9 @@ extension JSONSchema: Decodable {
17881794
}
17891795

17901796
self = schema
1797+
1798+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
1799+
self.vendorExtensions = try Self.decodeVenderExtensions(from: decoder)
17911800
return
17921801
}
17931802

@@ -1798,6 +1807,9 @@ extension JSONSchema: Decodable {
17981807
)
17991808

18001809
self = schema
1810+
1811+
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
1812+
self.vendorExtensions = try Self.decodeVenderExtensions(from: decoder)
18011813
return
18021814
}
18031815

@@ -1888,25 +1900,27 @@ extension JSONSchema: Decodable {
18881900

18891901
self.warnings = _warnings
18901902

1891-
// Ad-hoc vendor extension support since JSONSchema does coding keys differently.
1903+
self.vendorExtensions = try Self.decodeVenderExtensions(from: decoder)
1904+
}
1905+
1906+
private static func decodeVenderExtensions(from decoder: Decoder) throws -> [String: AnyCodable] {
18921907
guard VendorExtensionsConfiguration.isEnabled else {
1893-
self.vendorExtensions = [:]
1894-
return
1908+
return [:]
18951909
}
1896-
1910+
18971911
let decoded = try AnyCodable(from: decoder).value
1898-
1912+
18991913
guard (decoded as? [Any]) == nil else {
19001914
throw VendorExtensionDecodingError.selfIsArrayNotDict
19011915
}
1902-
1916+
19031917
guard let decodedAny = decoded as? [String: Any] else {
19041918
throw VendorExtensionDecodingError.foundNonStringKeys
19051919
}
1906-
1907-
let extensions = decodedAny.filter { $0.key.lowercased().starts(with: "x-") }
1908-
1909-
self.vendorExtensions = extensions.mapValues(AnyCodable.init)
1920+
1921+
return decodedAny
1922+
.filter { $0.key.lowercased().starts(with: "x-") }
1923+
.mapValues(AnyCodable.init)
19101924
}
19111925
}
19121926

Tests/OpenAPIKit30Tests/Schema Object/JSONSchemaTests.swift

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,6 +1508,64 @@ extension SchemaObjectTests {
15081508
)
15091509
}
15101510

1511+
func test_decodeAnyOfWithVendorExtension() throws {
1512+
let extensionSchema = """
1513+
{
1514+
"anyOf" : [
1515+
{ "type": "string" },
1516+
{ "type": "number" }
1517+
],
1518+
"x-hello" : "hello"
1519+
}
1520+
""".data(using: .utf8)!
1521+
1522+
var desiredSchema = JSONSchema.one(of: [JSONSchema.string, JSONSchema.number])
1523+
desiredSchema.vendorExtensions = ["x-hello": "hello"]
1524+
XCTAssertEqual(
1525+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1526+
desiredSchema
1527+
)
1528+
}
1529+
1530+
func test_decodeAllOfWithVendorExtension() throws {
1531+
let extensionSchema = """
1532+
{
1533+
"allOf" : [
1534+
{ "type": "string" },
1535+
{ "type": "number" }
1536+
],
1537+
"x-hello" : "hello"
1538+
}
1539+
""".data(using: .utf8)!
1540+
1541+
var desiredSchema = JSONSchema.one(of: [JSONSchema.string, JSONSchema.number])
1542+
desiredSchema.vendorExtensions = ["x-hello": "hello"]
1543+
XCTAssertEqual(
1544+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1545+
desiredSchema
1546+
)
1547+
}
1548+
1549+
func test_decodeOneOfWithVendorExtension() throws {
1550+
let extensionSchema = """
1551+
{
1552+
"oneOf" : [
1553+
{ "type": "string" },
1554+
{ "type": "number" }
1555+
],
1556+
"x-hello" : "hello"
1557+
}
1558+
""".data(using: .utf8)!
1559+
1560+
var desiredSchema = JSONSchema.one(of: [JSONSchema.string, JSONSchema.number])
1561+
desiredSchema.vendorExtensions = ["x-hello": "hello"]
1562+
XCTAssertEqual(
1563+
try orderUnstableDecode(JSONSchema.self, from: extensionSchema),
1564+
desiredSchema
1565+
)
1566+
}
1567+
1568+
15111569
func test_encodeBoolean() {
15121570
let requiredBoolean = JSONSchema.boolean(.init(format: .unspecified, required: true))
15131571
let optionalBoolean = JSONSchema.boolean(.init(format: .unspecified, required: false))

Tests/OpenAPIKitTests/Schema Object/JSONSchemaTests.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,24 @@ extension SchemaObjectTests {
19181918
JSONSchema.fragment(.init(examples: ["hello"])).with(vendorExtensions: ["x-hello": "hello"])
19191919
)
19201920
}
1921+
1922+
func test_encodeExamplesVendorExtension() throws {
1923+
let fragment = JSONSchema.fragment(.init(examples: ["hello"])).with(vendorExtensions: ["x-hello": "hello"])
1924+
1925+
let encoded = try orderUnstableTestStringFromEncoding(of: fragment)
1926+
1927+
assertJSONEquivalent(
1928+
encoded,
1929+
"""
1930+
{
1931+
"examples" : [
1932+
"hello"
1933+
],
1934+
"x-hello" : "hello"
1935+
}
1936+
"""
1937+
)
1938+
}
19211939

19221940
func test_decodeAnyOfWithVendorExtension() throws {
19231941
let extensionSchema = """
@@ -1970,24 +1988,6 @@ extension SchemaObjectTests {
19701988
)
19711989
}
19721990

1973-
func test_encodeExamplesVendorExtension() throws {
1974-
let fragment = JSONSchema.fragment(.init(examples: ["hello"])).with(vendorExtensions: ["x-hello": "hello"])
1975-
1976-
let encoded = try orderUnstableTestStringFromEncoding(of: fragment)
1977-
1978-
assertJSONEquivalent(
1979-
encoded,
1980-
"""
1981-
{
1982-
"examples" : [
1983-
"hello"
1984-
],
1985-
"x-hello" : "hello"
1986-
}
1987-
"""
1988-
)
1989-
}
1990-
19911991
func test_decodeNullType() throws {
19921992
let nullTypeData = """
19931993
{

0 commit comments

Comments
 (0)