Skip to content

Instantly share code, notes, and snippets.

@mattgrayson
Created April 18, 2017 21:46
Show Gist options
  • Save mattgrayson/968e454f1ef398bfff082336e39daf81 to your computer and use it in GitHub Desktop.
Save mattgrayson/968e454f1ef398bfff082336e39daf81 to your computer and use it in GitHub Desktop.
Helper class for presenting view controllers from context of an Xcode unit testing target.
//
// Helper class for presenting view controllers from context of an Xcode unit testing target.
//
// Ported from original Objective-C version at
// https://github.com/klaaspieter/KPAViewControllerTestHelper/blob/master/Classes/KPAViewControllerTestHelper.m
//
import Foundation
import UIKit
public class ViewControllerTestHelper {
typealias ContainerViewControllerPresentationBlock = (_ containerViewController: UIViewController, _ viewController: UIViewController) -> Void
static var testHelperWindows: [UIWindow] = [UIWindow]()
@discardableResult
static func prepareWindowWithRootViewController(rootViewController: UIViewController) -> UIWindow {
var frame = UIScreen.main.bounds
frame.origin = CGPoint(x: 0, y: 0)
let window = UIWindow(frame: frame)
window.backgroundColor = UIColor.white
window.makeKeyAndVisible()
window.rootViewController = rootViewController
wait()
testHelperWindows.append(window)
return window
}
static func presentViewController(viewController: UIViewController) {
makeViewControllerVisible(controller: viewController, inContainerViewController: emptyViewController()) { (containerViewController, viewController) -> Void in
containerViewController.present(viewController, animated: false, completion: nil)
}
}
static func pushViewController(viewController: UIViewController) {
let navigationController = UINavigationController(rootViewController: emptyViewController())
makeViewControllerVisible(controller: viewController, inContainerViewController: navigationController) { (containerViewController, viewController) -> Void in
navigationController.pushViewController(viewController, animated: false)
}
}
static func dismissViewController(viewController: UIViewController) {
viewController.dismiss(animated: false, completion: nil)
wait()
}
static func presentAndDismissViewController(viewController: UIViewController) {
presentViewController(viewController: viewController)
dismissViewController(viewController: viewController)
}
static func wait() {
wait(seconds: 0.01)
}
static func wait(seconds: TimeInterval) {
RunLoop.main.run(until: NSDate(timeIntervalSinceNow: seconds) as Date)
}
static func emptyViewController() -> UIViewController {
let viewController = UIViewController()
viewController.view = UIView()
return viewController
}
static func makeViewControllerVisible(controller: UIViewController, inContainerViewController container: UIViewController, withPresentationBlock presentationBlock: ContainerViewControllerPresentationBlock) {
prepareWindowWithRootViewController(rootViewController: container)
presentationBlock(container, controller)
wait()
}
static func tearDown() {
testHelperWindows.forEach { window in
window.isHidden = true
}
wait()
testHelperWindows = [UIWindow]()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment