|
| 1 | +// |
| 2 | +// MockItemProvider.swift |
| 3 | +// ViewStore |
| 4 | +// |
| 5 | +// Created by Michael Liberatore on 7/11/22. |
| 6 | +// |
| 7 | + |
| 8 | +import Foundation |
| 9 | +import Combine |
| 10 | +import Provider |
| 11 | +import Persister |
| 12 | +import Networking |
| 13 | + |
| 14 | +/// A provider meant to be usable by SwiftUI previews and unit tests to provide mocked, successful `Photo`s synchronously. |
| 15 | +final class MockItemProvider: Provider { |
| 16 | + private let photos: [Photo] |
| 17 | + |
| 18 | + /// Creates a new `MockItemProvider` with the specified `Photo`s. |
| 19 | + /// - Parameter photos: the `Photo`s that the provider will "retrieve" synchronously. |
| 20 | + init(photos: [Photo]) { |
| 21 | + self.photos = photos |
| 22 | + } |
| 23 | + |
| 24 | + /// Creates a new `MockItemProvider` by generating a `Photo` for each `Int` within the range of `(1...photosCount)`. |
| 25 | + /// - Parameter photosCount: The number of photos to generate. Note that the bundle must contain images named with the pattern "thumbnail-x.png" where x can be all values between `1` and `photosCount` (inclusive). |
| 26 | + init(photosCount: Int) { |
| 27 | + self.photos = (1...photosCount).map { index in |
| 28 | + let url = Bundle.main.url(forResource: "thumbnail-\(index)", withExtension: "png")! |
| 29 | + return Photo(albumId: 0, id: index, title: "Hello-\(index)", url: url, thumbnailUrl: url) |
| 30 | + } |
| 31 | + } |
| 32 | + |
| 33 | + // MARK: - Provider |
| 34 | + |
| 35 | + func provide<Item>(request: ProviderRequest, decoder: ItemDecoder, providerBehaviors: [ProviderBehavior], requestBehaviors: [RequestBehavior], handlerQueue: DispatchQueue, allowExpiredItem: Bool, itemHandler: @escaping (Result<Item, ProviderError>) -> Void) where Item : Identifiable, Item : Decodable, Item : Encodable { |
| 36 | + itemHandler((photos.first as? Item).flatMap { .success($0) } ?? .failure(.networkError(.noData))) |
| 37 | + } |
| 38 | + |
| 39 | + func provideItems<Item>(request: ProviderRequest, decoder: ItemDecoder, providerBehaviors: [ProviderBehavior], requestBehaviors: [RequestBehavior], handlerQueue: DispatchQueue, allowExpiredItems: Bool, itemsHandler: @escaping (Result<[Item], ProviderError>) -> Void) where Item : Identifiable, Item : Decodable, Item : Encodable { |
| 40 | + itemsHandler((photos as? [Item]).flatMap { .success($0) } ?? .failure(.networkError(.noData))) |
| 41 | + } |
| 42 | + |
| 43 | + func provide<Item>(request: ProviderRequest, decoder: ItemDecoder, providerBehaviors: [ProviderBehavior], requestBehaviors: [RequestBehavior], allowExpiredItem: Bool) -> AnyPublisher<Item, ProviderError> where Item : Identifiable, Item : Decodable, Item : Encodable { |
| 44 | + if let item = photos.first as? Item { |
| 45 | + return Just(item) |
| 46 | + .setFailureType(to: ProviderError.self) |
| 47 | + .eraseToAnyPublisher() |
| 48 | + } else { |
| 49 | + return Fail(error: ProviderError.networkError(.noData)) |
| 50 | + .eraseToAnyPublisher() |
| 51 | + } |
| 52 | + } |
| 53 | + |
| 54 | + func provideItems<Item>(request: ProviderRequest, decoder: ItemDecoder, providerBehaviors: [ProviderBehavior], requestBehaviors: [RequestBehavior], allowExpiredItems: Bool) -> AnyPublisher<[Item], ProviderError> where Item : Identifiable, Item : Decodable, Item : Encodable { |
| 55 | + if let items = photos as? [Item] { |
| 56 | + return Just(items) |
| 57 | + .setFailureType(to: ProviderError.self) |
| 58 | + .eraseToAnyPublisher() |
| 59 | + } else { |
| 60 | + return Fail(error: ProviderError.networkError(.noData)) |
| 61 | + .eraseToAnyPublisher() |
| 62 | + } |
| 63 | + } |
| 64 | +} |
0 commit comments