From 86da8b1bbaa83daa1c9143a9bd260d3609ecb584 Mon Sep 17 00:00:00 2001 From: Terry Yiu <963907+tyiu@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:48:26 -0500 Subject: [PATCH] Add fake price fetcher for debug mode --- SatsPrice.xcodeproj/project.pbxproj | 6 +++++- SatsPrice/ContentView.swift | 14 +++++++++----- SatsPrice/Network/FakePriceFetcher.swift | 18 ++++++++++++++++++ SatsPrice/Network/PriceFetcherDelegator.swift | 13 ++++++++++++- SatsPrice/{ => Network}/PriceSource.swift | 17 +++++++++++++++++ SatsPrice/SatsPriceApp.swift | 2 +- 6 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 SatsPrice/Network/FakePriceFetcher.swift rename SatsPrice/{ => Network}/PriceSource.swift (60%) diff --git a/SatsPrice.xcodeproj/project.pbxproj b/SatsPrice.xcodeproj/project.pbxproj index 5173396..0de329d 100644 --- a/SatsPrice.xcodeproj/project.pbxproj +++ b/SatsPrice.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* 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 */; }; 3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3A02B83338D00DE5F31 /* SatsPrice.xcdatamodeld */; }; 3AE2D3A42B83338D00DE5F31 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE2D3A32B83338D00DE5F31 /* ContentView.swift */; }; @@ -43,6 +44,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 3A7B2AA22B86407A00ACC4A7 /* FakePriceFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakePriceFetcher.swift; sourceTree = ""; }; 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 = ""; }; 3AE2D3A12B83338D00DE5F31 /* SatsPrice.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = SatsPrice.xcdatamodel; sourceTree = ""; }; @@ -115,7 +117,6 @@ children = ( 3AE2D3E82B856B1800DE5F31 /* Network */, 3AE2D3A32B83338D00DE5F31 /* ContentView.swift */, - 3AE2D3E42B846A8600DE5F31 /* PriceSource.swift */, 3AE2D39C2B83338D00DE5F31 /* SatsPriceApp.swift */, 3AE2D3D42B83E58500DE5F31 /* SatsViewModel.swift */, 3AE2D3A52B83338D00DE5F31 /* Assets.xcassets */, @@ -157,8 +158,10 @@ children = ( 3AE2D3E02B8459D600DE5F31 /* CoinbasePriceFetcher.swift */, 3AE2D3E22B8461FE00DE5F31 /* CoinGeckoPriceFetcher.swift */, + 3A7B2AA22B86407A00ACC4A7 /* FakePriceFetcher.swift */, 3AE2D3DE2B84597100DE5F31 /* PriceFetcher.swift */, 3AE2D3E62B85690200DE5F31 /* PriceFetcherDelegator.swift */, + 3AE2D3E42B846A8600DE5F31 /* PriceSource.swift */, ); path = Network; sourceTree = ""; @@ -301,6 +304,7 @@ files = ( 3AE2D3E52B846A8600DE5F31 /* PriceSource.swift in Sources */, 3AE2D3E72B85690200DE5F31 /* PriceFetcherDelegator.swift in Sources */, + 3A7B2AA32B86407A00ACC4A7 /* FakePriceFetcher.swift in Sources */, 3AE2D3E12B8459D600DE5F31 /* CoinbasePriceFetcher.swift in Sources */, 3AE2D39D2B83338D00DE5F31 /* SatsPriceApp.swift in Sources */, 3AE2D3A22B83338D00DE5F31 /* SatsPrice.xcdatamodeld in Sources */, diff --git a/SatsPrice/ContentView.swift b/SatsPrice/ContentView.swift index 84b1df3..ee0cc10 100644 --- a/SatsPrice/ContentView.swift +++ b/SatsPrice/ContentView.swift @@ -12,15 +12,19 @@ import Combine struct ContentView: View { @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.timeStyle = .short + + self.priceSource = priceSource + priceFetcherDelegator = PriceFetcherDelegator(priceSource) } @MainActor @@ -107,5 +111,5 @@ struct ContentView: View { } #Preview { - ContentView() + ContentView(.fake) } diff --git a/SatsPrice/Network/FakePriceFetcher.swift b/SatsPrice/Network/FakePriceFetcher.swift new file mode 100644 index 0000000..6e90d05 --- /dev/null +++ b/SatsPrice/Network/FakePriceFetcher.swift @@ -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 diff --git a/SatsPrice/Network/PriceFetcherDelegator.swift b/SatsPrice/Network/PriceFetcherDelegator.swift index a60eeaf..6077003 100644 --- a/SatsPrice/Network/PriceFetcherDelegator.swift +++ b/SatsPrice/Network/PriceFetcherDelegator.swift @@ -11,8 +11,15 @@ import BigDecimal class PriceFetcherDelegator: PriceFetcher { private let coinbasePriceFetcher = CoinbasePriceFetcher() 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 { switch priceSource { @@ -20,6 +27,10 @@ class PriceFetcherDelegator: PriceFetcher { coinbasePriceFetcher case .coingecko: coinGeckoPriceFetcher +#if DEBUG + case .fake: + fakePriceFetcher +#endif } } diff --git a/SatsPrice/PriceSource.swift b/SatsPrice/Network/PriceSource.swift similarity index 60% rename from SatsPrice/PriceSource.swift rename to SatsPrice/Network/PriceSource.swift index 4fdf6c5..6631b80 100644 --- a/SatsPrice/PriceSource.swift +++ b/SatsPrice/Network/PriceSource.swift @@ -8,15 +8,32 @@ import Foundation enum PriceSource: CaseIterable, CustomStringConvertible { + + static var allCases: [PriceSource] { +#if DEBUG + [.coinbase, .coingecko, .fake] +#else + [.coinbase, .coingecko] +#endif + } + case coinbase case coingecko +#if DEBUG + case fake +#endif + var description: String { switch self { case .coinbase: "Coinbase" case .coingecko: "CoinGecko" +#if DEBUG + case .fake: + "Fake" +#endif } } } diff --git a/SatsPrice/SatsPriceApp.swift b/SatsPrice/SatsPriceApp.swift index 1317949..f11b8b0 100644 --- a/SatsPrice/SatsPriceApp.swift +++ b/SatsPrice/SatsPriceApp.swift @@ -11,7 +11,7 @@ import SwiftUI struct SatsPriceApp: App { var body: some Scene { WindowGroup { - ContentView() + ContentView(.coinbase) } } }