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

Add BackupStorage utility

parent 4aa59f6d
No related branches found
No related tags found
2 merge requests!110Backup improvements & example,!102Release 1.0.0
import Foundation
import XCTestDynamicOverlay
import XXClient
public struct BackupStorage {
public struct Backup: Equatable {
public init(
date: Date,
data: Data
) {
self.date = date
self.data = data
}
public var date: Date
public var data: Data
}
public typealias Observer = (Backup?) -> Void
public var store: (Data) -> Void
public var observe: (@escaping Observer) -> Cancellable
public var remove: () -> Void
}
extension BackupStorage {
public static func live(
now: @escaping () -> Date
) -> BackupStorage {
var observers: [UUID: Observer] = [:]
var backup: Backup?
func notifyObservers() {
observers.values.forEach { $0(backup) }
}
return BackupStorage(
store: { data in
backup = Backup(
date: now(),
data: data
)
notifyObservers()
},
observe: { observer in
let id = UUID()
observers[id] = observer
defer { observers[id]?(backup) }
return Cancellable {
observers[id] = nil
}
},
remove: {
backup = nil
notifyObservers()
}
)
}
}
extension BackupStorage {
public static let unimplemented = BackupStorage(
store: XCTUnimplemented("\(Self.self).store"),
observe: XCTUnimplemented("\(Self.self).observe", placeholder: Cancellable {}),
remove: XCTUnimplemented("\(Self.self).remove")
)
}
import CustomDump
import XCTest
@testable import XXMessengerClient
final class BackupStorageTests: XCTestCase {
func testStorage() {
var now: Date = .init(0)
let storage: BackupStorage = .live(
now: { now }
)
var didObserveA: [BackupStorage.Backup?] = []
let observerA = storage.observe { backup in
didObserveA.append(backup)
}
XCTAssertNoDifference(didObserveA, [nil])
now = .init(1)
didObserveA = []
let data1 = "data-1".data(using: .utf8)!
storage.store(data1)
XCTAssertNoDifference(didObserveA, [.init(date: .init(1), data: data1)])
now = .init(2)
didObserveA = []
var didObserveB: [BackupStorage.Backup?] = []
let observerB = storage.observe { backup in
didObserveB.append(backup)
}
XCTAssertNoDifference(didObserveA, [])
XCTAssertNoDifference(didObserveB, [.init(date: .init(1), data: data1)])
now = .init(3)
didObserveA = []
didObserveB = []
let data2 = "data-2".data(using: .utf8)!
storage.store(data2)
XCTAssertNoDifference(didObserveA, [.init(date: .init(3), data: data2)])
XCTAssertNoDifference(didObserveB, [.init(date: .init(3), data: data2)])
now = .init(4)
didObserveA = []
didObserveB = []
observerA.cancel()
storage.remove()
XCTAssertNoDifference(didObserveA, [])
XCTAssertNoDifference(didObserveB, [nil])
now = .init(5)
didObserveA = []
didObserveB = []
observerB.cancel()
let data3 = "data-3".data(using: .utf8)!
storage.store(data3)
XCTAssertNoDifference(didObserveA, [])
XCTAssertNoDifference(didObserveB, [])
}
}
private extension Date {
init(_ timeIntervalSince1970: TimeInterval) {
self.init(timeIntervalSince1970: timeIntervalSince1970)
}
}
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