Add sparse document tests

This commit is contained in:
Mathew Polzin
2019-08-05 16:02:40 -07:00
parent 61f2edb59a
commit 83f7a7b60e
3 changed files with 246 additions and 14 deletions
@@ -15,10 +15,12 @@ public protocol Relationships: Codable & Equatable {}
/// properties of any types that are JSON encodable.
public protocol Attributes: Codable & Equatable {}
public typealias SparsableCodingKey = CodingKey & Equatable
/// Attributes containing publicly accessible and `Equatable`
/// CodingKeys are required to support Sparse Fieldsets.
public protocol SparsableAttributes: Attributes {
associatedtype CodingKeys: CodingKey & Equatable
associatedtype CodingKeys: SparsableCodingKey
}
/// Can be used as `Relationships` Type for Entities that do not
@@ -926,6 +926,217 @@ extension DocumentTests {
}
}
// MARK: Sparse Fieldset Documents
extension DocumentTests {
func test_sparsePrimaryResource() {
let primaryResource = Book(attributes: .init(pageCount: 100),
relationships: .init(author: "1234",
series: []),
meta: .none,
links: .none)
.sparse(with: [.pageCount])
let document = Document<
SingleResourceBody<Book.SparseType>,
NoMetadata,
NoLinks,
NoIncludes,
NoAPIDescription,
UnknownJSONAPIError
>(apiDescription: .none,
body: .init(resourceObject: primaryResource),
includes: .none,
meta: .none,
links: .none)
let encoded = try! JSONEncoder().encode(document)
let deserialized = try! JSONSerialization.jsonObject(with: encoded,
options: [])
let deserializedObj = deserialized as? [String: Any]
guard let deserializedObj1 = deserializedObj?["data"] as? [String: Any] else {
XCTFail("Expected to deserialize one object from document data")
return
}
XCTAssertNotNil(deserializedObj1["id"])
XCTAssertEqual(deserializedObj1["id"] as? String, primaryResource.resourceObject.id.rawValue)
XCTAssertNotNil(deserializedObj1["type"])
XCTAssertEqual(deserializedObj1["type"] as? String, Book.jsonType)
XCTAssertEqual((deserializedObj1["attributes"] as? [String: Any])?.count, 1)
XCTAssertEqual((deserializedObj1["attributes"] as? [String: Any])?["pageCount"] as? Int, 100)
XCTAssertNotNil(deserializedObj1["relationships"])
}
func test_sparsePrimaryResourceOptionalAndNil() {
let document = Document<
SingleResourceBody<Book.SparseType?>,
NoMetadata,
NoLinks,
NoIncludes,
NoAPIDescription,
UnknownJSONAPIError
>(apiDescription: .none,
body: .init(resourceObject: nil),
includes: .none,
meta: .none,
links: .none)
let encoded = try! JSONEncoder().encode(document)
let deserialized = try! JSONSerialization.jsonObject(with: encoded,
options: [])
let deserializedObj = deserialized as? [String: Any]
XCTAssertNotNil(deserializedObj?["data"] as? NSNull)
}
func test_sparseIncludeFullPrimaryResource() {
let bookInclude = Book(id: "444",
attributes: .init(pageCount: 113),
relationships: .init(author: "1234",
series: ["443"]),
meta: .none,
links: .none)
.sparse(with: [])
let primaryResource = Book(id: "443",
attributes: .init(pageCount: 100),
relationships: .init(author: "1234",
series: ["444"]),
meta: .none,
links: .none)
let document = Document<
SingleResourceBody<Book>,
NoMetadata,
NoLinks,
Include1<Book.SparseType>,
NoAPIDescription,
UnknownJSONAPIError
>(apiDescription: .none,
body: .init(resourceObject: primaryResource),
includes: .init(values: [.init(bookInclude)]),
meta: .none,
links: .none)
let encoded = try! JSONEncoder().encode(document)
let deserialized = try! JSONSerialization.jsonObject(with: encoded,
options: [])
let deserializedObj = deserialized as? [String: Any]
guard let deserializedObj1 = deserializedObj?["data"] as? [String: Any] else {
XCTFail("Expected to deserialize one object from document data")
return
}
XCTAssertNotNil(deserializedObj1["id"])
XCTAssertEqual(deserializedObj1["id"] as? String, primaryResource.id.rawValue)
XCTAssertNotNil(deserializedObj1["type"])
XCTAssertEqual(deserializedObj1["type"] as? String, Book.jsonType)
XCTAssertEqual((deserializedObj1["attributes"] as? [String: Any])?.count, 1)
XCTAssertEqual((deserializedObj1["attributes"] as? [String: Any])?["pageCount"] as? Int, 100)
XCTAssertNotNil(deserializedObj1["relationships"])
guard let deserializedIncludes = deserializedObj?["included"] as? [Any],
let deserializedObj2 = deserializedIncludes.first as? [String: Any] else {
XCTFail("Expected to deserialize one incude object")
return
}
XCTAssertNotNil(deserializedObj2["id"])
XCTAssertEqual(deserializedObj2["id"] as? String, bookInclude.resourceObject.id.rawValue)
XCTAssertNotNil(deserializedObj2["type"])
XCTAssertEqual(deserializedObj2["type"] as? String, Book.jsonType)
XCTAssertEqual((deserializedObj2["attributes"] as? [String: Any])?.count, 0)
XCTAssertNotNil(deserializedObj2["relationships"])
}
func test_sparseIncludeSparsePrimaryResource() {
let bookInclude = Book(id: "444",
attributes: .init(pageCount: 113),
relationships: .init(author: "1234",
series: ["443"]),
meta: .none,
links: .none)
.sparse(with: [])
let primaryResource = Book(id: "443",
attributes: .init(pageCount: 100),
relationships: .init(author: "1234",
series: ["444"]),
meta: .none,
links: .none)
.sparse(with: [])
let document = Document<
SingleResourceBody<Book.SparseType>,
NoMetadata,
NoLinks,
Include1<Book.SparseType>,
NoAPIDescription,
UnknownJSONAPIError
>(apiDescription: .none,
body: .init(resourceObject: primaryResource),
includes: .init(values: [.init(bookInclude)]),
meta: .none,
links: .none)
let encoded = try! JSONEncoder().encode(document)
let deserialized = try! JSONSerialization.jsonObject(with: encoded,
options: [])
let deserializedObj = deserialized as? [String: Any]
guard let deserializedObj1 = deserializedObj?["data"] as? [String: Any] else {
XCTFail("Expected to deserialize one object from document data")
return
}
XCTAssertNotNil(deserializedObj1["id"])
XCTAssertEqual(deserializedObj1["id"] as? String, primaryResource.resourceObject.id.rawValue)
XCTAssertNotNil(deserializedObj1["type"])
XCTAssertEqual(deserializedObj1["type"] as? String, Book.jsonType)
XCTAssertEqual((deserializedObj1["attributes"] as? [String: Any])?.count, 0)
XCTAssertNotNil(deserializedObj1["relationships"])
guard let deserializedIncludes = deserializedObj?["included"] as? [Any],
let deserializedObj2 = deserializedIncludes.first as? [String: Any] else {
XCTFail("Expected to deserialize one incude object")
return
}
XCTAssertNotNil(deserializedObj2["id"])
XCTAssertEqual(deserializedObj2["id"] as? String, bookInclude.resourceObject.id.rawValue)
XCTAssertNotNil(deserializedObj2["type"])
XCTAssertEqual(deserializedObj2["type"] as? String, Book.jsonType)
XCTAssertEqual((deserializedObj2["attributes"] as? [String: Any])?.count, 0)
XCTAssertNotNil(deserializedObj2["relationships"])
}
}
// MARK: Poly PrimaryResource Tests
extension DocumentTests {
func test_singleDocument_PolyPrimaryResource() {
@@ -1115,6 +1326,25 @@ extension DocumentTests {
typealias Article = BasicEntity<ArticleType>
enum BookType: ResourceObjectDescription {
static var jsonType: String { return "books" }
struct Attributes: JSONAPI.SparsableAttributes {
let pageCount: Attribute<Int>
enum CodingKeys: String, SparsableCodingKey {
case pageCount
}
}
struct Relationships: JSONAPI.Relationships {
let author: ToOneRelationship<Author, NoMetadata, NoLinks>
let series: ToManyRelationship<Book, NoMetadata, NoLinks>
}
}
typealias Book = BasicEntity<BookType>
struct TestPageMetadata: JSONAPI.Meta {
let total: Int
let limit: Int
+13 -13
View File
@@ -12,15 +12,15 @@ class IncludedTests: XCTestCase {
func test_zeroIncludes() {
let includes = decoded(type: Includes<NoIncludes>.self,
data: two_same_type_includes)
XCTAssertEqual(includes.count, 0)
}
func test_zeroIncludes_encode() {
XCTAssertThrowsError(try JSONEncoder().encode(decoded(type: Includes<NoIncludes>.self,
data: two_same_type_includes)))
}
XCTAssertThrowsError(try JSONEncoder().encode(decoded(type: Includes<NoIncludes>.self,
data: two_same_type_includes)))
}
func test_OneInclude() {
let includes = decoded(type: Includes<Include1<TestEntity>>.self,
data: one_include)
@@ -32,7 +32,7 @@ class IncludedTests: XCTestCase {
test_DecodeEncodeEquality(type: Includes<Include1<TestEntity>>.self,
data: one_include)
}
func test_TwoSameIncludes() {
let includes = decoded(type: Includes<Include1<TestEntity>>.self,
data: two_same_type_includes)
@@ -57,7 +57,7 @@ class IncludedTests: XCTestCase {
test_DecodeEncodeEquality(type: Includes<Include2<TestEntity, TestEntity2>>.self,
data: two_different_type_includes)
}
func test_ThreeDifferentIncludes() {
let includes = decoded(type: Includes<Include3<TestEntity, TestEntity2, TestEntity4>>.self,
data: three_different_type_includes)
@@ -71,11 +71,11 @@ class IncludedTests: XCTestCase {
test_DecodeEncodeEquality(type: Includes<Include3<TestEntity, TestEntity2, TestEntity4>>.self,
data: three_different_type_includes)
}
func test_FourDifferentIncludes() {
let includes = decoded(type: Includes<Include4<TestEntity, TestEntity2, TestEntity4, TestEntity6>>.self,
data: four_different_type_includes)
XCTAssertEqual(includes[TestEntity.self].count, 1)
XCTAssertEqual(includes[TestEntity2.self].count, 1)
XCTAssertEqual(includes[TestEntity4.self].count, 1)
@@ -86,11 +86,11 @@ class IncludedTests: XCTestCase {
test_DecodeEncodeEquality(type: Includes<Include4<TestEntity, TestEntity2, TestEntity4, TestEntity6>>.self,
data: four_different_type_includes)
}
func test_FiveDifferentIncludes() {
let includes = decoded(type: Includes<Include5<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity6>>.self,
data: five_different_type_includes)
XCTAssertEqual(includes[TestEntity.self].count, 1)
XCTAssertEqual(includes[TestEntity2.self].count, 1)
XCTAssertEqual(includes[TestEntity3.self].count, 1)
@@ -102,11 +102,11 @@ class IncludedTests: XCTestCase {
test_DecodeEncodeEquality(type: Includes<Include5<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity6>>.self,
data: five_different_type_includes)
}
func test_SixDifferentIncludes() {
let includes = decoded(type: Includes<Include6<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6>>.self,
data: six_different_type_includes)
XCTAssertEqual(includes[TestEntity.self].count, 1)
XCTAssertEqual(includes[TestEntity2.self].count, 1)
XCTAssertEqual(includes[TestEntity3.self].count, 1)