Skip to content

Commit

Permalink
wip: Test with non-main queue
Browse files Browse the repository at this point in the history
  • Loading branch information
tmandry committed Jan 21, 2019
1 parent 8cecfe7 commit 908d459
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 48 deletions.
1 change: 1 addition & 0 deletions Sources/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ private struct NewWindowHandler<UIElement: Equatable> {
}

mutating func windowCreated(_ windowElement: UIElement) {
print("queue: \(queue)")
dispatchPrecondition(condition: .onQueue(queue))
handlers.filter({ $0.windowElement == windowElement }).forEach { entry in
entry.handler()
Expand Down
4 changes: 2 additions & 2 deletions Sources/FakeAXSwift.swift
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,8 @@ class FakeObserver: ObserverType {
passedElement: TestUIElement) {
let watched = watchedElements[watchedElement] ?? []
if watched.contains(notification) {
let queue = PromiseKit.conf.Q.return ?? DispatchQueue.main
queue.async {
// AX observer notifications always go to the run loop on the main thread.
DispatchQueue.main.async {
self.callback(self, passedElement, notification)
}
}
Expand Down
18 changes: 12 additions & 6 deletions Sources/FakeSwindler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ public class FakeState {
fileprivate typealias Delegate =
OSXStateDelegate<TestUIElement, AppElement, FakeObserver>

public static func initialize(screens: [FakeScreen] = [FakeScreen()],
queue: DispatchQueue = DispatchQueue.main) -> Promise<FakeState> {
public static func initialize(screens: [FakeScreen] = [FakeScreen()]) -> Promise<FakeState> {
let appObserver = FakeApplicationObserver()
let screens = FakeSystemScreenDelegate(screens: screens.map{ $0.delegate })
return firstly {
Delegate.initialize(appObserver: appObserver, screens: screens, queue: queue)
Delegate.initialize(appObserver: appObserver, screens: screens,
queue: globalSwindlerQueue)
}.map { delegate in
FakeState(delegate, appObserver)
FakeState(delegate, appObserver, globalSwindlerQueue)
}
}

Expand All @@ -47,10 +47,15 @@ public class FakeState {
fileprivate var delegate: Delegate
var appObserver: FakeApplicationObserver

private init(_ delegate: Delegate, _ appObserver: FakeApplicationObserver) {
let queue: DispatchQueue

private init(_ delegate: Delegate,
_ appObserver: FakeApplicationObserver,
_ queue: DispatchQueue) {
self.state = State(delegate: delegate)
self.delegate = delegate
self.appObserver = appObserver
self.queue = queue
}
}

Expand Down Expand Up @@ -248,7 +253,8 @@ public class FakeScreen {
}

public init(frame: CGRect, applicationFrame: CGRect) {
delegate = FakeScreenDelegate(frame: frame, applicationFrame: applicationFrame)
delegate = FakeScreenDelegate(frame: frame, applicationFrame: applicationFrame,
queue: globalSwindlerQueue)
}
public convenience init(frame: CGRect, menuBarHeight: Int, dockHeight: Int) {
let af = CGRect(x: frame.origin.x,
Expand Down
2 changes: 1 addition & 1 deletion Sources/Screen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ final class FakeScreenDelegate: ScreenDelegate {
let applicationFrame: CGRect
let queue: DispatchQueue

init(frame: CGRect, applicationFrame: CGRect, queue: DispatchQueue = DispatchQueue.main) {
init(frame: CGRect, applicationFrame: CGRect, queue: DispatchQueue) {
self.frame = frame
self.applicationFrame = applicationFrame
self.queue = queue
Expand Down
3 changes: 2 additions & 1 deletion Sources/State.swift
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import AXSwift
import PromiseKit

fileprivate var globalSwindlerQueue: DispatchQueue = DispatchQueue.main
// Don't use directly. Only internal because FakeSwindler needs it.
internal var globalSwindlerQueue: DispatchQueue = DispatchQueue.main

public func configureSwindlerQueue(qos: DispatchQoS = .userInteractive) -> DispatchQueue {
globalSwindlerQueue = DispatchQueue(label: "Swindler", qos: qos)
Expand Down
24 changes: 12 additions & 12 deletions SwindlerTests/ApplicationSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import Nimble
import AXSwift
import PromiseKit

class OSXApplicationDelegateInitializeSpec: QuickSpec {
override func spec() {
class OSXApplicationDelegateInitializeSpec: SwindlerSpec {
override func specWithQueues() {

var notifier: TestNotifier!
beforeEach {
notifier = TestNotifier(queue: swindlerQueue)
notifier = TestNotifier(queue: self.swindlerQueue)
}

describe("initialize") {
Expand Down Expand Up @@ -84,7 +84,7 @@ class OSXApplicationDelegateInitializeSpec: QuickSpec {
weak var notifier: TestNotifier?
var appDelegate: AppDelegate?
waitUntil { done in
let n = TestNotifier(queue: swindlerQueue)
let n = TestNotifier(queue: self.swindlerQueue)
notifier = n
AppDelegate.initialize(
axElement: appElement, stateDelegate: StubStateDelegate(), notifier: n
Expand Down Expand Up @@ -163,15 +163,15 @@ class OSXApplicationDelegateInitializeSpec: QuickSpec {
}
}

class OSXApplicationDelegateNotificationSpec: QuickSpec {
override func spec() {
class OSXApplicationDelegateNotificationSpec: SwindlerSpec {
override func specWithQueues() {

describe("AXUIElement notifications") {
var appElement: AdversaryApplicationElement!
var notifier: TestNotifier!
beforeEach {
appElement = AdversaryApplicationElement()
notifier = TestNotifier(queue: swindlerQueue)
notifier = TestNotifier(queue: self.swindlerQueue)
}
beforeEach { AdversaryObserver.reset() }

Expand Down Expand Up @@ -370,8 +370,8 @@ class OSXApplicationDelegateNotificationSpec: QuickSpec {
}
}

class OSXApplicationDelegateSpec: QuickSpec {
override func spec() {
class OSXApplicationDelegateSpec: SwindlerSpec {
override func specWithQueues() {

var appDelegate: OSXApplicationDelegate<
TestUIElement, AdversaryApplicationElement, FakeObserver
Expand Down Expand Up @@ -400,7 +400,7 @@ class OSXApplicationDelegateSpec: QuickSpec {
}

beforeEach {
notifier = TestNotifier(queue: swindlerQueue)
notifier = TestNotifier(queue: self.swindlerQueue)
appElement = AdversaryApplicationElement()
initializeApp()
}
Expand Down Expand Up @@ -568,8 +568,8 @@ class OSXApplicationDelegateSpec: QuickSpec {
// dispatch_async to wait for WindowCreated doesn't always work, so we defeat
// that here.
observer.emit(.mainWindowChanged, forElement: windowElement)
DispatchQueue.main.async {
DispatchQueue.main.async {
self.swindlerQueue.async {
self.swindlerQueue.async {
observer.emit(.windowCreated, forElement: windowElement)
}
}
Expand Down
10 changes: 5 additions & 5 deletions SwindlerTests/DelegateStubs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ class StubStateDelegate: StateDelegate {
var frontmostApplication: WriteableProperty<OfOptionalType<Swindler.Application>>!
var knownWindows: [WindowDelegate] = []
var systemScreens: SystemScreenDelegate { return fakeScreens }
var notifier: EventNotifier = EventNotifier(queue: swindlerQueue)
var notifier: EventNotifier = EventNotifier(queue: swindlerTestQueue)

var fakeScreens: FakeSystemScreenDelegate = FakeSystemScreenDelegate(screens: [])

var queue: DispatchQueue { return swindlerQueue }
var queue: DispatchQueue { return swindlerTestQueue }
}

class StubApplicationDelegate: ApplicationDelegate {
Expand All @@ -26,7 +26,7 @@ class StubApplicationDelegate: ApplicationDelegate {
var isFrontmost: WriteableProperty<OfType<Bool>>!
var isHidden: WriteableProperty<OfType<Bool>>!

var queue: DispatchQueue { return swindlerQueue }
var queue: DispatchQueue { return swindlerTestQueue }

func equalTo(_ other: ApplicationDelegate) -> Bool { return self === other }
}
Expand All @@ -46,7 +46,7 @@ class StubWindowDelegate: WindowDelegate {
let position_ = StubPropertyDelegate(value: CGPoint.zero)
let size_ = StubPropertyDelegate(value: CGSize.zero)

var queue: DispatchQueue { return swindlerQueue }
var queue: DispatchQueue { return swindlerTestQueue }

init() {
let notifier = TestPropertyNotifier()
Expand All @@ -68,7 +68,7 @@ class StubScreenDelegate: ScreenDelegate {
applicationFrame = frame
}

var queue: DispatchQueue { return swindlerQueue }
var queue: DispatchQueue { return swindlerTestQueue }

var debugDescription: String { return "StubScreenDelegate" }

Expand Down
6 changes: 3 additions & 3 deletions SwindlerTests/DriverSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import AXSwift
import PromiseKit

/// Tests that integrate the whole OS X driver instead of testing just one piece.
class OSXDriverSpec: QuickSpec {
override func spec() {
class OSXDriverSpec: SwindlerSpec {
override func specWithQueues() {

beforeEach { TestApplicationElement.allApps = [] }
beforeEach { FakeObserver.observers = [] }
Expand All @@ -28,7 +28,7 @@ class OSXDriverSpec: QuickSpec {
let screenDel = FakeSystemScreenDelegate(screens: [FakeScreen().delegate])
state = State(delegate: OSXStateDelegate<
TestUIElement, TestApplicationElement, FakeObserver
>(StubApplicationObserver(), screenDel, swindlerQueue))
>(StubApplicationObserver(), screenDel, self.swindlerQueue))
observer = FakeObserver.observers.first!
observer.emit(.windowCreated, forElement: windowElement)
expect(state.knownWindows.count).toEventually(equal(1))
Expand Down
12 changes: 6 additions & 6 deletions SwindlerTests/ScreenSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ public func ==<NSScreenT>(lhs: OSXScreenDelegate<NSScreenT>, rhs: OSXScreenDeleg
}
extension OSXScreenDelegate: Equatable {}

class OSXSystemScreenDelegateSpec: QuickSpec {
override func spec() {
class OSXSystemScreenDelegateSpec: SwindlerSpec {
override func specWithQueues() {

describe("handleScreenChange") {

var screen1: OSXScreenDelegate<StubNSScreen>!
var screen2: OSXScreenDelegate<StubNSScreen>!
beforeEach {
screen1 = OSXScreenDelegate(nsScreen: StubNSScreen(1), queue: swindlerQueue)
screen2 = OSXScreenDelegate(nsScreen: StubNSScreen(2), queue: swindlerQueue)
screen1 = OSXScreenDelegate(nsScreen: StubNSScreen(1), queue: self.swindlerQueue)
screen2 = OSXScreenDelegate(nsScreen: StubNSScreen(2), queue: self.swindlerQueue)
}

context("when nothing changes") {
Expand Down Expand Up @@ -90,7 +90,7 @@ class OSXSystemScreenDelegateSpec: QuickSpec {
oldNSScreen.frame = CGRect(x: 0, y: 0, width: 1280, height: 1080)
let event = handleScreenChange(
newScreens: [screen1],
oldScreens: [OSXScreenDelegate(nsScreen: oldNSScreen, queue: swindlerQueue)]
oldScreens: [OSXScreenDelegate(nsScreen: oldNSScreen, queue: self.swindlerQueue)]
)
expect(event.addedScreens).to(haveCount(0))
expect(event.removedScreens).to(haveCount(0))
Expand All @@ -107,7 +107,7 @@ class OSXSystemScreenDelegateSpec: QuickSpec {
let event = handleScreenChange(
newScreens: [screen1, screen2],
oldScreens: [
OSXScreenDelegate(nsScreen: oldNSScreen1, queue: swindlerQueue),
OSXScreenDelegate(nsScreen: oldNSScreen1, queue: self.swindlerQueue),
screen2
]
)
Expand Down
6 changes: 3 additions & 3 deletions SwindlerTests/StateSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ class FakeApplicationObserver: ApplicationObserverType {
}
}

class OSXStateDelegateSpec: QuickSpec {
override func spec() {
class OSXStateDelegateSpec: SwindlerSpec {
override func specWithQueues() {

beforeEach { TestApplicationElement.allApps = [] }
beforeEach { FakeObserver.observers = [] }
Expand All @@ -60,7 +60,7 @@ class OSXStateDelegateSpec: QuickSpec {
let screenDel = FakeSystemScreenDelegate(screens: [FakeScreen().delegate])
let stateDel = OSXStateDelegate<
TestUIElement, TestApplicationElement, TestObserver
>(appObserver, screenDel, swindlerQueue)
>(appObserver, screenDel, self.swindlerQueue)
waitUntil { done in
stateDel.frontmostApplication.initialized.done { done() }.cauterize()
}
Expand Down
18 changes: 9 additions & 9 deletions SwindlerTests/WindowSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import PromiseKit
// ensure it doesn't get destroyed. Same for app -> state. See #3.
private let stubApplicationDelegate = StubApplicationDelegate()

class OSXWindowDelegateInitializeSpec: QuickSpec {
override func spec() {
class OSXWindowDelegateInitializeSpec: SwindlerSpec {
override func specWithQueues() {

typealias WinDelegate = OSXWindowDelegate<
TestUIElement, TestApplicationElement, TestObserver
Expand All @@ -26,7 +26,7 @@ class OSXWindowDelegateInitializeSpec: QuickSpec {
let screen = FakeScreen(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))
let systemScreens = FakeSystemScreenDelegate(screens: [screen.delegate])
return WinDelegate.initialize(appDelegate: stubApplicationDelegate,
notifier: TestNotifier(queue: swindlerQueue),
notifier: TestNotifier(queue: self.swindlerQueue),
axElement: winElement,
observer: TestObserver(),
systemScreens: systemScreens)
Expand Down Expand Up @@ -126,8 +126,8 @@ class OSXWindowDelegateInitializeSpec: QuickSpec {
}
}

class OSXWindowDelegateNotificationSpec: QuickSpec {
override func spec() {
class OSXWindowDelegateNotificationSpec: SwindlerSpec {
override func specWithQueues() {

describe("AXUIElement notifications") {
beforeEach { AdversaryObserver.reset() }
Expand Down Expand Up @@ -156,7 +156,7 @@ class OSXWindowDelegateNotificationSpec: QuickSpec {
return AppDelegate
.initialize(axElement: appElement,
stateDelegate: StubStateDelegate(),
notifier: TestNotifier(queue: swindlerQueue))
notifier: TestNotifier(queue: self.swindlerQueue))
.map { appDelegate -> WinDelegate in
observer = appDelegate.observer
guard let winDelegate = appDelegate.knownWindows.first
Expand Down Expand Up @@ -225,8 +225,8 @@ class OSXWindowDelegateNotificationSpec: QuickSpec {
}
}

class OSXWindowDelegateSpec: QuickSpec {
override func spec() {
class OSXWindowDelegateSpec: SwindlerSpec {
override func specWithQueues() {

typealias WinDelegate = OSXWindowDelegate<
TestUIElement, TestApplicationElement, TestObserver
Expand All @@ -241,7 +241,7 @@ class OSXWindowDelegateSpec: QuickSpec {
windowElement.attrs[.size] = CGSize(width: 100, height: 100)
windowElement.attrs[.title] = "a window"

notifier = TestNotifier(queue: swindlerQueue)
notifier = TestNotifier(queue: self.swindlerQueue)
waitUntil { done in
let screen = FakeScreen(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000))
let systemScreens = FakeSystemScreenDelegate(screens: [screen.delegate])
Expand Down
29 changes: 29 additions & 0 deletions SwindlerTests/support/ExpectationHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,35 @@ import PromiseKit

let swindlerQueue = DispatchQueue.main

var swindlerTestQueue: DispatchQueue!

class SwindlerSpec: QuickSpec {
var swindlerQueue: DispatchQueue!

let serialQueue = DispatchQueue(label: "SwindlerTest")

final override func spec() {
context("on main queue") {
beforeEach {
self.swindlerQueue = DispatchQueue.main
swindlerTestQueue = self.swindlerQueue
PromiseKit.conf.Q = (map: self.swindlerQueue, return: self.swindlerQueue)
}
specWithQueues()
}
//context("on dedicated queue") {
// beforeEach {
// self.swindlerQueue = self.serialQueue
// PromiseKit.conf.Q = (map: self.swindlerQueue, return: self.swindlerQueue)
// }
// specWithQueues()
//}
}

// Override this.
func specWithQueues() { }
}

func waitUntil(_ expression: @autoclosure @escaping () throws -> Bool,
file: String = #file,
line: UInt = #line) {
Expand Down

0 comments on commit 908d459

Please sign in to comment.