Naming & Docs
This commit is contained in:
parent
3cbf95efbf
commit
34cac2aab8
|
@ -25,7 +25,7 @@
|
|||
OBJ_101 /* XCTestManifests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_38 /* XCTestManifests.swift */; };
|
||||
OBJ_103 /* Schedule.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Schedule::Schedule::Product" /* Schedule.framework */; };
|
||||
OBJ_50 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_9 /* Atomic.swift */; };
|
||||
OBJ_51 /* Cabinet.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* Cabinet.swift */; };
|
||||
OBJ_51 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_10 /* Bag.swift */; };
|
||||
OBJ_52 /* DeinitObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_11 /* DeinitObserver.swift */; };
|
||||
OBJ_53 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_12 /* Deprecated.swift */; };
|
||||
OBJ_54 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_13 /* Extensions.swift */; };
|
||||
|
@ -44,7 +44,7 @@
|
|||
OBJ_74 /* Schedule.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = "Schedule::Schedule::Product" /* Schedule.framework */; };
|
||||
OBJ_81 /* Package.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_6 /* Package.swift */; };
|
||||
OBJ_92 /* AtomicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_29 /* AtomicTests.swift */; };
|
||||
OBJ_93 /* CabinetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* CabinetTests.swift */; };
|
||||
OBJ_93 /* BagTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_30 /* BagTests.swift */; };
|
||||
OBJ_94 /* DateTimeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_31 /* DateTimeTests.swift */; };
|
||||
OBJ_95 /* DeinitObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_32 /* DeinitObserverTests.swift */; };
|
||||
OBJ_96 /* ExtensionsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* ExtensionsTests.swift */; };
|
||||
|
@ -78,7 +78,7 @@
|
|||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
OBJ_10 /* Cabinet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cabinet.swift; sourceTree = "<group>"; };
|
||||
OBJ_10 /* Bag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bag.swift; sourceTree = "<group>"; };
|
||||
OBJ_11 /* DeinitObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeinitObserver.swift; sourceTree = "<group>"; };
|
||||
OBJ_12 /* Deprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Deprecated.swift; sourceTree = "<group>"; };
|
||||
OBJ_13 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
|
||||
|
@ -95,7 +95,7 @@
|
|||
OBJ_25 /* Log.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Log.swift; sourceTree = "<group>"; };
|
||||
OBJ_26 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
|
||||
OBJ_29 /* AtomicTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_30 /* CabinetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CabinetTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_30 /* BagTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BagTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_31 /* DateTimeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DateTimeTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_32 /* DeinitObserverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeinitObserverTests.swift; sourceTree = "<group>"; };
|
||||
OBJ_33 /* ExtensionsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionsTests.swift; sourceTree = "<group>"; };
|
||||
|
@ -139,13 +139,24 @@
|
|||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
6639192D223FD4B5000F412E /* Utils */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_29 /* AtomicTests.swift */,
|
||||
OBJ_30 /* BagTests.swift */,
|
||||
OBJ_32 /* DeinitObserverTests.swift */,
|
||||
OBJ_33 /* ExtensionsTests.swift */,
|
||||
);
|
||||
name = Utils;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
66C87992223A90D300A95D60 /* Utils */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_13 /* Extensions.swift */,
|
||||
OBJ_11 /* DeinitObserver.swift */,
|
||||
OBJ_9 /* Atomic.swift */,
|
||||
OBJ_10 /* Cabinet.swift */,
|
||||
OBJ_10 /* Bag.swift */,
|
||||
);
|
||||
name = Utils;
|
||||
sourceTree = "<group>";
|
||||
|
@ -183,11 +194,8 @@
|
|||
OBJ_28 /* ScheduleTests */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
OBJ_29 /* AtomicTests.swift */,
|
||||
OBJ_30 /* CabinetTests.swift */,
|
||||
6639192D223FD4B5000F412E /* Utils */,
|
||||
OBJ_31 /* DateTimeTests.swift */,
|
||||
OBJ_32 /* DeinitObserverTests.swift */,
|
||||
OBJ_33 /* ExtensionsTests.swift */,
|
||||
OBJ_34 /* Helpers.swift */,
|
||||
OBJ_35 /* PlanTests.swift */,
|
||||
OBJ_36 /* TaskCenterTests.swift */,
|
||||
|
@ -358,7 +366,7 @@
|
|||
buildActionMask = 0;
|
||||
files = (
|
||||
OBJ_50 /* Atomic.swift in Sources */,
|
||||
OBJ_51 /* Cabinet.swift in Sources */,
|
||||
OBJ_51 /* Bag.swift in Sources */,
|
||||
OBJ_52 /* DeinitObserver.swift in Sources */,
|
||||
OBJ_53 /* Deprecated.swift in Sources */,
|
||||
OBJ_54 /* Extensions.swift in Sources */,
|
||||
|
@ -397,7 +405,7 @@
|
|||
buildActionMask = 0;
|
||||
files = (
|
||||
OBJ_92 /* AtomicTests.swift in Sources */,
|
||||
OBJ_93 /* CabinetTests.swift in Sources */,
|
||||
OBJ_93 /* BagTests.swift in Sources */,
|
||||
OBJ_94 /* DateTimeTests.swift in Sources */,
|
||||
OBJ_95 /* DeinitObserverTests.swift in Sources */,
|
||||
OBJ_96 /* ExtensionsTests.swift in Sources */,
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import Foundation
|
||||
|
||||
/// A value box that can read and write the underlying value atomically.
|
||||
/// Represents a box that can read and write the underlying value atomically.
|
||||
final class Atomic<T> {
|
||||
|
||||
private var v: T
|
||||
private let lock = NSLock()
|
||||
|
||||
/// Init with the underlying value.
|
||||
init(_ value: T) {
|
||||
self.v = value
|
||||
}
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
import Foundation
|
||||
|
||||
/// A unique key used to remove the corresponding element from a bag.
|
||||
struct BagKey: Equatable {
|
||||
|
||||
fileprivate let i: UInt64
|
||||
|
||||
fileprivate init(underlying: UInt64) {
|
||||
self.i = underlying
|
||||
}
|
||||
|
||||
/// Returns a Boolean value indicating whether two BagKeys are equal.
|
||||
static func == (lhs: BagKey, rhs: BagKey) -> Bool {
|
||||
return lhs.i == rhs.i
|
||||
}
|
||||
}
|
||||
|
||||
/// A generator can generate a sequence of unique `BagKey`.
|
||||
///
|
||||
/// let k1 = gen.next()
|
||||
/// let k2 = gen.next()
|
||||
/// ...
|
||||
struct BagKeyGenerator: Sequence, IteratorProtocol {
|
||||
|
||||
typealias Element = BagKey
|
||||
|
||||
private var k = BagKey(underlying: 0)
|
||||
|
||||
/// Gets next BagKey.
|
||||
mutating func next() -> Element? {
|
||||
if k.i == UInt64.max {
|
||||
return nil
|
||||
}
|
||||
defer { k = BagKey(underlying: k.i + 1) }
|
||||
return k
|
||||
}
|
||||
}
|
||||
|
||||
/// A data structure used to store a sequence of elements.
|
||||
///
|
||||
/// let k1 = bag.append(e1)
|
||||
/// let k2 = bag.append(e2)
|
||||
///
|
||||
/// for e in bag {
|
||||
/// // -> e1
|
||||
/// // -> e2
|
||||
/// }
|
||||
///
|
||||
/// bag.delete(k1)
|
||||
struct Bag<Element> {
|
||||
|
||||
private typealias Entry = (key: BagKey, element: Element)
|
||||
|
||||
private var keys = BagKeyGenerator()
|
||||
private var entries: [Entry] = []
|
||||
|
||||
/// Pushes the given element on to the end of this container.
|
||||
@discardableResult
|
||||
mutating func append(_ new: Element) -> BagKey {
|
||||
let key = keys.next()!
|
||||
|
||||
let entry = (key: key, element: new)
|
||||
entries.append(entry)
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
/// Returns the element for key if key is in this container.
|
||||
func get(_ key: BagKey) -> Element? {
|
||||
if let entry = entries.first(where: { $0.key == key }) {
|
||||
return entry.element
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Deletes the element with the given key and returns this element.
|
||||
@discardableResult
|
||||
mutating func delete(_ key: BagKey) -> Element? {
|
||||
if let i = entries.firstIndex(where: { $0.key == key }) {
|
||||
return entries.remove(at: i).element
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/// Removes all elements from this containers.
|
||||
mutating func clear() {
|
||||
entries.removeAll()
|
||||
}
|
||||
|
||||
/// The number of elements in this containers.
|
||||
var count: Int {
|
||||
return entries.count
|
||||
}
|
||||
}
|
||||
|
||||
extension Bag: Sequence {
|
||||
|
||||
func makeIterator() -> AnyIterator<Element> {
|
||||
var iterator = entries.makeIterator()
|
||||
return AnyIterator<Element> {
|
||||
return iterator.next()?.element
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
import Foundation
|
||||
|
||||
struct CabinetKey: Equatable {
|
||||
|
||||
private let i: UInt64
|
||||
|
||||
init(underlying: UInt64) {
|
||||
self.i = underlying
|
||||
}
|
||||
|
||||
func increased() -> CabinetKey {
|
||||
return CabinetKey(underlying: i &+ 1)
|
||||
}
|
||||
|
||||
static func == (lhs: CabinetKey, rhs: CabinetKey) -> Bool {
|
||||
return lhs.i == rhs.i
|
||||
}
|
||||
}
|
||||
|
||||
struct Cabinet<Element> {
|
||||
|
||||
private typealias Entry = (key: CabinetKey, element: Element)
|
||||
|
||||
private var key = CabinetKey(underlying: 0)
|
||||
private var entries: [Entry] = []
|
||||
|
||||
@discardableResult
|
||||
mutating func append(_ new: Element) -> CabinetKey {
|
||||
defer { key = key.increased() }
|
||||
|
||||
let entry = (key: key, element: new)
|
||||
entries.append(entry)
|
||||
|
||||
return key
|
||||
}
|
||||
|
||||
func get(_ key: CabinetKey) -> Element? {
|
||||
if let entry = entries.first(where: { $0.key == key }) {
|
||||
return entry.element
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
mutating func delete(_ key: CabinetKey) -> Element? {
|
||||
if let i = entries.firstIndex(where: { $0.key == key }) {
|
||||
return entries.remove(at: i).element
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
mutating func clear() {
|
||||
entries.removeAll()
|
||||
}
|
||||
|
||||
var count: Int {
|
||||
return entries.count
|
||||
}
|
||||
}
|
||||
|
||||
extension Cabinet: Sequence {
|
||||
|
||||
func makeIterator() -> AnyIterator<Element> {
|
||||
var iterator = entries.makeIterator()
|
||||
return AnyIterator<Element> {
|
||||
return iterator.next()?.element
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +1,19 @@
|
|||
import Foundation
|
||||
|
||||
#if canImport(ObjectiveC)
|
||||
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
||||
|
||||
private var deinitObserverKey: Void = ()
|
||||
private var DEINIT_OBSERVER_KEY: Void = ()
|
||||
|
||||
/// Used to observe object deinit.
|
||||
///
|
||||
/// let observer = DeinitObserver.observe(target) {
|
||||
/// print("\(target) deinit")
|
||||
/// }
|
||||
///
|
||||
/// observer.cancel()
|
||||
class DeinitObserver {
|
||||
|
||||
private(set) weak var object: AnyObject?
|
||||
private(set) weak var observed: AnyObject?
|
||||
|
||||
private var action: (() -> Void)?
|
||||
|
||||
|
@ -14,23 +21,25 @@ class DeinitObserver {
|
|||
self.action = action
|
||||
}
|
||||
|
||||
/// Installs observation.
|
||||
@discardableResult
|
||||
static func observe(
|
||||
_ object: AnyObject,
|
||||
onDeinit action: @escaping () -> Void
|
||||
) -> DeinitObserver {
|
||||
let observer = DeinitObserver(action)
|
||||
observer.object = object
|
||||
observer.observed = object
|
||||
|
||||
objc_setAssociatedObject(object, &deinitObserverKey, observer, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
objc_setAssociatedObject(object, &DEINIT_OBSERVER_KEY, observer, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
|
||||
return observer
|
||||
}
|
||||
|
||||
func invalidate() {
|
||||
/// Uninstalls observation.
|
||||
func cancel() {
|
||||
action = nil
|
||||
if let o = object {
|
||||
objc_setAssociatedObject(o, &deinitObserverKey, nil, .OBJC_ASSOCIATION_ASSIGN)
|
||||
if let o = observed {
|
||||
objc_setAssociatedObject(o, &DEINIT_OBSERVER_KEY, nil, .OBJC_ASSOCIATION_ASSIGN)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ extension Int {
|
|||
|
||||
extension Calendar {
|
||||
|
||||
/// The gregorian calendar with `en_US_POSIX` locale.
|
||||
static let gregorian: Calendar = {
|
||||
var cal = Calendar(identifier: .gregorian)
|
||||
cal.locale = Locale(identifier: "en_US_POSIX")
|
||||
|
@ -31,6 +32,7 @@ extension Calendar {
|
|||
|
||||
extension Date {
|
||||
|
||||
/// Zero o'clock in the morning.
|
||||
var startOfToday: Date {
|
||||
return Calendar.gregorian.startOfDay(for: self)
|
||||
}
|
||||
|
@ -38,10 +40,17 @@ extension Date {
|
|||
|
||||
extension NSLocking {
|
||||
|
||||
/// Executes a closure returning a value while acquiring the lock.
|
||||
@inline(__always)
|
||||
func withLock<T>(_ body: () throws -> T) rethrows -> T {
|
||||
lock()
|
||||
defer { unlock() }
|
||||
lock(); defer { unlock() }
|
||||
return try body()
|
||||
}
|
||||
|
||||
/// Executes a closure returning a value while acquiring the lock.
|
||||
@inline(__always)
|
||||
func withLock(_ body: () throws -> Void) rethrows {
|
||||
lock(); defer { unlock() }
|
||||
try body()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,19 +3,21 @@ import Foundation
|
|||
/// `ActionKey` represents a token that can be used to remove the action.
|
||||
public struct ActionKey {
|
||||
|
||||
fileprivate let cabinetKey: CabinetKey
|
||||
fileprivate let bagKey: BagKey
|
||||
}
|
||||
|
||||
extension CabinetKey {
|
||||
extension BagKey {
|
||||
|
||||
func asActionKey() -> ActionKey {
|
||||
return ActionKey(cabinetKey: self)
|
||||
fileprivate func asActionKey() -> ActionKey {
|
||||
return ActionKey(bagKey: self)
|
||||
}
|
||||
}
|
||||
|
||||
/// `Task` represents a timed task.
|
||||
open class Task {
|
||||
|
||||
public let id = UUID()
|
||||
|
||||
public typealias Action = (Task) -> Void
|
||||
|
||||
private let _mutex = NSRecursiveLock()
|
||||
|
@ -23,8 +25,8 @@ open class Task {
|
|||
private var _iterator: AnyIterator<Interval>
|
||||
private var _timer: DispatchSourceTimer
|
||||
|
||||
private lazy var _onElapseActions = Cabinet<Action>()
|
||||
private lazy var _onDeinitActions = Cabinet<Action>()
|
||||
private lazy var _onElapseActions = Bag<Action>()
|
||||
private lazy var _onDeinitActions = Bag<Action>()
|
||||
|
||||
private lazy var _suspensions: UInt64 = 0
|
||||
private lazy var _timeline = Timeline()
|
||||
|
@ -34,8 +36,8 @@ open class Task {
|
|||
private lazy var _lifetime: Interval = Int.max.seconds
|
||||
private lazy var _lifetimeTimer: DispatchSourceTimer = {
|
||||
let timer = DispatchSource.makeTimerSource()
|
||||
timer.setEventHandler {
|
||||
self.cancel()
|
||||
timer.setEventHandler { [weak self] in
|
||||
self?.cancel()
|
||||
}
|
||||
timer.schedule(after: _lifetime)
|
||||
timer.resume()
|
||||
|
@ -100,7 +102,7 @@ open class Task {
|
|||
|
||||
/// Execute this task now, without disrupting its plan.
|
||||
public func execute() {
|
||||
let actions = _mutex.withLock { () -> Cabinet<Task.Action> in
|
||||
let actions = _mutex.withLock { () -> Bag<Task.Action> in
|
||||
let now = Date()
|
||||
if _timeline.firstExecution == nil {
|
||||
_timeline.firstExecution = now
|
||||
|
@ -117,7 +119,7 @@ open class Task {
|
|||
execute()
|
||||
}
|
||||
|
||||
#if canImport(ObjectiveC)
|
||||
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
||||
open func host(on target: AnyObject) {
|
||||
DeinitObserver.observe(target) { [weak self] in
|
||||
self?.cancel()
|
||||
|
@ -287,7 +289,7 @@ open class Task {
|
|||
/// Removes action by key from this task.
|
||||
public func removeAction(byKey key: ActionKey) {
|
||||
_mutex.withLock {
|
||||
_ = _onElapseActions.delete(key.cabinetKey)
|
||||
_ = _onElapseActions.delete(key.bagKey)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -306,9 +308,8 @@ open class Task {
|
|||
|
||||
extension Task: Hashable {
|
||||
|
||||
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(ObjectIdentifier(self))
|
||||
hasher.combine(id)
|
||||
}
|
||||
|
||||
/// Returns a boolean value indicating whether two tasks are equal.
|
||||
|
|
|
@ -22,13 +22,13 @@ extension Timeline: CustomStringConvertible {
|
|||
|
||||
/// A textual representation of this timeline.
|
||||
public var description: String {
|
||||
enum Cache {
|
||||
enum Lazy {
|
||||
static let fmt = ISO8601DateFormatter()
|
||||
}
|
||||
|
||||
let desc = { (d: Date?) -> String in
|
||||
guard let d = d else { return "nil" }
|
||||
return Cache.fmt.string(from: d)
|
||||
return Lazy.fmt.string(from: d)
|
||||
}
|
||||
|
||||
return "Timeline: { " +
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
import XCTest
|
||||
@testable import Schedule
|
||||
|
||||
final class CabinetTests: XCTestCase {
|
||||
final class BagTests: XCTestCase {
|
||||
|
||||
typealias Fn = () -> Int
|
||||
|
||||
func testCabinetKey() {
|
||||
let key = CabinetKey(underlying: 0)
|
||||
XCTAssertEqual(key.increased(), CabinetKey(underlying: 1))
|
||||
func testBagKey() {
|
||||
var g = BagKeyGenerator()
|
||||
let k1 = g.next()
|
||||
let k2 = g.next()
|
||||
XCTAssertNotNil(k1)
|
||||
XCTAssertNotNil(k2)
|
||||
XCTAssertNotEqual(k1, k2)
|
||||
}
|
||||
|
||||
func testAppend() {
|
||||
var cabinet = Cabinet<Fn>()
|
||||
let k1 = cabinet.append { 1 }
|
||||
let k2 = cabinet.append { 2 }
|
||||
var cabinet = Bag<Fn>()
|
||||
cabinet.append { 1 }
|
||||
cabinet.append { 2 }
|
||||
|
||||
XCTAssertEqual(k1.increased(), k2)
|
||||
XCTAssertEqual(cabinet.count, 2)
|
||||
}
|
||||
|
||||
func testGet() {
|
||||
var cabinet = Cabinet<Fn>()
|
||||
var cabinet = Bag<Fn>()
|
||||
let k1 = cabinet.append { 1 }
|
||||
let k2 = cabinet.append { 2 }
|
||||
|
||||
|
@ -33,12 +36,10 @@ final class CabinetTests: XCTestCase {
|
|||
}
|
||||
XCTAssertEqual(fn1(), 1)
|
||||
XCTAssertEqual(fn2(), 2)
|
||||
|
||||
XCTAssertNil(cabinet.get(k2.increased()))
|
||||
}
|
||||
|
||||
func testDelete() {
|
||||
var cabinet = Cabinet<Fn>()
|
||||
var cabinet = Bag<Fn>()
|
||||
|
||||
let k1 = cabinet.append { 1 }
|
||||
let k2 = cabinet.append { 2 }
|
||||
|
@ -52,12 +53,10 @@ final class CabinetTests: XCTestCase {
|
|||
XCTAssertNotNil(fn2)
|
||||
|
||||
XCTAssertEqual(cabinet.count, 0)
|
||||
|
||||
XCTAssertNil(cabinet.delete(k2.increased()))
|
||||
}
|
||||
|
||||
func testClear() {
|
||||
var cabinet = Cabinet<Fn>()
|
||||
var cabinet = Bag<Fn>()
|
||||
|
||||
cabinet.append { 1 }
|
||||
cabinet.append { 2 }
|
||||
|
@ -69,7 +68,7 @@ final class CabinetTests: XCTestCase {
|
|||
}
|
||||
|
||||
func testSequence() {
|
||||
var cabinet = Cabinet<Fn>()
|
||||
var cabinet = Bag<Fn>()
|
||||
cabinet.append { 0 }
|
||||
cabinet.append { 1 }
|
||||
cabinet.append { 2 }
|
||||
|
@ -82,7 +81,7 @@ final class CabinetTests: XCTestCase {
|
|||
}
|
||||
|
||||
static var allTests = [
|
||||
("testCabinetKey", testCabinetKey),
|
||||
("testBagKey", testBagKey),
|
||||
("testAppend", testAppend),
|
||||
("testGet", testGet),
|
||||
("testDelete", testDelete),
|
|
@ -1,7 +1,7 @@
|
|||
import XCTest
|
||||
@testable import Schedule
|
||||
|
||||
#if canImport(ObjectiveC)
|
||||
#if os(macOS) || os(iOS) || os(tvOS) || os(watchOS)
|
||||
|
||||
final class DeinitObserverTests: XCTestCase {
|
||||
|
||||
|
@ -21,7 +21,7 @@ final class DeinitObserverTests: XCTestCase {
|
|||
let observer = DeinitObserver.observe(obj) {
|
||||
i += 1
|
||||
}
|
||||
observer.invalidate()
|
||||
observer.cancel()
|
||||
}
|
||||
fn()
|
||||
XCTAssertEqual(i, 1)
|
||||
|
|
|
@ -8,7 +8,7 @@ public func allTests() -> [XCTestCaseEntry] {
|
|||
testCase(TaskCenterTests.allTests),
|
||||
testCase(TaskTests.allTests),
|
||||
testCase(AtomicTests.allTests),
|
||||
testCase(CabinetTests.allTests),
|
||||
testCase(BagTests.allTests),
|
||||
testCase(CalendarTests.allTests),
|
||||
testCase(ExtensionsTests.allTests)
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue