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))) ?? []
|
||||
|
||||
Reference in New Issue
Block a user