mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-03-30 11:18:38 -07:00
Move JSONAPIArbitrary and JSONAPIOpenAPI into their own packages.
This commit is contained in:
+2
-23
@@ -11,19 +11,10 @@ let package = Package(
|
||||
targets: ["JSONAPI"]),
|
||||
.library(
|
||||
name: "JSONAPITesting",
|
||||
targets: ["JSONAPITesting"]),
|
||||
.library(
|
||||
name: "JSONAPIArbitrary",
|
||||
targets: ["JSONAPIArbitrary"]),
|
||||
.library(
|
||||
name: "JSONAPIOpenAPI",
|
||||
targets: ["JSONAPIOpenAPI"])
|
||||
targets: ["JSONAPITesting"])
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/mattpolzin/Poly.git", from: "1.0.0"),
|
||||
.package(url: "https://github.com/mattpolzin/Sampleable.git", from: "1.0.0"),
|
||||
.package(url: "https://github.com/Flight-School/AnyCodable.git", from: "0.1.0"),
|
||||
.package(url: "https://github.com/typelift/SwiftCheck.git", from: "0.11.0")
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
@@ -32,24 +23,12 @@ let package = Package(
|
||||
.target(
|
||||
name: "JSONAPITesting",
|
||||
dependencies: ["JSONAPI"]),
|
||||
.target(
|
||||
name: "JSONAPIArbitrary",
|
||||
dependencies: ["JSONAPI", "SwiftCheck"]),
|
||||
.target(
|
||||
name: "JSONAPIOpenAPI",
|
||||
dependencies: ["JSONAPI", "AnyCodable", "JSONAPIArbitrary", "Sampleable"]),
|
||||
.testTarget(
|
||||
name: "JSONAPITests",
|
||||
dependencies: ["JSONAPI", "JSONAPITesting"]),
|
||||
.testTarget(
|
||||
name: "JSONAPITestingTests",
|
||||
dependencies: ["JSONAPI", "JSONAPITesting"]),
|
||||
.testTarget(
|
||||
name: "JSONAPIArbitraryTests",
|
||||
dependencies: ["JSONAPI", "SwiftCheck", "JSONAPIArbitrary"]),
|
||||
.testTarget(
|
||||
name: "JSONAPIOpenAPITests",
|
||||
dependencies: ["JSONAPI", "JSONAPIOpenAPI"])
|
||||
dependencies: ["JSONAPI", "JSONAPITesting"])
|
||||
],
|
||||
swiftLanguageVersions: [.v4_2]
|
||||
)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// APIDescription+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/21/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension APIDescription: Arbitrary where Meta: Arbitrary {
|
||||
public static var arbitrary: Gen<APIDescription<Meta>> {
|
||||
return Gen.compose { c in
|
||||
APIDescription(version: c.generate(),
|
||||
meta: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension NoAPIDescription: Arbitrary {
|
||||
public static var arbitrary: Gen<NoAPIDescription> {
|
||||
return Gen.pure(.none)
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
//
|
||||
// Attribute+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/15/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension Attribute: Arbitrary where RawValue: Arbitrary {
|
||||
public static var arbitrary: Gen<Attribute<RawValue>> {
|
||||
return RawValue.arbitrary.map { .init(value: $0) }
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot conform TransformedAttribute to Arbitrary here
|
||||
// because there is no way to guarantee that an arbitrary
|
||||
// RawValue will successfully transform or that an
|
||||
// arbitrary Value will successfully reverse-transform.
|
||||
@@ -1,110 +0,0 @@
|
||||
//
|
||||
// Document+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/21/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension Document.Body.Data: Arbitrary where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
|
||||
public static var arbitrary: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body.Data> {
|
||||
return Gen.compose { c in
|
||||
Document.Body.Data(primary: c.generate(),
|
||||
includes: c.generate(),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Document.Body: Arbitrary where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary {
|
||||
public static var arbitrary: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
|
||||
return Gen.one(of: [
|
||||
arbitraryData,
|
||||
arbitraryErrors
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Document.Body where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
|
||||
/// Arbitrary Document.Body with data (guaranteed to not
|
||||
/// be an error body).
|
||||
public static var arbitraryData: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
|
||||
return Document.Body.Data.arbitrary.map(Document.Body.data)
|
||||
}
|
||||
}
|
||||
|
||||
extension Document.Body where MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary {
|
||||
/// Arbitrary Document.Body with errors (guaranteed to not
|
||||
/// be a data body).
|
||||
public static var arbitraryErrors: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
|
||||
return Gen.compose { c in
|
||||
Document.Body.errors(c.generate(),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Document.Body where Error: Arbitrary {
|
||||
/// Arbitrary Document.Body with errors but no
|
||||
/// metadata or links (also guaranteed to not
|
||||
/// be a data body).
|
||||
public static var arbitraryErrorsWithoutMetaOrLinks: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>.Body> {
|
||||
return Gen.compose { c in
|
||||
Document.Body.errors(c.generate(),
|
||||
meta: nil,
|
||||
links: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Document: Arbitrary where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary, APIDescription: Arbitrary {
|
||||
public static var arbitrary: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
|
||||
return Gen.one(of: [
|
||||
arbitraryData,
|
||||
arbitraryErrors
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Document where PrimaryResourceBody: Arbitrary, IncludeType: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary, APIDescription: Arbitrary {
|
||||
/// Arbitrary Document with data (guaranteed to not
|
||||
/// be an error body).
|
||||
public static var arbitraryData: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
|
||||
return Gen.compose { c in
|
||||
Document(apiDescription: c.generate(),
|
||||
body: c.generate(),
|
||||
includes: c.generate(),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Document where MetaType: Arbitrary, LinksType: Arbitrary, Error: Arbitrary, APIDescription: Arbitrary {
|
||||
/// Arbitrary Document with errors (guaranteed to not
|
||||
/// be a data body).
|
||||
public static var arbitraryErrors: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
|
||||
return Gen.compose { c in
|
||||
Document(apiDescription: c.generate(),
|
||||
errors: c.generate(),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Document where Error: Arbitrary, APIDescription: Arbitrary {
|
||||
/// Arbitrary Document with errors but no
|
||||
/// metadata or links (also guaranteed to not
|
||||
/// be a data body).
|
||||
public static var arbitraryErrors: Gen<Document<PrimaryResourceBody, MetaType, LinksType, IncludeType, APIDescription, Error>> {
|
||||
return Gen.compose { c in
|
||||
Document(apiDescription: c.generate(),
|
||||
errors: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
//
|
||||
// Entity+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/14/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension NoMetadata: Arbitrary {
|
||||
public static var arbitrary: Gen<NoMetadata> {
|
||||
return Gen.pure(.none)
|
||||
}
|
||||
}
|
||||
|
||||
extension NoLinks: Arbitrary {
|
||||
public static var arbitrary: Gen<NoLinks> {
|
||||
return Gen.pure(.none)
|
||||
}
|
||||
}
|
||||
|
||||
extension NoAttributes: Arbitrary {
|
||||
public static var arbitrary: Gen<NoAttributes> {
|
||||
return Gen.pure(.none)
|
||||
}
|
||||
}
|
||||
|
||||
extension NoRelationships: Arbitrary {
|
||||
public static var arbitrary: Gen<NoRelationships> {
|
||||
return Gen.pure(.none)
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: Arbitrary conformance for MetaType, LinksType, Description.Attributes,
|
||||
// and Description.Relationships must all be provided BY YOU for Entity to
|
||||
// gain Arbitrary conformance (with the exception of NoMetadata, NoLinks,
|
||||
// NoAttributes, and NoRelationships which all have Arbitrary conformance
|
||||
// out of the box).
|
||||
extension Entity: Arbitrary where MetaType: Arbitrary, LinksType: Arbitrary, Description.Attributes: Arbitrary, Description.Relationships: Arbitrary, EntityRawIdType: Arbitrary {
|
||||
public static var arbitrary: Gen<Entity<Description, MetaType, LinksType, EntityRawIdType>> {
|
||||
return Gen.compose { c in
|
||||
Entity(id: c.generate(),
|
||||
attributes: c.generate(),
|
||||
relationships: c.generate(),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
//
|
||||
// Error+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/21/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension UnknownJSONAPIError: Arbitrary {
|
||||
public static var arbitrary: Gen<UnknownJSONAPIError> {
|
||||
return Gen.pure(.unknownError)
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
//
|
||||
// Id+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/14/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension Unidentified: Arbitrary {
|
||||
public static var arbitrary: Gen<Unidentified> {
|
||||
return Gen.pure(.init())
|
||||
}
|
||||
}
|
||||
|
||||
extension Id: Arbitrary where RawType: Arbitrary {
|
||||
public static var arbitrary: Gen<Id<RawType, IdentifiableType>> {
|
||||
return RawType.arbitrary.map { Id(rawValue: $0) }
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
//
|
||||
// Includes+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/21/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension Includes: Arbitrary where I: Arbitrary {
|
||||
public static var arbitrary: Gen<Includes<I>> {
|
||||
return I
|
||||
.arbitrary
|
||||
.proliferate
|
||||
.map(Includes.init(values:))
|
||||
}
|
||||
}
|
||||
|
||||
extension NoIncludes: Arbitrary {
|
||||
public static var arbitrary: Gen<NoIncludes> {
|
||||
return Gen.pure(NoIncludes())
|
||||
}
|
||||
}
|
||||
|
||||
extension Include1: Arbitrary where A: Arbitrary {
|
||||
public static var arbitrary: Gen<Include1<A>> {
|
||||
return Gen.one(of: [
|
||||
A.arbitrary.map(Include1.init)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include2: Arbitrary where A: Arbitrary, B: Arbitrary {
|
||||
public static var arbitrary: Gen<Include2<A, B>> {
|
||||
return Gen.one(of: [
|
||||
A.arbitrary.map(Include2.init),
|
||||
B.arbitrary.map(Include2.init)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include3: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary {
|
||||
public static var arbitrary: Gen<Include3<A, B, C>> {
|
||||
return Gen.one(of: [
|
||||
A.arbitrary.map(Include3.init),
|
||||
B.arbitrary.map(Include3.init),
|
||||
C.arbitrary.map(Include3.init)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include4: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary {
|
||||
public static var arbitrary: Gen<Include4<A, B, C, D>> {
|
||||
return Gen.one(of: [
|
||||
A.arbitrary.map(Include4.init),
|
||||
B.arbitrary.map(Include4.init),
|
||||
C.arbitrary.map(Include4.init),
|
||||
D.arbitrary.map(Include4.init)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include5: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary {
|
||||
public static var arbitrary: Gen<Include5<A, B, C, D, E>> {
|
||||
return Gen.one(of: [
|
||||
A.arbitrary.map(Include5.init),
|
||||
B.arbitrary.map(Include5.init),
|
||||
C.arbitrary.map(Include5.init),
|
||||
D.arbitrary.map(Include5.init),
|
||||
E.arbitrary.map(Include5.init)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include6: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary {
|
||||
public static var arbitrary: Gen<Include6<A, B, C, D, E, F>> {
|
||||
// Note broken up because compiler cannot typecheck entire array
|
||||
// before it times out
|
||||
let set1: [Gen<Include6<A, B, C, D, E, F>>] = [
|
||||
A.arbitrary.map(Include6.init),
|
||||
B.arbitrary.map(Include6.init),
|
||||
C.arbitrary.map(Include6.init)
|
||||
]
|
||||
|
||||
let set2: [Gen<Include6<A, B, C, D, E, F>>] = [
|
||||
D.arbitrary.map(Include6.init),
|
||||
E.arbitrary.map(Include6.init),
|
||||
F.arbitrary.map(Include6.init)
|
||||
]
|
||||
|
||||
return Gen.one(of: set1 + set2)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include7: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary {
|
||||
public static var arbitrary: Gen<Include7<A, B, C, D, E, F, G>> {
|
||||
// Note broken up because compiler cannot typecheck entire array
|
||||
// before it times out
|
||||
let set1: [Gen<Include7<A, B, C, D, E, F, G>>] = [
|
||||
A.arbitrary.map(Include7.init),
|
||||
B.arbitrary.map(Include7.init),
|
||||
C.arbitrary.map(Include7.init)
|
||||
]
|
||||
|
||||
let set2: [Gen<Include7<A, B, C, D, E, F, G>>] = [
|
||||
D.arbitrary.map(Include7.init),
|
||||
E.arbitrary.map(Include7.init),
|
||||
F.arbitrary.map(Include7.init),
|
||||
G.arbitrary.map(Include7.init)
|
||||
]
|
||||
|
||||
return Gen.one(of: set1 + set2)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include8: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary {
|
||||
public static var arbitrary: Gen<Include8<A, B, C, D, E, F, G, H>> {
|
||||
// Note broken up because compiler cannot typecheck entire array
|
||||
// before it times out
|
||||
let set1: [Gen<Include8<A, B, C, D, E, F, G, H>>] = [
|
||||
A.arbitrary.map(Include8.init),
|
||||
B.arbitrary.map(Include8.init),
|
||||
C.arbitrary.map(Include8.init)
|
||||
]
|
||||
|
||||
let set2: [Gen<Include8<A, B, C, D, E, F, G, H>>] = [
|
||||
D.arbitrary.map(Include8.init),
|
||||
E.arbitrary.map(Include8.init),
|
||||
F.arbitrary.map(Include8.init)
|
||||
]
|
||||
|
||||
let set3: [Gen<Include8<A, B, C, D, E, F, G, H>>] = [
|
||||
G.arbitrary.map(Include8.init),
|
||||
H.arbitrary.map(Include8.init)
|
||||
]
|
||||
|
||||
return Gen.one(of: set1 + set2 + set3)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include9: Arbitrary where A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, F: Arbitrary, G: Arbitrary, H: Arbitrary, I: Arbitrary {
|
||||
public static var arbitrary: Gen<Include9<A, B, C, D, E, F, G, H, I>> {
|
||||
// Note broken up because compiler cannot typecheck entire array
|
||||
// before it times out
|
||||
let set1: [Gen<Include9<A, B, C, D, E, F, G, H, I>>] = [
|
||||
A.arbitrary.map(Include9.init),
|
||||
B.arbitrary.map(Include9.init),
|
||||
C.arbitrary.map(Include9.init)
|
||||
]
|
||||
|
||||
let set2: [Gen<Include9<A, B, C, D, E, F, G, H, I>>] = [
|
||||
D.arbitrary.map(Include9.init),
|
||||
E.arbitrary.map(Include9.init),
|
||||
F.arbitrary.map(Include9.init)
|
||||
]
|
||||
|
||||
let set3: [Gen<Include9<A, B, C, D, E, F, G, H, I>>] = [
|
||||
G.arbitrary.map(Include9.init),
|
||||
H.arbitrary.map(Include9.init),
|
||||
I.arbitrary.map(Include9.init)
|
||||
]
|
||||
|
||||
return Gen.one(of: set1 + set2 + set3)
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
//
|
||||
// Relationship+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/15/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension ToOneRelationship: Arbitrary where Identifiable.Identifier: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
|
||||
public static var arbitrary: Gen<ToOneRelationship<Identifiable, MetaType, LinksType>> {
|
||||
return Gen.compose { c in
|
||||
return .init(id: c.generate(),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ToOneRelationship where MetaType: Arbitrary, LinksType: Arbitrary {
|
||||
/// Create a generator of arbitrary ToOneRelationships that will all
|
||||
/// point to one of the given entities. This allows you to create
|
||||
/// arbitrary relationships that make sense in a broader context where
|
||||
/// the relationship must actually point to another entity.
|
||||
public static func arbitrary<E: EntityType>(givenEntities: [E]) -> Gen<ToOneRelationship<Identifiable, MetaType, LinksType>> where E.Id == Identifiable.Identifier {
|
||||
|
||||
return Gen.compose { c in
|
||||
let idGen = Gen.fromElements(of: givenEntities).map { $0.id }
|
||||
return .init(id: c.generate(using: idGen),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ToManyRelationship: Arbitrary where Relatable.Identifier: Arbitrary, MetaType: Arbitrary, LinksType: Arbitrary {
|
||||
public static var arbitrary: Gen<ToManyRelationship<Relatable, MetaType, LinksType>> {
|
||||
return Gen.compose { c in
|
||||
return .init(ids: c.generate(),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension ToManyRelationship where MetaType: Arbitrary, LinksType: Arbitrary {
|
||||
/// Create a generator of arbitrary ToManyRelationships that will all
|
||||
/// point to some number of the given entities. This allows you to create
|
||||
/// arbitrary relationships that make sense in a broader context where
|
||||
/// the relationship must actually point to other existing entities.
|
||||
public static func arbitrary<E: EntityType>(givenEntities: [E]) -> Gen<ToManyRelationship<Relatable, MetaType, LinksType>> where E.Id == Relatable.Identifier {
|
||||
return Gen.compose { c in
|
||||
let idsGen = Gen.fromElements(of: givenEntities).map { $0.id }.proliferate
|
||||
return .init(ids: c.generate(using: idsGen),
|
||||
meta: c.generate(),
|
||||
links: c.generate())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
//
|
||||
// ResourceBody+Arbitrary.swift
|
||||
// JSONAPIArbitrary
|
||||
//
|
||||
// Created by Mathew Polzin on 1/21/19.
|
||||
//
|
||||
|
||||
import SwiftCheck
|
||||
import JSONAPI
|
||||
|
||||
extension SingleResourceBody: Arbitrary where Entity: Arbitrary {
|
||||
public static var arbitrary: Gen<SingleResourceBody<Entity>> {
|
||||
return Entity.arbitrary.map(SingleResourceBody.init(entity:))
|
||||
}
|
||||
}
|
||||
|
||||
extension ManyResourceBody: Arbitrary where Entity: Arbitrary {
|
||||
public static var arbitrary: Gen<ManyResourceBody<Entity>> {
|
||||
return Entity.arbitrary.proliferate.map(ManyResourceBody.init(entities:))
|
||||
}
|
||||
}
|
||||
|
||||
extension NoResourceBody: Arbitrary {
|
||||
public static var arbitrary: Gen<NoResourceBody> {
|
||||
return Gen.pure(.none)
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
//
|
||||
// JSONAPIAttribute+OpenAPI.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/28/19.
|
||||
//
|
||||
|
||||
import JSONAPI
|
||||
import Foundation
|
||||
import AnyCodable
|
||||
|
||||
private protocol _Optional {}
|
||||
extension Optional: _Optional {}
|
||||
|
||||
private protocol Wrapper {
|
||||
associatedtype Wrapped
|
||||
}
|
||||
extension Optional: Wrapper {}
|
||||
|
||||
// MARK: Attribute
|
||||
extension Attribute: OpenAPINodeType where RawValue: OpenAPINodeType {
|
||||
static public func openAPINode() 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.openAPINode().required {
|
||||
return try RawValue.openAPINode().requiredNode().nullableNode()
|
||||
}
|
||||
return try RawValue.openAPINode()
|
||||
}
|
||||
}
|
||||
|
||||
extension Attribute: RawOpenAPINodeType where RawValue: RawRepresentable, RawValue.RawValue: OpenAPINodeType {
|
||||
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()
|
||||
}
|
||||
return try RawValue.RawValue.openAPINode()
|
||||
}
|
||||
}
|
||||
|
||||
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: GenericOpenAPINodeType where RawValue: GenericOpenAPINodeType {
|
||||
public static func genericOpenAPINode(using encoder: JSONEncoder) 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.genericOpenAPINode(using: encoder).required {
|
||||
return try RawValue.genericOpenAPINode(using: encoder).requiredNode().nullableNode()
|
||||
}
|
||||
return try RawValue.genericOpenAPINode(using: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
extension Attribute: DateOpenAPINodeType where RawValue: DateOpenAPINodeType {
|
||||
public static func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> 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.dateOpenAPINodeGuess(using: encoder)?.required ?? true) {
|
||||
return RawValue.dateOpenAPINodeGuess(using: encoder)?.requiredNode().nullableNode()
|
||||
}
|
||||
return RawValue.dateOpenAPINodeGuess(using: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
extension Attribute: AnyJSONCaseIterable where RawValue: CaseIterable, RawValue: Codable {
|
||||
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
|
||||
return (try? allCases(from: Array(RawValue.allCases), using: encoder)) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
extension Attribute: AnyWrappedJSONCaseIterable where RawValue: AnyJSONCaseIterable {
|
||||
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
|
||||
return RawValue.allCases(using: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - TransformedAttribute
|
||||
extension TransformedAttribute: OpenAPINodeType where RawValue: OpenAPINodeType {
|
||||
static public func openAPINode() 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.openAPINode().required {
|
||||
return try RawValue.openAPINode().requiredNode().nullableNode()
|
||||
}
|
||||
return try RawValue.openAPINode()
|
||||
}
|
||||
}
|
||||
|
||||
extension TransformedAttribute: RawOpenAPINodeType where RawValue: RawRepresentable, RawValue.RawValue: OpenAPINodeType {
|
||||
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()
|
||||
}
|
||||
return try RawValue.RawValue.openAPINode()
|
||||
}
|
||||
}
|
||||
|
||||
extension TransformedAttribute: 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 TransformedAttribute: GenericOpenAPINodeType where RawValue: GenericOpenAPINodeType {
|
||||
public static func genericOpenAPINode(using encoder: JSONEncoder) 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.genericOpenAPINode(using: encoder).required {
|
||||
return try RawValue.genericOpenAPINode(using: encoder).requiredNode().nullableNode()
|
||||
}
|
||||
return try RawValue.genericOpenAPINode(using: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
extension TransformedAttribute: DateOpenAPINodeType where RawValue: DateOpenAPINodeType {
|
||||
public static func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> 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.dateOpenAPINodeGuess(using: encoder)?.required ?? true) {
|
||||
return RawValue.dateOpenAPINodeGuess(using: encoder)?.requiredNode().nullableNode()
|
||||
}
|
||||
return RawValue.dateOpenAPINodeGuess(using: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
extension TransformedAttribute: AnyJSONCaseIterable where RawValue: CaseIterable, RawValue: Codable {
|
||||
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
|
||||
return (try? allCases(from: Array(RawValue.allCases), using: encoder)) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
extension TransformedAttribute: AnyWrappedJSONCaseIterable where RawValue: AnyJSONCaseIterable {
|
||||
public static func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
|
||||
return RawValue.allCases(using: encoder)
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
//
|
||||
// JSONAPIInclude+OpenAPI.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/22/19.
|
||||
//
|
||||
|
||||
import JSONAPI
|
||||
import Foundation
|
||||
|
||||
extension Includes: OpenAPIEncodedNodeType where I: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
let includeNode = try I.openAPINode(using: encoder)
|
||||
|
||||
return .array(.init(format: .generic,
|
||||
required: true),
|
||||
.init(items: includeNode,
|
||||
uniqueItems: true))
|
||||
}
|
||||
}
|
||||
|
||||
extension Include0: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
throw OpenAPITypeError.invalidNode
|
||||
}
|
||||
}
|
||||
|
||||
extension Include1: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try A.openAPINode(using: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include2: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include3: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder),
|
||||
C.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include4: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder),
|
||||
C.openAPINode(using: encoder),
|
||||
D.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include5: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder),
|
||||
C.openAPINode(using: encoder),
|
||||
D.openAPINode(using: encoder),
|
||||
E.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include6: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder),
|
||||
C.openAPINode(using: encoder),
|
||||
D.openAPINode(using: encoder),
|
||||
E.openAPINode(using: encoder),
|
||||
F.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include7: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType, G: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder),
|
||||
C.openAPINode(using: encoder),
|
||||
D.openAPINode(using: encoder),
|
||||
E.openAPINode(using: encoder),
|
||||
F.openAPINode(using: encoder),
|
||||
G.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include8: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType, G: OpenAPIEncodedNodeType, H: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder),
|
||||
C.openAPINode(using: encoder),
|
||||
D.openAPINode(using: encoder),
|
||||
E.openAPINode(using: encoder),
|
||||
F.openAPINode(using: encoder),
|
||||
G.openAPINode(using: encoder),
|
||||
H.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
extension Include9: OpenAPIEncodedNodeType where A: OpenAPIEncodedNodeType, B: OpenAPIEncodedNodeType, C: OpenAPIEncodedNodeType, D: OpenAPIEncodedNodeType, E: OpenAPIEncodedNodeType, F: OpenAPIEncodedNodeType, G: OpenAPIEncodedNodeType, H: OpenAPIEncodedNodeType, I: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try .one(of: [
|
||||
A.openAPINode(using: encoder),
|
||||
B.openAPINode(using: encoder),
|
||||
C.openAPINode(using: encoder),
|
||||
D.openAPINode(using: encoder),
|
||||
E.openAPINode(using: encoder),
|
||||
F.openAPINode(using: encoder),
|
||||
G.openAPINode(using: encoder),
|
||||
H.openAPINode(using: encoder),
|
||||
I.openAPINode(using: encoder)
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
//
|
||||
// JSONAPIOpenAPITypes.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/13/19.
|
||||
//
|
||||
|
||||
import JSONAPI
|
||||
import Foundation
|
||||
import AnyCodable
|
||||
import Sampleable
|
||||
|
||||
private protocol _Optional {}
|
||||
extension Optional: _Optional {}
|
||||
|
||||
private protocol Wrapper {
|
||||
associatedtype Wrapped
|
||||
}
|
||||
extension Optional: Wrapper {}
|
||||
|
||||
extension RelationshipType {
|
||||
static func relationshipNode(nullable: Bool, jsonType: String) -> JSONNode {
|
||||
let propertiesDict: [String: JSONNode] = [
|
||||
"id": .string(.init(format: .generic,
|
||||
required: true),
|
||||
.init()),
|
||||
"type": .string(.init(format: .generic,
|
||||
required: true,
|
||||
allowedValues: [.init(jsonType)]),
|
||||
.init())
|
||||
]
|
||||
|
||||
return .object(.init(format: .generic,
|
||||
required: true,
|
||||
nullable: nullable),
|
||||
.init(properties: propertiesDict))
|
||||
}
|
||||
}
|
||||
|
||||
extension ToOneRelationship: OpenAPINodeType {
|
||||
// NOTE: const for json `type` not supported by OpenAPI 3.0
|
||||
// Will use "enum" with one possible value for now.
|
||||
|
||||
// TODO: metadata & links
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
let nullable = Identifiable.self is _Optional.Type
|
||||
return .object(.init(format: .generic,
|
||||
required: true),
|
||||
.init(properties: [
|
||||
"data": ToOneRelationship.relationshipNode(nullable: nullable, jsonType: Identifiable.jsonType)
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
extension ToManyRelationship: OpenAPINodeType {
|
||||
// NOTE: const for json `type` not supported by OpenAPI 3.0
|
||||
// Will use "enum" with one possible value for now.
|
||||
|
||||
// TODO: metadata & links
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .object(.init(format: .generic,
|
||||
required: true),
|
||||
.init(properties: [
|
||||
"data": .array(.init(format: .generic,
|
||||
required: true),
|
||||
.init(items: ToManyRelationship.relationshipNode(nullable: false, jsonType: Relatable.jsonType)))
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
extension Entity: OpenAPIEncodedNodeType where Description.Attributes: Sampleable, Description.Relationships: Sampleable {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
// NOTE: const for json `type` not supported by OpenAPI 3.0
|
||||
// Will use "enum" with one possible value for now.
|
||||
|
||||
// TODO: metadata, links
|
||||
|
||||
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,
|
||||
allowedValues: [.init(Entity.jsonType)]),
|
||||
.init())
|
||||
let typeProperty = ("type", typeNode)
|
||||
|
||||
let attributesNode: JSONNode? = Description.Attributes.self == NoAttributes.self
|
||||
? nil
|
||||
: try Description.Attributes.genericOpenAPINode(using: encoder)
|
||||
|
||||
let attributesProperty = attributesNode.map { ("attributes", $0) }
|
||||
|
||||
let relationshipsNode: JSONNode? = Description.Relationships.self == NoRelationships.self
|
||||
? nil
|
||||
: try Description.Relationships.genericOpenAPINode(using: encoder)
|
||||
|
||||
let relationshipsProperty = relationshipsNode.map { ("relationships", $0) }
|
||||
|
||||
let propertiesDict = Dictionary([
|
||||
idProperty,
|
||||
typeProperty,
|
||||
attributesProperty,
|
||||
relationshipsProperty
|
||||
].compactMap { $0 }) { _, value in value }
|
||||
|
||||
return .object(.init(format: .generic,
|
||||
required: true),
|
||||
.init(properties: propertiesDict))
|
||||
}
|
||||
}
|
||||
|
||||
extension SingleResourceBody: OpenAPIEncodedNodeType where Entity: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return try Entity.openAPINode(using: encoder)
|
||||
}
|
||||
}
|
||||
|
||||
extension ManyResourceBody: OpenAPIEncodedNodeType where Entity: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
return .array(.init(format: .generic,
|
||||
required: true),
|
||||
.init(items: try Entity.openAPINode(using: encoder)))
|
||||
}
|
||||
}
|
||||
|
||||
extension Document: OpenAPIEncodedNodeType where PrimaryResourceBody: OpenAPIEncodedNodeType, IncludeType: OpenAPIEncodedNodeType {
|
||||
public static func openAPINode(using encoder: JSONEncoder) throws -> JSONNode {
|
||||
// TODO: metadata, links, api description, errors
|
||||
// TODO: represent data and errors as the two distinct possible outcomes
|
||||
|
||||
let primaryDataNode: JSONNode? = try PrimaryResourceBody.openAPINode(using: encoder)
|
||||
|
||||
let primaryDataProperty = primaryDataNode.map { ("data", $0) }
|
||||
|
||||
let includeNode: JSONNode?
|
||||
do {
|
||||
includeNode = try Includes<Include>.openAPINode(using: encoder)
|
||||
} catch let err as OpenAPITypeError {
|
||||
guard case .invalidNode = err else {
|
||||
throw err
|
||||
}
|
||||
includeNode = nil
|
||||
}
|
||||
|
||||
let includeProperty = includeNode.map { ("included", $0) }
|
||||
|
||||
let propertiesDict = Dictionary([
|
||||
primaryDataProperty,
|
||||
includeProperty
|
||||
].compactMap { $0 }) { _, value in value }
|
||||
|
||||
return .object(.init(format: .generic,
|
||||
required: true),
|
||||
.init(properties: propertiesDict))
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
//
|
||||
// Date+OpenAPI.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/24/19.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
extension Date: DateOpenAPINodeType {
|
||||
public static func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> JSONNode? {
|
||||
|
||||
switch encoder.dateEncodingStrategy {
|
||||
case .deferredToDate, .custom:
|
||||
// I don't know if we can say anything about this case without
|
||||
// encoding the Date and looking at it, which is what `primitiveGuess()`
|
||||
// does.
|
||||
return nil
|
||||
|
||||
case .secondsSince1970,
|
||||
.millisecondsSince1970:
|
||||
return .number(.init(format: .double,
|
||||
required: true),
|
||||
.init())
|
||||
|
||||
case .iso8601:
|
||||
return .string(.init(format: .dateTime,
|
||||
required: true),
|
||||
.init())
|
||||
|
||||
case .formatted(let formatter):
|
||||
let hasTime = formatter.timeStyle != .none
|
||||
let format: JSONTypeFormat.StringFormat = hasTime ? .dateTime : .date
|
||||
|
||||
return .string(.init(format: format,
|
||||
required: true),
|
||||
.init())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,454 +0,0 @@
|
||||
//
|
||||
// OpenAPITypes+Codable.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/14/19.
|
||||
//
|
||||
|
||||
extension JSONNode.Context: Encodable {
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case type
|
||||
case format
|
||||
case allowedValues = "enum"
|
||||
case nullable
|
||||
case example
|
||||
// case constantValue = "const"
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(format.jsonType, forKey: .type)
|
||||
|
||||
if format != Format.unspecified {
|
||||
try container.encode(format, forKey: .format)
|
||||
}
|
||||
|
||||
if allowedValues != nil {
|
||||
try container.encode(allowedValues, forKey: .allowedValues)
|
||||
}
|
||||
|
||||
// if constantValue != nil {
|
||||
// try container.encode(constantValue, forKey: .constantValue)
|
||||
// }
|
||||
|
||||
try container.encode(nullable, forKey: .nullable)
|
||||
|
||||
if example != nil {
|
||||
try container.encode(example, forKey: .example)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension JSONNode.NumericContext: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case multipleOf
|
||||
case maximum
|
||||
case exclusiveMaximum
|
||||
case minimum
|
||||
case exclusiveMinimum
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if multipleOf != nil {
|
||||
try container.encode(multipleOf, forKey: .multipleOf)
|
||||
}
|
||||
|
||||
if maximum != nil {
|
||||
try container.encode(maximum, forKey: .maximum)
|
||||
}
|
||||
|
||||
if exclusiveMaximum != nil {
|
||||
try container.encode(exclusiveMaximum, forKey: .exclusiveMaximum)
|
||||
}
|
||||
|
||||
if minimum != nil {
|
||||
try container.encode(minimum, forKey: .minimum)
|
||||
}
|
||||
|
||||
if exclusiveMinimum != nil {
|
||||
try container.encode(exclusiveMinimum, forKey: .exclusiveMinimum)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension JSONNode.StringContext: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case maxLength
|
||||
case minLength
|
||||
case pattern
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if maxLength != nil {
|
||||
try container.encode(maxLength, forKey: .maxLength)
|
||||
}
|
||||
|
||||
try container.encode(minLength, forKey: .minLength)
|
||||
|
||||
if pattern != nil {
|
||||
try container.encode(pattern, forKey: .pattern)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension JSONNode.ArrayContext: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case items
|
||||
case maxItems
|
||||
case minItems
|
||||
case uniqueItems
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(items, forKey: .items)
|
||||
|
||||
if maxItems != nil {
|
||||
try container.encode(maxItems, forKey: .maxItems)
|
||||
}
|
||||
|
||||
try container.encode(minItems, forKey: .minItems)
|
||||
|
||||
try container.encode(uniqueItems, forKey: .uniqueItems)
|
||||
}
|
||||
}
|
||||
|
||||
extension JSONNode.ObjectContext : Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case maxProperties
|
||||
case minProperties
|
||||
case properties
|
||||
case additionalProperties
|
||||
case required
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if maxProperties != nil {
|
||||
try container.encode(maxProperties, forKey: .maxProperties)
|
||||
}
|
||||
|
||||
try container.encode(properties, forKey: .properties)
|
||||
|
||||
if additionalProperties != nil {
|
||||
try container.encode(additionalProperties, forKey: .additionalProperties)
|
||||
}
|
||||
|
||||
try container.encode(requiredProperties, forKey: .required)
|
||||
|
||||
try container.encode(minProperties, forKey: .minProperties)
|
||||
}
|
||||
}
|
||||
|
||||
extension JSONNode: Encodable {
|
||||
|
||||
private enum SubschemaCodingKeys: String, CodingKey {
|
||||
case allOf
|
||||
case oneOf
|
||||
case anyOf
|
||||
case not
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
switch self {
|
||||
case .boolean(let context):
|
||||
try context.encode(to: encoder)
|
||||
|
||||
case .object(let contextA as Encodable, let contextB as Encodable),
|
||||
.array(let contextA as Encodable, let contextB as Encodable),
|
||||
.number(let contextA as Encodable, let contextB as Encodable),
|
||||
.integer(let contextA as Encodable, let contextB as Encodable),
|
||||
.string(let contextA as Encodable, let contextB as Encodable):
|
||||
try contextA.encode(to: encoder)
|
||||
try contextB.encode(to: encoder)
|
||||
|
||||
case .all(of: let nodes):
|
||||
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
|
||||
|
||||
try container.encode(nodes, forKey: .allOf)
|
||||
|
||||
case .one(of: let nodes):
|
||||
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
|
||||
|
||||
try container.encode(nodes, forKey: .oneOf)
|
||||
|
||||
case .any(of: let nodes):
|
||||
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
|
||||
|
||||
try container.encode(nodes, forKey: .anyOf)
|
||||
|
||||
case .not(let node):
|
||||
var container = encoder.container(keyedBy: SubschemaCodingKeys.self)
|
||||
|
||||
try container.encode(node, forKey: .not)
|
||||
|
||||
case .reference(let reference):
|
||||
var container = encoder.singleValueContainer()
|
||||
|
||||
try container.encode(reference)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension JSONReference: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case ref = "$ref"
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
let referenceString: String = {
|
||||
switch self {
|
||||
case .file(let reference):
|
||||
return reference
|
||||
case .node(let reference):
|
||||
return "#/\(Root.refName)/\(reference.refName)/\(reference.selector)"
|
||||
}
|
||||
}()
|
||||
|
||||
try container.encode(referenceString, forKey: .ref)
|
||||
}
|
||||
}
|
||||
|
||||
extension RefDict: Encodable {
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
|
||||
try container.encode(dict)
|
||||
}
|
||||
}
|
||||
|
||||
extension OpenAPIResponse.Code: Encodable {
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
|
||||
let string: String
|
||||
switch self {
|
||||
case .`default`:
|
||||
string = "default"
|
||||
|
||||
case .status(code: let code):
|
||||
string = String(code)
|
||||
}
|
||||
|
||||
try container.encode(string)
|
||||
}
|
||||
}
|
||||
|
||||
extension OpenAPIRequestBody: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case description
|
||||
case content
|
||||
case required
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if description != nil {
|
||||
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)
|
||||
|
||||
try container.encode(required, forKey: .required)
|
||||
}
|
||||
}
|
||||
|
||||
extension OpenAPIPathItem.PathProperties.Operation: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case tags
|
||||
case summary
|
||||
case description
|
||||
case externalDocs
|
||||
case operationId
|
||||
case parameters
|
||||
case requestBody
|
||||
case responses
|
||||
case callbacks
|
||||
case deprecated
|
||||
case security
|
||||
case servers
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if tags != nil {
|
||||
try container.encode(tags, forKey: .tags)
|
||||
}
|
||||
|
||||
if summary != nil {
|
||||
try container.encode(summary, forKey: .summary)
|
||||
}
|
||||
|
||||
if description != nil {
|
||||
try container.encode(description, forKey: .description)
|
||||
}
|
||||
|
||||
try container.encode(operationId, forKey: .operationId)
|
||||
|
||||
try container.encode(parameters, forKey: .parameters)
|
||||
|
||||
if requestBody != nil {
|
||||
try container.encode(requestBody, forKey: .requestBody)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
extension OpenAPIPathItem.PathProperties: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case summary
|
||||
case description
|
||||
case servers
|
||||
case parameters
|
||||
|
||||
case get
|
||||
case put
|
||||
case post
|
||||
case delete
|
||||
case options
|
||||
case head
|
||||
case patch
|
||||
case trace
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
if summary != nil {
|
||||
try container.encode(summary, forKey: .summary)
|
||||
}
|
||||
|
||||
if description != nil {
|
||||
try container.encode(description, forKey: .description)
|
||||
}
|
||||
|
||||
try container.encode(parameters, forKey: .parameters)
|
||||
|
||||
if get != nil {
|
||||
try container.encode(get, forKey: .get)
|
||||
}
|
||||
|
||||
if put != nil {
|
||||
try container.encode(put, forKey: .put)
|
||||
}
|
||||
|
||||
if post != nil {
|
||||
try container.encode(post, forKey: .post)
|
||||
}
|
||||
|
||||
if delete != nil {
|
||||
try container.encode(delete, forKey: .delete)
|
||||
}
|
||||
|
||||
if options != nil {
|
||||
try container.encode(options, forKey: .options)
|
||||
}
|
||||
|
||||
if head != nil {
|
||||
try container.encode(head, forKey: .head)
|
||||
}
|
||||
|
||||
if patch != nil {
|
||||
try container.encode(patch, forKey: .patch)
|
||||
}
|
||||
|
||||
if trace != nil {
|
||||
try container.encode(trace, forKey: .trace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
|
||||
switch self {
|
||||
case .reference(let reference):
|
||||
try container.encode(reference)
|
||||
|
||||
case .operations(let operations):
|
||||
try container.encode(operations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension OpenAPISchema: Encodable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case openAPIVersion = "openapi"
|
||||
case info
|
||||
case servers
|
||||
case paths
|
||||
case components
|
||||
case security
|
||||
case tags
|
||||
case externalDocs
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try container.encode(openAPIVersion, forKey: .openAPIVersion)
|
||||
|
||||
try container.encode(info, forKey: .info)
|
||||
|
||||
// Hack to work around Dictionary encoding
|
||||
// itself as an array in this case:
|
||||
let stringKeyedDict = Dictionary(
|
||||
paths.map { ($0.key.rawValue, $0.value) },
|
||||
uniquingKeysWith: { $1 }
|
||||
)
|
||||
try container.encode(stringKeyedDict, forKey: .paths)
|
||||
|
||||
try container.encode(components, forKey: .components)
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,132 +0,0 @@
|
||||
//
|
||||
// PrimitiveTypes.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 01/13/19.
|
||||
//
|
||||
|
||||
import AnyCodable
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
|
||||
Notable omissions in this library's default offerings:
|
||||
|
||||
Base 64 encoded characters:
|
||||
.string(.byte)
|
||||
|
||||
Any sequence of octets:
|
||||
.string(.binary)
|
||||
|
||||
RFC3339 full-date:
|
||||
.string(.date)
|
||||
|
||||
RFC3339 date-time:
|
||||
.string(.dateTime)
|
||||
|
||||
A hint to UIs to obscure input:
|
||||
.string(.password)
|
||||
|
||||
Any object:
|
||||
.object(.generic)
|
||||
|
||||
**/
|
||||
|
||||
extension Optional: OpenAPINodeType where Wrapped: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return try Wrapped.openAPINode().optionalNode()
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: RawOpenAPINodeType where Wrapped: RawRepresentable, Wrapped.RawValue: OpenAPINodeType {
|
||||
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 func allCases(using encoder: JSONEncoder) -> [AnyCodable] {
|
||||
return (try? allCases(from: Array(Wrapped.allCases), using: encoder)) ?? []
|
||||
}
|
||||
}
|
||||
|
||||
extension Optional: DateOpenAPINodeType where Wrapped: DateOpenAPINodeType {
|
||||
static public func dateOpenAPINodeGuess(using encoder: JSONEncoder) -> JSONNode? {
|
||||
return Wrapped.dateOpenAPINodeGuess(using: encoder)?.optionalNode()
|
||||
}
|
||||
}
|
||||
|
||||
extension String: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .string(.init(format: .generic,
|
||||
required: true),
|
||||
.init())
|
||||
}
|
||||
}
|
||||
|
||||
extension Bool: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .boolean(.init(format: .generic,
|
||||
required: true))
|
||||
}
|
||||
}
|
||||
|
||||
extension Array: OpenAPINodeType where Element: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .array(.init(format: .generic,
|
||||
required: true),
|
||||
.init(items: try Element.openAPINode()))
|
||||
}
|
||||
}
|
||||
|
||||
extension Double: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .number(.init(format: .double,
|
||||
required: true),
|
||||
.init())
|
||||
}
|
||||
}
|
||||
|
||||
extension Float: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .number(.init(format: .float,
|
||||
required: true),
|
||||
.init())
|
||||
}
|
||||
}
|
||||
|
||||
extension Int: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .integer(.init(format: .generic,
|
||||
required: true),
|
||||
.init())
|
||||
}
|
||||
}
|
||||
|
||||
extension Int32: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .integer(.init(format: .int32,
|
||||
required: true),
|
||||
.init())
|
||||
}
|
||||
}
|
||||
|
||||
extension Int64: OpenAPINodeType {
|
||||
static public func openAPINode() throws -> JSONNode {
|
||||
return .integer(.init(format: .int64,
|
||||
required: true),
|
||||
.init())
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
//
|
||||
// Optional+ZipWith.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/19/19.
|
||||
//
|
||||
|
||||
/// Zip two optionals together with the given operation performed on
|
||||
/// the unwrapped contents. If either optional is nil, the zip
|
||||
/// yields nil.
|
||||
func zip<X, Y, Z>(_ left: X?, _ right: Y?, with fn: (X, Y) -> Z) -> Z? {
|
||||
return left.flatMap { lft in right.map { rght in fn(lft, rght) }}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
//
|
||||
// Include+Sampleable.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/23/19.
|
||||
//
|
||||
|
||||
import JSONAPI
|
||||
import Sampleable
|
||||
|
||||
extension Includes: Sampleable where I: Sampleable {
|
||||
public static var sample: Includes<I> {
|
||||
guard I.self != NoIncludes.self else {
|
||||
return .none
|
||||
}
|
||||
|
||||
return .init(values: I.samples)
|
||||
}
|
||||
}
|
||||
|
||||
extension NoIncludes: Sampleable {
|
||||
public static var sample: NoIncludes {
|
||||
return NoIncludes()
|
||||
}
|
||||
}
|
||||
|
||||
extension Include1: Sampleable where A: Sampleable {
|
||||
public static var sample: Include1<A> {
|
||||
return .init(A.sample)
|
||||
}
|
||||
|
||||
public static var samples: [Include1<A>] {
|
||||
return A.samples.map(Include1<A>.init)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include2: Sampleable where A: Sampleable, B: Sampleable {
|
||||
public static var sample: Include2<A, B> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include2<A, B>] {
|
||||
return A.samples.map(Include2<A, B>.init)
|
||||
+ B.samples.map(Include2<A, B>.init)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include3: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable {
|
||||
public static var sample: Include3<A, B, C> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include3<A, B, C>] {
|
||||
return A.samples.map(Include3<A, B, C>.init)
|
||||
+ B.samples.map(Include3<A, B, C>.init)
|
||||
+ C.samples.map(Include3<A, B, C>.init)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include4: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable {
|
||||
public static var sample: Include4<A, B, C, D> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include4<A, B, C, D>] {
|
||||
return A.samples.map(Include4<A, B, C, D>.init)
|
||||
+ B.samples.map(Include4<A, B, C, D>.init)
|
||||
+ C.samples.map(Include4<A, B, C, D>.init)
|
||||
+ D.samples.map(Include4<A, B, C, D>.init)
|
||||
}
|
||||
}
|
||||
|
||||
extension Include5: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable {
|
||||
public static var sample: Include5<A, B, C, D, E> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include5<A, B, C, D, E>] {
|
||||
let set1: [Include5<A, B, C, D, E>] = A.samples.map(Include5<A, B, C, D, E>.init)
|
||||
+ B.samples.map(Include5<A, B, C, D, E>.init)
|
||||
+ C.samples.map(Include5<A, B, C, D, E>.init)
|
||||
|
||||
let set2: [Include5<A, B, C, D, E>] = D.samples.map(Include5<A, B, C, D, E>.init)
|
||||
+ E.samples.map(Include5<A, B, C, D, E>.init)
|
||||
|
||||
return set1 + set2
|
||||
}
|
||||
}
|
||||
|
||||
extension Include6: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable {
|
||||
public static var sample: Include6<A, B, C, D, E, F> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include6<A, B, C, D, E, F>] {
|
||||
let set1: [Include6<A, B, C, D, E, F>] = A.samples.map(Include6<A, B, C, D, E, F>.init)
|
||||
+ B.samples.map(Include6<A, B, C, D, E, F>.init)
|
||||
+ C.samples.map(Include6<A, B, C, D, E, F>.init)
|
||||
|
||||
let set2: [Include6<A, B, C, D, E, F>] = D.samples.map(Include6<A, B, C, D, E, F>.init)
|
||||
+ E.samples.map(Include6<A, B, C, D, E, F>.init)
|
||||
+ F.samples.map(Include6<A, B, C, D, E, F>.init)
|
||||
|
||||
return set1 + set2
|
||||
}
|
||||
}
|
||||
|
||||
extension Include7: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable, G: Sampleable {
|
||||
public static var sample: Include7<A, B, C, D, E, F, G> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include7<A, B, C, D, E, F, G>] {
|
||||
let set1: [Include7<A, B, C, D, E, F, G>] = A.samples.map(Include7<A, B, C, D, E, F, G>.init)
|
||||
+ B.samples.map(Include7<A, B, C, D, E, F, G>.init)
|
||||
+ C.samples.map(Include7<A, B, C, D, E, F, G>.init)
|
||||
|
||||
let set2: [Include7<A, B, C, D, E, F, G>] = D.samples.map(Include7<A, B, C, D, E, F, G>.init)
|
||||
+ E.samples.map(Include7<A, B, C, D, E, F, G>.init)
|
||||
+ F.samples.map(Include7<A, B, C, D, E, F, G>.init)
|
||||
|
||||
let set3: [Include7<A, B, C, D, E, F, G>] = G.samples.map(Include7<A, B, C, D, E, F, G>.init)
|
||||
|
||||
return set1 + set2 + set3
|
||||
}
|
||||
}
|
||||
|
||||
extension Include8: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable, G: Sampleable, H: Sampleable {
|
||||
public static var sample: Include8<A, B, C, D, E, F, G, H> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include8<A, B, C, D, E, F, G, H>] {
|
||||
let set1: [Include8<A, B, C, D, E, F, G, H>] = A.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
+ B.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
+ C.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
|
||||
let set2: [Include8<A, B, C, D, E, F, G, H>] = D.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
+ E.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
+ F.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
|
||||
let set3: [Include8<A, B, C, D, E, F, G, H>] = G.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
+ H.samples.map(Include8<A, B, C, D, E, F, G, H>.init)
|
||||
|
||||
return set1 + set2 + set3
|
||||
}
|
||||
}
|
||||
|
||||
extension Include9: Sampleable where A: Sampleable, B: Sampleable, C: Sampleable, D: Sampleable, E: Sampleable, F: Sampleable, G: Sampleable, H: Sampleable, I: Sampleable {
|
||||
public static var sample: Include9<A, B, C, D, E, F, G, H, I> {
|
||||
let randomChoice = Int.random(in: 0..<samples.count)
|
||||
|
||||
return samples[randomChoice]
|
||||
}
|
||||
|
||||
public static var samples: [Include9<A, B, C, D, E, F, G, H, I>] {
|
||||
let set1: [Include9<A, B, C, D, E, F, G, H, I>] = A.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
+ B.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
+ C.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
|
||||
let set2: [Include9<A, B, C, D, E, F, G, H, I>] = D.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
+ E.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
+ F.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
|
||||
let set3: [Include9<A, B, C, D, E, F, G, H, I>] = G.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
+ H.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
+ I.samples.map(Include9<A, B, C, D, E, F, G, H, I>.init)
|
||||
|
||||
return set1 + set2 + set3
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
//
|
||||
// JSONAPI+Sampleable.swift
|
||||
// JSONAPIOpenAPI
|
||||
//
|
||||
// Created by Mathew Polzin on 1/24/19.
|
||||
//
|
||||
|
||||
import JSONAPI
|
||||
import Sampleable
|
||||
|
||||
extension NoAttributes: Sampleable {
|
||||
public static var sample: NoAttributes {
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
extension NoRelationships: Sampleable {
|
||||
public static var sample: NoRelationships {
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
extension NoMetadata: Sampleable {
|
||||
public static var sample: NoMetadata {
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
extension NoLinks: Sampleable {
|
||||
public static var sample: NoLinks {
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
extension NoAPIDescription: Sampleable {
|
||||
public static var sample: NoAPIDescription {
|
||||
return .none
|
||||
}
|
||||
}
|
||||
|
||||
extension UnknownJSONAPIError: Sampleable {
|
||||
public static var sample: UnknownJSONAPIError {
|
||||
return .unknownError
|
||||
}
|
||||
}
|
||||
|
||||
extension Unidentified: Sampleable {
|
||||
public static var sample: Unidentified {
|
||||
return Unidentified()
|
||||
}
|
||||
}
|
||||
|
||||
extension Attribute: Sampleable where RawValue: Sampleable {
|
||||
public static var sample: Attribute<RawValue> {
|
||||
return .init(value: RawValue.sample)
|
||||
}
|
||||
}
|
||||
|
||||
extension SingleResourceBody: Sampleable where Entity: Sampleable {
|
||||
public static var sample: SingleResourceBody<Entity> {
|
||||
return .init(entity: Entity.sample)
|
||||
}
|
||||
}
|
||||
|
||||
extension ManyResourceBody: Sampleable where Entity: Sampleable {
|
||||
public static var sample: ManyResourceBody<Entity> {
|
||||
return .init(entities: Entity.samples)
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user