-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
15 changed files
with
357 additions
and
0 deletions.
There are no files selected for viewing
72 changes: 72 additions & 0 deletions
72
Core/.swiftpm/xcode/xcshareddata/xcschemes/AboutPresentationTests.xcscheme
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Scheme | ||
LastUpgradeVersion = "1510" | ||
version = "1.7"> | ||
<BuildAction | ||
parallelizeBuildables = "YES" | ||
buildImplicitDependencies = "YES"> | ||
</BuildAction> | ||
<TestAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
shouldAutocreateTestPlan = "YES"> | ||
<Testables> | ||
<TestableReference | ||
skipped = "NO"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "AboutPresentationTests" | ||
BuildableName = "AboutPresentationTests" | ||
BlueprintName = "AboutPresentationTests" | ||
ReferencedContainer = "container:"> | ||
</BuildableReference> | ||
</TestableReference> | ||
</Testables> | ||
</TestAction> | ||
<LaunchAction | ||
buildConfiguration = "Debug" | ||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
launchStyle = "0" | ||
useCustomWorkingDirectory = "NO" | ||
ignoresPersistentStateOnLaunch = "NO" | ||
debugDocumentVersioning = "YES" | ||
debugServiceExtension = "internal" | ||
allowLocationSimulation = "YES"> | ||
<BuildableProductRunnable | ||
runnableDebuggingMode = "0"> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "6BD0FF1A2AF64E7F00CC9579" | ||
BuildableName = "Swiftly.app" | ||
BlueprintName = "Swiftly" | ||
ReferencedContainer = "container:../Swiftly.xcodeproj"> | ||
</BuildableReference> | ||
</BuildableProductRunnable> | ||
</LaunchAction> | ||
<ProfileAction | ||
buildConfiguration = "Release" | ||
shouldUseLaunchSchemeArgsEnv = "YES" | ||
savedToolIdentifier = "" | ||
useCustomWorkingDirectory = "NO" | ||
debugDocumentVersioning = "YES"> | ||
<MacroExpansion> | ||
<BuildableReference | ||
BuildableIdentifier = "primary" | ||
BlueprintIdentifier = "6BD0FF1A2AF64E7F00CC9579" | ||
BuildableName = "Swiftly.app" | ||
BlueprintName = "Swiftly" | ||
ReferencedContainer = "container:../Swiftly.xcodeproj"> | ||
</BuildableReference> | ||
</MacroExpansion> | ||
</ProfileAction> | ||
<AnalyzeAction | ||
buildConfiguration = "Debug"> | ||
</AnalyzeAction> | ||
<ArchiveAction | ||
buildConfiguration = "Release" | ||
revealArchiveInOrganizer = "YES"> | ||
</ArchiveAction> | ||
</Scheme> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import Provider | ||
|
||
public final class AboutDomainModule: Module { | ||
public init() {} | ||
|
||
public func register(on provider: Provider) { | ||
provider.register { RealGetAppVersion() as GetAppVersion } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
public struct AppVersion { | ||
public let major: Int | ||
public let minor: Int | ||
|
||
public init(major: Int, minor: Int) { | ||
self.major = major | ||
self.minor = minor | ||
} | ||
} | ||
|
||
public enum AppVersionError: Error { | ||
case unknown | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import Foundation | ||
|
||
public protocol GetAppVersion { | ||
|
||
func run() -> Result<AppVersion, AppVersionError> | ||
} | ||
|
||
class RealGetAppVersion: GetAppVersion { | ||
|
||
func run() -> Result<AppVersion, AppVersionError> { | ||
guard let appVersionString = getBundleVersion() else { | ||
return .failure(.unknown) | ||
} | ||
let parts = appVersionString.split(separator: ".") | ||
return .success( | ||
AppVersion( | ||
major: Int(parts[0])!, | ||
minor: Int(parts[1])! | ||
) | ||
) | ||
} | ||
|
||
private func getBundleVersion() -> String? { | ||
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String | ||
} | ||
} | ||
|
||
public class FakeGetAppVersion: GetAppVersion { | ||
|
||
let appVersionResult: Result<AppVersion, AppVersionError> | ||
|
||
public init(appVersionResult: Result<AppVersion, AppVersionError> = .failure(.unknown)) { | ||
self.appVersionResult = appVersionResult | ||
} | ||
|
||
public convenience init(appVersion: AppVersion) { | ||
self.init(appVersionResult: .success(appVersion)) | ||
} | ||
|
||
public func run() -> Result<AppVersion, AppVersionError> { | ||
appVersionResult | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
Core/Sources/About/Presentation/AboutPresentationModule.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import AboutDomain | ||
import Provider | ||
|
||
public final class AboutPresentationModule: Module { | ||
public init() {} | ||
|
||
public var dependencies: [Module.Type] = [ | ||
AboutDomainModule.self | ||
] | ||
|
||
public func register(on provider: Provider) { | ||
provider.register { | ||
AboutViewModel(getAppVersion: provider.get()) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import AboutDomain | ||
import Foundation | ||
import SwiftlyUtils | ||
|
||
public final class AboutViewModel: ViewModel { | ||
public typealias Action = AboutAction | ||
public typealias State = AboutState | ||
|
||
private let getAppVersion: GetAppVersion | ||
@Published public var state: AboutState | ||
|
||
init( | ||
getAppVersion: GetAppVersion, | ||
initialState: AboutState = AboutState.initial | ||
) { | ||
self.getAppVersion = getAppVersion | ||
state = initialState | ||
Task { load() } | ||
} | ||
|
||
public func send(_ action: AboutAction) { | ||
switch action { | ||
case .none: break | ||
} | ||
} | ||
|
||
private func load() { | ||
let appVersion: GenericLce<String> = getAppVersion.run() | ||
.map { "\($0.major).\($0.minor)" } | ||
.toLce() | ||
|
||
emit { | ||
self.state = AboutState(appVersion: appVersion) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
public enum AboutAction { | ||
case none | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import Foundation | ||
import SwiftlyUtils | ||
|
||
public struct AboutState { | ||
let appVersion: GenericLce<String> | ||
} | ||
|
||
extension AboutState { | ||
static var initial: AboutState { | ||
AboutState( | ||
appVersion: .loading | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import Provider | ||
import SwiftUI | ||
|
||
public struct AboutView: View { | ||
@StateObject var viewModel: AboutViewModel = getProvider().get() | ||
|
||
public init() {} | ||
|
||
public var body: some View { | ||
VStack { | ||
|
||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
AboutView() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
public struct GenericError: Error, Equatable {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
/// Loading, Content, Error construct | ||
public enum Lce<C, E: Error>: Equatable where C: Equatable, E: Equatable { | ||
case content(C) | ||
case error(E) | ||
case loading | ||
} | ||
|
||
/// Lce with GenericError | ||
public typealias GenericLce<C: Equatable> = Lce<C, GenericError> | ||
|
||
public extension Result where Success: Equatable { | ||
|
||
/// Map Result to Lce | ||
/// - Parameter error: closure that maps a Result's Failure to Lce's Error | ||
func toLce<E>(error: (Failure) -> E) -> Lce<Success, E> where E: Error, E: Equatable { | ||
switch self { | ||
case let .failure(e): Lce.error(error(e)) | ||
case let .success(content): Lce.content(content) | ||
} | ||
} | ||
|
||
/// Maps Result to GenericLce | ||
func toLce() -> GenericLce<Success> { | ||
toLce(error: { _ in GenericError() }) | ||
} | ||
} | ||
|
||
public extension Lce where E == GenericError { | ||
static var error: Lce { | ||
.error(GenericError()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
// | ||
// File.swift | ||
// | ||
// | ||
// Created by Davide Giuseppe Farella on 02/01/24. | ||
// | ||
|
||
import Foundation |
50 changes: 50 additions & 0 deletions
50
Core/Tests/About/PresentationTests/AboutViewModelTests.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import XCTest | ||
|
||
import AboutDomain | ||
import PowerAssert | ||
import SwiftlyTest | ||
@testable import AboutPresentation | ||
|
||
final class AboutViewModelTests: XCTestCase { | ||
|
||
func test_initialAppVersionIsLoading() { | ||
// given | ||
let scenario = Scenario() | ||
|
||
// then | ||
#assert(scenario.sut.state.appVersion == .loading) | ||
} | ||
|
||
func test_appVersionIsLoadedCorrectly() async { | ||
// given | ||
let scenario = Scenario(appVersion: AppVersion(major: 1, minor: 2)) | ||
|
||
// when | ||
await test(scenario.sut.$state.map(\.appVersion)) { turbine in | ||
await turbine.expectInitial(value: .loading) | ||
|
||
// then | ||
let result = await turbine.value() | ||
#assert(result == .content("1.2")) | ||
} | ||
} | ||
} | ||
|
||
private class Scenario { | ||
|
||
let sut: AboutViewModel | ||
|
||
init( | ||
getAppVersion: GetAppVersion = FakeGetAppVersion() | ||
) { | ||
sut = AboutViewModel(getAppVersion: getAppVersion) | ||
} | ||
|
||
convenience init( | ||
appVersion: AppVersion | ||
) { | ||
self.init( | ||
getAppVersion: FakeGetAppVersion(appVersion: appVersion) | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters