Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/SCFNotification/Observation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct Observation {

weak var observer: AnyObject?
weak var object: AnyObject?

var observerPtr: UnsafeMutableRawPointer? {
guard let observer = self.observer else {
return nil
Expand Down
19 changes: 19 additions & 0 deletions Sources/SCFNotification/ObservationStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ class ObservationStore {
localObservations = localObservations.cleanUpped()

darwinNotifyObservations = darwinNotifyObservations.cleanUpped()

#if os(macOS)
distributedObservations = distributedObservations.cleanUpped()
#endif
}

func notifyIfNeeded(center: SCFNotificationCenter.CenterType, observer: UnsafeMutableRawPointer?, name: CFNotificationName?, object: UnsafeRawPointer?, userInfo: CFDictionary?) {
Expand All @@ -103,3 +107,18 @@ class ObservationStore {
}

}

extension ObservationStore {
func observations(for center: SCFNotificationCenter.CenterType) -> [Observation] {
switch center {
case .local:
return localObservations
case .darwinNotify:
return darwinNotifyObservations
#if os(macOS)
case .distributed:
return distributedObservations
#endif
}
}
}
6 changes: 3 additions & 3 deletions Sources/SCFNotification/SCFNotificationCenter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ public class SCFNotificationCenter {

private let center: CenterType

private init(center: CenterType) {
init(center: CenterType) {
self.center = center
}

public func addObserver<Observer: AnyObject>(observer: Observer,
name: CFNotificationName,
name: CFNotificationName?,
object: AnyObject? = nil,
suspensionBehavior: CFNotificationSuspensionBehavior,
callback: @escaping SCFNotificationCallback<Observer, AnyObject>) {
Expand All @@ -31,7 +31,7 @@ public class SCFNotificationCenter {
}

public func removeObserver<Observer: AnyObject>(observer: Observer,
name: CFNotificationName,
name: CFNotificationName?,
object: AnyObject? = nil) {
Self.removeObserver(center: center,
observer: observer,
Expand Down
4 changes: 0 additions & 4 deletions Tests/SCFNotificationTests/CFNotificationTests.swift

This file was deleted.

105 changes: 105 additions & 0 deletions Tests/SCFNotificationTests/SCFDarwinNotificationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import XCTest
@testable import SCFNotification

class SCFDarwinNotificationTests: SCFNotificationTests {
override var centerType: SCFNotificationCenter.CenterType {
.darwinNotify
}

// Customized
// object is ignored
override func testObserveNamedWithObject() {
let exp = expectation(description: #function)

notificationCenter
.addObserver(observer: self,
name: .init(#function as CFString),
object: "hello" as CFString,
suspensionBehavior: .deliverImmediately) { center, observer, name, object, userInfo in
XCTAssertEqual(observer, self)
XCTAssertEqual(center?.centerType, self.centerType)
XCTAssertEqual(name?.rawValue, #function as CFString)
XCTAssertNil(object)
exp.fulfill()
}


notificationCenter.postNotification(name: .init(#function as CFString),
object: "hello" as CFString,
userInfo: [:] as CFDictionary,
deliverImmediately: true)

wait(for: [exp], timeout: timeout)
removeEveryObserver()
}

override func testObserveNamedWithObjectShouldNotCalled() {
let exp = expectation(description: #function)

notificationCenter
.addObserver(observer: self,
name: .init("\(#function)" as CFString),
object: "hello-aaa" as CFString,
suspensionBehavior: .deliverImmediately) { center, observer, name, object, userInfo in
exp.fulfill()
}


notificationCenter.postNotification(name: .init(#function as CFString),
object: "hello" as CFString,
userInfo: [:] as CFDictionary,
deliverImmediately: true)

wait(for: [exp], timeout: timeout)

removeEveryObserver()
}

// Custimized
// If center is a Darwin notification center, this value must not be NULL.
override func testObserveNilNamed() {
let exp = expectation(description: #function)
exp.isInverted = true

notificationCenter
.addObserver(observer: self,
name: nil,
suspensionBehavior: .deliverImmediately) { center, observer, name, object, userInfo in
exp.fulfill()
}


notificationCenter.postNotification(name: .init(#function as CFString),
userInfo: [:] as CFDictionary,
deliverImmediately: true)

wait(for: [exp], timeout: timeout)

removeEveryObserver()
}

// Custimized
// If center is a Darwin notification center, this value must not be NULL.
override func testObserveNilNamedWithObject() {
let exp = expectation(description: #function)
exp.isInverted = true

notificationCenter
.addObserver(observer: self,
name: nil,
object: "hello" as CFString,
suspensionBehavior: .deliverImmediately) { center, observer, name, object, userInfo in
exp.fulfill()
}


notificationCenter.postNotification(name: .init(#function as CFString),
object: "hello" as CFString,
userInfo: [:] as CFDictionary,
deliverImmediately: true)

wait(for: [exp], timeout: timeout)

removeEveryObserver()
}
}
30 changes: 30 additions & 0 deletions Tests/SCFNotificationTests/SCFDistributedNotificationTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import XCTest
@testable import SCFNotification

class SCFDistributedNotificationTests: SCFNotificationTests {
override var centerType: SCFNotificationCenter.CenterType {
.distributed
}

// Custimized
// For distributed notifications, object must be a CFString object ?
override func testObserveNilNamed() {
let exp = expectation(description: #function)
exp.isInverted = true

notificationCenter
.addObserver(observer: self,
name: nil,
suspensionBehavior: .deliverImmediately) { center, observer, name, object, userInfo in
exp.fulfill()
}

notificationCenter.postNotification(name: .init(#function as CFString),
userInfo: [:] as CFDictionary,
deliverImmediately: true)

wait(for: [exp], timeout: timeout)

removeEveryObserver()
}
}
Loading