Skip to content

Commit

Permalink
Merge pull request #103 from mattpolzin/add-include12-include13
Browse files Browse the repository at this point in the history
Add Include12 and Include13 types.
  • Loading branch information
mattpolzin authored Aug 24, 2022
2 parents a72ed5c + aec39fc commit 661dfc3
Show file tree
Hide file tree
Showing 15 changed files with 481 additions and 49 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ jobs:
- swift:5.4-focal
- swift:5.4-centos8
- swift:5.4-amazonlinux2
- swift:5.5-xenial
- swift:5.5-bionic
- swift:5.5-focal
- swift:5.5-centos8
- swift:5.5-amazonlinux2
- swift:5.6-bionic
- swift:5.6-focal
- swift:5.6-amazonlinux2
container: ${{ matrix.image }}
steps:
- name: Checkout code
Expand Down
4 changes: 2 additions & 2 deletions JSONAPI.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Pod::Spec.new do |spec|
#

spec.name = "MP-JSONAPI"
spec.version = "5.0.2"
spec.version = "5.1.0"
spec.summary = "Swift Codable JSON API framework."

# This description is used to generate tags and improve search results.
Expand Down Expand Up @@ -136,6 +136,6 @@ See the JSON API Spec here: https://jsonapi.org/format/
# spec.requires_arc = true

# spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
spec.dependency "Poly", "~> 2.4"
spec.dependency "Poly", "~> 2.6"

end
4 changes: 2 additions & 2 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
"repositoryURL": "https://github.com/mattpolzin/Poly.git",
"state": {
"branch": null,
"revision": "36ba3f624bffa34f5f9b9c7648eab3cfdcab4748",
"version": "2.5.0"
"revision": "c108e9e0a2904134719b082f6c18d64406afc6db",
"version": "2.6.0"
}
}
]
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ let package = Package(
targets: ["JSONAPITesting"])
],
dependencies: [
.package(url: "https://github.com/mattpolzin/Poly.git", .upToNextMajor(from: "2.4.0")),
.package(url: "https://github.com/mattpolzin/Poly.git", .upToNextMajor(from: "2.6.0")),
],
targets: [
.target(
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ If you find something wrong with this library and it isn't already mentioned und
### Swift Package Manager
Just include the following in your package's dependencies and add `JSONAPI` to the dependencies for any of your targets.
```swift
.package(url: "https://github.com/mattpolzin/JSONAPI.git", from: "5.0.2")
.package(url: "https://github.com/mattpolzin/JSONAPI.git", from: "5.1.0")
```

### Xcode project
Expand Down
2 changes: 1 addition & 1 deletion Sources/JSONAPI/Document/CompoundResource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ extension Sequence where Element: CompoundResourceProtocol {
}
}

extension EncodableJSONAPIDocument where PrimaryResourceBody: EncodableResourceBody, PrimaryResourceBody.PrimaryResource: ResourceObjectType {
extension EncodableJSONAPIDocument where PrimaryResourceBody.PrimaryResource: ResourceObjectType {
public typealias CompoundResource = JSONAPI.CompoundResource<PrimaryResourceBody.PrimaryResource, IncludeType>
}

Expand Down
7 changes: 7 additions & 0 deletions Sources/JSONAPI/Document/DocumentDecodingError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ public enum DocumentDecodingError: Swift.Error, Equatable {
self = .primaryResourceMissing
case .valueNotFound(let type, let context) where Location(context) == .data && type == UnkeyedDecodingContainer.self:
self = .primaryResourcesMissing
case .typeMismatch(let type, let context) where Location(context) == .data && type is _ArrayType.Type && context.debugDescription.hasSuffix("but found null instead."):
self = .primaryResourcesMissing
case .typeMismatch(_, let context) where Location(context) == .data && context.debugDescription.hasSuffix("but found null instead."):
self = .primaryResourceMissing
default:
return nil
}
Expand Down Expand Up @@ -71,3 +75,6 @@ extension DocumentDecodingError: CustomStringConvertible {
}
}
}

private protocol _ArrayType {}
extension Array: _ArrayType {}
16 changes: 16 additions & 0 deletions Sources/JSONAPI/Document/Includes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,22 @@ extension Includes where I: _Poly11 {
}
}

// MARK: - 12 includes
public typealias Include12 = Poly12
extension Includes where I: _Poly12 {
public subscript(_ lookup: I.L.Type) -> [I.L] {
return values.compactMap(\.l)
}
}

// MARK: - 13 includes
public typealias Include13 = Poly13
extension Includes where I: _Poly13 {
public subscript(_ lookup: I.M.Type) -> [I.M] {
return values.compactMap(\.m)
}
}

// MARK: - DecodingError
public struct IncludesDecodingError: Swift.Error, Equatable {
public let error: Swift.Error
Expand Down
64 changes: 64 additions & 0 deletions Sources/JSONAPI/Resource/Poly+PrimaryResource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,67 @@ extension Poly11: CodablePrimaryResource, OptionalCodablePrimaryResource
I: CodablePolyWrapped,
J: CodablePolyWrapped,
K: CodablePolyWrapped {}

// MARK: - 12 types
extension Poly12: EncodablePrimaryResource, OptionalEncodablePrimaryResource
where
A: EncodablePolyWrapped,
B: EncodablePolyWrapped,
C: EncodablePolyWrapped,
D: EncodablePolyWrapped,
E: EncodablePolyWrapped,
F: EncodablePolyWrapped,
G: EncodablePolyWrapped,
H: EncodablePolyWrapped,
I: EncodablePolyWrapped,
J: EncodablePolyWrapped,
K: EncodablePolyWrapped,
L: EncodablePolyWrapped {}

extension Poly12: CodablePrimaryResource, OptionalCodablePrimaryResource
where
A: CodablePolyWrapped,
B: CodablePolyWrapped,
C: CodablePolyWrapped,
D: CodablePolyWrapped,
E: CodablePolyWrapped,
F: CodablePolyWrapped,
G: CodablePolyWrapped,
H: CodablePolyWrapped,
I: CodablePolyWrapped,
J: CodablePolyWrapped,
K: CodablePolyWrapped,
L: CodablePolyWrapped {}

// MARK: - 13 types
extension Poly13: EncodablePrimaryResource, OptionalEncodablePrimaryResource
where
A: EncodablePolyWrapped,
B: EncodablePolyWrapped,
C: EncodablePolyWrapped,
D: EncodablePolyWrapped,
E: EncodablePolyWrapped,
F: EncodablePolyWrapped,
G: EncodablePolyWrapped,
H: EncodablePolyWrapped,
I: EncodablePolyWrapped,
J: EncodablePolyWrapped,
K: EncodablePolyWrapped,
L: EncodablePolyWrapped,
M: EncodablePolyWrapped {}

extension Poly13: CodablePrimaryResource, OptionalCodablePrimaryResource
where
A: CodablePolyWrapped,
B: CodablePolyWrapped,
C: CodablePolyWrapped,
D: CodablePolyWrapped,
E: CodablePolyWrapped,
F: CodablePolyWrapped,
G: CodablePolyWrapped,
H: CodablePolyWrapped,
I: CodablePolyWrapped,
J: CodablePolyWrapped,
K: CodablePolyWrapped,
L: CodablePolyWrapped,
M: CodablePolyWrapped {}
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,16 @@ public struct ResourceObjectDecodingError: Swift.Error, Equatable {
location = .type
}

let subjectPath: [CodingKey]
if location == .relationships && path.last?.stringValue == "data" {
subjectPath = path.dropLast()
} else {
subjectPath = path
}

return (
location,
name: path.last?.stringValue ?? "unnamed"
name: subjectPath.last?.stringValue ?? "unnamed"
)
}
}
Expand All @@ -130,15 +137,15 @@ extension ResourceObjectDecodingError: CustomStringConvertible {
case .keyNotFound where subjectName == ResourceObjectDecodingError.entireObject:
return "\(location) object is required and missing."
case .keyNotFound where location == .type:
return "'type' (a.k.a. JSON:API type name) is required and missing."
return "'type' (a.k.a. the JSON:API type name) is required and missing."
case .keyNotFound where location == .relationshipType:
return "'\(subjectName)' relationship does not have a 'type'."
case .keyNotFound where location == .relationshipId:
return "'\(subjectName)' relationship does not have an 'id'."
case .keyNotFound:
return "'\(subjectName)' \(location.singular) is required and missing."
case .valueNotFound where location == .type:
return "'\(location.singular)' (a.k.a. JSON:API type name) is not nullable but null was found."
return "'\(location.singular)' (a.k.a. the JSON:API type name) is not nullable but null was found."
case .valueNotFound:
return "'\(subjectName)' \(location.singular) is not nullable but null was found."
case .typeMismatch(expectedTypeName: let expected) where location == .type:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public struct ManyResourceObjectComparison: Equatable, PropertyComparison {
}
}

extension TestableResourceBody where TestablePrimaryResourceType: ResourceObjectType {
extension TestableResourceBody {
public func compare(to other: Self) -> PrimaryResourceBodyComparison {
guard let one = testableResourceObject,
let two = other.testableResourceObject else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ final class DocumentDecodingErrorTests: XCTestCase {
) { error in
guard let docError = error as? DocumentDecodingError,
case .primaryResourcesMissing = docError else {
XCTFail("Expected primary resource missing error. Got \(error)")
XCTFail("Expected primary resources missing error. Got \(error)")
return
}

Expand Down
69 changes: 69 additions & 0 deletions Tests/JSONAPITests/Includes/IncludeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,53 @@ class IncludedTests: XCTestCase {
test_DecodeEncodeEquality(type: Includes<Include11<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10, TestEntity11>>.self,
data: eleven_different_type_includes)
}

func test_TwelveDifferentIncludes() {
let includes = decoded(type: Includes<Include12<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10, TestEntity11, TestEntity12>>.self,
data: twelve_different_type_includes)

XCTAssertEqual(includes[TestEntity.self].count, 1)
XCTAssertEqual(includes[TestEntity2.self].count, 1)
XCTAssertEqual(includes[TestEntity3.self].count, 1)
XCTAssertEqual(includes[TestEntity4.self].count, 1)
XCTAssertEqual(includes[TestEntity5.self].count, 1)
XCTAssertEqual(includes[TestEntity6.self].count, 1)
XCTAssertEqual(includes[TestEntity7.self].count, 1)
XCTAssertEqual(includes[TestEntity8.self].count, 1)
XCTAssertEqual(includes[TestEntity9.self].count, 1)
XCTAssertEqual(includes[TestEntity10.self].count, 1)
XCTAssertEqual(includes[TestEntity11.self].count, 1)
XCTAssertEqual(includes[TestEntity12.self].count, 1)
}

func test_TwelveDifferentIncludes_encode() {
test_DecodeEncodeEquality(type: Includes<Include12<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10, TestEntity11, TestEntity12>>.self,
data: twelve_different_type_includes)
}

func test_ThirteenDifferentIncludes() {
let includes = decoded(type: Includes<Include13<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10, TestEntity11, TestEntity12, TestEntity13>>.self,
data: thirteen_different_type_includes)

XCTAssertEqual(includes[TestEntity.self].count, 1)
XCTAssertEqual(includes[TestEntity2.self].count, 1)
XCTAssertEqual(includes[TestEntity3.self].count, 1)
XCTAssertEqual(includes[TestEntity4.self].count, 1)
XCTAssertEqual(includes[TestEntity5.self].count, 1)
XCTAssertEqual(includes[TestEntity6.self].count, 1)
XCTAssertEqual(includes[TestEntity7.self].count, 1)
XCTAssertEqual(includes[TestEntity8.self].count, 1)
XCTAssertEqual(includes[TestEntity9.self].count, 1)
XCTAssertEqual(includes[TestEntity10.self].count, 1)
XCTAssertEqual(includes[TestEntity11.self].count, 1)
XCTAssertEqual(includes[TestEntity12.self].count, 1)
XCTAssertEqual(includes[TestEntity13.self].count, 1)
}

func test_ThirteenDifferentIncludes_encode() {
test_DecodeEncodeEquality(type: Includes<Include13<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10, TestEntity11, TestEntity12, TestEntity13>>.self,
data: thirteen_different_type_includes)
}
}

// MARK: - Appending
Expand Down Expand Up @@ -536,4 +583,26 @@ extension IncludedTests {
}

typealias TestEntity11 = BasicEntity<TestEntityType11>

enum TestEntityType12: ResourceObjectDescription {

typealias Attributes = NoAttributes

public static var jsonType: String { return "test_entity12" }

typealias Relationships = NoRelationships
}

typealias TestEntity12 = BasicEntity<TestEntityType12>

enum TestEntityType13: ResourceObjectDescription {

typealias Attributes = NoAttributes

public static var jsonType: String { return "test_entity13" }

typealias Relationships = NoRelationships
}

typealias TestEntity13 = BasicEntity<TestEntityType13>
}
Loading

0 comments on commit 661dfc3

Please sign in to comment.