diff --git a/Sources/Nimble/Matchers/PostNotification.swift b/Sources/Nimble/Matchers/PostNotification.swift index edfd43127..6ec3c0268 100644 --- a/Sources/Nimble/Matchers/PostNotification.swift +++ b/Sources/Nimble/Matchers/PostNotification.swift @@ -27,6 +27,41 @@ internal class NotificationCollector { private let mainThread = pthread_self() +public func postNotifications( + _ predicate: Predicate<[Notification]>, + fromNotificationCenter center: NotificationCenter = .default +) -> Predicate { + _ = mainThread // Force lazy-loading of this value + let collector = NotificationCollector(notificationCenter: center) + collector.startObserving() + var once: Bool = false + + return Predicate { actualExpression in + let collectorNotificationsExpression = Expression( + memoizedExpression: { _ in + return collector.observedNotifications + }, + location: actualExpression.location, + withoutCaching: true + ) + + assert(pthread_equal(mainThread, pthread_self()) != 0, "Only expecting closure to be evaluated on main thread.") + if !once { + once = true + _ = try actualExpression.evaluate() + } + + let failureMessage = FailureMessage() + let match = try predicate.matches(collectorNotificationsExpression, failureMessage: failureMessage) + if collector.observedNotifications.isEmpty { + failureMessage.actualValue = "no notifications" + } else { + failureMessage.actualValue = "<\(stringify(collector.observedNotifications))>" + } + return PredicateResult(bool: match, message: failureMessage.toExpectationMessage()) + } +} + public func postNotifications( _ notificationsMatcher: T, fromNotificationCenter center: NotificationCenter = .default) diff --git a/Sources/Nimble/Matchers/SatisfyAllOf.swift b/Sources/Nimble/Matchers/SatisfyAllOf.swift index da3ea9aac..15de060b9 100644 --- a/Sources/Nimble/Matchers/SatisfyAllOf.swift +++ b/Sources/Nimble/Matchers/SatisfyAllOf.swift @@ -1,5 +1,11 @@ import Foundation +/// A Nimble matcher that succeeds when the actual value matches with all of the matchers +/// provided in the variable list of matchers. +public func satisfyAllOf(_ predicates: Predicate...) -> Predicate { + return satisfyAllOf(predicates) +} + /// A Nimble matcher that succeeds when the actual value matches with all of the matchers /// provided in the variable list of matchers. public func satisfyAllOf(_ matchers: U...) -> Predicate diff --git a/Sources/Nimble/Matchers/SatisfyAnyOf.swift b/Sources/Nimble/Matchers/SatisfyAnyOf.swift index 672495643..e8b379f15 100644 --- a/Sources/Nimble/Matchers/SatisfyAnyOf.swift +++ b/Sources/Nimble/Matchers/SatisfyAnyOf.swift @@ -1,5 +1,11 @@ import Foundation +/// A Nimble matcher that succeeds when the actual value matches with any of the matchers +/// provided in the variable list of matchers. +public func satisfyAnyOf(_ predicates: Predicate...) -> Predicate { + return satisfyAnyOf(predicates) +} + /// A Nimble matcher that succeeds when the actual value matches with any of the matchers /// provided in the variable list of matchers. public func satisfyAnyOf(_ matchers: U...) -> Predicate