From 4d3597ef0e31cf19f845c34ad2fe6296476eefc8 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Sat, 27 Jul 2019 21:30:14 -0700 Subject: [PATCH 1/5] Update README.md --- README.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 993e727..de493ae 100644 --- a/README.md +++ b/README.md @@ -813,10 +813,18 @@ print(response.author) ``` # JSONAPI+Testing -The `JSONAPI` framework is packaged with a test library to help you test your `JSONAPI` integration. The test library is called `JSONAPITesting`. It provides literal expressibility for `Attribute`, `ToOneRelationship`, and `Id` in many situations so that you can easily write test `ResourceObject` values into your unit tests. It also provides a `check()` function for each `ResourceObject` type that can be used to catch problems with your `JSONAPI` structures that are not caught by Swift's type system. You can see the `JSONAPITesting` in action in the Playground included with the `JSONAPI` repository. +The `JSONAPI` framework is packaged with a test library to help you test your `JSONAPI` integration. + +The test library is called `JSONAPITesting`. It provides literal expressibility for `Attribute`, `ToOneRelationship`, and `Id` in many situations so that you can easily write test `ResourceObject` values into your unit tests. It also provides a `check()` function for each `ResourceObject` type that can be used to catch problems with your `JSONAPI` structures that are not caught by Swift's type system. + +You can see the `JSONAPITesting` in action in the Playground included with the `JSONAPI` repository. # JSONAPI+Arbitrary -This library has moved into its own Package. See https://github.com/mattpolzin/JSONAPI-Arbitrary +This library has moved into its own Package. See https://github.com/mattpolzin/JSONAPI-Arbitrary for more information. # JSONAPI+OpenAPI -This library has moved into its own Package. See https://github.com/mattpolzin/JSONAPI-OpenAPI +The `JSONAPI+OpenAPI` library generates OpenAPI compliant JSON Schema for models built with the `JSONAPI` library. If your Swift code is your preferred source of truth for API information, this is an easy way to document the response schemas of your API. + +`JSONAPI+OpenAPI` also has experimental support for generating `JSONAPI` Swift code from Open API documentation (this currently lives on the `feature/gen-swift` branch). + +See https://github.com/mattpolzin/JSONAPI-OpenAPI for more information. From c4f96c0376f27447d089be6530d6d1b0fd12e547 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Sun, 28 Jul 2019 13:10:42 -0700 Subject: [PATCH 2/5] Updated example in playground/documentation after realizing I was not using a variable I had created. --- .../Contents.swift | 2 +- README.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/JSONAPI.playground/Pages/Full Client & Server Example.xcplaygroundpage/Contents.swift b/JSONAPI.playground/Pages/Full Client & Server Example.xcplaygroundpage/Contents.swift index c8cbea1..e68aaa6 100644 --- a/JSONAPI.playground/Pages/Full Client & Server Example.xcplaygroundpage/Contents.swift +++ b/JSONAPI.playground/Pages/Full Client & Server Example.xcplaygroundpage/Contents.swift @@ -114,7 +114,7 @@ func articleDocument(includeAuthor: Bool) -> Either = .init(values: [.init(author)]) - return .init(document.including(.init(values: [.init(author)]))) + return .init(document.including(includes)) } } diff --git a/README.md b/README.md index de493ae..f00fafd 100644 --- a/README.md +++ b/README.md @@ -750,7 +750,7 @@ func articleDocument(includeAuthor: Bool) -> Either = .init(values: [.init(author)]) - return .init(document.including(.init(values: [.init(author)]))) + return .init(document.including(includes)) } } @@ -813,9 +813,9 @@ print(response.author) ``` # JSONAPI+Testing -The `JSONAPI` framework is packaged with a test library to help you test your `JSONAPI` integration. +The `JSONAPI` framework is packaged with a test library to help you test your `JSONAPI` integration. -The test library is called `JSONAPITesting`. It provides literal expressibility for `Attribute`, `ToOneRelationship`, and `Id` in many situations so that you can easily write test `ResourceObject` values into your unit tests. It also provides a `check()` function for each `ResourceObject` type that can be used to catch problems with your `JSONAPI` structures that are not caught by Swift's type system. +The test library is called `JSONAPITesting`. It provides literal expressibility for `Attribute`, `ToOneRelationship`, and `Id` in many situations so that you can easily write test `ResourceObject` values into your unit tests. It also provides a `check()` function for each `ResourceObject` type that can be used to catch problems with your `JSONAPI` structures that are not caught by Swift's type system. You can see the `JSONAPITesting` in action in the Playground included with the `JSONAPI` repository. @@ -823,8 +823,8 @@ You can see the `JSONAPITesting` in action in the Playground included with the ` This library has moved into its own Package. See https://github.com/mattpolzin/JSONAPI-Arbitrary for more information. # JSONAPI+OpenAPI -The `JSONAPI+OpenAPI` library generates OpenAPI compliant JSON Schema for models built with the `JSONAPI` library. If your Swift code is your preferred source of truth for API information, this is an easy way to document the response schemas of your API. +The `JSONAPI+OpenAPI` library generates OpenAPI compliant JSON Schema for models built with the `JSONAPI` library. If your Swift code is your preferred source of truth for API information, this is an easy way to document the response schemas of your API. -`JSONAPI+OpenAPI` also has experimental support for generating `JSONAPI` Swift code from Open API documentation (this currently lives on the `feature/gen-swift` branch). +`JSONAPI+OpenAPI` also has experimental support for generating `JSONAPI` Swift code from Open API documentation (this currently lives on the `feature/gen-swift` branch). See https://github.com/mattpolzin/JSONAPI-OpenAPI for more information. From f5eb343bd452c4fc3a9e0f6793247162a17817c3 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Mon, 29 Jul 2019 20:41:22 -0700 Subject: [PATCH 3/5] Complete test coverage of APIDescription --- .../APIDescription/APIDescriptionTests.swift | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/Tests/JSONAPITests/APIDescription/APIDescriptionTests.swift b/Tests/JSONAPITests/APIDescription/APIDescriptionTests.swift index d5706b6..9640352 100644 --- a/Tests/JSONAPITests/APIDescription/APIDescriptionTests.swift +++ b/Tests/JSONAPITests/APIDescription/APIDescriptionTests.swift @@ -10,6 +10,17 @@ import JSONAPI class APIDescriptionTests: XCTestCase { + func test_init() { + let _ = APIDescription(version: "hello", + meta: .none) + let _ = APIDescription(version: "world", + meta: .init(hello: "there", + number: 2)) + let _ = NoAPIDescription() + + XCTAssertEqual(NoAPIDescription(), NoAPIDescription.none) + } + func test_NoDescriptionString() { XCTAssertEqual(String(describing: NoAPIDescription()), "No JSON:API Object") } @@ -18,12 +29,18 @@ class APIDescriptionTests: XCTestCase { let description = decoded(type: APIDescription.self, data: api_description_empty) XCTAssertEqual(description.version, "1.0") + + test_DecodeEncodeEquality(type: APIDescription.self, + data: api_description_empty) } func test_WithVersion() { let description = decoded(type: APIDescription.self, data: api_description_with_version) XCTAssertEqual(description.version, "1.5") + + test_DecodeEncodeEquality(type: APIDescription.self, + data: api_description_with_version) } func test_WithMeta() { @@ -32,6 +49,9 @@ class APIDescriptionTests: XCTestCase { XCTAssertEqual(description.version, "1.0") XCTAssertEqual(description.meta.hello, "world") XCTAssertEqual(description.meta.number, 10) + + test_DecodeEncodeEquality(type: APIDescription.self, + data: api_description_with_meta) } func test_WithVersionAndMeta() { @@ -40,6 +60,9 @@ class APIDescriptionTests: XCTestCase { XCTAssertEqual(description.version, "2.0") XCTAssertEqual(description.meta.hello, "world") XCTAssertEqual(description.meta.number, 10) + + test_DecodeEncodeEquality(type: APIDescription.self, + data: api_description_with_version_and_meta) } func test_failsMissingMeta() { From 396f8453d169b39873bb29a0ec339804ec60c1ab Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Mon, 29 Jul 2019 21:00:44 -0700 Subject: [PATCH 4/5] swap out broken nil checks (not harming anything, but not working as evidenced by not getting hit by any test cases) --- Sources/JSONAPI/Document/ResourceBody.swift | 10 ++++++---- Sources/JSONAPI/Resource/Relationship.swift | 4 ---- .../JSONAPITests/ResourceBody/ResourceBodyTests.swift | 3 +++ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/Sources/JSONAPI/Document/ResourceBody.swift b/Sources/JSONAPI/Document/ResourceBody.swift index eed341e..b8f170c 100644 --- a/Sources/JSONAPI/Document/ResourceBody.swift +++ b/Sources/JSONAPI/Document/ResourceBody.swift @@ -71,10 +71,12 @@ extension SingleResourceBody { public func encode(to encoder: Encoder) throws { var container = encoder.singleValueContainer() - if (value as Any?) == nil { - try container.encodeNil() - return - } + let anyNil: Any? = nil + let nilValue = anyNil as? Entity + guard value != nilValue else { + try container.encodeNil() + return + } try container.encode(value) } diff --git a/Sources/JSONAPI/Resource/Relationship.swift b/Sources/JSONAPI/Resource/Relationship.swift index f6a4bdc..43f5457 100644 --- a/Sources/JSONAPI/Resource/Relationship.swift +++ b/Sources/JSONAPI/Resource/Relationship.swift @@ -190,10 +190,6 @@ extension ToOneRelationship: Codable where Identifiable.Identifier: OptionalId { public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: ResourceLinkageCodingKeys.self) - if (id as Any?) == nil { - try container.encodeNil(forKey: .data) - } - if MetaType.self != NoMetadata.self { try container.encode(meta, forKey: .meta) } diff --git a/Tests/JSONAPITests/ResourceBody/ResourceBodyTests.swift b/Tests/JSONAPITests/ResourceBody/ResourceBodyTests.swift index a20db8c..9bc3f2c 100644 --- a/Tests/JSONAPITests/ResourceBody/ResourceBodyTests.swift +++ b/Tests/JSONAPITests/ResourceBody/ResourceBodyTests.swift @@ -100,6 +100,9 @@ class ResourceBodyTests: XCTestCase { XCTAssertEqual(combined.values.count, 3) XCTAssertEqual(combined.values, body1.values + body2.values) } +} + +extension ResourceBodyTests { enum ArticleType: ResourceObjectDescription { public static var jsonType: String { return "articles" } From 60cd515fd6c86ac77bd69c30c07dce74a1761798 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Tue, 30 Jul 2019 17:44:06 -0700 Subject: [PATCH 5/5] just filling in a couple small holes in test coverage --- Tests/JSONAPITests/Entity/EntityTests.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Tests/JSONAPITests/Entity/EntityTests.swift b/Tests/JSONAPITests/Entity/EntityTests.swift index feaf9ee..7076358 100644 --- a/Tests/JSONAPITests/Entity/EntityTests.swift +++ b/Tests/JSONAPITests/Entity/EntityTests.swift @@ -30,6 +30,7 @@ class EntityTests: XCTestCase { let entity = TestEntity9(attributes: .none, relationships: .init(one: entity1.pointer, nullableOne: .init(resourceObject: entity1, meta: .none, links: .none), optionalOne: .init(resourceObject: entity1, meta: .none, links: .none), optionalNullableOne: nil, optionalMany: .init(resourceObjects: [entity1, entity1], meta: .none, links: .none)), meta: .none, links: .none) XCTAssertEqual(entity ~> \.optionalOne, entity1.id) + XCTAssertEqual((entity ~> \.optionalOne).rawValue, entity1.id.rawValue) } func test_toMany_relationship_operator_access() { @@ -393,6 +394,7 @@ extension EntityTests { XCTAssertEqual((entity ~> \.nullableOne)?.rawValue, "3323") XCTAssertEqual((entity ~> \.one).rawValue, "4459") XCTAssertNil(entity ~> \.optionalNullableOne) + XCTAssertNil((entity ~> \.optionalNullableOne).rawValue) XCTAssertNoThrow(try TestEntity9.check(entity)) testEncoded(entity: entity) @@ -651,6 +653,16 @@ extension EntityTests { XCTAssertEqual(entity1 ~> \.metaRelationship, "hello") } + + func test_toManyMetaRelationshipAccessWorks() { + let entity1 = TestEntityWithMetaRelationship(id: "even", + attributes: .none, + relationships: .init(), + meta: .none, + links: .none) + + XCTAssertEqual(entity1 ~> \.toManyMetaRelationship, ["hello"]) + } } // MARK: - Test Types @@ -883,6 +895,12 @@ extension EntityTests { return TestEntity1.Identifier(rawValue: "hello") } } + + var toManyMetaRelationship: (TestEntityWithMetaRelationship) -> [TestEntity1.Identifier] { + return { entity in + return [TestEntity1.Identifier.id(from: "hello")] + } + } } }