Skip to content
Snippets Groups Projects
Commit efb3ba76 authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Add MessengerWaitForNodes functor

parent 50d75ed3
No related branches found
No related tags found
2 merge requests!102Release 1.0.0,!33XXMessengerClient
import XXClient
import XCTestDynamicOverlay
public struct MessengerWaitForNodes {
public typealias Progress = (Double) -> Void
public enum Error: Swift.Error {
case notLoaded
case timeout
}
public var run: (Double, Int, Int, @escaping Progress) throws -> Void
public func callAsFunction(
targetRatio: Double = 0.8,
sleepMS: Int = 1_000,
retries: Int = 10,
onProgress: @escaping Progress = { _ in }
) throws {
try run(targetRatio, sleepMS, retries, onProgress)
}
}
extension MessengerWaitForNodes {
public static func live(_ env: MessengerEnvironment) -> MessengerWaitForNodes {
MessengerWaitForNodes { targetRatio, sleepMS, retries, onProgress in
guard let cMix = env.ctx.getCMix() else {
throw Error.notLoaded
}
func getProgress(_ report: NodeRegistrationReport) -> Double {
min(1, ((report.ratio / targetRatio) * 100).rounded() / 100)
}
var report = try cMix.getNodeRegistrationStatus()
var retries = retries
onProgress(getProgress(report))
while report.ratio < targetRatio && retries > 0 {
env.sleep(sleepMS)
retries -= 1
report = try cMix.getNodeRegistrationStatus()
onProgress(getProgress(report))
}
if report.ratio < targetRatio {
throw Error.timeout
}
}
}
}
extension MessengerWaitForNodes {
public static let unimplemented = MessengerWaitForNodes(
run: XCTUnimplemented("\(Self.self)")
)
}
...@@ -16,6 +16,7 @@ public struct Messenger { ...@@ -16,6 +16,7 @@ public struct Messenger {
public var isLoggedIn: MessengerIsLoggedIn public var isLoggedIn: MessengerIsLoggedIn
public var logIn: MessengerLogIn public var logIn: MessengerLogIn
public var waitForNetwork: MessengerWaitForNetwork public var waitForNetwork: MessengerWaitForNetwork
public var waitForNodes: MessengerWaitForNodes
} }
extension Messenger { extension Messenger {
...@@ -35,7 +36,8 @@ extension Messenger { ...@@ -35,7 +36,8 @@ extension Messenger {
register: .live(env), register: .live(env),
isLoggedIn: .live(env), isLoggedIn: .live(env),
logIn: .live(env), logIn: .live(env),
waitForNetwork: .live(env) waitForNetwork: .live(env),
waitForNodes: .live(env)
) )
} }
} }
...@@ -56,6 +58,7 @@ extension Messenger { ...@@ -56,6 +58,7 @@ extension Messenger {
register: .unimplemented, register: .unimplemented,
isLoggedIn: .unimplemented, isLoggedIn: .unimplemented,
logIn: .unimplemented, logIn: .unimplemented,
waitForNetwork: .unimplemented waitForNetwork: .unimplemented,
waitForNodes: .unimplemented
) )
} }
...@@ -16,6 +16,7 @@ public struct MessengerEnvironment { ...@@ -16,6 +16,7 @@ public struct MessengerEnvironment {
public var newCMix: NewCMix public var newCMix: NewCMix
public var newOrLoadUd: NewOrLoadUd public var newOrLoadUd: NewOrLoadUd
public var passwordStorage: PasswordStorage public var passwordStorage: PasswordStorage
public var sleep: (Int) -> Void
public var storageDir: String public var storageDir: String
public var udAddress: String? public var udAddress: String?
public var udCert: Data? public var udCert: Data?
...@@ -44,6 +45,7 @@ extension MessengerEnvironment { ...@@ -44,6 +45,7 @@ extension MessengerEnvironment {
newCMix: .live, newCMix: .live,
newOrLoadUd: .live, newOrLoadUd: .live,
passwordStorage: .keychain, passwordStorage: .keychain,
sleep: { Foundation.sleep(UInt32($0)) },
storageDir: MessengerEnvironment.defaultStorageDir, storageDir: MessengerEnvironment.defaultStorageDir,
udAddress: nil, udAddress: nil,
udCert: nil, udCert: nil,
...@@ -67,6 +69,7 @@ extension MessengerEnvironment { ...@@ -67,6 +69,7 @@ extension MessengerEnvironment {
newCMix: .unimplemented, newCMix: .unimplemented,
newOrLoadUd: .unimplemented, newOrLoadUd: .unimplemented,
passwordStorage: .unimplemented, passwordStorage: .unimplemented,
sleep: XCTUnimplemented("\(Self.self).sleep"),
storageDir: "unimplemented", storageDir: "unimplemented",
udAddress: nil, udAddress: nil,
udCert: nil, udCert: nil,
......
import CustomDump
import XCTest
import XXClient
@testable import XXMessengerClient
final class MessengerWaitForNodesTests: XCTestCase {
func testWaitWhenNotLoaded() {
var env: MessengerEnvironment = .unimplemented
env.ctx.getCMix = { nil }
let waitForNodes: MessengerWaitForNodes = .live(env)
XCTAssertThrowsError(try waitForNodes()) { error in
XCTAssertEqual(
error as? MessengerWaitForNodes.Error,
MessengerWaitForNodes.Error.notLoaded
)
}
}
func testWaitWhenHasTargetRatio() throws {
var didProgress: [Double] = []
var env: MessengerEnvironment = .unimplemented
env.ctx.getCMix = {
var cMix: CMix = .unimplemented
cMix.getNodeRegistrationStatus.run = {
NodeRegistrationReport(registered: 8, total: 10)
}
return cMix
}
let waitForNodes: MessengerWaitForNodes = .live(env)
try waitForNodes(
targetRatio: 0.7,
sleepMS: 123,
retries: 3,
onProgress: { didProgress.append($0) }
)
XCTAssertNoDifference(didProgress, [1])
}
func testWaitForTargetRatio() throws {
var didSleep: [Int] = []
var didProgress: [Double] = []
var reports: [NodeRegistrationReport] = [
.init(registered: 0, total: 10),
.init(registered: 3, total: 10),
.init(registered: 8, total: 10),
]
var env: MessengerEnvironment = .unimplemented
env.ctx.getCMix = {
var cMix: CMix = .unimplemented
cMix.getNodeRegistrationStatus.run = { reports.removeFirst() }
return cMix
}
env.sleep = { didSleep.append($0) }
let waitForNodes: MessengerWaitForNodes = .live(env)
try waitForNodes(
targetRatio: 0.7,
sleepMS: 123,
retries: 3,
onProgress: { didProgress.append($0) }
)
XCTAssertNoDifference(didSleep, [123, 123])
XCTAssertNoDifference(didProgress, [0, 0.43, 1])
}
func testWaitTimeout() {
var didSleep: [Int] = []
var didProgress: [Double] = []
var reports: [NodeRegistrationReport] = [
.init(registered: 0, total: 10),
.init(registered: 3, total: 10),
.init(registered: 5, total: 10),
.init(registered: 6, total: 10),
]
var env: MessengerEnvironment = .unimplemented
env.ctx.getCMix = {
var cMix: CMix = .unimplemented
cMix.getNodeRegistrationStatus.run = { reports.removeFirst() }
return cMix
}
env.sleep = { didSleep.append($0) }
let waitForNodes: MessengerWaitForNodes = .live(env)
XCTAssertThrowsError(try waitForNodes(
targetRatio: 0.7,
sleepMS: 123,
retries: 3,
onProgress: { didProgress.append($0) }
)) { error in
XCTAssertEqual(
error as? MessengerWaitForNodes.Error,
MessengerWaitForNodes.Error.timeout
)
}
XCTAssertNoDifference(didSleep, [123, 123, 123])
XCTAssertNoDifference(didProgress, [0, 0.43, 0.71, 0.86])
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment