mirror of
https://github.com/XcodesOrg/XcodesApp.git
synced 2026-03-25 08:55:46 +00:00
Merge pull request #40 from RobotsAndPencils/test-scaffolding
Test scaffolding
This commit is contained in:
commit
4cb2e195ed
7 changed files with 179 additions and 5 deletions
|
|
@ -13,6 +13,8 @@
|
|||
CA39711924495F0E00AFFB77 /* AppStoreButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA39711824495F0E00AFFB77 /* AppStoreButtonStyle.swift */; };
|
||||
CA44901F2463AD34003D8213 /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA44901E2463AD34003D8213 /* Tag.swift */; };
|
||||
CA452BB0259FD9770072DFA4 /* ProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA452BAF259FD9770072DFA4 /* ProgressIndicator.swift */; };
|
||||
CA452BC0259FDDFE0072DFA4 /* Stub-0.0.0.plist in Resources */ = {isa = PBXBuildFile; fileRef = CA452BBE259FDDFE0072DFA4 /* Stub-0.0.0.plist */; };
|
||||
CA452BC1259FDDFE0072DFA4 /* Stub-version.plist in Resources */ = {isa = PBXBuildFile; fileRef = CA452BBF259FDDFE0072DFA4 /* Stub-version.plist */; };
|
||||
CA5D781E257365D6008EDE9D /* PinCodeTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA5D781D257365D6008EDE9D /* PinCodeTextView.swift */; };
|
||||
CA61A6E0259835580008926E /* Xcode.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA61A6DF259835580008926E /* Xcode.swift */; };
|
||||
CA735109257BF96D00EA9CF8 /* AttributedText.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA735108257BF96D00EA9CF8 /* AttributedText.swift */; };
|
||||
|
|
@ -65,6 +67,8 @@
|
|||
CAC281C8259F97E100B8AB0B /* InstallationStepView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAC281C7259F97E100B8AB0B /* InstallationStepView.swift */; };
|
||||
CAC281CD259F97FA00B8AB0B /* ObservingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAC281CC259F97FA00B8AB0B /* ObservingProgressIndicator.swift */; };
|
||||
CAC281DA259F985100B8AB0B /* InstallationStep.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAC281D9259F985100B8AB0B /* InstallationStep.swift */; };
|
||||
CAC281E2259FA44600B8AB0B /* Bundle+XcodesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAC281E1259FA44600B8AB0B /* Bundle+XcodesTests.swift */; };
|
||||
CAC281E7259FA45A00B8AB0B /* Environment+Mock.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAC281E6259FA45A00B8AB0B /* Environment+Mock.swift */; };
|
||||
CAD2E7A22449574E00113D76 /* XcodesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7A12449574E00113D76 /* XcodesApp.swift */; };
|
||||
CAD2E7A42449574E00113D76 /* XcodeListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAD2E7A32449574E00113D76 /* XcodeListView.swift */; };
|
||||
CAD2E7A62449575000113D76 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CAD2E7A52449575000113D76 /* Assets.xcassets */; };
|
||||
|
|
@ -128,6 +132,8 @@
|
|||
CA39711824495F0E00AFFB77 /* AppStoreButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStoreButtonStyle.swift; sourceTree = "<group>"; };
|
||||
CA44901E2463AD34003D8213 /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = "<group>"; };
|
||||
CA452BAF259FD9770072DFA4 /* ProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressIndicator.swift; sourceTree = "<group>"; };
|
||||
CA452BBE259FDDFE0072DFA4 /* Stub-0.0.0.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Stub-0.0.0.plist"; sourceTree = "<group>"; };
|
||||
CA452BBF259FDDFE0072DFA4 /* Stub-version.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Stub-version.plist"; sourceTree = "<group>"; };
|
||||
CA538A0C255A4F1A00E64DD7 /* AppleAPI */ = {isa = PBXFileReference; lastKnownFileType = folder; name = AppleAPI; path = Xcodes/AppleAPI; sourceTree = "<group>"; };
|
||||
CA5D781D257365D6008EDE9D /* PinCodeTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PinCodeTextView.swift; sourceTree = "<group>"; };
|
||||
CA61A6DF259835580008926E /* Xcode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Xcode.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -187,6 +193,8 @@
|
|||
CAC281C7259F97E100B8AB0B /* InstallationStepView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallationStepView.swift; sourceTree = "<group>"; };
|
||||
CAC281CC259F97FA00B8AB0B /* ObservingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObservingProgressIndicator.swift; sourceTree = "<group>"; };
|
||||
CAC281D9259F985100B8AB0B /* InstallationStep.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstallationStep.swift; sourceTree = "<group>"; };
|
||||
CAC281E1259FA44600B8AB0B /* Bundle+XcodesTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Bundle+XcodesTests.swift"; sourceTree = "<group>"; };
|
||||
CAC281E6259FA45A00B8AB0B /* Environment+Mock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Environment+Mock.swift"; sourceTree = "<group>"; };
|
||||
CAD2E79E2449574E00113D76 /* Xcodes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Xcodes.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
CAD2E7A12449574E00113D76 /* XcodesApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodesApp.swift; sourceTree = "<group>"; };
|
||||
CAD2E7A32449574E00113D76 /* XcodeListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XcodeListView.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -251,6 +259,15 @@
|
|||
path = Common;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CA452BBD259FDDBF0072DFA4 /* Fixtures */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CA452BBE259FDDFE0072DFA4 /* Stub-0.0.0.plist */,
|
||||
CA452BBF259FDDFE0072DFA4 /* Stub-version.plist */,
|
||||
);
|
||||
path = Fixtures;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
CA538A12255A4F7C00E64DD7 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
|
@ -438,6 +455,9 @@
|
|||
CAD2E7B62449575100113D76 /* XcodesTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
CA452BBD259FDDBF0072DFA4 /* Fixtures */,
|
||||
CAC281E1259FA44600B8AB0B /* Bundle+XcodesTests.swift */,
|
||||
CAC281E6259FA45A00B8AB0B /* Environment+Mock.swift */,
|
||||
CAD2E7B72449575100113D76 /* XcodesTests.swift */,
|
||||
CAD2E7B92449575100113D76 /* Info.plist */,
|
||||
);
|
||||
|
|
@ -576,6 +596,8 @@
|
|||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CA452BC0259FDDFE0072DFA4 /* Stub-0.0.0.plist in Resources */,
|
||||
CA452BC1259FDDFE0072DFA4 /* Stub-version.plist in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -685,6 +707,8 @@
|
|||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
CAD2E7B82449575100113D76 /* XcodesTests.swift in Sources */,
|
||||
CAC281E7259FA45A00B8AB0B /* Environment+Mock.swift in Sources */,
|
||||
CAC281E2259FA44600B8AB0B /* Bundle+XcodesTests.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import Version
|
|||
|
||||
class AppState: ObservableObject {
|
||||
private let client = AppleAPI.Client()
|
||||
private let helperClient = HelperClient()
|
||||
private var cancellables = Set<AnyCancellable>()
|
||||
private var selectPublisher: AnyCancellable?
|
||||
private var uninstallPublisher: AnyCancellable?
|
||||
|
|
@ -184,14 +183,14 @@ class AppState: ObservableObject {
|
|||
// MARK: - Helper
|
||||
|
||||
func installHelper() {
|
||||
HelperInstaller.install()
|
||||
Current.helper.install()
|
||||
checkIfHelperIsInstalled()
|
||||
}
|
||||
|
||||
private func checkIfHelperIsInstalled() {
|
||||
helperInstallState = .unknown
|
||||
|
||||
helperClient.checkIfLatestHelperIsInstalled()
|
||||
Current.helper.checkIfLatestHelperIsInstalled()
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(
|
||||
receiveValue: { installed in
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public struct Environment {
|
|||
public var keychain = Keychain()
|
||||
public var defaults = Defaults()
|
||||
public var date: () -> Date = Date.init
|
||||
public var helper = Helper()
|
||||
}
|
||||
|
||||
public var Current = Environment()
|
||||
|
|
@ -91,8 +92,12 @@ private func _installedXcodes(destination: Path) -> [InstalledXcode] {
|
|||
public struct Network {
|
||||
private static let client = AppleAPI.Client()
|
||||
|
||||
public var dataTask: (URLRequest) -> URLSession.DataTaskPublisher = { AppleAPI.Current.network.session.dataTaskPublisher(for: $0) }
|
||||
public func dataTask(with request: URLRequest) -> URLSession.DataTaskPublisher {
|
||||
public var dataTask: (URLRequest) -> AnyPublisher<URLSession.DataTaskPublisher.Output, Error> = {
|
||||
AppleAPI.Current.network.session.dataTaskPublisher(for: $0)
|
||||
.mapError { $0 as Error }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
public func dataTask(with request: URLRequest) -> AnyPublisher<URLSession.DataTaskPublisher.Output, Error> {
|
||||
dataTask(request)
|
||||
}
|
||||
|
||||
|
|
@ -152,3 +157,11 @@ public struct Defaults {
|
|||
removeObject(key)
|
||||
}
|
||||
}
|
||||
|
||||
private let helperClient = HelperClient()
|
||||
public struct Helper {
|
||||
var install: () -> Void = HelperInstaller.install
|
||||
var checkIfLatestHelperIsInstalled: () -> AnyPublisher<Bool, Never> = helperClient.checkIfLatestHelperIsInstalled
|
||||
var getVersion: () -> AnyPublisher<String, Error> = helperClient.getVersion
|
||||
var switchXcodePath: (_ absolutePath: String) -> AnyPublisher<Void, Error> = helperClient.switchXcodePath
|
||||
}
|
||||
|
|
|
|||
9
XcodesTests/Bundle+XcodesTests.swift
Normal file
9
XcodesTests/Bundle+XcodesTests.swift
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import Foundation
|
||||
|
||||
extension Bundle {
|
||||
static var xcodesTests: Bundle {
|
||||
Bundle(for: BundleMember.self)
|
||||
}
|
||||
}
|
||||
|
||||
private class BundleMember {}
|
||||
111
XcodesTests/Environment+Mock.swift
Normal file
111
XcodesTests/Environment+Mock.swift
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import Combine
|
||||
import Foundation
|
||||
@testable import Xcodes
|
||||
|
||||
extension Environment {
|
||||
static var mock = Environment(
|
||||
shell: .mock,
|
||||
files: .mock,
|
||||
network: .mock,
|
||||
logging: .mock,
|
||||
keychain: .mock,
|
||||
defaults: .mock,
|
||||
date: Date.mock,
|
||||
helper: .mock
|
||||
)
|
||||
}
|
||||
|
||||
extension Shell {
|
||||
static var processOutputMock: ProcessOutput = (0, "", "")
|
||||
|
||||
static var mock = Shell(
|
||||
unxip: { _ in return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
spctlAssess: { _ in return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
codesignVerify: { _ in return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
buildVersion: { return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
xcodeBuildVersion: { _ in return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
getUserCacheDir: { return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
touchInstallCheck: { _, _, _ in return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
xcodeSelectPrintPath: { return Just(Shell.processOutputMock).setFailureType(to: Error.self).eraseToAnyPublisher() }
|
||||
)
|
||||
}
|
||||
|
||||
extension Files {
|
||||
static var mock = Files(
|
||||
fileExistsAtPath: { _ in return true },
|
||||
moveItem: { _, _ in return },
|
||||
contentsAtPath: { path in
|
||||
if path.contains("Info.plist") {
|
||||
let url = Bundle.xcodesTests.url(forResource: "Stub-0.0.0.Info", withExtension: "plist")!
|
||||
return try? Data(contentsOf: url)
|
||||
}
|
||||
else if path.contains("version.plist") {
|
||||
let url = Bundle.xcodesTests.url(forResource: "Stub.version", withExtension: "plist")!
|
||||
return try? Data(contentsOf: url)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
},
|
||||
removeItem: { _ in },
|
||||
trashItem: { _ in return URL(fileURLWithPath: "\(NSHomeDirectory())/.Trash") },
|
||||
createFile: { _, _, _ in return true },
|
||||
createDirectory: { _, _, _ in },
|
||||
installedXcodes: { _ in [] }
|
||||
)
|
||||
}
|
||||
|
||||
extension Network {
|
||||
static var mock = Network(
|
||||
dataTask: { url in
|
||||
Just((data: Data(), response: HTTPURLResponse(url: url.url!, statusCode: 200, httpVersion: nil, headerFields: nil)! as URLResponse))
|
||||
.setFailureType(to: Error.self)
|
||||
.eraseToAnyPublisher()
|
||||
},
|
||||
downloadTask: { url, saveLocation, _ in
|
||||
return (
|
||||
Progress(),
|
||||
Just((saveLocation, HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)!))
|
||||
.setFailureType(to: Error.self)
|
||||
.eraseToAnyPublisher()
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
extension Logging {
|
||||
static var mock = Logging(
|
||||
log: { print($0) }
|
||||
)
|
||||
}
|
||||
|
||||
extension Keychain {
|
||||
static var mock = Keychain(
|
||||
getString: { _ in return nil },
|
||||
set: { _, _ in },
|
||||
remove: { _ in }
|
||||
)
|
||||
}
|
||||
|
||||
extension Defaults {
|
||||
static var mock = Defaults(
|
||||
string: { _ in nil },
|
||||
date: { _ in nil },
|
||||
setDate: { _, _ in },
|
||||
set: { _, _ in },
|
||||
removeObject: { _ in }
|
||||
)
|
||||
}
|
||||
|
||||
extension Date {
|
||||
static var mock = { Date(timeIntervalSince1970: 1609479735) }
|
||||
}
|
||||
|
||||
extension Helper {
|
||||
static var mock = Helper(
|
||||
install: { },
|
||||
checkIfLatestHelperIsInstalled: { Just(false).eraseToAnyPublisher() },
|
||||
getVersion: { Just("").setFailureType(to: Error.self).eraseToAnyPublisher() },
|
||||
switchXcodePath: { _ in Just(()).setFailureType(to: Error.self).eraseToAnyPublisher() }
|
||||
)
|
||||
}
|
||||
10
XcodesTests/Fixtures/Stub-0.0.0.plist
Normal file
10
XcodesTests/Fixtures/Stub-0.0.0.plist
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.dt.Xcode</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.0.0</string>
|
||||
</dict>
|
||||
</plist>
|
||||
8
XcodesTests/Fixtures/Stub-version.plist
Normal file
8
XcodesTests/Fixtures/Stub-version.plist
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>ProductBuildVersion</key>
|
||||
<string>ABC123</string>
|
||||
</dict>
|
||||
</plist>
|
||||
Loading…
Reference in a new issue