Add support for Relationship Meta and Links (untested)

This commit is contained in:
Mathew Polzin
2018-12-05 09:14:38 -08:00
parent d667e91a6a
commit 35d6cbb440
14 changed files with 171 additions and 65 deletions
+9 -7
View File
@@ -23,8 +23,10 @@ extension String: CreatableRawIdType {
}
}
// MARK: - Entity typealias for convenience
// MARK: - typealiases for convenience
public typealias ExampleEntity<Description: EntityDescription> = Entity<Description, NoMetadata, NoLinks, String>
public typealias ToOne<E: OptionalRelatable> = ToOneRelationship<E, NoMetadata, NoLinks>
public typealias ToMany<E: Relatable> = ToManyRelationship<E, NoMetadata, NoLinks>
// MARK: - A few resource objects (entities)
public enum PersonDescription: EntityDescription {
@@ -46,11 +48,11 @@ public enum PersonDescription: EntityDescription {
}
public struct Relationships: JSONAPI.Relationships {
public let friends: ToManyRelationship<Person>
public let dogs: ToManyRelationship<Dog>
public let home: ToOneRelationship<House>
public let friends: ToMany<Person>
public let dogs: ToMany<Dog>
public let home: ToOne<House>
public init(friends: ToManyRelationship<Person>, dogs: ToManyRelationship<Dog>, home: ToOneRelationship<House>) {
public init(friends: ToMany<Person>, dogs: ToMany<Dog>, home: ToOne<House>) {
self.friends = friends
self.dogs = dogs
self.home = home
@@ -79,9 +81,9 @@ public enum DogDescription: EntityDescription {
}
public struct Relationships: JSONAPI.Relationships {
public let owner: ToOneRelationship<Person?>
public let owner: ToOne<Person?>
public init(owner: ToOneRelationship<Person?>) {
public init(owner: ToOne<Person?>) {
self.owner = owner
}
}
+2 -2
View File
@@ -52,8 +52,8 @@ Note that Playground support for importing non-system Frameworks is still a bit
#### Relationship Object
- [x] `data`
- [ ] `links`
- [ ] `meta`
- [x] `links` (untested)
- [x] `meta` (untested)
#### Links Object
- [x] `href`
+8 -4
View File
@@ -354,8 +354,12 @@ extension Entity where MetaType == NoMetadata, LinksType == NoLinks, EntityRawId
public extension Entity where EntityRawIdType: JSONAPI.RawIdType {
/// Get a pointer to this entity that can be used as a
/// relationship to another entity.
public var pointer: ToOneRelationship<Entity> {
return ToOneRelationship(entity: self)
public var pointer: ToOneRelationship<Entity, NoMetadata, NoLinks> {
return ToOneRelationship(entity: self, meta: .none, links: .none)
}
public func pointer<MType: JSONAPI.Meta, LType: JSONAPI.Links>(withMeta meta: MType, andLinks links: LType) -> ToOneRelationship<Entity, MType, LType> {
return ToOneRelationship(entity: self, meta: meta, links: links)
}
}
@@ -388,14 +392,14 @@ public extension EntityProxy {
/// Access to an Id of a `ToOneRelationship`.
/// This allows you to write `entity ~> \.other` instead
/// of `entity.relationships.other.id`.
public static func ~><OtherEntity: OptionalRelatable>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity>>) -> OtherEntity.WrappedIdentifier {
public static func ~><OtherEntity: OptionalRelatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToOneRelationship<OtherEntity, MType, LType>>) -> OtherEntity.WrappedIdentifier {
return entity.relationships[keyPath: path].id
}
/// Access to all Ids of a `ToManyRelationship`.
/// This allows you to write `entity ~> \.others` instead
/// of `entity.relationships.others.ids`.
public static func ~><OtherEntity: Relatable>(entity: Self, path: KeyPath<Description.Relationships, ToManyRelationship<OtherEntity>>) -> [OtherEntity.Identifier] {
public static func ~><OtherEntity: Relatable, MType: JSONAPI.Meta, LType: JSONAPI.Links>(entity: Self, path: KeyPath<Description.Relationships, ToManyRelationship<OtherEntity, MType, LType>>) -> [OtherEntity.Identifier] {
return entity.relationships[keyPath: path].ids
}
}
+111 -15
View File
@@ -5,30 +5,59 @@
// Created by Mathew Polzin on 8/31/18.
//
public protocol RelationshipType: Codable {}
public protocol RelationshipType: Codable {
associatedtype LinksType
associatedtype MetaType
var links: LinksType { get }
var meta: MetaType { get }
}
/// An Entity relationship that can be encoded to or decoded from
/// a JSON API "Resource Linkage."
/// See https://jsonapi.org/format/#document-resource-object-linkage
/// A convenient typealias might make your code much more legible: `One<EntityDescription>`
public struct ToOneRelationship<Relatable: JSONAPI.OptionalRelatable>: RelationshipType, Equatable {
public struct ToOneRelationship<Relatable: JSONAPI.OptionalRelatable, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links>: RelationshipType, Equatable {
public let id: Relatable.WrappedIdentifier
public init(id: Relatable.WrappedIdentifier) {
public let meta: MetaType
public let links: LinksType
public init(id: Relatable.WrappedIdentifier, meta: MetaType, links: LinksType) {
self.id = id
self.meta = meta
self.links = links
}
}
extension ToOneRelationship where MetaType == NoMetadata, LinksType == NoLinks {
public init(id: Relatable.WrappedIdentifier) {
self.init(id: id, meta: .none, links: .none)
}
}
extension ToOneRelationship where Relatable.WrappedIdentifier == Relatable.Identifier {
public init<E: EntityType>(entity: E, meta: MetaType, links: LinksType) where E.Description == Relatable.Description, E.Id == Relatable.Identifier {
self.init(id: entity.id, meta: meta, links: links)
}
}
extension ToOneRelationship where Relatable.WrappedIdentifier == Relatable.Identifier, MetaType == NoMetadata, LinksType == NoLinks {
public init<E: EntityType>(entity: E) where E.Description == Relatable.Description, E.Id == Relatable.Identifier {
id = entity.id
self.init(id: entity.id, meta: .none, links: .none)
}
}
extension ToOneRelationship where Relatable.WrappedIdentifier == Relatable.Identifier? {
public init<E: EntityType>(entity: E?, meta: MetaType, links: LinksType) where E.Description == Relatable.Description, E.Id == Relatable.Identifier {
self.init(id: entity?.id, meta: meta, links: links)
}
}
extension ToOneRelationship where Relatable.WrappedIdentifier == Relatable.Identifier?, MetaType == NoMetadata, LinksType == NoLinks {
public init<E: EntityType>(entity: E?) where E.Description == Relatable.Description, E.Id == Relatable.Identifier {
id = entity?.id
self.init(id: entity?.id, meta: .none, links: .none)
}
}
@@ -36,30 +65,54 @@ extension ToOneRelationship where Relatable.WrappedIdentifier == Relatable.Ident
/// a JSON API "Resource Linkage."
/// See https://jsonapi.org/format/#document-resource-object-linkage
/// A convenient typealias might make your code much more legible: `Many<EntityDescription>`
public struct ToManyRelationship<Relatable: JSONAPI.Relatable>: RelationshipType, Equatable {
public struct ToManyRelationship<Relatable: JSONAPI.Relatable, MetaType: JSONAPI.Meta, LinksType: JSONAPI.Links>: RelationshipType, Equatable {
public let ids: [Relatable.Identifier]
public init(ids: [Relatable.Identifier]) {
public let meta: MetaType
public let links: LinksType
public init(ids: [Relatable.Identifier], meta: MetaType, links: LinksType) {
self.ids = ids
self.meta = meta
self.links = links
}
public init<T: JSONAPI.Relatable>(relationships: [ToOneRelationship<T>]) where T.WrappedIdentifier == Relatable.Identifier {
public init<T: JSONAPI.Relatable>(relationships: [ToOneRelationship<T, NoMetadata, NoLinks>], meta: MetaType, links: LinksType) where T.WrappedIdentifier == Relatable.Identifier {
ids = relationships.map { $0.id }
self.meta = meta
self.links = links
}
private init() {
ids = []
public init<E: EntityType>(entities: [E], meta: MetaType, links: LinksType) where E.Description == Relatable.Description, E.Id == Relatable.Identifier {
self.init(ids: entities.map { $0.id }, meta: meta, links: links)
}
private init(meta: MetaType, links: LinksType) {
self.init(ids: [], meta: meta, links: links)
}
public static var none: ToManyRelationship {
return .init()
public static func none(withMeta meta: MetaType, links: LinksType) -> ToManyRelationship {
return ToManyRelationship(meta: meta, links: links)
}
}
extension ToManyRelationship {
extension ToManyRelationship where MetaType == NoMetadata, LinksType == NoLinks {
public init(ids: [Relatable.Identifier]) {
self.init(ids: ids, meta: .none, links: .none)
}
public init<T: JSONAPI.Relatable>(relationships: [ToOneRelationship<T, NoMetadata, NoLinks>]) where T.WrappedIdentifier == Relatable.Identifier {
self.init(relationships: relationships, meta: .none, links: .none)
}
public static var none: ToManyRelationship {
return .none(withMeta: .none, links: .none)
}
public init<E: EntityType>(entities: [E]) where E.Description == Relatable.Description, E.Id == Relatable.Identifier {
ids = entities.map { $0.id }
self.init(entities: entities, meta: .none, links: .none)
}
}
@@ -85,6 +138,8 @@ extension Optional: OptionalRelatable where Wrapped: Relatable {
// MARK: Codable
private enum ResourceLinkageCodingKeys: String, CodingKey {
case data = "data"
case meta = "meta"
case links = "links"
}
private enum ResourceIdentifierCodingKeys: String, CodingKey {
case id = "id"
@@ -103,6 +158,18 @@ extension ToOneRelationship {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: ResourceLinkageCodingKeys.self)
if let noMeta = NoMetadata() as? MetaType {
meta = noMeta
} else {
meta = try container.decode(MetaType.self, forKey: .meta)
}
if let noLinks = NoLinks() as? LinksType {
links = noLinks
} else {
links = try container.decode(LinksType.self, forKey: .links)
}
// A little trickery follows. If the id is nil, the
// container.decode(Identifier.self) will fail even if Identifier
// is Optional. However, we can check if decoding nil
@@ -133,6 +200,14 @@ extension ToOneRelationship {
try container.encodeNil(forKey: .data)
}
if MetaType.self != NoMetadata.self {
try container.encode(meta, forKey: .meta)
}
if LinksType.self != NoLinks.self {
try container.encode(links, forKey: .links)
}
var identifier = container.nestedContainer(keyedBy: ResourceIdentifierCodingKeys.self, forKey: .data)
try identifier.encode(id, forKey: .id)
@@ -143,7 +218,19 @@ extension ToOneRelationship {
extension ToManyRelationship {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: ResourceLinkageCodingKeys.self)
if let noMeta = NoMetadata() as? MetaType {
meta = noMeta
} else {
meta = try container.decode(MetaType.self, forKey: .meta)
}
if let noLinks = NoLinks() as? LinksType {
links = noLinks
} else {
links = try container.decode(LinksType.self, forKey: .links)
}
var identifiers = try container.nestedUnkeyedContainer(forKey: .data)
var newIds = [Relatable.Identifier]()
@@ -163,6 +250,15 @@ extension ToManyRelationship {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: ResourceLinkageCodingKeys.self)
if MetaType.self != NoMetadata.self {
try container.encode(meta, forKey: .meta)
}
if LinksType.self != NoLinks.self {
try container.encode(links, forKey: .links)
}
var identifiers = container.nestedUnkeyedContainer(forKey: .data)
for id in ids {
+5 -1
View File
@@ -45,6 +45,10 @@ extension TransformedAttribute: AttributeTypeWithOptionalArray where RawValue: O
private protocol OptionalRelationshipType {}
extension Optional: OptionalRelationshipType where Wrapped: RelationshipType {}
private protocol _RelationshipType {}
extension ToOneRelationship: _RelationshipType {}
extension ToManyRelationship: _RelationshipType {}
public extension Entity {
public static func check(_ entity: Entity) throws {
var problems = [EntityCheckError]()
@@ -72,7 +76,7 @@ public extension Entity {
}
for relationship in relationshipsMirror.children {
if relationship.value as? RelationshipType == nil {
if relationship.value as? _RelationshipType == nil {
problems.append(.nonRelationship(named: relationship.label ?? "unnamed"))
}
}
@@ -7,14 +7,14 @@
import JSONAPI
extension ToOneRelationship: ExpressibleByNilLiteral where Relatable.WrappedIdentifier: ExpressibleByNilLiteral {
extension ToOneRelationship: ExpressibleByNilLiteral where Relatable.WrappedIdentifier: ExpressibleByNilLiteral, MetaType == NoMetadata, LinksType == NoLinks {
public init(nilLiteral: ()) {
self.init(id: Relatable.WrappedIdentifier(nilLiteral: ()))
}
}
extension ToOneRelationship: ExpressibleByUnicodeScalarLiteral where Relatable.WrappedIdentifier: ExpressibleByUnicodeScalarLiteral {
extension ToOneRelationship: ExpressibleByUnicodeScalarLiteral where Relatable.WrappedIdentifier: ExpressibleByUnicodeScalarLiteral, MetaType == NoMetadata, LinksType == NoLinks {
public typealias UnicodeScalarLiteralType = Relatable.WrappedIdentifier.UnicodeScalarLiteralType
public init(unicodeScalarLiteral value: UnicodeScalarLiteralType) {
@@ -22,7 +22,7 @@ extension ToOneRelationship: ExpressibleByUnicodeScalarLiteral where Relatable.W
}
}
extension ToOneRelationship: ExpressibleByExtendedGraphemeClusterLiteral where Relatable.WrappedIdentifier: ExpressibleByExtendedGraphemeClusterLiteral {
extension ToOneRelationship: ExpressibleByExtendedGraphemeClusterLiteral where Relatable.WrappedIdentifier: ExpressibleByExtendedGraphemeClusterLiteral, MetaType == NoMetadata, LinksType == NoLinks {
public typealias ExtendedGraphemeClusterLiteralType = Relatable.WrappedIdentifier.ExtendedGraphemeClusterLiteralType
public init(extendedGraphemeClusterLiteral value: ExtendedGraphemeClusterLiteralType) {
@@ -30,7 +30,7 @@ extension ToOneRelationship: ExpressibleByExtendedGraphemeClusterLiteral where R
}
}
extension ToOneRelationship: ExpressibleByStringLiteral where Relatable.WrappedIdentifier: ExpressibleByStringLiteral {
extension ToOneRelationship: ExpressibleByStringLiteral where Relatable.WrappedIdentifier: ExpressibleByStringLiteral, MetaType == NoMetadata, LinksType == NoLinks {
public typealias StringLiteralType = Relatable.WrappedIdentifier.StringLiteralType
public init(stringLiteral value: StringLiteralType) {
@@ -38,7 +38,7 @@ extension ToOneRelationship: ExpressibleByStringLiteral where Relatable.WrappedI
}
}
extension ToManyRelationship: ExpressibleByArrayLiteral {
extension ToManyRelationship: ExpressibleByArrayLiteral where MetaType == NoMetadata, LinksType == NoLinks {
public typealias ArrayLiteralElement = Relatable.Identifier
public init(arrayLiteral elements: ArrayLiteralElement...) {
@@ -49,9 +49,9 @@ extension ComputedPropertiesTests {
}
public struct Relationships: JSONAPI.Relationships {
public let other: ToOneRelationship<TestType>
public let other: ToOneRelationship<TestType, NoMetadata, NoLinks>
public var computed: ToOneRelationship<TestType> {
public var computed: ToOneRelationship<TestType, NoMetadata, NoLinks> {
return other
}
}
@@ -978,7 +978,7 @@ extension DocumentTests {
typealias Attributes = NoAttributes
struct Relationships: JSONAPI.Relationships {
let author: ToOneRelationship<Author>
let author: ToOneRelationship<Author, NoMetadata, NoLinks>
}
}
+7 -7
View File
@@ -459,7 +459,7 @@ extension EntityTests {
typealias Attributes = NoAttributes
struct Relationships: JSONAPI.Relationships {
let other: ToOneRelationship<TestEntity1>
let other: ToOneRelationship<TestEntity1, NoMetadata, NoLinks>
}
}
@@ -471,7 +471,7 @@ extension EntityTests {
typealias Attributes = NoAttributes
struct Relationships: JSONAPI.Relationships {
let others: ToManyRelationship<TestEntity1>
let others: ToManyRelationship<TestEntity1, NoMetadata, NoLinks>
}
}
@@ -481,7 +481,7 @@ extension EntityTests {
static var type: String { return "fourth_test_entities"}
struct Relationships: JSONAPI.Relationships {
let other: ToOneRelationship<TestEntity2>
let other: ToOneRelationship<TestEntity2, NoMetadata, NoLinks>
}
struct Attributes: JSONAPI.Attributes {
@@ -562,9 +562,9 @@ extension EntityTests {
typealias Attributes = NoAttributes
public struct Relationships: JSONAPI.Relationships {
let one: ToOneRelationship<TestEntity1>
let one: ToOneRelationship<TestEntity1, NoMetadata, NoLinks>
let nullableOne: ToOneRelationship<TestEntity1?>
let nullableOne: ToOneRelationship<TestEntity1?, NoMetadata, NoLinks>
// a nullable many is not allowed. it should
// just be an empty array.
@@ -584,8 +584,8 @@ extension EntityTests {
typealias Attributes = NoAttributes
public struct Relationships: JSONAPI.Relationships {
let selfRef: ToOneRelationship<TestEntity10>
let selfRefs: ToManyRelationship<TestEntity10>
let selfRef: ToOneRelationship<TestEntity10, NoMetadata, NoLinks>
let selfRefs: ToManyRelationship<TestEntity10, NoMetadata, NoLinks>
}
}
@@ -144,7 +144,7 @@ extension IncludedTests {
public static var type: String { return "test_entity2" }
public struct Relationships: JSONAPI.Relationships {
let entity1: ToOneRelationship<TestEntity>
let entity1: ToOneRelationship<TestEntity, NoMetadata, NoLinks>
}
public struct Attributes: JSONAPI.Attributes {
@@ -162,8 +162,8 @@ extension IncludedTests {
public static var type: String { return "test_entity3" }
public struct Relationships: JSONAPI.Relationships {
let entity1: ToOneRelationship<TestEntity>
let entity2: ToManyRelationship<TestEntity2>
let entity1: ToOneRelationship<TestEntity, NoMetadata, NoLinks>
let entity2: ToManyRelationship<TestEntity2, NoMetadata, NoLinks>
}
}
@@ -198,7 +198,7 @@ extension IncludedTests {
public static var type: String { return "test_entity6" }
struct Relationships: JSONAPI.Relationships {
let entity4: ToOneRelationship<TestEntity4>
let entity4: ToOneRelationship<TestEntity4, NoMetadata, NoLinks>
}
}
@@ -115,7 +115,7 @@ extension EntityCheckTests {
public typealias Attributes = NoAttributes
public struct Relationships: JSONAPI.Relationships {
let x: ToOneRelationship<OkEntity>
let x: ToOneRelationship<OkEntity, NoMetadata, NoLinks>
let y: Id<String, OkEntity>
}
}
@@ -12,16 +12,16 @@ import JSONAPITestLib
class Relationship_LiteralTests: XCTestCase {
func test_NilLiteral() {
XCTAssertEqual(ToOneRelationship<TestEntity?>(id: nil), nil)
XCTAssertEqual(ToOneRelationship<TestEntity?, NoMetadata, NoLinks>(id: nil), nil)
}
func test_ArrayLiteral() {
XCTAssertEqual(ToManyRelationship<TestEntity>(ids: ["1", "2", "3"]), ["1", "2", "3"])
XCTAssertEqual(ToManyRelationship<TestEntity, NoMetadata, NoLinks>(ids: ["1", "2", "3"]), ["1", "2", "3"])
}
func test_StringLiteral() {
XCTAssertEqual(ToOneRelationship<TestEntity>(id: "123"), "123")
XCTAssertEqual(ToOneRelationship<TestEntity?>(id: "123"), "123")
XCTAssertEqual(ToOneRelationship<TestEntity, NoMetadata, NoLinks>(id: "123"), "123")
XCTAssertEqual(ToOneRelationship<TestEntity?, NoMetadata, NoLinks>(id: "123"), "123")
}
}
+4 -4
View File
@@ -282,7 +282,7 @@ extension PolyTests {
public static var type: String { return "test_entity2" }
public struct Relationships: JSONAPI.Relationships {
let entity1: ToOneRelationship<TestEntity>
let entity1: ToOneRelationship<TestEntity, NoMetadata, NoLinks>
}
public struct Attributes: JSONAPI.Attributes {
@@ -300,8 +300,8 @@ extension PolyTests {
public static var type: String { return "test_entity3" }
public struct Relationships: JSONAPI.Relationships {
let entity1: ToOneRelationship<TestEntity>
let entity2: ToManyRelationship<TestEntity2>
let entity1: ToOneRelationship<TestEntity, NoMetadata, NoLinks>
let entity2: ToManyRelationship<TestEntity2, NoMetadata, NoLinks>
}
}
@@ -336,7 +336,7 @@ extension PolyTests {
public static var type: String { return "test_entity6" }
struct Relationships: JSONAPI.Relationships {
let entity4: ToOneRelationship<TestEntity4>
let entity4: ToOneRelationship<TestEntity4, NoMetadata, NoLinks>
}
}
@@ -15,7 +15,7 @@ class RelationshipTests: XCTestCase {
let entity2 = TestEntity1()
let entity3 = TestEntity1()
let entity4 = TestEntity1()
let relationship = ToManyRelationship<TestEntity1>(entities: [entity1, entity2, entity3, entity4])
let relationship = ToManyRelationship<TestEntity1, NoMetadata, NoLinks>(entities: [entity1, entity2, entity3, entity4])
XCTAssertEqual(relationship.ids.count, 4)
XCTAssertEqual(relationship.ids, [entity1, entity2, entity3, entity4].map { $0.id })
@@ -26,7 +26,7 @@ class RelationshipTests: XCTestCase {
let entity2 = TestEntity1()
let entity3 = TestEntity1()
let entity4 = TestEntity1()
let relationship = ToManyRelationship<TestEntity1>(relationships: [entity1.pointer, entity2.pointer, entity3.pointer, entity4.pointer])
let relationship = ToManyRelationship<TestEntity1, NoMetadata, NoLinks>(relationships: [entity1.pointer, entity2.pointer, entity3.pointer, entity4.pointer])
XCTAssertEqual(relationship.ids.count, 4)
XCTAssertEqual(relationship.ids, [entity1, entity2, entity3, entity4].map { $0.id })
@@ -36,26 +36,26 @@ class RelationshipTests: XCTestCase {
// MARK: - Encode/Decode
extension RelationshipTests {
func test_ToOneRelationship() {
let relationship = decoded(type: ToOneRelationship<TestEntity1>.self,
let relationship = decoded(type: ToOneRelationship<TestEntity1, NoMetadata, NoLinks>.self,
data: to_one_relationship)
XCTAssertEqual(relationship.id.rawValue, "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF")
}
func test_ToOneRelationship_encode() {
test_DecodeEncodeEquality(type: ToOneRelationship<TestEntity1>.self,
test_DecodeEncodeEquality(type: ToOneRelationship<TestEntity1, NoMetadata, NoLinks>.self,
data: to_one_relationship)
}
func test_ToManyRelationship() {
let relationship = decoded(type: ToManyRelationship<TestEntity1>.self,
let relationship = decoded(type: ToManyRelationship<TestEntity1, NoMetadata, NoLinks>.self,
data: to_many_relationship)
XCTAssertEqual(relationship.ids.map { $0.rawValue }, ["2DF03B69-4B0A-467F-B52E-B0C9E44FCECF", "90F03B69-4DF1-467F-B52E-B0C9E44FC333", "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF"])
}
func test_ToManyRelationship_encode() {
test_DecodeEncodeEquality(type: ToManyRelationship<TestEntity1>.self,
test_DecodeEncodeEquality(type: ToManyRelationship<TestEntity1, NoMetadata, NoLinks>.self,
data: to_many_relationship)
}
}
@@ -63,11 +63,11 @@ extension RelationshipTests {
// MARK: Failure tests
extension RelationshipTests {
func test_ToManyTypeMismatch() {
XCTAssertThrowsError(try JSONDecoder().decode(ToManyRelationship<TestEntity1>.self, from: to_many_relationship_type_mismatch))
XCTAssertThrowsError(try JSONDecoder().decode(ToManyRelationship<TestEntity1, NoMetadata, NoLinks>.self, from: to_many_relationship_type_mismatch))
}
func test_ToOneTypeMismatch() {
XCTAssertThrowsError(try JSONDecoder().decode(ToOneRelationship<TestEntity1>.self, from: to_one_relationship_type_mismatch))
XCTAssertThrowsError(try JSONDecoder().decode(ToOneRelationship<TestEntity1, NoMetadata, NoLinks>.self, from: to_one_relationship_type_mismatch))
}
}