Skip to content

Commit dd5f3b1

Browse files
committed
Added check for nullable array attributes
1 parent 7d7b3d7 commit dd5f3b1

4 files changed

Lines changed: 38 additions & 7 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ To create an Xcode project for JSONAPI, run
7676
- [x] `meta`
7777

7878
### Entity Validator (using reflection)
79-
- [ ] Disallow optional array in `Attribute` and `Relationship` (should be empty array, not `null`).
79+
- [x] Disallow optional array in `Attribute` (should be empty array, not `null`).
8080
- [x] Only allow `TransformedAttribute` and its derivatives within `Attributes` struct.
8181
- [x] Only allow `ToManyRelationship` and `ToOneRelationship` within `Relationships` struct.
8282

Sources/JSONAPITestLib/EntityCheck.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,28 @@ import JSONAPI
1010
public enum EntityCheckError: Swift.Error {
1111
case attributesNotStruct
1212
case relationshipsNotStruct
13-
case badAttribute(named: String)
14-
case badRelationship(named: String)
13+
case nonAttribute(named: String)
14+
case nonRelationship(named: String)
15+
case nullArray(named: String)
1516
case badId
1617
}
1718

1819
public struct EntityCheckErrors: Swift.Error {
1920
let problems: [EntityCheckError]
2021
}
2122

22-
public protocol OptionalAttributeType {}
23-
23+
private protocol OptionalAttributeType {}
2424
extension Optional: OptionalAttributeType where Wrapped: AttributeType {}
2525

26+
private protocol OptionalArray {}
27+
extension Optional: OptionalArray where Wrapped: ArrayType {}
28+
29+
private protocol AttributeTypeWithOptionalArray {}
30+
extension TransformedAttribute: AttributeTypeWithOptionalArray where RawValue: OptionalArray {}
31+
32+
private protocol OptionalRelationshipType {}
33+
extension Optional: OptionalRelationshipType where Wrapped: RelationshipType {}
34+
2635
public extension Entity {
2736
public static func check(_ entity: Entity) throws {
2837
var problems = [EntityCheckError]()
@@ -40,7 +49,10 @@ public extension Entity {
4049
for attribute in attributesMirror.children {
4150
if attribute.value as? AttributeType == nil,
4251
attribute.value as? OptionalAttributeType == nil {
43-
problems.append(.badAttribute(named: attribute.label ?? "unnamed"))
52+
problems.append(.nonAttribute(named: attribute.label ?? "unnamed"))
53+
}
54+
if attribute.value as? AttributeTypeWithOptionalArray != nil {
55+
problems.append(.nullArray(named: attribute.label ?? "unnamed"))
4456
}
4557
}
4658

@@ -52,7 +64,7 @@ public extension Entity {
5264

5365
for relationship in relationshipsMirror.children {
5466
if relationship.value as? RelationshipType == nil {
55-
problems.append(.badRelationship(named: relationship.label ?? "unnamed"))
67+
problems.append(.nonRelationship(named: relationship.label ?? "unnamed"))
5668
}
5769
}
5870

Tests/JSONAPITests/TestLib/EntityCheckTests.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ class EntityCheckTests: XCTestCase {
3636
let entity = BadRelationshipEntity(relationships: .init(x: OkEntity().pointer, y: OkEntity().id))
3737
XCTAssertThrowsError(try BadRelationshipEntity.check(entity))
3838
}
39+
40+
func test_failsWithOptionalArrayAttribute() {
41+
let entity = OptionalArrayAttributeEntity(attributes: .init(x: ["hello"], y: nil))
42+
XCTAssertThrowsError(try OptionalArrayAttributeEntity.check(entity))
43+
}
3944
}
4045

4146
// MARK: - Test types
@@ -121,4 +126,17 @@ extension EntityCheckTests {
121126
}
122127

123128
public typealias BadRelationshipEntity = Entity<BadRelationshipDescription>
129+
130+
enum OptionalArrayAttributeDescription: EntityDescription {
131+
public static var type: String { return "hello" }
132+
133+
public struct Attributes: JSONAPI.Attributes {
134+
let x: Attribute<[String]>
135+
let y: Attribute<[String]?>
136+
}
137+
138+
public typealias Relationships = NoRelationships
139+
}
140+
141+
public typealias OptionalArrayAttributeEntity = Entity<OptionalArrayAttributeDescription>
124142
}

Tests/JSONAPITests/XCTestManifests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ extension EntityCheckTests {
7474
("test_failsWithBadRelationship", test_failsWithBadRelationship),
7575
("test_failsWithEnumAttributes", test_failsWithEnumAttributes),
7676
("test_failsWithEnumRelationships", test_failsWithEnumRelationships),
77+
("test_failsWithOptionalArrayAttribute", test_failsWithOptionalArrayAttribute),
7778
]
7879
}
7980

0 commit comments

Comments
 (0)