fill out some of the relationship tests

This commit is contained in:
Mathew Polzin
2019-01-14 23:14:25 -08:00
parent a9e1e49a79
commit 3c29244540
3 changed files with 260 additions and 8 deletions
@@ -7,21 +7,33 @@
import JSONAPI
private protocol _Optional {}
extension Optional: _Optional {}
extension Attribute: OpenAPINodeType where RawValue: OpenAPINodeType {
static public var openAPINode: OpenAPI.JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if !RawValue.openAPINode.required {
return RawValue.openAPINode.requiredNode().nullableNode()
}
return RawValue.openAPINode
}
}
extension TransformedAttribute: OpenAPINodeType where RawValue: OpenAPINodeType {
static public var openAPINode: OpenAPI.JSONNode {
// If the RawValue is not required, we actually consider it
// nullable. To be not required is for the Attribute itself
// to be optional.
if !RawValue.openAPINode.required {
return RawValue.openAPINode.requiredNode().nullableNode()
}
return RawValue.openAPINode
}
}
private protocol _Optional {}
extension Optional: _Optional {}
extension ToOneRelationship: OpenAPINodeType {
// TODO: const for json `type`
static public var openAPINode: OpenAPI.JSONNode {
+32 -2
View File
@@ -12,7 +12,7 @@ public protocol OpenAPINodeType {
}
public protocol SwiftTyped {
associatedtype SwiftType: Codable
associatedtype SwiftType: Codable, Equatable
}
public protocol OpenAPIFormat: SwiftTyped, Codable, Equatable {
@@ -173,7 +173,7 @@ public extension OpenAPI.JSONTypeFormat {
}
extension OpenAPI.JSONNode {
public struct Context<Format: OpenAPIFormat>: JSONNodeContext {
public struct Context<Format: OpenAPIFormat>: JSONNodeContext, Equatable {
public let format: Format
public let required: Bool
public let nullable: Bool
@@ -197,6 +197,7 @@ extension OpenAPI.JSONNode {
public func optionalContext() -> Context {
return .init(format: format,
required: false,
nullable: nullable,
allowedValues: allowedValues)
}
@@ -204,6 +205,15 @@ extension OpenAPI.JSONNode {
public func requiredContext() -> Context {
return .init(format: format,
required: true,
nullable: nullable,
allowedValues: allowedValues)
}
/// Return the nullable version of this context
public func nullableContext() -> Context {
return .init(format: format,
required: required,
nullable: true,
allowedValues: allowedValues)
}
}
@@ -369,4 +379,24 @@ extension OpenAPI.JSONNode {
return self
}
}
/// Return the nullable version of this JSONNode
public func nullableNode() -> OpenAPI.JSONNode {
switch self {
case .boolean(let context):
return .boolean(context.nullableContext())
case .object(let contextA, let contextB):
return .object(contextA.nullableContext(), contextB)
case .array(let contextA, let contextB):
return .array(contextA.nullableContext(), contextB)
case .number(let context, let contextB):
return .number(context.nullableContext(), contextB)
case .integer(let context, let contextB):
return .integer(context.nullableContext(), contextB)
case .string(let context, let contextB):
return .string(context.nullableContext(), contextB)
case .allOf, .oneOf, .anyOf, .not:
return self
}
}
}
@@ -14,11 +14,221 @@ import JSONAPIOpenAPI
class JSONAPIRelationshipsOpenAPITests: XCTestCase {
func test_ToOne() {
let node = ToOneRelationship<TestEntity1, NoMetadata, NoLinks>.openAPINode
XCTAssertTrue(node.required)
XCTAssertEqual(node.jsonTypeFormat, .object(.generic))
guard case .object(let contextA, let objectContext1) = node else {
XCTFail("Expected object Node")
return
}
XCTAssertEqual(contextA, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext1.additionalProperties)
XCTAssertEqual(Array(objectContext1.properties.keys), ["data"])
guard case .object(let contextB, let objectContext2)? = objectContext1.properties["data"] else {
XCTFail("Expected object node within properties")
return
}
XCTAssertEqual(contextB, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext2.additionalProperties)
XCTAssertEqual(Set(objectContext2.properties.keys), Set(["id", "type"]))
}
func test_OptionalToOne() {
let node = ToOneRelationship<TestEntity1, NoMetadata, NoLinks>?.openAPINode
XCTAssertFalse(node.required)
XCTAssertEqual(node.jsonTypeFormat, .object(.generic))
guard case .object(let contextA, let objectContext1) = node else {
XCTFail("Expected object Node")
return
}
XCTAssertEqual(contextA, .init(format: .generic,
required: false,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext1.additionalProperties)
XCTAssertEqual(Array(objectContext1.properties.keys), ["data"])
guard case .object(let contextB, let objectContext2)? = objectContext1.properties["data"] else {
XCTFail("Expected object node within properties")
return
}
XCTAssertEqual(contextB, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext2.additionalProperties)
XCTAssertEqual(Set(objectContext2.properties.keys), Set(["id", "type"]))
}
func test_NullableToOne() {
let node = ToOneRelationship<TestEntity1?, NoMetadata, NoLinks>.openAPINode
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
print(String(data: (try? encoder.encode(node))!, encoding: .utf8)!)
XCTAssertTrue(node.required)
XCTAssertEqual(node.jsonTypeFormat, .object(.generic))
guard case .object(let contextA, let objectContext1) = node else {
XCTFail("Expected object Node")
return
}
XCTAssertEqual(contextA, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext1.additionalProperties)
XCTAssertEqual(Array(objectContext1.properties.keys), ["data"])
guard case .object(let contextB, let objectContext2)? = objectContext1.properties["data"] else {
XCTFail("Expected object node within properties")
return
}
XCTAssertEqual(contextB, .init(format: .generic,
required: true,
nullable: true,
allowedValues: nil))
XCTAssertNil(objectContext2.additionalProperties)
XCTAssertEqual(Set(objectContext2.properties.keys), Set(["id", "type"]))
}
func test_OptionalNullableToOne() {
let node = ToOneRelationship<TestEntity1?, NoMetadata, NoLinks>?.openAPINode
XCTAssertFalse(node.required)
XCTAssertEqual(node.jsonTypeFormat, .object(.generic))
guard case .object(let contextA, let objectContext1) = node else {
XCTFail("Expected object Node")
return
}
XCTAssertEqual(contextA, .init(format: .generic,
required: false,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext1.additionalProperties)
XCTAssertEqual(Array(objectContext1.properties.keys), ["data"])
guard case .object(let contextB, let objectContext2)? = objectContext1.properties["data"] else {
XCTFail("Expected object node within properties")
return
}
XCTAssertEqual(contextB, .init(format: .generic,
required: true,
nullable: true,
allowedValues: nil))
XCTAssertNil(objectContext2.additionalProperties)
XCTAssertEqual(Set(objectContext2.properties.keys), Set(["id", "type"]))
}
func test_ToMany() {
let node = ToManyRelationship<TestEntity1, NoMetadata, NoLinks>.openAPINode
XCTAssertTrue(node.required)
XCTAssertEqual(node.jsonTypeFormat, .object(.generic))
guard case .object(let contextA, let objectContext1) = node else {
XCTFail("Expected object Node")
return
}
XCTAssertEqual(contextA, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext1.additionalProperties)
XCTAssertEqual(Array(objectContext1.properties.keys), ["data"])
guard case .array(let contextB, let arrayContext)? = objectContext1.properties["data"] else {
XCTFail("Expected array node within properties")
return
}
XCTAssertEqual(contextB, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
guard case .object(let contextC, let objectContext2) = arrayContext.items else {
XCTFail("Expected object node within items")
return
}
XCTAssertEqual(contextC, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext2.additionalProperties)
XCTAssertEqual(Set(objectContext2.properties.keys), Set(["id", "type"]))
}
func test_OptionalToMany() {
let node = ToManyRelationship<TestEntity1, NoMetadata, NoLinks>?.openAPINode
XCTAssertFalse(node.required)
XCTAssertEqual(node.jsonTypeFormat, .object(.generic))
guard case .object(let contextA, let objectContext1) = node else {
XCTFail("Expected object Node")
return
}
XCTAssertEqual(contextA, .init(format: .generic,
required: false,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext1.additionalProperties)
XCTAssertEqual(Array(objectContext1.properties.keys), ["data"])
guard case .array(let contextB, let arrayContext)? = objectContext1.properties["data"] else {
XCTFail("Expected array node within properties")
return
}
XCTAssertEqual(contextB, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
guard case .object(let contextC, let objectContext2) = arrayContext.items else {
XCTFail("Expected object node within items")
return
}
XCTAssertEqual(contextC, .init(format: .generic,
required: true,
nullable: false,
allowedValues: nil))
XCTAssertNil(objectContext2.additionalProperties)
XCTAssertEqual(Set(objectContext2.properties.keys), Set(["id", "type"]))
}
}