Add fake price fetcher for debug mode

This commit is contained in:
2024-02-21 09:48:26 -05:00
parent e9c44eec2c
commit 86da8b1bba
6 changed files with 62 additions and 8 deletions

View File

@@ -7,6 +7,7 @@
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
3A7B2AA32B86407A00ACC4A7 /* FakePriceFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A7B2AA22B86407A00ACC4A7 /* FakePriceFetcher.swift */; };
3AE2D39D2B83338D00DE5F31 /* SatsPriceApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */; }; 3AE2D39D2B83338D00DE5F31 /* SatsPriceApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */; };
3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3A02B83338D00DE5F31 /* SatsPrice.xcdatamodeld */; }; 3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3A02B83338D00DE5F31 /* SatsPrice.xcdatamodeld */; };
3AE2D3A42B83338D00DE5F31 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3A32B83338D00DE5F31 /* ContentView.swift */; }; 3AE2D3A42B83338D00DE5F31 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3A32B83338D00DE5F31 /* ContentView.swift */; };
@@ -43,6 +44,7 @@
/* End PBXContainerItemProxy section */ /* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
3A7B2AA22B86407A00ACC4A7 /* FakePriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakePriceFetcher.swift; sourceTree = "<group>"; };
3AE2D3992B83338D00DE5F31 /* SatsPrice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SatsPrice.app; sourceTree = BUILT_PRODUCTS_DIR; }; 3AE2D3992B83338D00DE5F31 /* SatsPrice.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SatsPrice.app; sourceTree = BUILT_PRODUCTS_DIR; };
3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsPriceApp.swift; sourceTree = "<group>"; }; 3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SatsPriceApp.swift; sourceTree = "<group>"; };
3AE2D3A12B83338D00DE5F31 /* SatsPrice.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = SatsPrice.xcdatamodel; sourceTree = "<group>"; }; 3AE2D3A12B83338D00DE5F31 /* SatsPrice.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = SatsPrice.xcdatamodel; sourceTree = "<group>"; };
@@ -115,7 +117,6 @@
children = ( children = (
3AE2D3E82B856B1800DE5F31 /* Network */, 3AE2D3E82B856B1800DE5F31 /* Network */,
3AE2D3A32B83338D00DE5F31 /* ContentView.swift */, 3AE2D3A32B83338D00DE5F31 /* ContentView.swift */,
3AE2D3E42B846A8600DE5F31 /* PriceSource.swift */,
3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */, 3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */,
3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */, 3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */,
3AE2D3A52B83338D00DE5F31 /* Assets.xcassets */, 3AE2D3A52B83338D00DE5F31 /* Assets.xcassets */,
@@ -157,8 +158,10 @@
children = ( children = (
3AE2D3E02B8459D600DE5F31 /* CoinbasePriceFetcher.swift */, 3AE2D3E02B8459D600DE5F31 /* CoinbasePriceFetcher.swift */,
3AE2D3E22B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift */, 3AE2D3E22B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift */,
3A7B2AA22B86407A00ACC4A7 /* FakePriceFetcher.swift */,
3AE2D3DE2B84597100DE5F31 /* PriceFetcher.swift */, 3AE2D3DE2B84597100DE5F31 /* PriceFetcher.swift */,
3AE2D3E62B85690200DE5F31 /* PriceFetcherDelegator.swift */, 3AE2D3E62B85690200DE5F31 /* PriceFetcherDelegator.swift */,
3AE2D3E42B846A8600DE5F31 /* PriceSource.swift */,
); );
path = Network; path = Network;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -301,6 +304,7 @@
files = ( files = (
3AE2D3E52B846A8600DE5F31 /* PriceSource.swift in Sources */, 3AE2D3E52B846A8600DE5F31 /* PriceSource.swift in Sources */,
3AE2D3E72B85690200DE5F31 /* PriceFetcherDelegator.swift in Sources */, 3AE2D3E72B85690200DE5F31 /* PriceFetcherDelegator.swift in Sources */,
3A7B2AA32B86407A00ACC4A7 /* FakePriceFetcher.swift in Sources */,
3AE2D3E12B8459D600DE5F31 /* CoinbasePriceFetcher.swift in Sources */, 3AE2D3E12B8459D600DE5F31 /* CoinbasePriceFetcher.swift in Sources */,
3AE2D39D2B83338D00DE5F31 /* SatsPriceApp.swift in Sources */, 3AE2D39D2B83338D00DE5F31 /* SatsPriceApp.swift in Sources */,
3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */, 3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */,

View File

@@ -12,15 +12,19 @@ import Combine
struct ContentView: View { struct ContentView: View {
@ObservedObject private var satsViewModel = SatsViewModel() @ObservedObject private var satsViewModel = SatsViewModel()
@State private var priceSource: PriceSource = .coinbase @State private var priceSource: PriceSource
private let dateFormatter = DateFormatter() private let dateFormatter: DateFormatter
private let priceFetcherDelegator = PriceFetcherDelegator() private let priceFetcherDelegator: PriceFetcherDelegator
init() { init(_ priceSource: PriceSource) {
dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short dateFormatter.timeStyle = .short
self.priceSource = priceSource
priceFetcherDelegator = PriceFetcherDelegator(priceSource)
} }
@MainActor @MainActor
@@ -107,5 +111,5 @@ struct ContentView: View {
} }
#Preview { #Preview {
ContentView() ContentView(.fake)
} }

View File

@@ -0,0 +1,18 @@
//
// FakePriceFetcher.swift
// SatsPrice
//
// Created by Terry Yiu on 2/21/24.
//
#if DEBUG
import Foundation
import BigDecimal
/// Fake price fetcher that returns a randomized price. Useful for development testing without requiring a network call.
class FakePriceFetcher: PriceFetcher {
func btcToUsd() async throws -> BigDecimal? {
BigDecimal(Double.random(in: 10000...100000))
}
}
#endif

View File

@@ -11,8 +11,15 @@ import BigDecimal
class PriceFetcherDelegator: PriceFetcher { class PriceFetcherDelegator: PriceFetcher {
private let coinbasePriceFetcher = CoinbasePriceFetcher() private let coinbasePriceFetcher = CoinbasePriceFetcher()
private let coinGeckoPriceFetcher = CoinGeckoPriceFetcher() private let coinGeckoPriceFetcher = CoinGeckoPriceFetcher()
#if DEBUG
private let fakePriceFetcher = FakePriceFetcher()
#endif
var priceSource: PriceSource = .coinbase var priceSource: PriceSource
init(_ priceSource: PriceSource) {
self.priceSource = priceSource
}
private var delegate: PriceFetcher { private var delegate: PriceFetcher {
switch priceSource { switch priceSource {
@@ -20,6 +27,10 @@ class PriceFetcherDelegator: PriceFetcher {
coinbasePriceFetcher coinbasePriceFetcher
case .coingecko: case .coingecko:
coinGeckoPriceFetcher coinGeckoPriceFetcher
#if DEBUG
case .fake:
fakePriceFetcher
#endif
} }
} }

View File

@@ -8,15 +8,32 @@
import Foundation import Foundation
enum PriceSource: CaseIterable, CustomStringConvertible { enum PriceSource: CaseIterable, CustomStringConvertible {
static var allCases: [PriceSource] {
#if DEBUG
[.coinbase, .coingecko, .fake]
#else
[.coinbase, .coingecko]
#endif
}
case coinbase case coinbase
case coingecko case coingecko
#if DEBUG
case fake
#endif
var description: String { var description: String {
switch self { switch self {
case .coinbase: case .coinbase:
"Coinbase" "Coinbase"
case .coingecko: case .coingecko:
"CoinGecko" "CoinGecko"
#if DEBUG
case .fake:
"Fake"
#endif
} }
} }
} }

View File

@@ -11,7 +11,7 @@ import SwiftUI
struct SatsPriceApp: App { struct SatsPriceApp: App {
var body: some Scene { var body: some Scene {
WindowGroup { WindowGroup {
ContentView() ContentView(.coinbase)
} }
} }
} }