Skip to content
This repository was archived by the owner on Jan 11, 2024. It is now read-only.

Commit 74fd0b4

Browse files
committed
test: add tests for dynamic JSON decoding with user context provider
1 parent 79935b4 commit 74fd0b4

13 files changed

Lines changed: 235 additions & 112 deletions

File tree

Sources/DynamicCodableKit/DynamicCodableKit.docc/Guides/ContainerCodingKey.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,9 @@ struct PostPage: Decodable {
112112
### Type Aliases
113113

114114
- ``StrictDynamicDecodingArrayDictionaryWrapper``
115+
- ``DefaultValueDynamicDecodingArrayDictionaryWrapper``
115116
- ``LossyDynamicDecodingArrayDictionaryWrapper``
116117
- ``StrictDynamicDecodingCollectionDictionaryWrapper``
118+
- ``DefaultValueDynamicDecodingCollectionDictionaryWrapper``
117119
- ``LossyDynamicDecodingCollectionDictionaryWrapper``
118120
- ``OptionalPathCodingKeyWrapper``

Tests/DynamicCodableKitTests/DynamicDecodingContextCodingKey/DynamicDecodingWrapper.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,3 @@ final class DynamicDecodingWrapperTests: XCTestCase {
3535
XCTAssertNil(postPage.content)
3636
}
3737
}
38-
39-
struct SinglePostPage: Decodable {
40-
let next: URL
41-
@DynamicDecodingWrapper<PostCodingKey> var content: Post
42-
}
43-
44-
struct OptionalSinglePostPage: Decodable {
45-
let next: URL
46-
@OptionalDynamicDecodingWrapper<PostCodingKey> var content: Post?
47-
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import XCTest
2+
@testable import DynamicCodableKit
3+
4+
struct SinglePostPage: Decodable {
5+
let next: URL
6+
@DynamicDecodingWrapper<PostCodingKey> var content: Post
7+
}
8+
9+
struct OptionalSinglePostPage: Decodable {
10+
let next: URL
11+
@OptionalDynamicDecodingWrapper<PostCodingKey> var content: Post?
12+
}
13+
14+
struct ThrowingPostPage: Decodable {
15+
let next: URL
16+
@StrictDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
17+
}
18+
19+
struct DefaultPostPage: Decodable {
20+
let next: URL
21+
@DefaultValueDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
22+
}
23+
24+
struct LossyPostPage: Decodable {
25+
let next: URL
26+
@LossyDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
27+
}
28+
29+
struct ThrowingPostPageSet: Decodable {
30+
let next: URL
31+
@StrictDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
32+
}
33+
34+
struct DefaultPostPageSet: Decodable {
35+
let next: URL
36+
@DefaultValueDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
37+
}
38+
39+
struct LossyPostPageSet: Decodable {
40+
let next: URL
41+
@LossyDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
42+
}

Tests/DynamicCodableKitTests/DynamicDecodingContextContainerCodingKey/DynamicDecodingCollectionDictionaryWrapper.swift

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,3 @@ final class DynamicDecodingCollectionDictionaryWrapperTests: XCTestCase {
5050
}
5151
}
5252
}
53-
54-
struct ThrowingKeyedPostPageCollection: Decodable {
55-
let next: URL
56-
@StrictDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
57-
}
58-
59-
struct DefaultValueKeyedPostPageCollection: Decodable {
60-
let next: URL
61-
@DefaultValueDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
62-
}
63-
64-
struct LossyKeyedPostPageCollection: Decodable {
65-
let next: URL
66-
@LossyDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
67-
}

Tests/DynamicCodableKitTests/DynamicDecodingContextContainerCodingKey/DynamicDecodingDictionaryWrapper.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,3 @@ final class DynamicDecodingDictionaryWrapperTests: XCTestCase {
2929
postPage.content.forEach { XCTAssertEqual($1.type, $0) }
3030
}
3131
}
32-
33-
struct ThrowingKeyedPostPage: Decodable {
34-
let next: URL
35-
@StrictDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
36-
}
37-
38-
struct LossyKeyedPostPage: Decodable {
39-
let next: URL
40-
@LossyDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
41-
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import XCTest
2+
@testable import DynamicCodableKit
3+
4+
struct ThrowingKeyedPostPage: Decodable {
5+
let next: URL
6+
@StrictDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
7+
}
8+
9+
struct LossyKeyedPostPage: Decodable {
10+
let next: URL
11+
@LossyDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
12+
}
13+
14+
struct ThrowingKeyedPostPageCollection: Decodable {
15+
let next: URL
16+
@StrictDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
17+
}
18+
19+
struct DefaultValueKeyedPostPageCollection: Decodable {
20+
let next: URL
21+
@DefaultValueDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
22+
}
23+
24+
struct LossyKeyedPostPageCollection: Decodable {
25+
let next: URL
26+
@LossyDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
27+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import XCTest
2+
@testable import DynamicCodableKit
3+
4+
struct CommonPost: Decodable {
5+
let id: UUID
6+
let author: UUID
7+
let likes: Int
8+
let createdAt: String
9+
@PathCodingKeyWrapper var type: PostType
10+
}
11+
12+
struct OptionalTypeCommonPost: Decodable {
13+
let id: UUID
14+
let author: UUID
15+
let likes: Int
16+
let createdAt: String
17+
@OptionalPathCodingKeyWrapper var type: PostType?
18+
}
19+
20+
struct CommonPostPage: Decodable {
21+
let next: URL
22+
@PostData var content: [PostType: [CommonPost]]
23+
}
24+
25+
struct ThrowingCommonPostPage: Decodable {
26+
let next: URL
27+
var content: [String: [CommonPost]]
28+
}
29+
30+
struct OptionalTypeCommonPostPage: Decodable {
31+
let next: URL
32+
var content: [String: [OptionalTypeCommonPost]]
33+
}
34+
35+
@propertyWrapper
36+
struct PostData: Decodable {
37+
public var wrappedValue: [PostType: [CommonPost]]
38+
39+
public init(wrappedValue: [PostType: [CommonPost]]) {
40+
self.wrappedValue = wrappedValue
41+
}
42+
43+
public init(from decoder: Decoder) throws {
44+
let container = try decoder.container(keyedBy: PostType.self)
45+
self.wrappedValue = try container.allKeys.reduce(into: [:], { values, key in
46+
values[key] = try container.decode([CommonPost].self, forKey: key)
47+
})
48+
}
49+
}

Tests/DynamicCodableKitTests/DynamicDecodingContextContainerCodingKey/PathCodingKeyWrapper.swift

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -33,50 +33,3 @@ final class PathCodingKeyWrapperTests: XCTestCase {
3333
}
3434
}
3535
}
36-
37-
struct CommonPost: Decodable {
38-
let id: UUID
39-
let author: UUID
40-
let likes: Int
41-
let createdAt: String
42-
@PathCodingKeyWrapper var type: PostType
43-
}
44-
45-
struct OptionalTypeCommonPost: Decodable {
46-
let id: UUID
47-
let author: UUID
48-
let likes: Int
49-
let createdAt: String
50-
@OptionalPathCodingKeyWrapper var type: PostType?
51-
}
52-
53-
struct CommonPostPage: Decodable {
54-
let next: URL
55-
@PostData var content: [PostType: [CommonPost]]
56-
}
57-
58-
struct ThrowingCommonPostPage: Decodable {
59-
let next: URL
60-
var content: [String: [CommonPost]]
61-
}
62-
63-
struct OptionalTypeCommonPostPage: Decodable {
64-
let next: URL
65-
var content: [String: [OptionalTypeCommonPost]]
66-
}
67-
68-
@propertyWrapper
69-
struct PostData: Decodable {
70-
public var wrappedValue: [PostType: [CommonPost]]
71-
72-
public init(wrappedValue: [PostType: [CommonPost]]) {
73-
self.wrappedValue = wrappedValue
74-
}
75-
76-
public init(from decoder: Decoder) throws {
77-
let container = try decoder.container(keyedBy: PostType.self)
78-
self.wrappedValue = try container.allKeys.reduce(into: [:], { values, key in
79-
values[key] = try container.decode([CommonPost].self, forKey: key)
80-
})
81-
}
82-
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import XCTest
2+
@testable import DynamicCodableKit
3+
4+
final class DynamicDecodingCollectionContextBasedWrapperTests: XCTestCase {
5+
func testDecoding() throws {
6+
let url = Bundle.module.url(forResource: "identifier-collection-decode", withExtension: "json")!
7+
let data = try Data(contentsOf: url)
8+
let decoder = JSONDecoder()
9+
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(withKey: PostCodingKey.self)
10+
let postPage = try decoder.decode(ProviderBasedThrowingPostPage.self, from: data)
11+
XCTAssertEqual(postPage.content.count, 4)
12+
XCTAssertEqual(postPage.content.map(\.type), [.text, .picture, .audio, .video])
13+
}
14+
15+
func testInvalidDataDecodingWithThrowConfig() throws {
16+
let url = Bundle.module.url(forResource: "identifier-collection-decode-with-invalid-data", withExtension: "json")!
17+
let data = try Data(contentsOf: url)
18+
let decoder = JSONDecoder()
19+
XCTAssertThrowsError(try decoder.decode(ProviderBasedThrowingPostPage.self, from: data))
20+
}
21+
22+
func testInvalidDataDecodingWithDefaultConfig() throws {
23+
let url = Bundle.module.url(forResource: "identifier-collection-decode-with-invalid-data", withExtension: "json")!
24+
let data = try Data(contentsOf: url)
25+
let decoder = JSONDecoder()
26+
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(withKey: PostCodingKey.self)
27+
let postPage = try decoder.decode(ProviderBasedDefaultPostPage.self, from: data)
28+
XCTAssertEqual(postPage.content.count, 0)
29+
}
30+
31+
func testInvalidDataDecodingWithLossyConfig() throws {
32+
let url = Bundle.module.url(forResource: "identifier-collection-decode-with-invalid-data", withExtension: "json")!
33+
let data = try Data(contentsOf: url)
34+
let decoder = JSONDecoder()
35+
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(withKey: PostCodingKey.self)
36+
let postPage = try decoder.decode(ProviderBasedLossyPostPage.self, from: data)
37+
XCTAssertEqual(postPage.content.count, 4)
38+
XCTAssertEqual(postPage.content.map(\.type), [.text, .picture, .audio, .video])
39+
}
40+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import XCTest
2+
@testable import DynamicCodableKit
3+
4+
final class DynamicDecodingContextBasedWrapperTests: XCTestCase {
5+
func testDecoding() throws {
6+
let url = Bundle.module.url(forResource: "identifier-decode", withExtension: "json")!
7+
let data = try Data(contentsOf: url)
8+
let decoder = JSONDecoder()
9+
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(decoding: VideoPost.self)
10+
let postPage = try decoder.decode(ProviderBasedSinglePostPage.self, from: data)
11+
XCTAssertEqual(postPage.content.type, .video)
12+
XCTAssertEqual(postPage.content.likes, 2345)
13+
}
14+
15+
func testOptionalDecoding() throws {
16+
let url = Bundle.module.url(forResource: "identifier-decode", withExtension: "json")!
17+
let data = try Data(contentsOf: url)
18+
let decoder = JSONDecoder()
19+
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(decoding: VideoPost.self)
20+
let postPage = try decoder.decode(ProviderBasedOptionalSinglePostPage.self, from: data)
21+
XCTAssertEqual(postPage.content?.type, .video)
22+
XCTAssertEqual(postPage.content?.likes, 2345)
23+
}
24+
25+
func testInvalidDataDecodingWithThrowConfig() throws {
26+
let url = Bundle.module.url(forResource: "identifier-decode-with-invalid-data", withExtension: "json")!
27+
let data = try Data(contentsOf: url)
28+
let decoder = JSONDecoder()
29+
XCTAssertThrowsError(try decoder.decode(ProviderBasedSinglePostPage.self, from: data))
30+
}
31+
32+
func testInvalidDataDecodingWithDefaultConfig() throws {
33+
let url = Bundle.module.url(forResource: "identifier-decode-with-invalid-data", withExtension: "json")!
34+
let data = try Data(contentsOf: url)
35+
let decoder = JSONDecoder()
36+
let postPage = try decoder.decode(ProviderBasedOptionalSinglePostPage.self, from: data)
37+
XCTAssertNil(postPage.content)
38+
}
39+
}

0 commit comments

Comments
 (0)