From c30a2615f204e2c95de1aad60dec069acdc52eda Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Sun, 25 Nov 2018 00:02:37 -0800 Subject: [PATCH] Added links to document but currently untested --- Sources/JSONAPI/Document/Document.swift | 138 +++++++++++----- Sources/JSONAPI/Meta/Links.swift | 5 +- Sources/JSONAPI/Resource/Relationship.swift | 1 + .../JSONAPITests/Document/DocumentTests.swift | 154 +++++++++--------- 4 files changed, 179 insertions(+), 119 deletions(-) diff --git a/Sources/JSONAPI/Document/Document.swift b/Sources/JSONAPI/Document/Document.swift index 6f15dc4..5dd6b8d 100644 --- a/Sources/JSONAPI/Document/Document.swift +++ b/Sources/JSONAPI/Document/Document.swift @@ -12,58 +12,105 @@ /// API uses snake case, you will want to use /// a conversion such as the one offerred by the /// Foundation JSONEncoder/Decoder: `KeyDecodingStrategy` -public struct JSONAPIDocument: Equatable { +public struct JSONAPIDocument: Equatable { public typealias Include = IncludeType public let body: Body // public let jsonApi: APIDescription? -// public let links: Links? public enum Body: Equatable { - case errors([Error], meta: MetaType?) - case data(primary: ResourceBody, included: Includes, meta: MetaType) - case meta(MetaType) - + case errors([Error], meta: MetaType?, links: LinksType?) + case data(primary: ResourceBody, included: Includes, meta: MetaType, links: LinksType) + public var isError: Bool { guard case .errors = self else { return false } return true } + + public var errors: [Error]? { + guard case let .errors(errors, meta: _, links: _) = self else { return nil } + return errors + } - public var data: (primary: ResourceBody, included: Includes, meta: MetaType)? { - guard case let .data(primary: body, included: includes, meta: meta) = self else { return nil } - return (primary: body, included: includes, meta: meta) + public var primaryData: ResourceBody? { + guard case let .data(primary: body, included: _, meta: _, links: _) = self else { return nil } + return body + } + + public var includes: Includes? { + guard case let .data(primary: _, included: includes, meta: _, links: _) = self else { return nil } + return includes } public var meta: MetaType? { - guard case let .meta(metadata) = self else { return nil } - return metadata + switch self { + case .data(primary: _, included: _, meta: let metadata, links: _), + .errors(_, meta: let metadata?, links: _): + return metadata + default: + return nil + } + } + + public var links: LinksType? { + switch self { + case .data(primary: _, included: _, meta: _, links: let links), + .errors(_, meta: _, links: let links?): + return links + default: + return nil + } } } - public init(errors: [Error], meta: MetaType? = nil) { - body = .errors(errors, meta: meta) + public init(errors: [Error], meta: MetaType? = nil, links: LinksType? = nil) { + body = .errors(errors, meta: meta, links: links) } - public init(body: ResourceBody, includes: Includes, meta: MetaType) { - self.body = .data(primary: body, included: includes, meta: meta) + public init(body: ResourceBody, includes: Includes, meta: MetaType, links: LinksType) { + self.body = .data(primary: body, included: includes, meta: meta, links: links) } } extension JSONAPIDocument where IncludeType == NoIncludes { - public init(body: ResourceBody, meta: MetaType) { - self.body = .data(primary: body, included: .none, meta: meta) + public init(body: ResourceBody, meta: MetaType, links: LinksType) { + self.body = .data(primary: body, included: .none, meta: meta, links: links) } } extension JSONAPIDocument where MetaType == NoMetadata { - public init(body: ResourceBody, includes: Includes) { - self.body = .data(primary: body, included: includes, meta: .none) + public init(body: ResourceBody, includes: Includes, links: LinksType) { + self.body = .data(primary: body, included: includes, meta: .none, links: links) + } +} + +extension JSONAPIDocument where LinksType == NoLinks { + public init(body: ResourceBody, includes: Includes, meta: MetaType) { + self.body = .data(primary: body, included: includes, meta: meta, links: .none) + } +} + +extension JSONAPIDocument where IncludeType == NoIncludes, LinksType == NoLinks { + public init(body: ResourceBody, meta: MetaType) { + self.body = .data(primary: body, included: .none, meta: meta, links: .none) } } extension JSONAPIDocument where IncludeType == NoIncludes, MetaType == NoMetadata { + public init(body: ResourceBody, links: LinksType) { + self.body = .data(primary: body, included: .none, meta: .none, links: links) + } +} + +extension JSONAPIDocument where MetaType == NoMetadata, LinksType == NoLinks { + public init(body: ResourceBody, includes: Includes) { + self.body = .data(primary: body, included: includes, meta: .none, links: .none) + } +} + +extension JSONAPIDocument where IncludeType == NoIncludes, MetaType == NoMetadata, LinksType == NoLinks { public init(body: ResourceBody) { - self.body = .data(primary: body, included: .none, meta: .none) + self.body = .data(primary: body, included: .none, meta: .none, links: .none) } } @@ -93,28 +140,28 @@ extension JSONAPIDocument: Codable { } } + let links: LinksType? + if let noLinks = NoLinks() as? LinksType { + links = noLinks + } else { + do { + links = try container.decode(LinksType.self, forKey: .links) + } catch { + links = nil + } + } + // If there are errors, there cannot be a body. Return errors and any metadata found. if let errors = errors { - body = .errors(errors, meta: meta) + body = .errors(errors, meta: meta, links: links) return } - let maybeData: ResourceBody? - if ResourceBody.self == NoResourceBody.self { - maybeData = nil + let data: ResourceBody + if let noData = NoResourceBody() as? ResourceBody { + data = noData } else { - maybeData = try container.decode(ResourceBody.self, forKey: .data) - } - - // If there were not errors but there is also no data, try to find metadata. - // No metadata is against JSON API Spec, but otherwise we can form a - // metadat-only document. - guard let data = maybeData else { - guard let metaVal = meta else { - throw JSONAPIEncodingError.missingOrMalformedMetadata - } - body = .meta(metaVal) - return + data = try container.decode(ResourceBody.self, forKey: .data) } let maybeIncludes = try container.decodeIfPresent(Includes.self, forKey: .included) @@ -124,15 +171,18 @@ extension JSONAPIDocument: Codable { guard let metaVal = meta else { throw JSONAPIEncodingError.missingOrMalformedMetadata } + guard let linksVal = links else { + throw JSONAPIEncodingError.missingOrMalformedLinks + } - body = .data(primary: data, included: maybeIncludes ?? Includes.none, meta: metaVal) + body = .data(primary: data, included: maybeIncludes ?? Includes.none, meta: metaVal, links: linksVal) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: RootCodingKeys.self) switch body { - case .errors(let errors, let meta): + case .errors(let errors, meta: let meta, links: let links): var errContainer = container.nestedUnkeyedContainer(forKey: .errors) for error in errors { @@ -144,7 +194,12 @@ extension JSONAPIDocument: Codable { try container.encode(metaVal, forKey: .meta) } - case .data(primary: let resourceBody, included: let includes, let meta): + if LinksType.self != NoLinks.self, + let linksVal = links { + try container.encode(linksVal, forKey: .links) + } + + case .data(primary: let resourceBody, included: let includes, let meta, links: let links): try container.encode(resourceBody, forKey: .data) if Include.self != NoIncludes.self { @@ -155,8 +210,9 @@ extension JSONAPIDocument: Codable { try container.encode(meta, forKey: .meta) } - case .meta(let metadata): - try container .encode(metadata, forKey: .meta) + if LinksType.self != NoLinks.self { + try container.encode(links, forKey: .links) + } } } } diff --git a/Sources/JSONAPI/Meta/Links.swift b/Sources/JSONAPI/Meta/Links.swift index 8c91f16..53e8585 100644 --- a/Sources/JSONAPI/Meta/Links.swift +++ b/Sources/JSONAPI/Meta/Links.swift @@ -9,7 +9,10 @@ public protocol Links: Codable, Equatable {} /// Use NoLinks where no links should belong to a JSON API component -public struct NoLinks: Links {} +public struct NoLinks: Links { + public static var none: NoLinks { return NoLinks() } + public init() {} +} public protocol URL: Codable, Equatable {} diff --git a/Sources/JSONAPI/Resource/Relationship.swift b/Sources/JSONAPI/Resource/Relationship.swift index 47b5564..27e7d1b 100644 --- a/Sources/JSONAPI/Resource/Relationship.swift +++ b/Sources/JSONAPI/Resource/Relationship.swift @@ -98,6 +98,7 @@ public enum JSONAPIEncodingError: Swift.Error { case illegalEncoding(String) case illegalDecoding(String) case missingOrMalformedMetadata + case missingOrMalformedLinks } extension ToOneRelationship { diff --git a/Tests/JSONAPITests/Document/DocumentTests.swift b/Tests/JSONAPITests/Document/DocumentTests.swift index 5e99d50..1de6022 100644 --- a/Tests/JSONAPITests/Document/DocumentTests.swift +++ b/Tests/JSONAPITests/Document/DocumentTests.swift @@ -11,28 +11,28 @@ import JSONAPI class DocumentTests: XCTestCase { func test_singleDocumentNull() { - let document = decoded(type: JSONAPIDocument, NoMetadata, NoIncludes, BasicJSONAPIError>.self, + let document = decoded(type: JSONAPIDocument, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_null) XCTAssertFalse(document.body.isError) - XCTAssertNotNil(document.body.data) - XCTAssertNil(document.body.meta) - XCTAssertNil(document.body.data?.primary.value) - XCTAssertEqual(document.body.data?.included.count, 0) + XCTAssertNotNil(document.body.primaryData) + XCTAssertEqual(document.body.meta, NoMetadata()) + XCTAssertNil(document.body.primaryData?.value) + XCTAssertEqual(document.body.includes?.count, 0) } func test_singleDocumentNull_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoIncludes, BasicJSONAPIError>.self, + test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_null) } func test_unknownErrorDocumentNoMeta() { - let document = decoded(type: JSONAPIDocument.self, + let document = decoded(type: JSONAPIDocument.self, data: error_document_no_metadata) XCTAssertTrue(document.body.isError) - XCTAssertNil(document.body.meta) - XCTAssertNil(document.body.data) + XCTAssertEqual(document.body.meta, NoMetadata()) + XCTAssertNil(document.body.primaryData) guard case let .errors(errors) = document.body else { XCTFail("Needed body to be in errors case but it was not.") @@ -45,16 +45,16 @@ class DocumentTests: XCTestCase { } func test_unknownErrorDocumentNoMeta_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument.self, + test_DecodeEncodeEquality(type: JSONAPIDocument.self, data: error_document_no_metadata) } func test_unknownErrorDocumentMissingMeta() { - let document = decoded(type: JSONAPIDocument.self, data: error_document_no_metadata) + let document = decoded(type: JSONAPIDocument.self, data: error_document_no_metadata) XCTAssertTrue(document.body.isError) XCTAssertNil(document.body.meta) - XCTAssertNil(document.body.data) + XCTAssertNil(document.body.primaryData) guard case let .errors(errors) = document.body else { XCTFail("Needed body to be in errors case but it was not.") @@ -67,16 +67,16 @@ class DocumentTests: XCTestCase { } func test_unknownErrorDocumentMissingMeta_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument.self, data: error_document_no_metadata) + test_DecodeEncodeEquality(type: JSONAPIDocument.self, data: error_document_no_metadata) } func test_errorDocumentNoMeta() { - let document = decoded(type: JSONAPIDocument.self, + let document = decoded(type: JSONAPIDocument.self, data: error_document_no_metadata) XCTAssertTrue(document.body.isError) - XCTAssertNil(document.body.meta) - XCTAssertNil(document.body.data) + XCTAssertEqual(document.body.meta, NoMetadata()) + XCTAssertNil(document.body.primaryData) guard case let .errors(errors) = document.body else { XCTFail("Needed body to be in errors case but it was not.") @@ -89,17 +89,17 @@ class DocumentTests: XCTestCase { } func test_errorDocumentNoMeta_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument.self, + test_DecodeEncodeEquality(type: JSONAPIDocument.self, data: error_document_no_metadata) } func test_unknownErrorDocumentWithMeta() { - let document = decoded(type: JSONAPIDocument.self, + let document = decoded(type: JSONAPIDocument.self, data: error_document_with_metadata) XCTAssertTrue(document.body.isError) - XCTAssertNil(document.body.meta) - XCTAssertNil(document.body.data) + XCTAssertEqual(document.body.meta, TestPageMetadata(total: 70, limit: 40, offset: 10)) + XCTAssertNil(document.body.primaryData) guard case let .errors(errors) = document.body else { XCTFail("Needed body to be in errors case but it was not.") @@ -111,12 +111,12 @@ class DocumentTests: XCTestCase { } func test_unknownErrorDocumentWithMeta_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument.self, + test_DecodeEncodeEquality(type: JSONAPIDocument.self, data: error_document_with_metadata) } func test_metaDataDocument() { - let document = decoded(type: JSONAPIDocument.self, + let document = decoded(type: JSONAPIDocument.self, data: metadata_document) XCTAssertFalse(document.body.isError) @@ -126,136 +126,136 @@ class DocumentTests: XCTestCase { } func test_metaDataDocument_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument.self, + test_DecodeEncodeEquality(type: JSONAPIDocument.self, data: metadata_document) } func test_metaDocumentMissingMeta() { - XCTAssertThrowsError(try JSONDecoder().decode(JSONAPIDocument.self, from: metadata_document_missing_metadata)) + XCTAssertThrowsError(try JSONDecoder().decode(JSONAPIDocument.self, from: metadata_document_missing_metadata)) - XCTAssertThrowsError(try JSONDecoder().decode(JSONAPIDocument.self, from: metadata_document_missing_metadata2)) + XCTAssertThrowsError(try JSONDecoder().decode(JSONAPIDocument.self, from: metadata_document_missing_metadata2)) } func test_singleDocumentNoIncludes() { - let document = decoded(type: JSONAPIDocument, NoMetadata, NoIncludes, BasicJSONAPIError>.self, + let document = decoded(type: JSONAPIDocument, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes) XCTAssertFalse(document.body.isError) - XCTAssertNotNil(document.body.data) - XCTAssertEqual(document.body.data?.0.value?.id.rawValue, "1") - XCTAssertEqual(document.body.data?.included.count, 0) - XCTAssertEqual(document.body.data?.meta, NoMetadata()) + XCTAssertNotNil(document.body.primaryData) + XCTAssertEqual(document.body.primaryData?.value?.id.rawValue, "1") + XCTAssertEqual(document.body.includes?.count, 0) + XCTAssertEqual(document.body.meta, NoMetadata()) } func test_singleDocumentNoIncludes_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoIncludes, BasicJSONAPIError>.self, + test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes) } func test_singleDocumentNoIncludesWithMetadata() { - let document = decoded(type: JSONAPIDocument, TestPageMetadata, NoIncludes, BasicJSONAPIError>.self, + let document = decoded(type: JSONAPIDocument, TestPageMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes_with_metadata) XCTAssertFalse(document.body.isError) - XCTAssertNotNil(document.body.data) - XCTAssertEqual(document.body.data?.0.value?.id.rawValue, "1") - XCTAssertEqual(document.body.data?.included.count, 0) - XCTAssertEqual(document.body.data?.meta, TestPageMetadata(total: 70, limit: 40, offset: 10)) + XCTAssertNotNil(document.body.primaryData) + XCTAssertEqual(document.body.primaryData?.value?.id.rawValue, "1") + XCTAssertEqual(document.body.includes?.count, 0) + XCTAssertEqual(document.body.meta, TestPageMetadata(total: 70, limit: 40, offset: 10)) } func test_singleDocumentNoIncludesWithMetadata_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument, TestPageMetadata, NoIncludes, BasicJSONAPIError>.self, + test_DecodeEncodeEquality(type: JSONAPIDocument, TestPageMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes_with_metadata) } func test_singleDocumentNoIncludesMissingMetadata() { - XCTAssertThrowsError(try JSONDecoder().decode(JSONAPIDocument, TestPageMetadata, NoIncludes, BasicJSONAPIError>.self, from: single_document_no_includes)) + XCTAssertThrowsError(try JSONDecoder().decode(JSONAPIDocument, TestPageMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, from: single_document_no_includes)) } func test_singleDocumentSomeIncludes() { - let document = decoded(type: JSONAPIDocument, NoMetadata, Include1, BasicJSONAPIError>.self, + let document = decoded(type: JSONAPIDocument, NoMetadata, NoLinks, Include1, BasicJSONAPIError>.self, data: single_document_some_includes) XCTAssertFalse(document.body.isError) - XCTAssertNotNil(document.body.data) - XCTAssertEqual(document.body.data?.0.value?.id.rawValue, "1") - XCTAssertEqual(document.body.data?.included.count, 1) - XCTAssertEqual(document.body.data?.included[Author.self].count, 1) - XCTAssertEqual(document.body.data?.included[Author.self][0].id.rawValue, "33") + XCTAssertNotNil(document.body.primaryData) + XCTAssertEqual(document.body.primaryData?.value?.id.rawValue, "1") + XCTAssertEqual(document.body.includes?.count, 1) + XCTAssertEqual(document.body.includes?[Author.self].count, 1) + XCTAssertEqual(document.body.includes?[Author.self][0].id.rawValue, "33") } func test_singleDocumentSomeIncludes_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, Include1, BasicJSONAPIError>.self, + test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoLinks, Include1, BasicJSONAPIError>.self, data: single_document_some_includes) } func test_singleDocumentSomeIncludesWithMetadata() { - let document = decoded(type: JSONAPIDocument, TestPageMetadata, Include1, BasicJSONAPIError>.self, + let document = decoded(type: JSONAPIDocument, TestPageMetadata, NoLinks, Include1, BasicJSONAPIError>.self, data: single_document_some_includes_with_metadata) XCTAssertFalse(document.body.isError) - XCTAssertNotNil(document.body.data) - XCTAssertEqual(document.body.data?.0.value?.id.rawValue, "1") - XCTAssertEqual(document.body.data?.included.count, 1) - XCTAssertEqual(document.body.data?.included[Author.self].count, 1) - XCTAssertEqual(document.body.data?.included[Author.self][0].id.rawValue, "33") - XCTAssertEqual(document.body.data?.meta, TestPageMetadata(total: 70, limit: 40, offset: 10)) + XCTAssertNotNil(document.body.primaryData) + XCTAssertEqual(document.body.primaryData?.value?.id.rawValue, "1") + XCTAssertEqual(document.body.includes?.count, 1) + XCTAssertEqual(document.body.includes?[Author.self].count, 1) + XCTAssertEqual(document.body.includes?[Author.self][0].id.rawValue, "33") + XCTAssertEqual(document.body.meta, TestPageMetadata(total: 70, limit: 40, offset: 10)) } func test_singleDocumentSomeIncludesWithMetadata_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument, TestPageMetadata, Include1, BasicJSONAPIError>.self, + test_DecodeEncodeEquality(type: JSONAPIDocument, TestPageMetadata, NoLinks, Include1, BasicJSONAPIError>.self, data: single_document_some_includes_with_metadata) } func test_singleDocument_PolyPrimaryResource() { let article = Article(id: Id(rawValue: "1"), relationships: .init(author: ToOneRelationship(id: Id(rawValue: "33")))) - let document = decoded(type: JSONAPIDocument>, NoMetadata, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes) + let document = decoded(type: JSONAPIDocument>, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes) - XCTAssertEqual(document.body.data?.primary.value?[Article.self], article) - XCTAssertNil(document.body.data?.primary.value?[Author.self]) + XCTAssertEqual(document.body.primaryData?.value?[Article.self], article) + XCTAssertNil(document.body.primaryData?.value?[Author.self]) } func test_singleDocument_PolyPrimaryResource_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument>, NoMetadata, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes) + test_DecodeEncodeEquality(type: JSONAPIDocument>, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: single_document_no_includes) } func test_manyDocumentNoIncludes() { - let document = decoded(type: JSONAPIDocument, NoMetadata, NoIncludes, BasicJSONAPIError>.self, + let document = decoded(type: JSONAPIDocument, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: many_document_no_includes) XCTAssertFalse(document.body.isError) - XCTAssertNotNil(document.body.data) - XCTAssertEqual(document.body.data?.0.values.count, 3) - XCTAssertEqual(document.body.data?.0.values[0].id.rawValue, "1") - XCTAssertEqual(document.body.data?.0.values[1].id.rawValue, "2") - XCTAssertEqual(document.body.data?.0.values[2].id.rawValue, "3") - XCTAssertEqual(document.body.data?.included.count, 0) + XCTAssertNotNil(document.body.primaryData) + XCTAssertEqual(document.body.primaryData?.values.count, 3) + XCTAssertEqual(document.body.primaryData?.values[0].id.rawValue, "1") + XCTAssertEqual(document.body.primaryData?.values[1].id.rawValue, "2") + XCTAssertEqual(document.body.primaryData?.values[2].id.rawValue, "3") + XCTAssertEqual(document.body.includes?.count, 0) } func test_manyDocumentNoIncludes_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoIncludes, BasicJSONAPIError>.self, + test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoLinks, NoIncludes, BasicJSONAPIError>.self, data: many_document_no_includes) } func test_manyDocumentSomeIncludes() { - let document = decoded(type: JSONAPIDocument, NoMetadata, Include1, BasicJSONAPIError>.self, + let document = decoded(type: JSONAPIDocument, NoMetadata, NoLinks, Include1, BasicJSONAPIError>.self, data: many_document_some_includes) XCTAssertFalse(document.body.isError) - XCTAssertNotNil(document.body.data) - XCTAssertEqual(document.body.data?.0.values.count, 3) - XCTAssertEqual(document.body.data?.0.values[0].id.rawValue, "1") - XCTAssertEqual(document.body.data?.0.values[1].id.rawValue, "2") - XCTAssertEqual(document.body.data?.0.values[2].id.rawValue, "3") - XCTAssertEqual(document.body.data?.included.count, 3) - XCTAssertEqual(document.body.data?.included[Author.self].count, 3) - XCTAssertEqual(document.body.data?.included[Author.self][0].id.rawValue, "33") - XCTAssertEqual(document.body.data?.included[Author.self][1].id.rawValue, "22") - XCTAssertEqual(document.body.data?.included[Author.self][2].id.rawValue, "11") + XCTAssertNotNil(document.body.primaryData) + XCTAssertEqual(document.body.primaryData?.values.count, 3) + XCTAssertEqual(document.body.primaryData?.values[0].id.rawValue, "1") + XCTAssertEqual(document.body.primaryData?.values[1].id.rawValue, "2") + XCTAssertEqual(document.body.primaryData?.values[2].id.rawValue, "3") + XCTAssertEqual(document.body.includes?.count, 3) + XCTAssertEqual(document.body.includes?[Author.self].count, 3) + XCTAssertEqual(document.body.includes?[Author.self][0].id.rawValue, "33") + XCTAssertEqual(document.body.includes?[Author.self][1].id.rawValue, "22") + XCTAssertEqual(document.body.includes?[Author.self][2].id.rawValue, "11") } func test_manyDocumentSomeIncludes_encode() { - test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, Include1, BasicJSONAPIError>.self, + test_DecodeEncodeEquality(type: JSONAPIDocument, NoMetadata, NoLinks, Include1, BasicJSONAPIError>.self, data: many_document_some_includes) } }