Add Unit tests
This commit is contained in:
parent
a4e4611b2a
commit
20bdda6747
Binary file not shown.
|
@ -26,7 +26,8 @@
|
|||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
codeCoverageEnabled = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
|
|
|
@ -23,7 +23,7 @@ public enum SModalStatus {
|
|||
}
|
||||
|
||||
public class SModal {
|
||||
static let modalWindow: UIWindow = {
|
||||
public static let modalWindow: UIWindow = {
|
||||
let window = UIWindow(frame: UIScreen.main.bounds)
|
||||
window.backgroundColor = .clear
|
||||
window.windowLevel = windowLevel
|
||||
|
@ -31,15 +31,31 @@ public class SModal {
|
|||
return window
|
||||
}()
|
||||
|
||||
static var stack: [SModalPresentation] = []
|
||||
public static var stack: [SModalPresentation] = []
|
||||
|
||||
static var windowLevel: UIWindowLevel {
|
||||
public static var shouldMakeKey: Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
public static var windowLevel: UIWindowLevel {
|
||||
return UIWindowLevelAlert - 1
|
||||
}
|
||||
|
||||
static var animationDuration: TimeInterval {
|
||||
public static var animationDuration: TimeInterval {
|
||||
return 0.2
|
||||
}
|
||||
|
||||
fileprivate static func dropRootViewController() {
|
||||
modalWindow.isHidden = true
|
||||
modalWindow.rootViewController = nil
|
||||
modalWindow.resignKey()
|
||||
}
|
||||
|
||||
fileprivate static func makeKey() {
|
||||
if shouldMakeKey {
|
||||
SModal.modalWindow.makeKey()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public protocol SModalStack {
|
||||
|
@ -79,29 +95,29 @@ extension SModalPresentation {
|
|||
}
|
||||
|
||||
extension SModalPresentation where Self: UIViewController {
|
||||
func sReplace<T: UIViewController>(with controller: T, animated: Bool, completion: (() -> Void)?) where T: SModalPresentation {
|
||||
public func sReplace<T: UIViewController>(with controller: T, animated: Bool = false, completion: (() -> Void)? = nil) where T: SModalPresentation {
|
||||
if animated {
|
||||
SModal.modalWindow.isHidden = false
|
||||
UIView.animate(withDuration: SModal.animationDuration, animations: {
|
||||
SModal.modalWindow.rootViewController = controller
|
||||
SModal.modalWindow.makeKey()
|
||||
SModal.makeKey()
|
||||
SModal.modalWindow.alpha = 1
|
||||
}, completion: { completed in
|
||||
completion?()
|
||||
})
|
||||
} else {
|
||||
SModal.modalWindow.rootViewController = controller
|
||||
SModal.modalWindow.makeKey()
|
||||
SModal.makeKey()
|
||||
SModal.modalWindow.isHidden = false
|
||||
completion?()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func sPresent(animated: Bool, completion: (() -> Void)?) {
|
||||
public func sPresent(animated: Bool = false, completion: (() -> Void)? = nil) {
|
||||
guard let currentPresented = SModal.modalWindow.rootViewController else {
|
||||
SModal.modalWindow.rootViewController = self
|
||||
SModal.modalWindow.makeKey()
|
||||
SModal.makeKey()
|
||||
if animated {
|
||||
SModal.modalWindow.alpha = 0
|
||||
SModal.modalWindow.isHidden = false
|
||||
|
@ -116,40 +132,39 @@ extension SModalPresentation where Self: UIViewController {
|
|||
}
|
||||
return
|
||||
}
|
||||
if let sModalController = currentPresented as? Self, sModalController.canDismiss == true {
|
||||
sModalController.sReplace(with: self, animated: animated, completion: completion)
|
||||
SModal.stack.append(self)
|
||||
if (currentPresented as? SModalPresentation)?.canDismiss == true {
|
||||
(currentPresented as? SModalPresentation)?.sWithdraw(animated: animated, completion: completion)
|
||||
} else {
|
||||
SModal.stack.append(self)
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
func sWithdraw(animated: Bool, completion: (() -> Void)?) {
|
||||
public func sWithdraw(animated: Bool = false, completion: (() -> Void)? = nil) {
|
||||
func completedProcedure() {
|
||||
if let controller = SModal.stack.sorted(by: {$0.priority > $1.priority}).first {
|
||||
SModal.stack = SModal.stack.filter({ $0 !== controller })
|
||||
controller.sPresent(animated: animated, completion: completion)
|
||||
}else {
|
||||
completion?()
|
||||
}
|
||||
}
|
||||
|
||||
if SModal.modalWindow.rootViewController === self {
|
||||
if animated {
|
||||
SModal.modalWindow.alpha = 1
|
||||
UIView.animate(withDuration: SModal.animationDuration, animations: {
|
||||
SModal.modalWindow.alpha = 0
|
||||
}, completion: { completed in
|
||||
SModal.modalWindow.isHidden = true
|
||||
completion?()
|
||||
SModal.dropRootViewController()
|
||||
completedProcedure()
|
||||
})
|
||||
} else {
|
||||
SModal.modalWindow.isHidden = true
|
||||
completion?()
|
||||
SModal.dropRootViewController()
|
||||
completedProcedure()
|
||||
}
|
||||
SModal.modalWindow.rootViewController = nil
|
||||
SModal.modalWindow.resignKey()
|
||||
} else if SModal.stack.contains(where: { $0 === self }) {
|
||||
SModal.stack = SModal.stack.filter() { !($0 === self) }
|
||||
}
|
||||
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + SModal.animationDuration) {
|
||||
if let controller = SModal.stack.sorted(by: {$0.priority > $1.priority}).first {
|
||||
SModal.stack.removeFirst()
|
||||
controller.sPresent(animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -13,23 +13,166 @@ class SWindowTests: XCTestCase {
|
|||
|
||||
override func setUp() {
|
||||
super.setUp()
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDown() {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
func testExample() {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||
func testLowPriority() {
|
||||
XCTAssert(SModalPriority.Low == 250)
|
||||
}
|
||||
|
||||
func testPerformanceExample() {
|
||||
// This is an example of a performance test case.
|
||||
self.measure {
|
||||
// Put the code you want to measure the time of here.
|
||||
func testRequiredPriority() {
|
||||
XCTAssert(SModalPriority.Required == 500)
|
||||
}
|
||||
|
||||
func testHighPriority() {
|
||||
XCTAssert(SModalPriority.High == 750)
|
||||
}
|
||||
|
||||
func testSModalWindow() {
|
||||
XCTAssertNotNil(SModal.modalWindow)
|
||||
}
|
||||
|
||||
func testSModalWindowLevel() {
|
||||
XCTAssert(SModal.windowLevel == UIWindowLevelAlert - 1)
|
||||
}
|
||||
|
||||
func testSModalWindowStack() {
|
||||
XCTAssertNotNil(SModal.stack)
|
||||
}
|
||||
|
||||
func testSModalDuration() {
|
||||
XCTAssertEqualWithAccuracy(SModal.animationDuration, 0.2, accuracy: 0.01)
|
||||
}
|
||||
|
||||
func testModalCanDismiss() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
XCTAssert(!controller.canDismiss)
|
||||
}
|
||||
|
||||
func testModalStatusNone() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
XCTAssert(controller.modalStatus == .none)
|
||||
}
|
||||
|
||||
func testModalStatusPresented() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
SModal.modalWindow.rootViewController = controller
|
||||
XCTAssert(controller.modalStatus == .presented)
|
||||
}
|
||||
|
||||
func testModalStatusWaitingInStack() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
SModal.stack.append(controller)
|
||||
XCTAssert(controller.modalStatus == .waitingInStack)
|
||||
}
|
||||
|
||||
func testModalStatusStack() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
XCTAssertNotNil(controller.stack)
|
||||
}
|
||||
|
||||
func testModalStatusPriority() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
XCTAssertNotNil(controller.priority == .Required)
|
||||
}
|
||||
|
||||
func testModalPresentationStack() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
SModal.modalWindow.rootViewController = controller
|
||||
|
||||
let controllerToPresent = Controller()
|
||||
controllerToPresent.sPresent()
|
||||
XCTAssert(SModal.stack.contains(where: { $0 === controllerToPresent }))
|
||||
}
|
||||
|
||||
func testModalPresentationCanDismiss() {
|
||||
class Controller: UIViewController, SModalPresentation {
|
||||
var canDismiss: Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
let controller = Controller()
|
||||
SModal.modalWindow.rootViewController = controller
|
||||
class ControllerHigh: UIViewController, SModalPresentation {}
|
||||
let controllerToPresent = ControllerHigh()
|
||||
controllerToPresent.sPresent {
|
||||
XCTAssertTrue(SModal.modalWindow.rootViewController === controllerToPresent)
|
||||
}
|
||||
}
|
||||
|
||||
func testModalPresentationStackWithdraw() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
|
||||
class ControllerTwo: UIViewController, SModalPresentation {}
|
||||
let controllerTwo = ControllerTwo()
|
||||
|
||||
class ControllerThree: UIViewController, SModalPresentation {}
|
||||
let controllerThree = ControllerThree()
|
||||
|
||||
SModal.stack.append(controller)
|
||||
SModal.stack.append(controllerTwo)
|
||||
SModal.stack.append(controllerThree)
|
||||
|
||||
controllerTwo.sWithdraw {
|
||||
XCTAssertFalse(controller.modalStatus == .waitingInStack)
|
||||
}
|
||||
}
|
||||
|
||||
func testModalPresentationPriorityAnimated() {
|
||||
class Controller: UIViewController, SModalPresentation {
|
||||
var canDismiss: Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
let controller = Controller()
|
||||
SModal.modalWindow.rootViewController = controller
|
||||
class ControllerHigh: UIViewController, SModalPresentation {}
|
||||
let controllerToPresent = ControllerHigh()
|
||||
controllerToPresent.sPresent(animated: true) {
|
||||
XCTAssertFalse(SModal.modalWindow.rootViewController === controller)
|
||||
}
|
||||
}
|
||||
|
||||
func testModalPresentationStackWithdrawAnimated() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
|
||||
class ControllerTwo: UIViewController, SModalPresentation {}
|
||||
let controllerTwo = ControllerTwo()
|
||||
|
||||
class ControllerThree: UIViewController, SModalPresentation {}
|
||||
let controllerThree = ControllerThree()
|
||||
|
||||
SModal.stack.append(controller)
|
||||
SModal.stack.append(controllerTwo)
|
||||
SModal.stack.append(controllerThree)
|
||||
|
||||
controllerTwo.sWithdraw(animated: true) {
|
||||
XCTAssertFalse(controller.modalStatus == .waitingInStack)
|
||||
}
|
||||
}
|
||||
|
||||
func testModalPresentationReplace() {
|
||||
class Controller: UIViewController, SModalPresentation {}
|
||||
let controller = Controller()
|
||||
|
||||
class ControllerTwo: UIViewController, SModalPresentation {}
|
||||
let controllerTwo = ControllerTwo()
|
||||
|
||||
SModal.modalWindow.rootViewController = controller
|
||||
controller.sReplace(with: controllerTwo) {
|
||||
XCTAssertTrue(SModal.modalWindow.rootViewController === controllerTwo)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue