mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-03-30 11:18:38 -07:00
Add some tests around Attribute OpenAPI descriptions
This commit is contained in:
@@ -24,8 +24,10 @@ extension Attribute: OpenAPINodeType where RawValue: OpenAPINodeType {
|
||||
}
|
||||
|
||||
extension Attribute: RawOpenAPINodeType where RawValue: RawRepresentable, RawValue.RawValue: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
|
||||
static public func rawOpenAPINode() throws -> 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 try !RawValue.RawValue.openAPINode().required {
|
||||
return try RawValue.RawValue.openAPINode().requiredNode().nullableNode()
|
||||
}
|
||||
@@ -33,6 +35,18 @@ extension Attribute: RawOpenAPINodeType where RawValue: RawRepresentable, RawVal
|
||||
}
|
||||
}
|
||||
|
||||
extension Attribute: WrappedRawOpenAPIType where RawValue: RawOpenAPINodeType {
|
||||
public static func wrappedOpenAPINode() throws -> 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 try !RawValue.rawOpenAPINode().required {
|
||||
return try RawValue.rawOpenAPINode().requiredNode().nullableNode()
|
||||
}
|
||||
return try RawValue.rawOpenAPINode()
|
||||
}
|
||||
}
|
||||
|
||||
extension Attribute: AnyJSONCaseIterable where RawValue: CaseIterable, RawValue: Codable {
|
||||
public static var allCases: [AnyCodable] {
|
||||
return (try? allCases(from: Array(RawValue.allCases))) ?? []
|
||||
|
||||
@@ -23,7 +23,30 @@ public protocol OpenAPINodeType {
|
||||
/// different schema. The "different" conditions have to do
|
||||
/// with Raw Representability, hence the name of this protocol.
|
||||
public protocol RawOpenAPINodeType {
|
||||
static func openAPINode() throws -> JSONNode
|
||||
static func rawOpenAPINode() throws -> JSONNode
|
||||
}
|
||||
|
||||
/// Anything conforming to `RawOpenAPINodeType` can provide an
|
||||
/// OpenAPI schema representing itself. This third protocol is
|
||||
/// necessary so that one type can conditionally provide a
|
||||
/// schema and then (under different conditions) provide a
|
||||
/// different schema. The "different" conditions have to do
|
||||
/// with Optionality, hence the name of this protocol.
|
||||
public protocol WrappedRawOpenAPIType {
|
||||
static func wrappedOpenAPINode() throws -> JSONNode
|
||||
}
|
||||
|
||||
/// Anything conforming to `RawOpenAPINodeType` can provide an
|
||||
/// OpenAPI schema representing itself. This third protocol is
|
||||
/// necessary so that one type can conditionally provide a
|
||||
/// schema and then (under different conditions) provide a
|
||||
/// different schema. The "different" conditions have to do
|
||||
/// with Optionality, hence the name of this protocol.
|
||||
public protocol DoubleWrappedRawOpenAPIType {
|
||||
// NOTE: This is definitely a rabbit hole... hopefully I
|
||||
// will realize I've been missing something obvious
|
||||
// and dig my way back out at some point...
|
||||
static func wrappedOpenAPINode() throws -> JSONNode
|
||||
}
|
||||
|
||||
/// Anything conforming to `AnyJSONCaseIterable` can provide a
|
||||
@@ -209,7 +232,7 @@ public enum JSONTypeFormat: Equatable {
|
||||
|
||||
/// A JSON Node is what OpenAPI calls a
|
||||
/// "Schema Object"
|
||||
public enum JSONNode {
|
||||
public enum JSONNode: Equatable {
|
||||
case boolean(Context<JSONTypeFormat.BooleanFormat>)
|
||||
indirect case object(Context<JSONTypeFormat.ObjectFormat>, ObjectContext)
|
||||
indirect case array(Context<JSONTypeFormat.ArrayFormat>, ArrayContext)
|
||||
@@ -281,7 +304,7 @@ public enum JSONNode {
|
||||
}
|
||||
}
|
||||
|
||||
public struct NumericContext {
|
||||
public struct NumericContext: Equatable {
|
||||
/// A numeric instance is valid only if division by this keyword's value results in an integer. Defaults to nil.
|
||||
public let multipleOf: Double?
|
||||
public let maximum: Double?
|
||||
@@ -302,7 +325,7 @@ public enum JSONNode {
|
||||
}
|
||||
}
|
||||
|
||||
public struct StringContext {
|
||||
public struct StringContext: Equatable {
|
||||
public let maxLength: Int?
|
||||
public let minLength: Int
|
||||
|
||||
@@ -318,7 +341,7 @@ public enum JSONNode {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ArrayContext {
|
||||
public struct ArrayContext: Equatable {
|
||||
/// A JSON Type Node that describes
|
||||
/// the type of each element in the array.
|
||||
public let items: JSONNode
|
||||
@@ -346,7 +369,7 @@ public enum JSONNode {
|
||||
}
|
||||
}
|
||||
|
||||
public struct ObjectContext {
|
||||
public struct ObjectContext: Equatable {
|
||||
public let maxProperties: Int?
|
||||
public let minProperties: Int
|
||||
public let properties: [String: JSONNode]
|
||||
|
||||
@@ -38,7 +38,10 @@ extension Sampleable {
|
||||
return try valType.openAPINode()
|
||||
|
||||
case let valType as RawOpenAPINodeType.Type:
|
||||
return try valType.openAPINode()
|
||||
return try valType.rawOpenAPINode()
|
||||
|
||||
case let valType as WrappedRawOpenAPIType.Type:
|
||||
return try valType.wrappedOpenAPINode()
|
||||
|
||||
default:
|
||||
return nil
|
||||
|
||||
@@ -38,11 +38,23 @@ extension Optional: OpenAPINodeType where Wrapped: OpenAPINodeType {
|
||||
}
|
||||
|
||||
extension Optional: RawOpenAPINodeType where Wrapped: RawRepresentable, Wrapped.RawValue: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
static public func rawOpenAPINode() throws -> JSONNode {
|
||||
return try Wrapped.RawValue.openAPINode().optionalNode()
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: WrappedRawOpenAPIType where Wrapped: RawOpenAPINodeType {
|
||||
static public func wrappedOpenAPINode() throws -> JSONNode {
|
||||
return try Wrapped.rawOpenAPINode().optionalNode()
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: DoubleWrappedRawOpenAPIType where Wrapped: WrappedRawOpenAPIType {
|
||||
static public func wrappedOpenAPINode() throws -> JSONNode {
|
||||
return try Wrapped.wrappedOpenAPINode().optionalNode()
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: AnyJSONCaseIterable where Wrapped: CaseIterable, Wrapped: Codable {
|
||||
public static var allCases: [AnyCodable] {
|
||||
return (try? allCases(from: Array(Wrapped.allCases))) ?? []
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,59 @@
|
||||
import XCTest
|
||||
|
||||
extension JSONAPIAttributeOpenAPITests {
|
||||
static let __allTests = [
|
||||
("test_Arrayttribute", test_Arrayttribute),
|
||||
("test_BooleanAttribute", test_BooleanAttribute),
|
||||
("test_EnumAttribute", test_EnumAttribute),
|
||||
("test_FloatNumberAttribute", test_FloatNumberAttribute),
|
||||
("test_IntegerAttribute", test_IntegerAttribute),
|
||||
("test_NullableArrayAttribute", test_NullableArrayAttribute),
|
||||
("test_NullableBooleanAttribute", test_NullableBooleanAttribute),
|
||||
("test_NullableEnumAttribute", test_NullableEnumAttribute),
|
||||
("test_NullableIntegerAttribute", test_NullableIntegerAttribute),
|
||||
("test_NullableNumberAttribute", test_NullableNumberAttribute),
|
||||
("test_NullableStringAttribute", test_NullableStringAttribute),
|
||||
("test_NumberAttribute", test_NumberAttribute),
|
||||
("test_OptionalArrayAttribute", test_OptionalArrayAttribute),
|
||||
("test_OptionalBooleanAttribute", test_OptionalBooleanAttribute),
|
||||
("test_OptionalEnumAttribute", test_OptionalEnumAttribute),
|
||||
("test_OptionalIntegerAttribute", test_OptionalIntegerAttribute),
|
||||
("test_OptionalNullableArrayAttribute", test_OptionalNullableArrayAttribute),
|
||||
("test_OptionalNullableBooleanAttribute", test_OptionalNullableBooleanAttribute),
|
||||
("test_OptionalNullableEnumAttribute", test_OptionalNullableEnumAttribute),
|
||||
("test_OptionalNullableIntegerAttribute", test_OptionalNullableIntegerAttribute),
|
||||
("test_OptionalNullableNumberAttribute", test_OptionalNullableNumberAttribute),
|
||||
("test_OptionalNullableStringAttribute", test_OptionalNullableStringAttribute),
|
||||
("test_OptionalNumberAttribute", test_OptionalNumberAttribute),
|
||||
("test_OptionalStringAttribute", test_OptionalStringAttribute),
|
||||
("test_StringAttribute", test_StringAttribute),
|
||||
]
|
||||
}
|
||||
|
||||
extension JSONAPIEntityOpenAPITests {
|
||||
static let __allTests = [
|
||||
("test_AttributesEntity", test_AttributesEntity),
|
||||
("test_EmptyEntity", test_EmptyEntity),
|
||||
]
|
||||
}
|
||||
|
||||
extension JSONAPIRelationshipsOpenAPITests {
|
||||
static let __allTests = [
|
||||
("test_NullableToOne", test_NullableToOne),
|
||||
("test_OptionalNullableToOne", test_OptionalNullableToOne),
|
||||
("test_OptionalToMany", test_OptionalToMany),
|
||||
("test_OptionalToOne", test_OptionalToOne),
|
||||
("test_ToMany", test_ToMany),
|
||||
("test_ToOne", test_ToOne),
|
||||
]
|
||||
}
|
||||
|
||||
#if !os(macOS)
|
||||
public func __allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(JSONAPIAttributeOpenAPITests.__allTests),
|
||||
testCase(JSONAPIEntityOpenAPITests.__allTests),
|
||||
testCase(JSONAPIRelationshipsOpenAPITests.__allTests),
|
||||
]
|
||||
}
|
||||
#endif
|
||||
@@ -1,10 +1,12 @@
|
||||
import XCTest
|
||||
|
||||
import JSONAPITests
|
||||
import JSONAPITestLibTests
|
||||
import JSONAPITestingTests
|
||||
import JSONAPIOpenAPITests
|
||||
|
||||
var tests = [XCTestCaseEntry]()
|
||||
tests += JSONAPITests.__allTests()
|
||||
tests += JSONAPITestLibTests.__allTests()
|
||||
tests += JSONAPITestingTests.__allTests()
|
||||
tests += JSONAPIOpenAPITests.__allTests()
|
||||
|
||||
XCTMain(tests)
|
||||
|
||||
Reference in New Issue
Block a user