mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-03-30 11:18:38 -07:00
Merge branch 'master' into feature/OpenAPISchema
This commit is contained in:
@@ -99,27 +99,27 @@ Note that Playground support for importing non-system Frameworks is still a bit
|
||||
#### Document
|
||||
- `data`
|
||||
- [x] Encoding/Decoding
|
||||
- [ ] Arbitrary
|
||||
- [x] Arbitrary
|
||||
- [ ] OpenAPI
|
||||
- `included`
|
||||
- [x] Encoding/Decoding
|
||||
- [ ] Arbitrary
|
||||
- [x] Arbitrary
|
||||
- [ ] OpenAPI
|
||||
- `errors`
|
||||
- [x] Encoding/Decoding
|
||||
- [ ] Arbitrary
|
||||
- [x] Arbitrary
|
||||
- [ ] OpenAPI
|
||||
- `meta`
|
||||
- [x] Encoding/Decoding
|
||||
- [ ] Arbitrary
|
||||
- [x] Arbitrary
|
||||
- [ ] OpenAPI
|
||||
- `jsonapi` (i.e. API Information)
|
||||
- [x] Encoding/Decoding
|
||||
- [ ] Arbitrary
|
||||
- [x] Arbitrary
|
||||
- [ ] OpenAPI
|
||||
- `links`
|
||||
- [x] Encoding/Decoding
|
||||
- [ ] Arbitrary
|
||||
- [x] Arbitrary
|
||||
- [ ] OpenAPI
|
||||
|
||||
#### Resource Object
|
||||
@@ -838,7 +838,7 @@ The `JSONAPI` framework is packaged with a test library to help you test your `J
|
||||
# JSONAPI+Arbitrary
|
||||
The `JSONAPIArbitrary` framework adds `Arbitrary` support via `SwiftCheck`. With a little extra work on your part, this framework will allow you to create "arbitrary" (i.e. randomly generated) instances of your JSONAPI entities, includes, documents, etc.
|
||||
|
||||
This library does not offer full support of all `JSONAPI` types yet. The documentation will grow as the framework becomes more complete.
|
||||
This Framework is currently undocumented, but familiarity with `SwiftCheck` will likely afford the user enough information to use this library to aid in the generation of arbitrary JSONAPI Documents for testing purposes.
|
||||
|
||||
# JSONAPI+OpenAPI
|
||||
The `JSONAPIOpenAPI` framework adds the ability to generate OpenAPI compliant JSON documentation of a JSONAPI Document.
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ extension Attribute: Arbitrary where RawValue: Arbitrary {
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot extend TransformedAttribute here
|
||||
// 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.
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
//
|
||||
// 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())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user