mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-03-30 11:18:38 -07:00
Add support for Relationship Meta and Links (untested)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user