Skip to content

Commit

Permalink
Merge pull request #15 from mattpolzin/feature/OpenAPISchema
Browse files Browse the repository at this point in the history
Feature/open api schema
  • Loading branch information
mattpolzin authored Jan 27, 2019
2 parents 8d057b4 + 3b73dc9 commit b45fc73
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 7 deletions.
10 changes: 6 additions & 4 deletions Sources/JSONAPIOpenAPI/JSONAPI/JSONAPITypes+OpenAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,12 @@ extension Entity: OpenAPIEncodedNodeType where Description.Attributes: Sampleabl

// TODO: metadata, links

let idNode = JSONNode.string(.init(format: .generic,
required: true),
.init())
let idProperty = ("id", idNode)
let idNode: JSONNode? = Id.RawType.self != Unidentified.self
? JSONNode.string(.init(format: .generic,
required: true),
.init())
: nil
let idProperty = idNode.map { ("id", $0) }

let typeNode = JSONNode.string(.init(format: .generic,
required: true,
Expand Down
31 changes: 30 additions & 1 deletion Sources/JSONAPIOpenAPI/OpenAPI/OpenAPITypes+Codable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,13 @@ extension OpenAPIPathItem.PathProperties.Operation: Encodable {

try container.encode(parameters, forKey: .parameters)

try container.encode(responses, forKey: .responses)
// Hack to work around Dictionary encoding
// itself as an array in this case:
let stringKeyedDict = Dictionary(
responses.map { ($0.key.rawValue, $0.value) },
uniquingKeysWith: { $1 }
)
try container.encode(stringKeyedDict, forKey: .responses)

try container.encode(deprecated, forKey: .deprecated)
}
Expand Down Expand Up @@ -346,6 +352,29 @@ extension OpenAPIPathItem.PathProperties: Encodable {
}
}

extension OpenAPIResponse: Encodable {
private enum CodingKeys: String, CodingKey {
case description
case headers
case content
case links
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)

try container.encode(description, forKey: .description)

// Hack to work around Dictionary encoding
// itself as an array in this case:
let stringKeyedDict = Dictionary(
content.map { ($0.key.rawValue, $0.value) },
uniquingKeysWith: { $1 }
)
try container.encode(stringKeyedDict, forKey: .content)
}
}

extension OpenAPIPathItem: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
Expand Down
24 changes: 22 additions & 2 deletions Sources/JSONAPIOpenAPI/OpenAPI/OpenAPITypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ public enum OpenAPIPathItem: Equatable {
}
}

public struct OpenAPIResponse: Encodable, Equatable {
public struct OpenAPIResponse: Equatable {
public let description: String
// public let headers:
public let content: ContentMap
Expand All @@ -801,9 +801,29 @@ public struct OpenAPIResponse: Encodable, Equatable {

public typealias ContentMap = [ContentType: Content]

public enum Code: Equatable, Hashable {
public enum Code: RawRepresentable, Equatable, Hashable {
public typealias RawValue = String

case `default`
case status(code: Int)

public var rawValue: String {
switch self {
case .default:
return "default"

case .status(code: let code):
return String(code)
}
}

public init?(rawValue: String) {
if let val = Int(rawValue) {
self = .status(code: val)
} else {
self = .default
}
}
}

public enum ContentType: String, Encodable, Equatable, Hashable {
Expand Down
26 changes: 26 additions & 0 deletions Tests/JSONAPIOpenAPITests/JSONAPIEntityOpenAPITests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,31 @@ class JSONAPIEntityOpenAPITests: XCTestCase {
.init()))
}

func test_UnidentifiedEmptyEntity() {
let node = try! UnidentifiedTestType1.openAPINode(using: JSONEncoder())

XCTAssertTrue(node.required)
XCTAssertEqual(node.jsonTypeFormat, .object(.generic))

guard case let .object(contextA, objectContext1) = node else {
XCTFail("Expected Object node")
return
}

XCTAssertEqual(contextA, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))

XCTAssertEqual(objectContext1.minProperties, 1)
XCTAssertEqual(Set(objectContext1.requiredProperties), Set(["type"]))
XCTAssertEqual(Set(objectContext1.properties.keys), Set(["type"]))
XCTAssertEqual(objectContext1.properties["type"], .string(.init(format: .generic,
required: true,
allowedValues: [.init(TestType1.jsonType)]),
.init()))
}

func test_AttributesEntity() {

let dateFormatter = DateFormatter()
Expand Down Expand Up @@ -272,6 +297,7 @@ extension JSONAPIEntityOpenAPITests {
}

typealias TestType1 = BasicEntity<TestType1Description>
typealias UnidentifiedTestType1 = JSONAPI.Entity<TestType1Description, NoMetadata, NoLinks, Unidentified>

enum TestType2Description: EntityDescription {
public static var jsonType: String { return "test2" }
Expand Down

0 comments on commit b45fc73

Please sign in to comment.