diff --git a/UIUTestBDDExample/UIUTestExample.xcodeproj/project.pbxproj b/UIUTestBDDExample/UIUTestExample.xcodeproj/project.pbxproj index 0f14765..9b6c864 100644 --- a/UIUTestBDDExample/UIUTestExample.xcodeproj/project.pbxproj +++ b/UIUTestBDDExample/UIUTestExample.xcodeproj/project.pbxproj @@ -25,7 +25,9 @@ 8E381D5E670EED0B2BA006DC /* Pods_UIUTestExampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5C0EB2299B7315E9B5B563D /* Pods_UIUTestExampleTests.framework */; }; AD99DB5B2133497C00E57823 /* Features in Resources */ = {isa = PBXBuildFile; fileRef = AD99DB5A2133497700E57823 /* Features */; }; AD99DB5D21334D2800E57823 /* CucumberTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD99DB5C21334D2800E57823 /* CucumberTests.swift */; }; - AD99DB6021334D5000E57823 /* Authentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD99DB5F21334D5000E57823 /* Authentication.swift */; }; + AD99DB6021334D5000E57823 /* AuthenticationFromGherkinFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD99DB5F21334D5000E57823 /* AuthenticationFromGherkinFile.swift */; }; + CA571B5125227C370002D19A /* AuthenticationDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA571B5025227C370002D19A /* AuthenticationDSL.swift */; }; + CA571B5525227C530002D19A /* TestAuthenticator.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA571B5425227C530002D19A /* TestAuthenticator.swift */; }; D1AC973D0D54D9C95EB42AA5 /* Pods_UIUTestExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C08288D10456E19BC088E068 /* Pods_UIUTestExample.framework */; }; /* End PBXBuildFile section */ @@ -54,8 +56,10 @@ 664BAE291D419502044471C9 /* Pods-UIUTestExampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UIUTestExampleTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-UIUTestExampleTests/Pods-UIUTestExampleTests.release.xcconfig"; sourceTree = ""; }; AD99DB5A2133497700E57823 /* Features */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Features; sourceTree = ""; }; AD99DB5C21334D2800E57823 /* CucumberTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CucumberTests.swift; sourceTree = ""; }; - AD99DB5F21334D5000E57823 /* Authentication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Authentication.swift; sourceTree = ""; }; + AD99DB5F21334D5000E57823 /* AuthenticationFromGherkinFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationFromGherkinFile.swift; sourceTree = ""; }; C08288D10456E19BC088E068 /* Pods_UIUTestExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UIUTestExample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CA571B5025227C370002D19A /* AuthenticationDSL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationDSL.swift; sourceTree = ""; }; + CA571B5425227C530002D19A /* TestAuthenticator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestAuthenticator.swift; sourceTree = ""; }; D1436C3D90C9E895E2892341 /* Pods-UIUTestExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-UIUTestExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-UIUTestExample/Pods-UIUTestExample.debug.xcconfig"; sourceTree = ""; }; D5C0EB2299B7315E9B5B563D /* Pods_UIUTestExampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_UIUTestExampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -127,6 +131,7 @@ AD99DB5A2133497700E57823 /* Features */, 010B1BB7201D924E00448B0E /* Info.plist */, AD99DB5C21334D2800E57823 /* CucumberTests.swift */, + CA571B5425227C530002D19A /* TestAuthenticator.swift */, ); path = UIUTestExampleTests; sourceTree = ""; @@ -155,7 +160,8 @@ AD99DB5E21334D4400E57823 /* Step_Definitions */ = { isa = PBXGroup; children = ( - AD99DB5F21334D5000E57823 /* Authentication.swift */, + AD99DB5F21334D5000E57823 /* AuthenticationFromGherkinFile.swift */, + CA571B5025227C370002D19A /* AuthenticationDSL.swift */, ); path = Step_Definitions; sourceTree = ""; @@ -358,7 +364,9 @@ buildActionMask = 2147483647; files = ( AD99DB5D21334D2800E57823 /* CucumberTests.swift in Sources */, - AD99DB6021334D5000E57823 /* Authentication.swift in Sources */, + CA571B5525227C530002D19A /* TestAuthenticator.swift in Sources */, + AD99DB6021334D5000E57823 /* AuthenticationFromGherkinFile.swift in Sources */, + CA571B5125227C370002D19A /* AuthenticationDSL.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/UIUTestBDDExample/UIUTestExampleTests/CucumberTests.swift b/UIUTestBDDExample/UIUTestExampleTests/CucumberTests.swift index 5d31315..f68173a 100644 --- a/UIUTestBDDExample/UIUTestExampleTests/CucumberTests.swift +++ b/UIUTestBDDExample/UIUTestExampleTests/CucumberTests.swift @@ -1,9 +1,8 @@ // // CucumberTests.swift -// UIUTestExampleTests // // Created by Tyler Thompson on 8/26/18. -// Copyright © 2018 Purgatory Design. All rights reserved. +// Copyright © 2018-2021 Purgatory Design. All rights reserved. // import Foundation @@ -16,9 +15,8 @@ extension Cucumber: StepImplementation { } public func setupSteps() { - UIViewController.initializeTestable() - setupAuthenticationTests() + AuthenticationDSLSteps().setup() } } diff --git a/UIUTestBDDExample/UIUTestExampleTests/Features/AuthenticationTests.feature b/UIUTestBDDExample/UIUTestExampleTests/Features/AuthenticationTests.feature index 9ad99b6..063df75 100644 --- a/UIUTestBDDExample/UIUTestExampleTests/Features/AuthenticationTests.feature +++ b/UIUTestBDDExample/UIUTestExampleTests/Features/AuthenticationTests.feature @@ -10,7 +10,7 @@ Feature: Authentication Scenario: I want to know if I can't sign in Given I am not logged in When I have not entered a valid username - Or I have not entered a valid password + And I have not entered a valid password Then I can't sign in Scenario: I want to see my password diff --git a/UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/AuthenticationDSL.swift b/UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/AuthenticationDSL.swift new file mode 100644 index 0000000..31688fd --- /dev/null +++ b/UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/AuthenticationDSL.swift @@ -0,0 +1,123 @@ +// +// AuthenticationDSL.swift +// UIUTestExampleTests +// +// Created by thompsty on 9/28/20. +// Copyright © 2020 Purgatory Design. All rights reserved. +// + +import Foundation +import CucumberSwift +import UIUTest +import XCTest +import UIUTestExample + +extension Cucumber { + class AuthenticationDSLSteps { + var viewController: AuthenticationViewController! + var userNameField: UITextField! + var passwordField: UITextField! + var showPasswordButton: UIButton! + var authenticateButton: UIButton! + var invalidCredentialsLabel: UILabel! + func setup() { + Feature("Authentication") { () -> [ScenarioDSL] in + Scenario("I want to know when I can sign in") { [self] in + Given(I: amNotLoggedIn()) + When(I: enterAValidUsername()) + And(I: enterAValidPassword()) + Then(I: canSignIn()) + } + Scenario("I want to know if I can't sign in") { [self] in + Given(I: amNotLoggedIn()) + When(I: haveNotEnteredAValidUsername()) + And(I: haveNotEnteredAValidPassword()) + Then(I: cannotSignIn()) + } + Scenario("I want to see my password") { [self] in + Given(I: amNotLoggedIn()) + When(I: enterAValidPassword()) + And(I: wantToSeeWhatITyped()) + Then(my: passwordIsNotObscured()) + } + Scenario("I log in successfully") { [self] in + Given(I: amNotLoggedIn()) + When(I: enterValidCredentials()) + And(I: signIn()) + Then(I: seeTheNextScreen()) + } + Scenario("I enter the wrong credentials") { [self] in + Given(I: amNotLoggedIn()) + When(I: enterAValidUsername()) + But(I: haveNotEnteredAValidPassword()) + Then(I: amNotLoggedIn()) + } + } + } + + private func amNotLoggedIn() { + viewController = (UIViewController.loadFromStoryboard(identifier: "Authentication") as! AuthenticationViewController) + let view = viewController.view! + userNameField = (view.viewWithAccessibilityIdentifier("userName") as! UITextField) + passwordField = (view.viewWithAccessibilityIdentifier("password") as! UITextField) + showPasswordButton = (view.viewWithAccessibilityIdentifier("showPassword") as! UIButton) + authenticateButton = (view.viewWithAccessibilityIdentifier("authenticate") as! UIButton) + invalidCredentialsLabel = (view.viewWithAccessibilityIdentifier("invalidCredentials") as! UILabel) + XCTAssertFalse(authenticateButton.isEnabled) + } + + private func enterValidCredentials() { + viewController.setAuthenticator(TestAuthenticator()) + userNameField.text = TestAuthenticator.validUser + passwordField.setTextAndNotify(TestAuthenticator.validPassword) + } + + private func enterAValidUsername() { + userNameField.simulateTouch() + userNameField.simulateTyping("Test User") + } + + private func haveNotEnteredAValidUsername() { + userNameField.simulateTouch() + userNameField.simulateTyping(nil) + } + + private func haveNotEnteredAValidPassword() { + passwordField.setTextAndNotify(TestAuthenticator.invalidPassword) + } + + private func enterAValidPassword() { + passwordField.simulateTouch() + passwordField.simulateTyping("Test Password") + } + + private func canSignIn() { + XCTAssertTrue(authenticateButton.isEnabled) + } + + private func cannotSignIn() { + XCTAssertFalse(authenticateButton.isEnabled) + } + + private func wantToSeeWhatITyped() { + XCTAssertTrue(viewController.passwordIsSecure) + XCTAssertTrue(passwordField.isSecureTextEntry) + XCTAssertEqual(showPasswordButton.currentTitle!, "SHOW") + showPasswordButton.simulateTouch() + } + + private func passwordIsNotObscured() { + XCTAssertFalse(viewController.passwordIsSecure) + XCTAssertFalse(passwordField.isSecureTextEntry) + XCTAssertEqual(showPasswordButton.currentTitle!, "HIDE") + } + + private func seeTheNextScreen() { + XCTAssertTrue(viewController.hasBeenDismissed) + } + + private func signIn() { + authenticateButton.simulateTouch() + } + } +} diff --git a/UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/Authentication.swift b/UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/AuthenticationFromGherkinFile.swift similarity index 84% rename from UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/Authentication.swift rename to UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/AuthenticationFromGherkinFile.swift index c1ae684..5f45dd7 100644 --- a/UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/Authentication.swift +++ b/UIUTestBDDExample/UIUTestExampleTests/Step_Definitions/AuthenticationFromGherkinFile.swift @@ -12,18 +12,6 @@ import UIUTest import XCTest import UIUTestExample -struct TestAuthenticator: Authenticator -{ - static let validUser = "Test User" - static let invalidUser = "Invalid User" - static let validPassword = "Test Password" - static let invalidPassword = "Invalid Password" - - func authenticate(user: String, password: String) -> Bool { - return (user == TestAuthenticator.validUser && password == TestAuthenticator.validPassword) - } -} - extension Cucumber { func setupAuthenticationTests() { var viewController: AuthenticationViewController! @@ -31,7 +19,6 @@ extension Cucumber { var passwordField: UITextField! var showPasswordButton: UIButton! var authenticateButton: UIButton! - var invalidCredentialsLabel: UILabel! MatchAll("^I am not logged in$") { _, _ in viewController = (UIViewController.loadFromStoryboard(identifier: "Authentication") as! AuthenticationViewController) @@ -40,7 +27,6 @@ extension Cucumber { passwordField = (view.viewWithAccessibilityIdentifier("password") as! UITextField) showPasswordButton = (view.viewWithAccessibilityIdentifier("showPassword") as! UIButton) authenticateButton = (view.viewWithAccessibilityIdentifier("authenticate") as! UIButton) - invalidCredentialsLabel = (view.viewWithAccessibilityIdentifier("invalidCredentials") as! UILabel) XCTAssertFalse(authenticateButton.isEnabled) } When("^I enter a valid username$") { _, _ in diff --git a/UIUTestBDDExample/UIUTestExampleTests/TestAuthenticator.swift b/UIUTestBDDExample/UIUTestExampleTests/TestAuthenticator.swift new file mode 100644 index 0000000..0c6b5b8 --- /dev/null +++ b/UIUTestBDDExample/UIUTestExampleTests/TestAuthenticator.swift @@ -0,0 +1,22 @@ +// +// TestAuthenticator.swift +// UIUTestExampleTests +// +// Created by thompsty on 9/28/20. +// Copyright © 2020 Purgatory Design. All rights reserved. +// + +import Foundation +import UIUTestExample + +struct TestAuthenticator: Authenticator +{ + static let validUser = "Test User" + static let invalidUser = "Invalid User" + static let validPassword = "Test Password" + static let invalidPassword = "Invalid Password" + + func authenticate(user: String, password: String) -> Bool { + return (user == TestAuthenticator.validUser && password == TestAuthenticator.validPassword) + } +} diff --git a/UIUTestCocoaPodsExample/UIUTestExampleTests/AuthenticationTests.swift b/UIUTestCocoaPodsExample/UIUTestExampleTests/AuthenticationTests.swift index 1c107ae..790de9a 100644 --- a/UIUTestCocoaPodsExample/UIUTestExampleTests/AuthenticationTests.swift +++ b/UIUTestCocoaPodsExample/UIUTestExampleTests/AuthenticationTests.swift @@ -1,7 +1,7 @@ // // AuthenticationTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -31,8 +31,6 @@ class AuthenticationTests: XCTestCase override func setUp() { super.setUp() - - UIViewController.initializeTestable() initializeTest() } diff --git a/UIUTestCocoaPodsExample/UIUTestExampleTests/ButtonsViewControllerTests.swift b/UIUTestCocoaPodsExample/UIUTestExampleTests/ButtonsViewControllerTests.swift index 0ab2c66..81c77ee 100644 --- a/UIUTestCocoaPodsExample/UIUTestExampleTests/ButtonsViewControllerTests.swift +++ b/UIUTestCocoaPodsExample/UIUTestExampleTests/ButtonsViewControllerTests.swift @@ -1,7 +1,7 @@ // // ButtonsViewControllerTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -10,11 +10,6 @@ import UIUTestExample class ButtonsViewControllerTests: XCTestCase { - override func setUp() { - super.setUp() - UIViewController.initializeTestable() - } - override func tearDown() { super.tearDown() UIViewController.flushPendingTestArtifacts() diff --git a/UIUTestCocoaPodsExample/UIUTestExampleTests/InfoViewControllerTests.swift b/UIUTestCocoaPodsExample/UIUTestExampleTests/InfoViewControllerTests.swift index 32bbe29..fde626b 100644 --- a/UIUTestCocoaPodsExample/UIUTestExampleTests/InfoViewControllerTests.swift +++ b/UIUTestCocoaPodsExample/UIUTestExampleTests/InfoViewControllerTests.swift @@ -1,7 +1,7 @@ // // InfoViewControllerTests.swift // -// Copyright © 2017-2019 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -16,7 +16,6 @@ class InfoViewControllerTests: XCTestCase super.setUp() self.continueAfterFailure = false - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard(identifier: "InfoViewController") as! InfoViewController) view = viewController.view! } diff --git a/UIUTestCocoaPodsExample/UIUTestExampleTests/SwitchesViewControllerTests.swift b/UIUTestCocoaPodsExample/UIUTestExampleTests/SwitchesViewControllerTests.swift index 5a819d4..21f88d8 100644 --- a/UIUTestCocoaPodsExample/UIUTestExampleTests/SwitchesViewControllerTests.swift +++ b/UIUTestCocoaPodsExample/UIUTestExampleTests/SwitchesViewControllerTests.swift @@ -1,7 +1,7 @@ // // SwitchesViewControllerTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -15,7 +15,6 @@ class SwitchesViewControllerTests: XCTestCase override func setUp() { super.setUp() - UIViewController.initializeTestable() let viewController = UIViewController.loadFromStoryboard(identifier: "SwitchesViewController") as! SwitchesViewController view = viewController.view! } diff --git a/UIUTestCocoaPodsExample/UIUTestExampleTests/TabBarControllerTests.swift b/UIUTestCocoaPodsExample/UIUTestExampleTests/TabBarControllerTests.swift index 2532bb0..ba82dfb 100644 --- a/UIUTestCocoaPodsExample/UIUTestExampleTests/TabBarControllerTests.swift +++ b/UIUTestCocoaPodsExample/UIUTestExampleTests/TabBarControllerTests.swift @@ -1,7 +1,7 @@ // // TabBarControllerTests.swift // -// Copyright © 2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2018-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -14,8 +14,6 @@ class TabBarControllerTests: XCTestCase override func setUp() { super.setUp() - - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard() as! UITabBarController) } diff --git a/UIUTestCocoaPodsExample/UIUTestExampleTests/TableViewControllerTests.swift b/UIUTestCocoaPodsExample/UIUTestExampleTests/TableViewControllerTests.swift index 9bed617..c562442 100644 --- a/UIUTestCocoaPodsExample/UIUTestExampleTests/TableViewControllerTests.swift +++ b/UIUTestCocoaPodsExample/UIUTestExampleTests/TableViewControllerTests.swift @@ -1,7 +1,7 @@ // // TableViewControllerTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -16,7 +16,6 @@ class TableViewControllerTests: XCTestCase override func setUp() { super.setUp() - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard(identifier: "TableViewController") as! TableViewController) tableView = viewController.tableView! } diff --git a/UIUTestCocoaPodsExample/UIUTestExampleTests/ToolbarViewControllerTests.swift b/UIUTestCocoaPodsExample/UIUTestExampleTests/ToolbarViewControllerTests.swift index eb8aae3..047064e 100644 --- a/UIUTestCocoaPodsExample/UIUTestExampleTests/ToolbarViewControllerTests.swift +++ b/UIUTestCocoaPodsExample/UIUTestExampleTests/ToolbarViewControllerTests.swift @@ -1,7 +1,7 @@ // // ToolbarViewControllerTests.swift // -// Copyright © 2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2018-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -17,7 +17,6 @@ class ToolbarViewControllerTests: XCTestCase override func setUp() { super.setUp() - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard(identifier: "ToolbarViewController") as! ToolbarViewController) view = viewController.view! } diff --git a/UIUTestSPMExample/UIUTestExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/UIUTestSPMExample/UIUTestExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 3d722af..9b1ebc4 100644 --- a/UIUTestSPMExample/UIUTestExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/UIUTestSPMExample/UIUTestExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "repositoryURL": "https://github.com/nallick/UIUTest.git", "state": { "branch": null, - "revision": "f5c04ab82cc118ffc2818b0c8c607eed0fc1e381", - "version": "1.4.0" + "revision": "33cc7be1352dfdb37984e38e4276daa65030c5bc", + "version": "1.8.0" } } ] diff --git a/UIUTestSPMExample/UIUTestExample/Main.storyboard b/UIUTestSPMExample/UIUTestExample/Main.storyboard index 6a3f38b..b587ad4 100644 --- a/UIUTestSPMExample/UIUTestExample/Main.storyboard +++ b/UIUTestSPMExample/UIUTestExample/Main.storyboard @@ -1,11 +1,9 @@ - - - - + + - + @@ -23,11 +21,11 @@ - + - + + @@ -682,7 +713,7 @@ - + @@ -733,13 +764,14 @@ + @@ -748,7 +780,6 @@ - @@ -767,7 +798,7 @@ - + diff --git a/UIUTestSPMExample/UIUTestExample/SwitchesViewController.swift b/UIUTestSPMExample/UIUTestExample/SwitchesViewController.swift index f2a6f15..1ce0b70 100644 --- a/UIUTestSPMExample/UIUTestExample/SwitchesViewController.swift +++ b/UIUTestSPMExample/UIUTestExample/SwitchesViewController.swift @@ -14,7 +14,10 @@ public class SwitchesViewController: UIViewController @IBOutlet private var switchBulbLabel: UILabel! @IBOutlet private var sliderBulbLabel: UILabel! @IBOutlet private var textBulbLabel: UILabel! - @IBOutlet private var sliderAlphaLabel: UILabel! + @IBOutlet private var sliderAlphaLabel: UILabel! + @IBOutlet private var injectedLabel: UILabel! + + private var injectedText = "" @IBAction private func toggleButtonBulb(_ sender: Any) { self.buttonBulbLabel.isHidden = !self.buttonBulbLabel.isHidden @@ -30,6 +33,16 @@ public class SwitchesViewController: UIViewController self.sliderAlphaLabel.text = "\(Int(round(sliderValue*100.0)))%" } + public convenience init?(coder: NSCoder, injectedText: String) { + self.init(coder: coder) + self.injectedText = injectedText + } + + public override func viewDidLoad() { + super.viewDidLoad() + self.injectedLabel.text = self.injectedText + } + public override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.switchBulbLabel.isHidden = !self.bulbSwitch.isOn diff --git a/UIUTestSPMExample/UIUTestExample/TableViewController.swift b/UIUTestSPMExample/UIUTestExample/TableViewController.swift index 3cb9544..45a8d6d 100644 --- a/UIUTestSPMExample/UIUTestExample/TableViewController.swift +++ b/UIUTestSPMExample/UIUTestExample/TableViewController.swift @@ -1,25 +1,59 @@ // // TableViewController.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import UIKit public class TableViewController: UITableViewController { - var recursive = false + public private(set) var editableCellIndex = 2 + + private let allCellIdentifiers = ["SignInCell", "InfoCell", "EditCell", "NextCell"] + private var currentCellIdentifiers: [String] = [] + + @IBAction func toggleEditMode() { + self.tableView.isEditing.toggle() + } + + public override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.currentCellIdentifiers = self.allCellIdentifiers + self.editableCellIndex = 2 + self.tableView.reloadData() + } public override func prepare(for segue: UIStoryboardSegue, sender: Any?) { super.prepare(for: segue, sender: sender) } public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 3 + return self.currentCellIdentifiers.count } public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let identifiers = ["SignInCell", "InfoCell", "NextCell"] - return tableView.dequeueReusableCell(withIdentifier: identifiers[indexPath.row], for: indexPath) + return tableView.dequeueReusableCell(withIdentifier: currentCellIdentifiers[indexPath.row], for: indexPath) + } + + public override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { + return self.currentCellIdentifiers.count == self.allCellIdentifiers.count && indexPath.row == editableCellIndex + } + + public override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { + guard editingStyle == .delete else { return } + self.currentCellIdentifiers.remove(at: editableCellIndex) + tableView.deleteRows(at: [indexPath], with: .fade) + } + + public override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { + return self.currentCellIdentifiers.count == self.allCellIdentifiers.count && indexPath.row == editableCellIndex + } + + public override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { + let identifier = self.currentCellIdentifiers[sourceIndexPath.row] + self.currentCellIdentifiers.remove(at: sourceIndexPath.row) + self.currentCellIdentifiers.insert(identifier, at: destinationIndexPath.row) + self.editableCellIndex = destinationIndexPath.row } } diff --git a/UIUTestSPMExample/UIUTestExampleTests/AuthenticationTests.swift b/UIUTestSPMExample/UIUTestExampleTests/AuthenticationTests.swift index 8e075f4..9758db0 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/AuthenticationTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/AuthenticationTests.swift @@ -1,7 +1,7 @@ // // AuthenticationTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -30,8 +30,6 @@ class AuthenticationTests: XCTestCase override func setUp() { super.setUp() - - UIViewController.initializeTestable() initializeTest() } @@ -50,6 +48,14 @@ class AuthenticationTests: XCTestCase invalidCredentialsLabel = (view.viewWithAccessibilityIdentifier("invalidCredentials") as! UILabel) } + func testTextFieldDoesNotRecognizeTapWhenDisabled() { + userNameField.isEnabled = true + XCTAssertTrue(userNameField.willRespondToUser) + + userNameField.isEnabled = false + XCTAssertFalse(userNameField.willRespondToUser) + } + func testAuthenticateEnabled() { XCTAssertFalse(authenticateButton.isEnabled) diff --git a/UIUTestSPMExample/UIUTestExampleTests/ButtonsViewControllerTests.swift b/UIUTestSPMExample/UIUTestExampleTests/ButtonsViewControllerTests.swift index cc8556b..1882991 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/ButtonsViewControllerTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/ButtonsViewControllerTests.swift @@ -1,7 +1,7 @@ // // ButtonsViewControllerTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -9,11 +9,6 @@ import UIUTestExample class ButtonsViewControllerTests: XCTestCase { - override func setUp() { - super.setUp() - UIViewController.initializeTestable() - } - override func tearDown() { super.tearDown() UIViewController.flushPendingTestArtifacts() diff --git a/UIUTestSPMExample/UIUTestExampleTests/InfoViewControllerTests.swift b/UIUTestSPMExample/UIUTestExampleTests/InfoViewControllerTests.swift index 32bbe29..fde626b 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/InfoViewControllerTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/InfoViewControllerTests.swift @@ -1,7 +1,7 @@ // // InfoViewControllerTests.swift // -// Copyright © 2017-2019 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -16,7 +16,6 @@ class InfoViewControllerTests: XCTestCase super.setUp() self.continueAfterFailure = false - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard(identifier: "InfoViewController") as! InfoViewController) view = viewController.view! } diff --git a/UIUTestSPMExample/UIUTestExampleTests/MapViewControllerTests.swift b/UIUTestSPMExample/UIUTestExampleTests/MapViewControllerTests.swift index 488a8db..faecdff 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/MapViewControllerTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/MapViewControllerTests.swift @@ -1,9 +1,8 @@ // // MapViewControllerTests.swift -// UIUTestExampleTests // // Created by Tyler Thompson on 5/28/19. -// Copyright © 2019 Purgatory Design. All rights reserved. +// Copyright © 2019-2021 Purgatory Design. All rights reserved. // import Foundation @@ -21,7 +20,6 @@ class MapViewControllerTests: XCTestCase { override func setUp() { super.setUp() continueAfterFailure = false - UIViewController.initializeTestable() viewController = UIViewController.loadFromStoryboard(identifier: "MapViewController") as? MapViewController view = viewController.view! } diff --git a/UIUTestSPMExample/UIUTestExampleTests/MiscellaneousTests.swift b/UIUTestSPMExample/UIUTestExampleTests/MiscellaneousTests.swift index 0e81390..a8e6f9f 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/MiscellaneousTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/MiscellaneousTests.swift @@ -1,9 +1,9 @@ // // MiscellaneousTests.swift // -// These tests are mostly just here to get the code coverage to 100%. +// These tests are mostly just here to test UIUTest itself or get the code coverage to 100%. // -// Copyright © 2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2018-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -27,4 +27,38 @@ class MiscellaneousTests: XCTestCase XCTAssertTrue(defaultAuthenticator.authenticate(user: DefaultAuthenticator.validUser, password: DefaultAuthenticator.validPassword)) } + + func testViewControllerEndsLifecycleWhenTestArtifactsAreFlushed() { + let viewController = SpyViewController() + viewController.loadForTesting() + RunLoop.current.singlePass() + RunLoop.current.singlePass() + + XCTAssertEqual(viewController.viewDidAppearCount, 1) + XCTAssertEqual(viewController.viewDidDisappearCallCount, 0) + + UIViewController.flushPendingTestArtifacts() + + XCTAssertEqual(viewController.viewDidAppearCount, 1) + XCTAssertEqual(viewController.viewDidDisappearCallCount, 1) + } +} + +extension MiscellaneousTests +{ + class SpyViewController: UIViewController + { + var viewDidAppearCount = 0 + var viewDidDisappearCallCount = 0 + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + self.viewDidAppearCount += 1 + } + + override func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + self.viewDidDisappearCallCount += 1 + } + } } diff --git a/UIUTestSPMExample/UIUTestExampleTests/SwitchesViewControllerTests.swift b/UIUTestSPMExample/UIUTestExampleTests/SwitchesViewControllerTests.swift index af211b3..75c7fd9 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/SwitchesViewControllerTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/SwitchesViewControllerTests.swift @@ -1,7 +1,7 @@ // // SwitchesViewControllerTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -14,7 +14,6 @@ class SwitchesViewControllerTests: XCTestCase override func setUp() { super.setUp() - UIViewController.initializeTestable() let viewController = UIViewController.loadFromStoryboard(identifier: "SwitchesViewController") as! SwitchesViewController view = viewController.view! } @@ -80,3 +79,19 @@ class SwitchesViewControllerTests: XCTestCase XCTAssertFalse(lightBulbLabel.isHidden) } } + +@available(iOS 13, *) +extension SwitchesViewControllerTests +{ + func testDependencyInjectionInitializer() { + let expectedText = "injection test" + + let viewController = UIViewController.createFromStoryboard(identifier: "SwitchesViewController") { coder in + return SwitchesViewController(coder: coder, injectedText: expectedText) + } + view = viewController!.view! + let injectedLabel = view.viewWithAccessibilityIdentifier("InjectedLabel") as! UILabel + + XCTAssertEqual(injectedLabel.text, expectedText) + } +} diff --git a/UIUTestSPMExample/UIUTestExampleTests/TabBarControllerTests.swift b/UIUTestSPMExample/UIUTestExampleTests/TabBarControllerTests.swift index 2c6ba60..5052fca 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/TabBarControllerTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/TabBarControllerTests.swift @@ -1,7 +1,7 @@ // // TabBarControllerTests.swift // -// Copyright © 2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2018-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -13,8 +13,6 @@ class TabBarControllerTests: XCTestCase override func setUp() { super.setUp() - - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard() as! UITabBarController) } diff --git a/UIUTestSPMExample/UIUTestExampleTests/TableViewControllerTests.swift b/UIUTestSPMExample/UIUTestExampleTests/TableViewControllerTests.swift index c32561a..bbb7edb 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/TableViewControllerTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/TableViewControllerTests.swift @@ -1,7 +1,7 @@ // // TableViewControllerTests.swift // -// Copyright © 2017-2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2017-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -15,7 +15,6 @@ class TableViewControllerTests: XCTestCase override func setUp() { super.setUp() - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard(identifier: "TableViewController") as! TableViewController) tableView = viewController.tableView! } @@ -28,16 +27,40 @@ class TableViewControllerTests: XCTestCase func testSegueFromInfoButtonToInfoViewController() { tableView.simulateAccessoryTouch(at: IndexPath(row: 1, section: 0)) - let segue = viewController.mostRecentlyPerformedSegue! - XCTAssertEqual(segue.identifier, "Info") - XCTAssertNotNil(segue.destination as? InfoViewController) + let segue = viewController.mostRecentlyPerformedSegue + XCTAssertEqual(segue?.identifier, "Info") + XCTAssertNotNil(segue?.destination as? InfoViewController) } func testSegueFromTableToNextViewController() { - tableView.simulateTouch(at: IndexPath(row: 2, section: 0)) + tableView.simulateTouch(at: IndexPath(row: 3, section: 0)) - let segue = viewController.mostRecentlyPerformedSegue! - XCTAssertEqual(segue.identifier, "Next") - XCTAssertNotNil(segue.destination as? ButtonsViewController) + let segue = viewController.mostRecentlyPerformedSegue + XCTAssertEqual(segue?.identifier, "Next") + XCTAssertNotNil(segue?.destination as? ButtonsViewController) } - } + + func testDeleteEditableTableViewCell() { + let initialRowCount = viewController.tableView(tableView, numberOfRowsInSection: 0) + + tableView.simulateEdit(.delete, rowAt: IndexPath(row: viewController.editableCellIndex, section: 0)) + let finalRowCount = viewController.tableView(tableView, numberOfRowsInSection: 0) + + XCTAssertEqual(finalRowCount, initialRowCount - 1) + } + + func testMoveEditableTableViewCell() { + let initialRowCount = viewController.tableView(tableView, numberOfRowsInSection: 0) + let initialIndex = IndexPath(row: viewController.editableCellIndex, section: 0) + let finalIndex = IndexPath(row: 0, section: 0) + let initialCell = tableView.cellForRow(at: initialIndex) + + tableView.isEditing = true + tableView.simulateEdit(moveRowAt: initialIndex, to: finalIndex) + let finalRowCount = viewController.tableView(tableView, numberOfRowsInSection: 0) + let finalCell = tableView.cellForRow(at: finalIndex) + + XCTAssertEqual(finalRowCount, initialRowCount) + XCTAssertEqual(finalCell, initialCell) + } +} diff --git a/UIUTestSPMExample/UIUTestExampleTests/ToolbarViewControllerTests.swift b/UIUTestSPMExample/UIUTestExampleTests/ToolbarViewControllerTests.swift index 989481a..f84d220 100644 --- a/UIUTestSPMExample/UIUTestExampleTests/ToolbarViewControllerTests.swift +++ b/UIUTestSPMExample/UIUTestExampleTests/ToolbarViewControllerTests.swift @@ -1,7 +1,7 @@ // // ToolbarViewControllerTests.swift // -// Copyright © 2018 Purgatory Design. Licensed under the MIT License. +// Copyright © 2018-2021 Purgatory Design. Licensed under the MIT License. // import XCTest @@ -16,7 +16,6 @@ class ToolbarViewControllerTests: XCTestCase override func setUp() { super.setUp() - UIViewController.initializeTestable() viewController = (UIViewController.loadFromStoryboard(identifier: "ToolbarViewController") as! ToolbarViewController) view = viewController.view! }