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

Commit

Permalink
test: add tests for dynamic JSON decoding with user context provider
Browse files Browse the repository at this point in the history
  • Loading branch information
soumyamahunt committed Jun 4, 2022
1 parent 79935b4 commit 74fd0b4
Show file tree
Hide file tree
Showing 13 changed files with 235 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ struct PostPage: Decodable {
### Type Aliases

- ``StrictDynamicDecodingArrayDictionaryWrapper``
- ``DefaultValueDynamicDecodingArrayDictionaryWrapper``
- ``LossyDynamicDecodingArrayDictionaryWrapper``
- ``StrictDynamicDecodingCollectionDictionaryWrapper``
- ``DefaultValueDynamicDecodingCollectionDictionaryWrapper``
- ``LossyDynamicDecodingCollectionDictionaryWrapper``
- ``OptionalPathCodingKeyWrapper``
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,3 @@ final class DynamicDecodingWrapperTests: XCTestCase {
XCTAssertNil(postPage.content)
}
}

struct SinglePostPage: Decodable {
let next: URL
@DynamicDecodingWrapper<PostCodingKey> var content: Post
}

struct OptionalSinglePostPage: Decodable {
let next: URL
@OptionalDynamicDecodingWrapper<PostCodingKey> var content: Post?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import XCTest
@testable import DynamicCodableKit

struct SinglePostPage: Decodable {
let next: URL
@DynamicDecodingWrapper<PostCodingKey> var content: Post
}

struct OptionalSinglePostPage: Decodable {
let next: URL
@OptionalDynamicDecodingWrapper<PostCodingKey> var content: Post?
}

struct ThrowingPostPage: Decodable {
let next: URL
@StrictDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
}

struct DefaultPostPage: Decodable {
let next: URL
@DefaultValueDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
}

struct LossyPostPage: Decodable {
let next: URL
@LossyDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
}

struct ThrowingPostPageSet: Decodable {
let next: URL
@StrictDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
}

struct DefaultPostPageSet: Decodable {
let next: URL
@DefaultValueDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
}

struct LossyPostPageSet: Decodable {
let next: URL
@LossyDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,3 @@ final class DynamicDecodingCollectionDictionaryWrapperTests: XCTestCase {
}
}
}

struct ThrowingKeyedPostPageCollection: Decodable {
let next: URL
@StrictDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
}

struct DefaultValueKeyedPostPageCollection: Decodable {
let next: URL
@DefaultValueDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
}

struct LossyKeyedPostPageCollection: Decodable {
let next: URL
@LossyDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,3 @@ final class DynamicDecodingDictionaryWrapperTests: XCTestCase {
postPage.content.forEach { XCTAssertEqual($1.type, $0) }
}
}

struct ThrowingKeyedPostPage: Decodable {
let next: URL
@StrictDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
}

struct LossyKeyedPostPage: Decodable {
let next: URL
@LossyDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import XCTest
@testable import DynamicCodableKit

struct ThrowingKeyedPostPage: Decodable {
let next: URL
@StrictDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
}

struct LossyKeyedPostPage: Decodable {
let next: URL
@LossyDynamicDecodingDictionaryWrapper<PostType> var content: [PostType: Post]
}

struct ThrowingKeyedPostPageCollection: Decodable {
let next: URL
@StrictDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
}

struct DefaultValueKeyedPostPageCollection: Decodable {
let next: URL
@DefaultValueDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
}

struct LossyKeyedPostPageCollection: Decodable {
let next: URL
@LossyDynamicDecodingArrayDictionaryWrapper<PostType> var content: [PostType: [Post]]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import XCTest
@testable import DynamicCodableKit

struct CommonPost: Decodable {
let id: UUID
let author: UUID
let likes: Int
let createdAt: String
@PathCodingKeyWrapper var type: PostType
}

struct OptionalTypeCommonPost: Decodable {
let id: UUID
let author: UUID
let likes: Int
let createdAt: String
@OptionalPathCodingKeyWrapper var type: PostType?
}

struct CommonPostPage: Decodable {
let next: URL
@PostData var content: [PostType: [CommonPost]]
}

struct ThrowingCommonPostPage: Decodable {
let next: URL
var content: [String: [CommonPost]]
}

struct OptionalTypeCommonPostPage: Decodable {
let next: URL
var content: [String: [OptionalTypeCommonPost]]
}

@propertyWrapper
struct PostData: Decodable {
public var wrappedValue: [PostType: [CommonPost]]

public init(wrappedValue: [PostType: [CommonPost]]) {
self.wrappedValue = wrappedValue
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: PostType.self)
self.wrappedValue = try container.allKeys.reduce(into: [:], { values, key in
values[key] = try container.decode([CommonPost].self, forKey: key)
})
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,50 +33,3 @@ final class PathCodingKeyWrapperTests: XCTestCase {
}
}
}

struct CommonPost: Decodable {
let id: UUID
let author: UUID
let likes: Int
let createdAt: String
@PathCodingKeyWrapper var type: PostType
}

struct OptionalTypeCommonPost: Decodable {
let id: UUID
let author: UUID
let likes: Int
let createdAt: String
@OptionalPathCodingKeyWrapper var type: PostType?
}

struct CommonPostPage: Decodable {
let next: URL
@PostData var content: [PostType: [CommonPost]]
}

struct ThrowingCommonPostPage: Decodable {
let next: URL
var content: [String: [CommonPost]]
}

struct OptionalTypeCommonPostPage: Decodable {
let next: URL
var content: [String: [OptionalTypeCommonPost]]
}

@propertyWrapper
struct PostData: Decodable {
public var wrappedValue: [PostType: [CommonPost]]

public init(wrappedValue: [PostType: [CommonPost]]) {
self.wrappedValue = wrappedValue
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: PostType.self)
self.wrappedValue = try container.allKeys.reduce(into: [:], { values, key in
values[key] = try container.decode([CommonPost].self, forKey: key)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import XCTest
@testable import DynamicCodableKit

final class DynamicDecodingCollectionContextBasedWrapperTests: XCTestCase {
func testDecoding() throws {
let url = Bundle.module.url(forResource: "identifier-collection-decode", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(withKey: PostCodingKey.self)
let postPage = try decoder.decode(ProviderBasedThrowingPostPage.self, from: data)
XCTAssertEqual(postPage.content.count, 4)
XCTAssertEqual(postPage.content.map(\.type), [.text, .picture, .audio, .video])
}

func testInvalidDataDecodingWithThrowConfig() throws {
let url = Bundle.module.url(forResource: "identifier-collection-decode-with-invalid-data", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
XCTAssertThrowsError(try decoder.decode(ProviderBasedThrowingPostPage.self, from: data))
}

func testInvalidDataDecodingWithDefaultConfig() throws {
let url = Bundle.module.url(forResource: "identifier-collection-decode-with-invalid-data", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(withKey: PostCodingKey.self)
let postPage = try decoder.decode(ProviderBasedDefaultPostPage.self, from: data)
XCTAssertEqual(postPage.content.count, 0)
}

func testInvalidDataDecodingWithLossyConfig() throws {
let url = Bundle.module.url(forResource: "identifier-collection-decode-with-invalid-data", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(withKey: PostCodingKey.self)
let postPage = try decoder.decode(ProviderBasedLossyPostPage.self, from: data)
XCTAssertEqual(postPage.content.count, 4)
XCTAssertEqual(postPage.content.map(\.type), [.text, .picture, .audio, .video])
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import XCTest
@testable import DynamicCodableKit

final class DynamicDecodingContextBasedWrapperTests: XCTestCase {
func testDecoding() throws {
let url = Bundle.module.url(forResource: "identifier-decode", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(decoding: VideoPost.self)
let postPage = try decoder.decode(ProviderBasedSinglePostPage.self, from: data)
XCTAssertEqual(postPage.content.type, .video)
XCTAssertEqual(postPage.content.likes, 2345)
}

func testOptionalDecoding() throws {
let url = Bundle.module.url(forResource: "identifier-decode", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
decoder.userInfo[.postKey] = DynamicDecodingContext<Post>(decoding: VideoPost.self)
let postPage = try decoder.decode(ProviderBasedOptionalSinglePostPage.self, from: data)
XCTAssertEqual(postPage.content?.type, .video)
XCTAssertEqual(postPage.content?.likes, 2345)
}

func testInvalidDataDecodingWithThrowConfig() throws {
let url = Bundle.module.url(forResource: "identifier-decode-with-invalid-data", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
XCTAssertThrowsError(try decoder.decode(ProviderBasedSinglePostPage.self, from: data))
}

func testInvalidDataDecodingWithDefaultConfig() throws {
let url = Bundle.module.url(forResource: "identifier-decode-with-invalid-data", withExtension: "json")!
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
let postPage = try decoder.decode(ProviderBasedOptionalSinglePostPage.self, from: data)
XCTAssertNil(postPage.content)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import XCTest
@testable import DynamicCodableKit

extension CodingUserInfoKey {
static let postKey = CodingUserInfoKey(rawValue: "post_key")!
}

struct PostDecodingProvider: UserInfoDynamicDecodingContextProvider {
typealias Identified = Post
static var infoKey: CodingUserInfoKey { .postKey }
}

struct ProviderBasedSinglePostPage: Decodable {
let next: URL
@DynamicDecodingContextBasedWrapper<PostDecodingProvider> var content: Post
}

struct ProviderBasedOptionalSinglePostPage: Decodable {
let next: URL
@OptionalDynamicDecodingContextBasedWrapper<PostDecodingProvider> var content: Post?
}

struct ProviderBasedThrowingPostPage: Decodable {
let next: URL
@StrictDynamicDecodingArrayContextBasedWrapper<PostDecodingProvider> var content: [Post]
}

struct ProviderBasedDefaultPostPage: Decodable {
let next: URL
@DefaultValueDynamicDecodingArrayContextBasedWrapper<PostDecodingProvider> var content: [Post]
}

struct ProviderBasedLossyPostPage: Decodable {
let next: URL
@LossyDynamicDecodingArrayContextBasedWrapper<PostDecodingProvider> var content: [Post]
}
15 changes: 0 additions & 15 deletions Tests/DynamicCodableKitTests/Models/HashablePost.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,3 @@ enum PostSetCodingKey: String, DynamicDecodingContextIdentifierCodingKey {
case type
static var identifierCodingKey: Self { .type }
}

struct ThrowingPostPageSet: Decodable {
let next: URL
@StrictDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
}

struct DefaultPostPageSet: Decodable {
let next: URL
@DefaultValueDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
}

struct LossyPostPageSet: Decodable {
let next: URL
@LossyDynamicDecodingCollectionWrapper<PostSetCodingKey, Set<AnyPost<Post>>> var content: Set<AnyPost<Post>>
}
15 changes: 0 additions & 15 deletions Tests/DynamicCodableKitTests/Models/Post.swift
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,3 @@ enum PostCodingKey: String, DynamicDecodingContextIdentifierCodingKey {
case type
static var identifierCodingKey: Self { .type }
}

struct ThrowingPostPage: Decodable {
let next: URL
@StrictDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
}

struct DefaultPostPage: Decodable {
let next: URL
@DefaultValueDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
}

struct LossyPostPage: Decodable {
let next: URL
@LossyDynamicDecodingArrayWrapper<PostCodingKey> var content: [Post]
}

0 comments on commit 74fd0b4

Please sign in to comment.