From 492e6c8f894eeb183a88f3cc2b227cb6e44f8232 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 2 Dec 2019 19:38:25 +0100 Subject: [PATCH 1/5] Convert Row specs to XCTests --- Tests/Row/NavigationRowSpec.swift | 336 +++++++++++++++++------------- Tests/Row/OptionRowSpec.swift | 237 +++++++++++---------- Tests/Row/SwitchRowSpec.swift | 222 +++++++++++--------- Tests/Row/TapActionRowSpec.swift | 104 ++++----- 4 files changed, 502 insertions(+), 397 deletions(-) diff --git a/Tests/Row/NavigationRowSpec.swift b/Tests/Row/NavigationRowSpec.swift index 1233a985..87307d81 100644 --- a/Tests/Row/NavigationRowSpec.swift +++ b/Tests/Row/NavigationRowSpec.swift @@ -1,5 +1,5 @@ // -// NavigationRowSpec.swift +// NavigationRowTests.swift // QuickTableViewControllerTests // // Created by Ben on 17/01/2016. @@ -24,154 +24,192 @@ // SOFTWARE. // -import Nimble -import Quick -@testable import QuickTableViewController - -internal final class NavigationRowSpec: QuickSpec { - - override func spec() { - -#if os(iOS) - describe("initialization") { - let detailText = DetailText.subtitle("subtitle") - let icon = Icon.named("icon") - - var actionInvoked = false - var accessoryButtonActionInvoked = false - - let row = NavigationRow( - text: "title", - detailText: detailText, - icon: icon, - action: { _ in actionInvoked = true }, - accessoryButtonAction: { _ in accessoryButtonActionInvoked = true } - ) - - it("should initialize with given parameters") { - expect(row.text) == "title" - expect(row.detailText) == detailText - expect(row.icon) == icon - expect(row.cellReuseIdentifier) == "UITableViewCell.subtitle" - - row.action?(row) - expect(actionInvoked) == true - - row.accessoryButtonAction?(row) - expect(accessoryButtonActionInvoked) == true - } - } - -#elseif os(tvOS) - - describe("initialization") { - let detailText = DetailText.subtitle("subtitle") - let icon = Icon.named("icon") - - var invoked = false - let row = NavigationRow(text: "title", detailText: detailText, icon: icon, action: { _ in invoked = true }) - - it("should initialize with given parameters") { - expect(row.text) == "title" - expect(row.detailText) == detailText - expect(row.icon) == icon - expect(row.cellReuseIdentifier) == "UITableViewCell.subtitle" - - row.action?(row) - expect(invoked) == true - } - - it("should conform to the protocol") { - expect(row).to(beAKindOf(NavigationRowCompatible.self)) - } - } - -#endif - - describe("cellReuseIdentifier") { - let a = NavigationRow(text: "", detailText: .none) - let b = NavigationRow(text: "", detailText: .subtitle("")) - let c = NavigationRow(text: "", detailText: .value1("")) - let d = NavigationRow(text: "", detailText: .value2("")) - - it("should return the backward compatible strings") { - expect(a.cellReuseIdentifier) == "UITableViewCell.default" - expect(b.cellReuseIdentifier) == "UITableViewCell.subtitle" - expect(c.cellReuseIdentifier) == "UITableViewCell.value1" - expect(d.cellReuseIdentifier) == "UITableViewCell.value2" - } - } - - #if os(iOS) - - describe("accessoryType") { - let a = NavigationRow(text: "", detailText: .none) - let b = NavigationRow(text: "", detailText: .none, action: { _ in }) - let c = NavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in }) - let d = NavigationRow(text: "", detailText: .none, action: { _ in }, accessoryButtonAction: { _ in }) - - it("should return the corresponding accessory type") { - expect(a.accessoryType) == UITableViewCell.AccessoryType.none - expect(b.accessoryType) == UITableViewCell.AccessoryType.disclosureIndicator - expect(c.accessoryType) == UITableViewCell.AccessoryType.detailButton - expect(d.accessoryType) == UITableViewCell.AccessoryType.detailDisclosureButton - } - } - - #elseif os(iOS) - - describe("accessoryType") { - let a = NavigationRow(text: "", detailText: .none) - let b = NavigationRow(text: "", detailText: .none, action: { _ in }) - - it("should return the the corresponding accessory type") { - expect(a.accessoryType) == UITableViewCell.AccessoryType.none - expect(b.accessoryType) == UITableViewCell.AccessoryType.disclosureIndicator - } - } - - #endif - - describe("equatable") { - let image = UIImage() - let row = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) - - context("identical parameters") { - let this = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) - it("should be equal") { - expect(this) == row - } - } - - context("different texts") { - let this = NavigationRow(text: "Different", detailText: .subtitle("Same"), icon: .image(image), action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different detail texts") { - let this = NavigationRow(text: "Same", detailText: .subtitle("Different"), icon: .image(image), action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different icons") { - let image = UIImage(named: "icon", in: Bundle(for: IconSpec.self), compatibleWith: nil)! - let this = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different actions") { - let this = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: { _ in }) - it("should be equal regardless of the actions attached") { - expect(this) == row - } - } - } +import QuickTableViewController +import XCTest + +internal final class NavigationRowTests: XCTestCase { + + // MARK: - Initialization + + #if os(iOS) + func testInitialiation_iOS() { + // Given + let detailText = DetailText.subtitle("subtitle") + let icon = Icon.named("icon") + var actionInvoked = false + var accessoryButtonActionInvoked = false + + // When + let row = NavigationRow( + text: "title", + detailText: detailText, + icon: icon, + action: { _ in actionInvoked = true }, + accessoryButtonAction: { _ in accessoryButtonActionInvoked = true } + ) + + // Then it should have the given parameters + XCTAssertEqual(row.text, "title") + XCTAssertEqual(row.detailText, detailText) + + // With RowStyle + XCTAssertEqual(row.cellReuseIdentifier, "UITableViewCell.subtitle") + XCTAssertEqual(row.cellStyle, .subtitle) + XCTAssertEqual(row.icon, icon) + XCTAssertEqual(row.accessoryType, .detailDisclosureButton) + XCTAssertEqual(row.isSelectable, true) + XCTAssertNil(row.customize) + + // When + row.action?(row) + row.accessoryButtonAction?(row) + + // Then + XCTAssertEqual(actionInvoked, true) + XCTAssertEqual(accessoryButtonActionInvoked, true) } + #endif + + #if os(tvOS) + func testInitialiation_tvOS() { + // Given + let detailText = DetailText.subtitle("subtitle") + let icon = Icon.named("icon") + var actionInvoked = false + + // When + let row = NavigationRow(text: "title", detailText: detailText, icon: icon, action: { _ in actionInvoked = true }) + + // Then it should have the given parameters + XCTAssertEqual(row.text, "title") + XCTAssertEqual(row.detailText, detailText) + + // With RowStyle + XCTAssertEqual(row.cellReuseIdentifier, "UITableViewCell.subtitle") + XCTAssertEqual(row.cellStyle, .subtitle) + XCTAssertEqual(row.icon, icon) + XCTAssertEqual(row.accessoryType, .disclosureIndicator) + XCTAssertEqual(row.isSelectable, true) + XCTAssertNil(row.customize) + + // When + row.action?(row) + + // Then + XCTAssertEqual(actionInvoked, true) + } + #endif + + func testCellReuseIdentifier() { + // When + let a = NavigationRow(text: "", detailText: .none) + let b = NavigationRow(text: "", detailText: .subtitle("")) + let c = NavigationRow(text: "", detailText: .value1("")) + let d = NavigationRow(text: "", detailText: .value2("")) + + // Then + XCTAssertEqual(a.cellReuseIdentifier, "UITableViewCell.default") + XCTAssertEqual(b.cellReuseIdentifier, "UITableViewCell.subtitle") + XCTAssertEqual(c.cellReuseIdentifier, "UITableViewCell.value1") + XCTAssertEqual(d.cellReuseIdentifier, "UITableViewCell.value2") + } + + #if os(iOS) + func testAccessoryType_iOS() { + // When + let a = NavigationRow(text: "", detailText: .none) + let b = NavigationRow(text: "", detailText: .none, action: { _ in }) + let c = NavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in }) + let d = NavigationRow(text: "", detailText: .none, action: { _ in }, accessoryButtonAction: { _ in }) + + // Then + XCTAssertEqual(a.accessoryType, .none) + XCTAssertEqual(b.accessoryType, .disclosureIndicator) + XCTAssertEqual(c.accessoryType, .detailButton) + XCTAssertEqual(d.accessoryType, .detailDisclosureButton) + } + #endif + + #if os(tvOS) + func testAccessoryType_tvOS() { + // When + let a = NavigationRow(text: "", detailText: .none) + let b = NavigationRow(text: "", detailText: .none, action: { _ in }) + + // Then + XCTAssertEqual(a.accessoryType, .none) + XCTAssertEqual(b.accessoryType, .disclosureIndicator) + } + #endif + + // MARK: - Equatable + + func testEquatable_withIdenticalParameters() { + // Given + let one = NavigationRow(text: "Same", detailText: .subtitle("Same"), action: nil) + + // When + let another = NavigationRow(text: "Same", detailText: .subtitle("Same"), action: nil) + + // Then + XCTAssert(one == another) + } + + func testEquatable_withDifferentTexts() { + // Given + let one = NavigationRow(text: "Same", detailText: .subtitle("Same"), action: nil) + + // When + let another = NavigationRow(text: "Different", detailText: .subtitle("Same"), action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentDetailTexts() { + // Given + let one = NavigationRow(text: "Same", detailText: .subtitle("Same"), action: nil) + + // When + let another = NavigationRow(text: "Same", detailText: .subtitle("Different"), action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentIcons() { + // Given + let one = NavigationRow(text: "Same", detailText: .subtitle("Same"), action: nil) + + // When + let another = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(UIImage()), action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentActions() { + // Given + let one = NavigationRow(text: "Same", detailText: .subtitle("Same"), action: nil) + + // When + let another = NavigationRow(text: "Same", detailText: .subtitle("Same"), action: { _ in }) + + // Then it should be equal regardless of the actions attached + XCTAssert(one == another) + } + + #if os(iOS) + func testEquatable_withDifferentAccessoryButtonActions() { + // Given + let one = NavigationRow(text: "Same", detailText: .subtitle("Same"), accessoryButtonAction: nil) + + // When + let another = NavigationRow(text: "Same", detailText: .subtitle("Same"), accessoryButtonAction: { _ in }) + + // Then it should be equal regardless of the actions attached + XCTAssert(one == another) + } + #endif } diff --git a/Tests/Row/OptionRowSpec.swift b/Tests/Row/OptionRowSpec.swift index ef46af1e..d0ac2cad 100644 --- a/Tests/Row/OptionRowSpec.swift +++ b/Tests/Row/OptionRowSpec.swift @@ -1,5 +1,5 @@ // -// OptionRowSpec.swift +// OptionRowTests.swift // QuickTableViewControllerTests // // Created by Ben on 17/08/2017. @@ -24,112 +24,139 @@ // SOFTWARE. // -import Nimble -import Quick import QuickTableViewController +import XCTest -internal final class OptionRowSpec: QuickSpec { - - override func spec() { - describe("initialiation") { - let detailText = DetailText.subtitle("subtitle") - let icon = Icon.named("icon") - - var invoked = false - let row = OptionRow(text: "title", detailText: detailText, isSelected: true, icon: icon) { _ in invoked = true } - - it("should initialize with given parameters") { - // Row - expect(row.text) == "title" - expect(row.detailText) == detailText - expect(row.isSelected) == true - - row.action?(row) - expect(invoked) == true - - // RowStyle - expect(row.cellReuseIdentifier) == "UITableViewCell" - expect(row.cellStyle) == UITableViewCell.CellStyle.default - expect(row.icon) == icon - expect(row.accessoryType) == UITableViewCell.AccessoryType.checkmark - expect(row.isSelectable) == true - expect(row.customize).to(beNil()) - } - - it("should conform to the protocol") { - expect(row).to(beAKindOf(OptionRowCompatible.self)) - } - } - - describe("equatable") { - let row = OptionRow(text: "Same", isSelected: true, action: nil) - - context("identical parameters") { - let this = OptionRow(text: "Same", isSelected: true, action: nil) - it("should be qeaul") { - expect(this) == row - } - } - - context("different texts") { - let this = OptionRow(text: "Different", isSelected: true, action: nil) - it("should not be eqaul") { - expect(this) != row - } - } - - context("different detail texts") { - let this = OptionRow(text: "Same", detailText: .subtitle("Different"), isSelected: true, action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different selection state") { - let this = OptionRow(text: "Same", isSelected: false, action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different icons") { - let this = OptionRow(text: "Same", isSelected: true, icon: .image(UIImage()), action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different actions") { - let this = OptionRow(text: "Same", isSelected: true, action: { _ in }) - it("should be equal regardless of the actions attached") { - expect(this) == row - } - } - } - - describe("action invocation") { - context("when the selection is toggled") { - var invoked = false - let row = OptionRow(text: "", isSelected: false) { _ in invoked = true } - - it("should invoke the action closure") { - row.isSelected = true - expect(row.accessoryType) == UITableViewCell.AccessoryType.checkmark - expect(invoked).toEventually(beTrue()) - } - } - - context("when the selection stays the same") { - var invoked = false - let row = OptionRow(text: "", isSelected: false) { _ in invoked = true } - - it("should not invoke the action closure") { - row.isSelected = false - expect(row.accessoryType) == UITableViewCell.AccessoryType.none - expect(invoked).toEventually(beFalse()) - } - } - } +internal final class OptionRowTests: XCTestCase { + + // MARK: - Initialization + + func testInitialiation() { + // Given + let detailText = DetailText.subtitle("subtitle") + let icon = Icon.named("icon") + var actionInvoked = false + + // When + let row = OptionRow(text: "title", detailText: detailText, isSelected: true, icon: icon) { _ in actionInvoked = true } + + // Then it should have the given parameters + XCTAssertEqual(row.text, "title") + XCTAssertEqual(row.detailText, detailText) + XCTAssertEqual(row.isSelected, true) + + // With RowStyle + XCTAssertEqual(row.cellReuseIdentifier, "UITableViewCell") + XCTAssertEqual(row.cellStyle, .default) + XCTAssertEqual(row.icon, icon) + XCTAssertEqual(row.accessoryType, .checkmark) + XCTAssertEqual(row.isSelectable, true) + XCTAssertNil(row.customize) + + // When + row.action?(row) + + // Then + XCTAssertEqual(actionInvoked, true) + } + + // MARK: - Equatable + + func testEquatable_withIdenticalParameters() { + // Given + let one = OptionRow(text: "Same", isSelected: true, action: nil) + + // When + let another = OptionRow(text: "Same", isSelected: true, action: nil) + + // Then + XCTAssert(one == another) + } + + func testEquatable_withDifferentTexts() { + // Given + let one = OptionRow(text: "Same", isSelected: true, action: nil) + + // When + let another = OptionRow(text: "Different", isSelected: true, action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentDetailTexts() { + // Given + let one = OptionRow(text: "Same", isSelected: true, action: nil) + + // When + let another = OptionRow(text: "Same", detailText: .subtitle("Different"), isSelected: true, action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentSelectionStates() { + // Given + let one = OptionRow(text: "Same", isSelected: true, action: nil) + + // When + let another = OptionRow(text: "Same", isSelected: false, action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentIcons() { + // Given + let one = OptionRow(text: "Same", isSelected: true, action: nil) + + // When + let another = OptionRow(text: "Same", isSelected: true, icon: .image(UIImage()), action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentActions() { + // Given + let one = OptionRow(text: "Same", isSelected: true, action: nil) + + // When + let another = OptionRow(text: "Same", isSelected: true, action: { _ in }) + + // Then it should be equal regardless of the actions attached + XCTAssert(one == another) + } + + // MARK: - Action Invocation + + func testActionInvocationWhenSelectionIsToggled() { + let expectation = self.expectation(description: "it should invoke the action closure") + + // Given an option row that's not selected + let row = OptionRow(text: "", isSelected: false) { _ in expectation.fulfill() } + + // When the selection is toggled + row.isSelected = true + + // Then + waitForExpectations(timeout: 1, handler: nil) + XCTAssertEqual(row.accessoryType, .checkmark) + } + + func testActionInvocationWhenSelectionIsNotToggled() { + let expectation = self.expectation(description: "it should not invoke the action closure") + expectation.isInverted = true + + // Given an option row that's not selected + let row = OptionRow(text: "", isSelected: false) { _ in expectation.fulfill() } + + // When the selection is not toggled + row.isSelected = false + + // Then + waitForExpectations(timeout: 1, handler: nil) + XCTAssertEqual(row.accessoryType, .none) } } diff --git a/Tests/Row/SwitchRowSpec.swift b/Tests/Row/SwitchRowSpec.swift index 38533512..a0ec708b 100644 --- a/Tests/Row/SwitchRowSpec.swift +++ b/Tests/Row/SwitchRowSpec.swift @@ -1,5 +1,5 @@ // -// SwitchRowSpec.swift +// SwitchRowTests.swift // QuickTableViewControllerTests // // Created by Ben on 17/01/2016. @@ -24,103 +24,133 @@ // SOFTWARE. // -import Nimble -import Quick import QuickTableViewController +import XCTest -internal final class SwitchRowSpec: QuickSpec { - - override func spec() { - describe("initialization") { - let detailText = DetailText.subtitle("subtitle") - let icon = Icon.named("icon") - - var invoked = false - let row = SwitchRow(text: "title", detailText: detailText, switchValue: true, icon: icon) { _ in invoked = true } - - it("should initialize with given parameters") { - expect(row.text) == "title" - expect(row.detailText) == detailText - expect(row.icon) == icon - expect(row.switchValue) == true - expect(row.cellReuseIdentifier) == "SwitchCell" - - row.action?(row) - expect(invoked) == true - } - - it("should conform to the protocol") { - expect(row).to(beAKindOf(SwitchRowCompatible.self)) - } - } - - describe("equatable") { - let row = SwitchRow(text: "Same", switchValue: true, action: nil) - - context("identical parameters") { - let this = SwitchRow(text: "Same", switchValue: true, action: nil) - it("should be qeaul") { - expect(this) == row - } - } - - context("different texts") { - let this = SwitchRow(text: "Different", switchValue: true, action: nil) - it("should not be eqaul") { - expect(this) != row - } - } - - context("different detail texts") { - let this = SwitchRow(text: "Same", detailText: .subtitle("Different"), switchValue: true, action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different switch values") { - let this = SwitchRow(text: "Same", switchValue: false, action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different icons") { - let this = SwitchRow(text: "Same", switchValue: true, icon: .image(UIImage()), action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different actions") { - let this = SwitchRow(text: "Same", switchValue: true, action: { _ in }) - it("should be equal regardless of the actions attached") { - expect(this) == row - } - } - } - - describe("action invocation") { - context("when the switch value is changed") { - var invoked = false - let row = SwitchRow(text: "", switchValue: false) { _ in invoked = true } - - it("should invoke the action closure") { - row.switchValue = true - expect(invoked).toEventually(beTrue()) - } - } - - context("when the switch value stays the same") { - var invoked = false - let row = SwitchRow(text: "", switchValue: false) { _ in invoked = true } - - it("should not invoke the action closure") { - row.switchValue = false - expect(invoked).toEventually(beFalse()) - } - } - } +internal final class SwitchRowTests: XCTestCase { + + // MARK: - Initialization + + func testInitialiation() { + // Given + let detailText = DetailText.subtitle("subtitle") + let icon = Icon.named("icon") + var actionInvoked = false + + // When + let row = SwitchRow(text: "title", detailText: detailText, switchValue: true, icon: icon) { _ in actionInvoked = true } + + // Then it should have the given parameters + XCTAssertEqual(row.text, "title") + XCTAssertEqual(row.detailText, detailText) + XCTAssertEqual(row.switchValue, true) + + // With RowStyle + XCTAssertEqual(row.icon, icon) + XCTAssertEqual(row.cellReuseIdentifier, "SwitchCell") + + // When + row.action?(row) + + // Then + XCTAssertEqual(actionInvoked, true) + } + + // MARK: - Equatable + + func testEquatable_withIdenticalParameters() { + // Given + let one = SwitchRow(text: "Same", switchValue: true, action: nil) + + // When + let another = SwitchRow(text: "Same", switchValue: true, action: nil) + + // Then + XCTAssert(one == another) + } + + func testEquatable_withDifferentTexts() { + // Given + let one = SwitchRow(text: "Same", switchValue: true, action: nil) + + // When + let another = SwitchRow(text: "Different", switchValue: true, action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentDetailTexts() { + // Given + let one = SwitchRow(text: "Same", switchValue: true, action: nil) + + // When + let another = SwitchRow(text: "Same", detailText: .subtitle("Different"), switchValue: true, action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentSwitchValues() { + // Given + let one = SwitchRow(text: "Same", switchValue: true, action: nil) + + // When + let another = SwitchRow(text: "Same", switchValue: false, action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentIcons() { + // Given + let one = SwitchRow(text: "Same", switchValue: true, action: nil) + + // When + let another = SwitchRow(text: "Same", switchValue: true, icon: .image(UIImage()), action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentActions() { + // Given + let one = SwitchRow(text: "Same", switchValue: true, action: nil) + + // When + let another = SwitchRow(text: "Same", switchValue: true, action: { _ in }) + + // Then it should be equal regardless of the actions attached + XCTAssert(one == another) + } + + // MARK: - Action Invocation + + func testActionInvocationWhenSwitchValueIsToggled() { + let expectation = self.expectation(description: "it should invoke the action closure") + + // Given a switch row that's off + let row = SwitchRow(text: "", switchValue: false) { _ in expectation.fulfill() } + + // When the switch value is toggled + row.switchValue = true + + // Then + waitForExpectations(timeout: 1) + } + + func testActionInvocationWhenSwitchValueIsNotToggled() { + let expectation = self.expectation(description: "it should not invoke the action closure") + expectation.isInverted = true + + // Given a switch row that's off + let row = SwitchRow(text: "", switchValue: false) { _ in expectation.fulfill() } + + // When the switch value is not toggled + row.switchValue = false + + // Then + waitForExpectations(timeout: 1) } } diff --git a/Tests/Row/TapActionRowSpec.swift b/Tests/Row/TapActionRowSpec.swift index ff7d6925..ae630fb3 100644 --- a/Tests/Row/TapActionRowSpec.swift +++ b/Tests/Row/TapActionRowSpec.swift @@ -1,5 +1,5 @@ // -// TapActionRowSpec.swift +// TapActionRowTests.swift // QuickTableViewControllerTests // // Created by Ben on 17/01/2016. @@ -24,54 +24,64 @@ // SOFTWARE. // -import Nimble -import Quick import QuickTableViewController +import XCTest -internal final class TapActionRowSpec: QuickSpec { - - override func spec() { - describe("initialization") { - var invoked = false - let row = TapActionRow(text: "title") { _ in invoked = true } - - it("should initialize with given parameters") { - expect(row.text) == "title" - expect(row.cellReuseIdentifier) == "TapActionCell" - - row.action?(row) - expect(invoked) == true - } - - it("should conform to the protocol") { - expect(row).to(beAKindOf(TapActionRowCompatible.self)) - } - } - - describe("equatable") { - let row = TapActionRow(text: "Same", action: nil) - - context("identical titles") { - let this = TapActionRow(text: "Same", action: nil) - it("should be equal") { - expect(this) == row - } - } - - context("different texts") { - let this = TapActionRow(text: "Different", action: nil) - it("should not be equal") { - expect(this) != row - } - } - - context("different actions") { - let this = TapActionRow(text: "Same", action: { _ in }) - it("should be equal regardless of the actions attached") { - expect(this) == row - } - } - } +internal final class TapActionRowTests: XCTestCase { + + // MARK: - Initialization + + func testInitialiation() { + // Given + var actionInvoked = false + + // When + let row = TapActionRow(text: "title") { _ in actionInvoked = true } + + // Then it should have the given parameters + XCTAssertEqual(row.text, "title") + XCTAssertEqual(row.cellReuseIdentifier, "TapActionCell") + + // When + row.action?(row) + + // Then + XCTAssertEqual(actionInvoked, true) + } + + // MARK: - Equatable + + func testEquatable_withIdenticalParameters() { + // Given + let one = TapActionRow(text: "Same", action: nil) + + // When + let another = TapActionRow(text: "Same", action: nil) + + // Then + XCTAssert(one == another) + } + + func testEquatable_withDifferentTexts() { + // Given + let one = TapActionRow(text: "Same", action: nil) + + // When + let another = TapActionRow(text: "Different", action: nil) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentActions() { + // Given + let one = TapActionRow(text: "Same", action: nil) + + // When + let another = TapActionRow(text: "Same", action: { _ in }) + + // Then it should be equal regardless of the actions attached + XCTAssert(one == another) } } From 37b2498506e825a1fbb6c1fc5c793ceed117ca32 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 14 Jan 2020 11:38:58 +0800 Subject: [PATCH 2/5] Convert Model specs to XCTests --- Tests/Model/DetailTextSpec.swift | 133 +++++---- Tests/Model/IconSpec.swift | 160 ++++++----- Tests/Model/RadioSectionSpec.swift | 423 +++++++++++++++-------------- Tests/Model/SectionSpec.swift | 30 +- Tests/Model/SubtitleSpec.swift | 222 +++++++-------- 5 files changed, 503 insertions(+), 465 deletions(-) diff --git a/Tests/Model/DetailTextSpec.swift b/Tests/Model/DetailTextSpec.swift index d6733058..c223c89d 100644 --- a/Tests/Model/DetailTextSpec.swift +++ b/Tests/Model/DetailTextSpec.swift @@ -1,5 +1,5 @@ // -// DetailTextSpec.swift +// DetailTextTests.swift // QuickTableViewController // // Created by bcylin on 31/12/2018. @@ -24,85 +24,80 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest -internal final class DetailTextSpec: QuickSpec { +internal final class DetailTextTests: XCTestCase { - override func spec() { - describe("cell style") { - it("should return the descriptive name of the style") { - expect(DetailText.none.style) == .default - expect(DetailText.subtitle("text").style) == .subtitle - expect(DetailText.value1("text").style) == .value1 - expect(DetailText.value2("text").style) == .value2 - } - } + func testCellStyle() { + // It should return the descriptive name of the style + XCTAssertEqual(DetailText.none.style, .default) + XCTAssertEqual(DetailText.subtitle("text").style, .subtitle) + XCTAssertEqual(DetailText.value1("text").style, .value1) + XCTAssertEqual(DetailText.value2("text").style, .value2) + } - describe("associtated value") { - it("should return the associated text") { - expect(DetailText.none.text).to(beNil()) - expect(DetailText.subtitle("3").text) == "3" - expect(DetailText.value1("1").text) == "1" - expect(DetailText.value2("2").text) == "2" - } - } + func testAssocitatedValue() { + // It should return the associated text + XCTAssertNil(DetailText.none.text) + XCTAssertEqual(DetailText.subtitle("3").text, "3") + XCTAssertEqual(DetailText.value1("1").text, "1") + XCTAssertEqual(DetailText.value2("2").text, "2") + } - describe("equatable") { - context(".none") { - it("should be equal when both are .none") { - let a = DetailText.none - let b = DetailText.none - expect(a) == b - } - } + // MARK: - Equatable - context(".subtitle") { - let a = DetailText.subtitle("Same") - let b = DetailText.subtitle("Same") - let c = DetailText.subtitle("Different") - let d = DetailText.value1("Same") - let e = DetailText.none + func testEquatableNone() { + // Given + let a = DetailText.none + let b = DetailText.none - it("should be equal only when type and associated value match") { - expect(a) == b - expect(a) != c - expect(a) != d - expect(a) != e - } - } + // Then it should be equal when both are .none + XCTAssert(a == b) + } - context(".value1") { - let a = DetailText.value1("Same") - let b = DetailText.value1("Same") - let c = DetailText.value1("Different") - let d = DetailText.value2("Same") - let e = DetailText.none + func testEquatableSubtitle() { + // Given + let a = DetailText.subtitle("Same") + let b = DetailText.subtitle("Same") + let c = DetailText.subtitle("Different") + let d = DetailText.value1("Same") + let e = DetailText.none - it("should be equal only when type and associated value match") { - expect(a) == b - expect(a) != c - expect(a) != d - expect(a) != e - } - } + // Then it should be equal only when both type and associated value match + XCTAssert(a == b) + XCTAssert(a != c) + XCTAssert(a != d) + XCTAssert(a != e) + } - context(".value2") { - let a = DetailText.value2("Same") - let b = DetailText.value2("Same") - let c = DetailText.value2("Different") - let d = DetailText.subtitle("Same") - let e = DetailText.none + func testEquatableValue1() { + // Given + let a = DetailText.value1("Same") + let b = DetailText.value1("Same") + let c = DetailText.value1("Different") + let d = DetailText.value2("Same") + let e = DetailText.none - it("should be equal only when type and associated value match") { - expect(a) == b - expect(a) != c - expect(a) != d - expect(a) != e - } - } - } + // Then it should be equal only when both type and associated value match + XCTAssert(a == b) + XCTAssert(a != c) + XCTAssert(a != d) + XCTAssert(a != e) } + func testEquatableValue2() { + // Given + let a = DetailText.value2("Same") + let b = DetailText.value2("Same") + let c = DetailText.value2("Different") + let d = DetailText.subtitle("Same") + let e = DetailText.none + + // Then it should be equal only when both type and associated value match + XCTAssert(a == b) + XCTAssert(a != c) + XCTAssert(a != d) + XCTAssert(a != e) + } } diff --git a/Tests/Model/IconSpec.swift b/Tests/Model/IconSpec.swift index 18b4e4ad..85bb571f 100644 --- a/Tests/Model/IconSpec.swift +++ b/Tests/Model/IconSpec.swift @@ -1,5 +1,5 @@ // -// IconSpec.swift +// IconTests.swift // QuickTableViewControllerTests // // Created by Ben on 17/01/2016. @@ -24,81 +24,93 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest -internal final class IconSpec: QuickSpec { - - override func spec() { - let image = UIImage(named: "icon", in: Bundle(for: IconSpec.self), compatibleWith: nil)! - let highlighted = UIImage(named: "icon-highlighted", in: Bundle(for: IconSpec.self), compatibleWith: nil)! - - describe("initialization") { - context("image") { - let icon = Icon.image(image) - it("should initialize with the image") { - expect(icon.image) == image - expect(icon.highlightedImage).to(beNil()) - } - } - - context("image name") { - let icon = Icon.named("name") - it("should initialize with the image name") { - expect(icon.image).to(beNil()) - expect(icon.highlightedImage).to(beNil()) - } - } - } - - describe("equatable") { - let a = Icon.image(image) - - context("identical images") { - let b = Icon.image(image) - it("should be equal") { - expect(a) == b - } - } - - context("different images") { - let c = Icon.image(highlighted) - it("should not be equal") { - expect(a) != c - } - } - - context("different highlighted images") { - let d = Icon.images(normal: image, highlighted: highlighted) - let e = Icon.images(normal: image, highlighted: UIImage()) - it("should not be equal") { - expect(d) != e - } - } - - let f = Icon.named("Same") - - context("different image specification") { - it("should not be queal") { - expect(a) != f - } - } - - context("identical image names") { - let g = Icon.named("Same") - it("should be eqaul") { - expect(f) == g - } - } - - context("different image names") { - let h = Icon.named("Different") - it("should not be equal") { - expect(f) != h - } - } - } +internal final class IconTests: XCTestCase { + + private let image = UIImage(named: "icon", in: Bundle(for: IconTests.self), compatibleWith: nil)! + private let highlighted = UIImage(named: "icon-highlighted", in: Bundle(for: IconTests.self), compatibleWith: nil)! + + // MARK: - Initialization + + func testInitialiation() { + // Given + let image = self.image + + // When + let icon = Icon.image(image) + + // Then + XCTAssertEqual(icon.image, image) + XCTAssertNil(icon.highlightedImage) } + // MARK: - Equatable + + func testEquatable_withIdenticalParameters() { + // Given + let one = Icon.image(image) + + // When + let another = Icon.image(image) + + // Then + XCTAssert(one == another) + } + + func testEquatable_withDifferentImages() { + // Given + let one = Icon.image(image) + + // When + let another = Icon.image(highlighted) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentHighlightedImages() { + // Given + let one = Icon.images(normal: image, highlighted: highlighted) + + // When + let another = Icon.images(normal: image, highlighted: UIImage()) + + // Then + XCTAssert(one != another) + } + + func testEquatable_withDifferentImageSpecifications() { + // Given + let one = Icon.image(image) + + // When + let another = Icon.named("image") + + // Then + XCTAssert(one != another) + } + + func testEquatable_withIdenticalImageNames() { + // Given + let one = Icon.named("Same") + + // When + let another = Icon.named("Same") + + // Then + XCTAssert(one == another) + } + + func testEquatable_withDifferentImageNames() { + // Given + let one = Icon.named("Same") + + // When + let another = Icon.named("Different") + + // Then + XCTAssert(one != another) + } } diff --git a/Tests/Model/RadioSectionSpec.swift b/Tests/Model/RadioSectionSpec.swift index c3a6eb55..5063ae79 100644 --- a/Tests/Model/RadioSectionSpec.swift +++ b/Tests/Model/RadioSectionSpec.swift @@ -1,5 +1,5 @@ // -// RadioSectionSpec.swift +// RadioSectionTests.swift // QuickTableViewController // // Created by Ben on 17/08/2017. @@ -24,207 +24,230 @@ // SOFTWARE. // -import Nimble -import Quick import QuickTableViewController +import XCTest -internal final class RadioSectionSpec: QuickSpec { - - override func spec() { - describe("initialization") { - let row = OptionRow(text: "", isSelected: false, action: nil) - let section = RadioSection(title: "title", options: [row], footer: "footer") - - it("should initialize with given parameters") { - expect(section.title) == "title" - expect(section.rows).to(haveCount(1)) - expect(section.rows.first as? OptionRow) == row - expect(section.options).to(haveCount(1)) - expect(section.options.first) === row - expect(section.footer) == "footer" - } - } - - describe("rows") { - context("getter") { - let options = [ - OptionRow(text: "0", isSelected: false, action: nil), - OptionRow(text: "1", isSelected: true, action: nil) - ] - let section = RadioSection(title: "", options: options) - - it("should return options as rows") { - expect(section.rows).to(beAKindOf([OptionRowCompatible].self)) - expect(section.rows as? [OptionRow]) == options - } - } - - context("setter") { - context("given empty array") { - let section = RadioSection(title: "", options: [ - OptionRow(text: "", isSelected: true, action: nil) - ]) - - it("should change rows") { - expect(section.rows).to(haveCount(1)) - section.rows = [] - expect(section.rows).to(beEmpty()) - } - } - - context("given incompatible type") { - let options = [OptionRow(text: "0", isSelected: false, action: nil)] - let section = RadioSection(title: "", options: options) - - it("should not change rows") { - expect(section.rows).to(haveCount(1)) - section.rows = [ - NavigationRow(text: "", detailText: .none), - NavigationRow(text: "", detailText: .none) - ] - expect(section.rows).to(haveCount(1)) - expect(section.rows as? [OptionRow]) == options - } - } - - context("given compatible type") { - let options = [ - OptionRow(text: "0", isSelected: false, action: nil), - OptionRow(text: "1", isSelected: true, action: nil) - ] - let section = RadioSection(title: "", options: []) - - it("should change rows") { - expect(section.rows).to(beEmpty()) - section.rows = options - expect(section.rows).to(haveCount(2)) - expect(section.rows as? [OptionRow]) == options - } - } - } - } - - describe("always selects one option") { - context("when set to false") { - let section = RadioSection(title: "title", options: [ - OptionRow(text: "Option 1", isSelected: false, action: nil) - ]) - section.alwaysSelectsOneOption = false - - it("should do nothing") { - expect(section.options).to(haveCount(1)) - expect(section.selectedOption).to(beNil()) - } - } - - context("when set to true with empty options") { - let section = RadioSection(title: "title", options: []) - section.alwaysSelectsOneOption = true - - it("should do nothing") { - expect(section.options).to(beEmpty()) - expect(section.selectedOption).to(beNil()) - } - } - - context("when set to true with nothing selected") { - let section = RadioSection(title: "title", options: [ - OptionRow(text: "Option 1", isSelected: false, action: nil), - OptionRow(text: "Option 2", isSelected: false, action: nil) - ]) - section.alwaysSelectsOneOption = true - - it("should select the first option") { - expect(section.selectedOption) === section.options[0] - expect(section.options[0].isSelected) == true - expect(section.options[1].isSelected) == false - } - } - - context("when set to true with something selected") { - let section = RadioSection(title: "title", options: [ - OptionRow(text: "Option 1", isSelected: false, action: nil), - OptionRow(text: "Option 2", isSelected: true, action: nil) - ]) - section.alwaysSelectsOneOption = true - - it("should do nothing") { - expect(section.selectedOption) === section.options[1] - expect(section.options[0].isSelected) == false - expect(section.options[1].isSelected) == true - } - } - } - - describe("toggle options") { - let mock = { - RadioSection(title: "Radio", options: [ - OptionRow(text: "Option 1", isSelected: true, action: nil), - OptionRow(text: "Option 2", isSelected: false, action: nil), - OptionRow(text: "Option 3", isSelected: false, action: nil) - ]) - } - - context("when the option to toggle is not in the section") { - let section = mock() - let option = OptionRow(text: "", isSelected: true, action: nil) - let result = section.toggle(option) - - it("should return an empty index set") { - expect(result) == [] - } - } - - context("when the option is selected and it allows none selected") { - let section = mock() - _ = section.toggle(section.options[0]) - - it("should deselect the option") { - expect(section.selectedOption).to(beNil()) - expect(section.options[0].isSelected) == false - expect(section.options[1].isSelected) == false - expect(section.options[2].isSelected) == false - } - } - - context("when the option is selected and it doesn't allow none selected") { - let section = mock() - section.alwaysSelectsOneOption = true - _ = section.toggle(section.options[0]) - - it("should do nothing") { - expect(section.selectedOption) === section.options[0] - expect(section.options[0].isSelected) == true - expect(section.options[1].isSelected) == false - expect(section.options[2].isSelected) == false - } - } - - context("when there's nothing selected") { - let section = mock() - _ = section.toggle(section.options[0]) - _ = section.toggle(section.options[1]) - - it("should select the option") { - expect(section.selectedOption) === section.options[1] - expect(section.options[0].isSelected) == false - expect(section.options[1].isSelected) == true - expect(section.options[2].isSelected) == false - } - } - - context("when there's already another option selected") { - let section = mock() - _ = section.toggle(section.options[2]) - - it("should deselect the other option") { - expect(section.selectedOption) === section.options[2] - expect(section.options[0].isSelected) == false - expect(section.options[1].isSelected) == false - expect(section.options[2].isSelected) == true - } - } - } +internal final class RadioSectionTests: XCTestCase { + + // MARK: - Initialization + + func testInitialiation() { + // Given + let row = OptionRow(text: "", isSelected: false, action: nil) + + // When + let section = RadioSection(title: "title", options: [row], footer: "footer") + + // Then it should have the given parameters + XCTAssertEqual(section.title, "title") + XCTAssertEqual(section.rows.count, 1) + XCTAssertEqual(section.rows.first as? OptionRow, row) + XCTAssertEqual(section.options.count, 1) + XCTAssertEqual(section.options.first as? OptionRow, row) + XCTAssertEqual(section.footer, "footer") + } + + // MARK: - Rows + + func testRowsGetter() { + // Given + let options = [ + OptionRow(text: "0", isSelected: false, action: nil), + OptionRow(text: "1", isSelected: true, action: nil) + ] + + // When + let section = RadioSection(title: "", options: options) + + // Then it should return options as rows + XCTAssert(section.rows is [OptionRowCompatible]) + XCTAssertEqual(section.rows as? [OptionRow], options) + } + + func testRowsSetter_empty() { + // Given + let section = RadioSection(title: "", options: [ + OptionRow(text: "", isSelected: true, action: nil) + ]) + + // When + section.rows = [] + + // Then + XCTAssert(section.rows.isEmpty) + } + + func testRowsSetter_incompatibleType() { + // Given + let unchanged = [OptionRow(text: "0", isSelected: false, action: nil)] + let section = RadioSection(title: "", options: unchanged) + + // When + section.rows = [ + NavigationRow(text: "", detailText: .none), + NavigationRow(text: "", detailText: .none) + ] + + // Then the rows should not change + XCTAssertEqual(section.rows as? [OptionRow], unchanged) + } + + func testRowsSetter_compatibleType() { + // Given + let section = RadioSection(title: "", options: []) + + // When + let changed = [ + OptionRow(text: "0", isSelected: false, action: nil), + OptionRow(text: "1", isSelected: true, action: nil) + ] + section.rows = changed + + // Then the rows should change + XCTAssertEqual(section.rows as? [OptionRow], changed) + } + + // MARK: - Always Selects One Option + + func testAlwaysSelectsOneOption_whenSetToFalse() { + // Given + let section = RadioSection(title: "title", options: [ + OptionRow(text: "Option 1", isSelected: false, action: nil) + ]) + + // When + section.alwaysSelectsOneOption = false + + // Then it should do nothing + XCTAssertEqual(section.options.count, 1) + XCTAssertNil(section.selectedOption) + } + + func testAlwaysSelectsOneOption_whenSetToTrueWithEmptyOptions() { + // Given + let section = RadioSection(title: "title", options: []) + + // When + section.alwaysSelectsOneOption = true + + // Then it should do nothing + XCTAssert(section.options.isEmpty) + XCTAssertNil(section.selectedOption) + } + + func testAlwaysSelectsOneOption_whenSetToTrueWithNothingSelected() { + // Given + let section = RadioSection(title: "title", options: [ + OptionRow(text: "Option 1", isSelected: false, action: nil), + OptionRow(text: "Option 2", isSelected: false, action: nil) + ]) + + // When + section.alwaysSelectsOneOption = true + + // Then it should select the first option + XCTAssert(section.selectedOption === section.options[0]) + XCTAssertEqual(section.options[0].isSelected, true) + XCTAssertEqual(section.options[1].isSelected, false) + } + + func testAlwaysSelectsOneOption_whenSetToTrueWithSomethingSelected() { + // Given + let section = RadioSection(title: "title", options: [ + OptionRow(text: "Option 1", isSelected: false, action: nil), + OptionRow(text: "Option 2", isSelected: true, action: nil) + ]) + + // When + section.alwaysSelectsOneOption = true + + // Then it should do nothing + XCTAssert(section.selectedOption === section.options[1]) + XCTAssertEqual(section.options[0].isSelected, false) + XCTAssertEqual(section.options[1].isSelected, true) + } + + // MARK: - Toggle Options + + private func sectionWithThreeRows() -> RadioSection { + return RadioSection(title: "Radio", options: [ + OptionRow(text: "Option 1", isSelected: true, action: nil), + OptionRow(text: "Option 2", isSelected: false, action: nil), + OptionRow(text: "Option 3", isSelected: false, action: nil) + ]) + } + + func testToggleOptions_whenOptionToToggleNotInSection() { + // Given + let section = sectionWithThreeRows() + + // When + let option = OptionRow(text: "", isSelected: true, action: nil) + let result = section.toggle(option) + + // Then it should return an empty index set + XCTAssert(result.isEmpty) + } + + func testToggleOptions_whenOptionIsSelected() { + // Given + let section = sectionWithThreeRows() + + // When + _ = section.toggle(section.options[0]) + + // Then it should deselect the option + XCTAssertNil(section.selectedOption) + XCTAssertEqual(section.options[0].isSelected, false) + XCTAssertEqual(section.options[1].isSelected, false) + XCTAssertEqual(section.options[2].isSelected, false) + } + + func testToggleOptions_withAlwaysSelectsOneOption() { + // Given + let section = sectionWithThreeRows() + section.alwaysSelectsOneOption = true + + // When + _ = section.toggle(section.options[0]) + + // Then it should do nothing + XCTAssert(section.selectedOption === section.options[0]) + XCTAssertEqual(section.options[0].isSelected, true) + XCTAssertEqual(section.options[1].isSelected, false) + XCTAssertEqual(section.options[2].isSelected, false) + } + + func testToggleOptions_whenNothingIsSelected() { + // Given + let section = RadioSection(title: "Radio", options: [ + OptionRow(text: "Option 1", isSelected: false, action: nil), + OptionRow(text: "Option 2", isSelected: false, action: nil), + OptionRow(text: "Option 3", isSelected: false, action: nil) + ]) + + // When + _ = section.toggle(section.options[1]) + + // Then it should select the option + XCTAssert(section.selectedOption === section.options[1]) + XCTAssertEqual(section.options[0].isSelected, false) + XCTAssertEqual(section.options[1].isSelected, true) + XCTAssertEqual(section.options[2].isSelected, false) + } + + func testToggleOptions_whenAnotherOptionIsSelected() { + // Given + let section = sectionWithThreeRows() + + // When + _ = section.toggle(section.options[2]) + + // Then it should deselect the other option + XCTAssert(section.selectedOption === section.options[2]) + XCTAssertEqual(section.options[0].isSelected, false) + XCTAssertEqual(section.options[1].isSelected, false) + XCTAssertEqual(section.options[2].isSelected, true) } } diff --git a/Tests/Model/SectionSpec.swift b/Tests/Model/SectionSpec.swift index 02473f1a..720c9524 100644 --- a/Tests/Model/SectionSpec.swift +++ b/Tests/Model/SectionSpec.swift @@ -1,5 +1,5 @@ // -// SectionSpec.swift +// SectionTests.swift // QuickTableViewController // // Created by Ben on 18/01/2016. @@ -24,23 +24,23 @@ // SOFTWARE. // -import Nimble -import Quick import QuickTableViewController +import XCTest -internal final class SectionSpec: QuickSpec { +internal final class SectionTests: XCTestCase { - override func spec() { - describe("initialization") { - let row = NavigationRow(text: "", detailText: .none) - let section = Section(title: "title", rows: [row], footer: "footer") - it("should initialize with given parameters") { - expect(section.title) == "title" - expect(section.rows).to(haveCount(1)) - expect(section.rows.first as? NavigationRow) == row - expect(section.footer) == "footer" - } - } + func testInitialiation() { + // Given + let row = NavigationRow(text: "", detailText: .none) + + // When + let section = Section(title: "title", rows: [row], footer: "footer") + + // Then it should have the given parameters + XCTAssertEqual(section.title, "title") + XCTAssertEqual(section.rows.count, 1) + XCTAssertEqual(section.rows.first as? NavigationRow, row) + XCTAssertEqual(section.footer, "footer") } } diff --git a/Tests/Model/SubtitleSpec.swift b/Tests/Model/SubtitleSpec.swift index b5d71eac..cc5b6ee2 100644 --- a/Tests/Model/SubtitleSpec.swift +++ b/Tests/Model/SubtitleSpec.swift @@ -1,5 +1,5 @@ // -// SubtitleSpec.swift +// SubtitleTests.swift // QuickTableViewControllerTests // // Created by Ben on 28/10/2015. @@ -24,115 +24,123 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest @available(*, deprecated, message: "Compatibility tests") -internal final class SubtitleSpec: QuickSpec { - - override func spec() { - describe("compatibility") { - it("should return the corresponding detail text") { - expect(Subtitle.none.detailText) == DetailText.none - expect(Subtitle.belowTitle("text").detailText) == .subtitle("text") - expect(Subtitle.rightAligned("text").detailText) == .value1("text") - expect(Subtitle.leftAligned("text").detailText) == .value2("text") - } - - context("NavigationRow") { - let subtitle = Subtitle.belowTitle("detail text") - let detailText = DetailText.subtitle("detail text") - let icon = Icon.named("icon") - - var invoked = false - let row = NavigationRow(title: "text", subtitle: subtitle, icon: icon, action: { _ in invoked = true }) - - it("should support deprecated initializers") { - expect(row.text) == "text" - expect(row.detailText) == detailText - expect(row.icon) == icon - expect(row.cellReuseIdentifier) == "UITableViewCell.subtitle" - - row.action?(row) - expect(invoked) == true - } - - it("should support deprecated properties") { - expect(row.title) == "text" - expect(row.subtitle?.text) == "detail text" - } - } - - context("OptionRow") { - let icon = Icon.named("icon") - - var invoked = false - let row = OptionRow(title: "text", isSelected: true, icon: icon) { _ in invoked = true } - - it("should support deprecated initializers") { - // Row - expect(row.text) == "text" - expect(row.detailText).to(beNil()) - expect(row.isSelected) == true - - row.action?(row) - expect(invoked) == true - - // RowStyle - expect(row.cellReuseIdentifier) == "UITableViewCell" - expect(row.cellStyle) == UITableViewCell.CellStyle.default - expect(row.icon) == icon - expect(row.accessoryType) == UITableViewCell.AccessoryType.checkmark - expect(row.isSelectable) == true - expect(row.customize).to(beNil()) - } - - it("should support deprecated properties") { - expect(row.title) == "text" - expect(row.subtitle?.text).to(beNil()) - } - } - - context("SwitchRow") { - var invoked = false - let row = SwitchRow(title: "text", switchValue: true) { _ in invoked = true } - - it("should support deprecated initializers") { - expect(row.text) == "text" - expect(row.detailText).to(beNil()) - expect(row.switchValue) == true - expect(row.cellReuseIdentifier) == "SwitchCell" - - row.action?(row) - expect(invoked) == true - } - - it("should support deprecated properties") { - expect(row.title) == "text" - expect(row.subtitle?.text).to(beNil()) - } - } - - context("TapActionRow") { - var invoked = false - let row = TapActionRow(title: "text") { _ in invoked = true } - - it("should initialize with given parameters") { - expect(row.text) == "text" - expect(row.detailText).to(beNil()) - expect(row.cellReuseIdentifier) == "TapActionCell" - - row.action?(row) - expect(invoked) == true - } - - it("should support deprecated properties") { - expect(row.title) == "text" - expect(row.subtitle?.text).to(beNil()) - } - } - } +internal final class SubtitleTests: XCTestCase { + + func testCompatibility() { + XCTAssertEqual(Subtitle.none.detailText, .none) + XCTAssertEqual(Subtitle.belowTitle("text").detailText, .subtitle("text")) + XCTAssertEqual(Subtitle.rightAligned("text").detailText, .value1("text")) + XCTAssertEqual(Subtitle.leftAligned("text").detailText, .value2("text")) + } + + func testNavigationRow() { + // Given + let subtitle = Subtitle.belowTitle("detail text") + let detailText = DetailText.subtitle("detail text") + let icon = Icon.named("icon") + var invoked = false + + // When + let row = NavigationRow(title: "text", subtitle: subtitle, icon: icon, action: { _ in invoked = true }) + + // Then it should have the given parameters + XCTAssertEqual(row.text, "text") + XCTAssertEqual(row.detailText, detailText) + XCTAssertEqual(row.icon, icon) + XCTAssertEqual(row.cellReuseIdentifier, "UITableViewCell.subtitle") + + // It should support deprecated properties + XCTAssertEqual(row.title, "text") + XCTAssertEqual(row.subtitle?.text, "detail text") + + // When + row.action?(row) + + // Then + XCTAssertEqual(invoked, true) + } + + func testOptionRow() { + // Given + let icon = Icon.named("icon") + var invoked = false + + // When + let row = OptionRow(title: "text", isSelected: true, icon: icon) { _ in invoked = true } + + // Then it should have the given parameters + XCTAssertEqual(row.text, "text") + XCTAssertNil(row.detailText) + XCTAssertEqual(row.isSelected, true) + + // With RowStyle + XCTAssertEqual(row.cellReuseIdentifier, "UITableViewCell") + XCTAssertEqual(row.cellStyle, .default) + XCTAssertEqual(row.icon, icon) + XCTAssertEqual(row.accessoryType, .checkmark) + XCTAssertEqual(row.isSelectable, true) + XCTAssertNil(row.customize) + + // It should support deprecated properties + XCTAssertEqual(row.title, "text") + XCTAssertNil(row.subtitle?.text) + + // When + row.action?(row) + + // Then + XCTAssertEqual(invoked, true) + } + + func testSwitchRow() { + // Given + var invoked = false + + // When + let row = SwitchRow(title: "text", switchValue: true) { _ in invoked = true } + + // Then it should have the given parameters + XCTAssertEqual(row.text, "text") + XCTAssertNil(row.detailText) + XCTAssertEqual(row.switchValue, true) + XCTAssertEqual(row.cellReuseIdentifier, "SwitchCell") + + // It should support deprecated properties + XCTAssertEqual(row.title, "text") + XCTAssertNil(row.subtitle?.text) + + // When + row.action?(row) + + // Then + XCTAssertEqual(invoked, true) + } + + func testTapActionRow() { + // Given + var invoked = false + + // When + let row = TapActionRow(title: "text") { _ in invoked = true } + + // Then it should initialize with given parameters + XCTAssertEqual(row.text, "text") + XCTAssertNil(row.detailText) + XCTAssertEqual(row.cellReuseIdentifier, "TapActionCell") + + // It should support deprecated properties + XCTAssertEqual(row.title, "text") + XCTAssertNil(row.subtitle?.text) + + // When + row.action?(row) + + // Then + XCTAssertEqual(invoked, true) } } From 5d3a039c775d49844cff7248be93663d94702ae4 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 16 Feb 2020 16:40:41 +0000 Subject: [PATCH 3/5] Convert Configurable specs to XCTests --- Tests/View/ConfigurableSpec.swift | 233 +++++++++++++++--------------- Tests/View/ReusableSpec.swift | 99 +++++++------ 2 files changed, 167 insertions(+), 165 deletions(-) diff --git a/Tests/View/ConfigurableSpec.swift b/Tests/View/ConfigurableSpec.swift index 98abe10d..5caa2e2f 100644 --- a/Tests/View/ConfigurableSpec.swift +++ b/Tests/View/ConfigurableSpec.swift @@ -1,5 +1,5 @@ // -// ConfigurableSpec.swift +// ConfigurableTests.swift // QuickTableViewControllerTests // // Created by Ben on 27/12/2017. @@ -24,125 +24,122 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest -internal final class ConfigurableSpec: QuickSpec { - - override func spec() { - describe("configure(with:)") { - context("default row and cell") { - it("should set the switch to true") { - let cell = SwitchCell() - let row = SwitchRow(text: "", switchValue: true, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == true - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark - #endif - } - - it("should set the switch to false") { - let cell = SwitchCell() - let row = SwitchRow(text: "", switchValue: false, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == false - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.none - #endif - } - } - - context("custom row") { - it("should set the switch to true") { - let cell = SwitchCell() - let row = CustomSwitchRow(text: "", switchValue: true, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == true - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark - #endif - } - - it("should set the switch to false") { - let cell = SwitchCell() - let row = CustomSwitchRow(text: "", switchValue: false, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == false - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.none - #endif - } - } - - context("custom cell") { - it("should set the switch to true") { - let cell = CustomSwitchCell() - let row = SwitchRow(text: "", switchValue: true, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == true - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark - #endif - } - - it("should set the switch to false") { - let cell = CustomSwitchCell() - let row = SwitchRow(text: "", switchValue: false, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == false - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.none - #endif - } - } - - context("custom row and cell") { - it("should set the switch to true") { - let cell = CustomSwitchCell() - let row = CustomSwitchRow(text: "", switchValue: true, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == true - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark - #endif - } - - it("should set the switch to false") { - let cell = CustomSwitchCell() - let row = CustomSwitchRow(text: "", switchValue: false, action: nil) - cell.configure(with: row) - #if os(iOS) - expect(cell.accessoryView) == cell.switchControl - expect(cell.switchControl.isOn) == false - #elseif os(tvOS) - expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.none - #endif - } - } +internal final class ConfigurableTests: XCTestCase { + + func testConfiguration_default() { + do { + // Given + let cell = SwitchCell() + let row = SwitchRow(text: "", switchValue: true, action: nil) + + // When + cell.configure(with: row) + + // Then + #if os(iOS) + XCTAssertEqual(cell.accessoryView, cell.switchControl) + XCTAssertEqual(cell.switchControl.isOn, true) + #elseif os(tvOS) + XCTAssertNil(cell.accessoryView) + XCTAssertEqual(cell.accessoryType, .checkmark) + #endif + } + + do { + // Given + let cell = SwitchCell() + let row = SwitchRow(text: "", switchValue: false, action: nil) + + // When + cell.configure(with: row) + + // Then + #if os(iOS) + XCTAssertEqual(cell.accessoryView, cell.switchControl) + XCTAssertEqual(cell.switchControl.isOn, false) + #elseif os(tvOS) + XCTAssertNil(cell.accessoryView) + XCTAssertEqual(cell.accessoryType, .none) + #endif + } + } + + func testConfiguration_customRow() { + do { + // Given + let cell = SwitchCell() + let row = CustomSwitchRow(text: "", switchValue: true, action: nil) + + // When + cell.configure(with: row) + + // Then + #if os(iOS) + XCTAssertEqual(cell.accessoryView, cell.switchControl) + XCTAssertEqual(cell.switchControl.isOn, true) + #elseif os(tvOS) + XCTAssertNil(cell.accessoryView) + XCTAssertEqual(cell.accessoryType, .checkmark) + #endif + } + + do { + // Given + let cell = SwitchCell() + let row = CustomSwitchRow(text: "", switchValue: false, action: nil) + + // When + cell.configure(with: row) + + // Then + #if os(iOS) + XCTAssertEqual(cell.accessoryView, cell.switchControl) + XCTAssertEqual(cell.switchControl.isOn, false) + #elseif os(tvOS) + XCTAssertNil(cell.accessoryView) + XCTAssertEqual(cell.accessoryType, .none) + #endif + } + } + + func testConfiguration_customCell() { + do { + // Given + let cell = CustomSwitchCell() + let row = CustomSwitchRow(text: "", switchValue: true, action: nil) + + // When + cell.configure(with: row) + + // Then + #if os(iOS) + XCTAssertEqual(cell.accessoryView, cell.switchControl) + XCTAssertEqual(cell.switchControl.isOn, true) + #elseif os(tvOS) + XCTAssertNil(cell.accessoryView) + XCTAssertEqual(cell.accessoryType, .checkmark) + #endif + } + + do { + // Given + let cell = CustomSwitchCell() + let row = CustomSwitchRow(text: "", switchValue: false, action: nil) + + // When + cell.configure(with: row) + + // Then + #if os(iOS) + XCTAssertEqual(cell.accessoryView, cell.switchControl) + XCTAssertEqual(cell.switchControl.isOn, false) + #elseif os(tvOS) + XCTAssertNil(cell.accessoryView) + XCTAssertEqual(cell.accessoryType, .none) + #endif } } diff --git a/Tests/View/ReusableSpec.swift b/Tests/View/ReusableSpec.swift index 8556943e..22fb2dc9 100644 --- a/Tests/View/ReusableSpec.swift +++ b/Tests/View/ReusableSpec.swift @@ -1,5 +1,5 @@ // -// ReusableSpec.swift +// ReusableTests.swift // QuickTableViewController // // Created by Ben on 21/08/2017. @@ -24,57 +24,62 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest -internal final class ReusableSpec: QuickSpec { +internal final class ReusableTests: XCTestCase { private class CustomCell: UITableViewCell {} - override func spec() { - describe("matches of pattern") { - let pattern = String.typeDescriptionPattern - - context("invalid pattern") { - it("should return an empty array") { - let matches = String(describing: type(of: self)).matches(of: "\\") - expect(matches).to(beEmpty()) - } - } - - context("type with special format") { - it("should match the pattern") { - let type = "(CustomCell in _B5334F301B8CC6AA00C64A6D)" - let matches = type.matches(of: pattern) - expect(matches).to(haveCount(2)) - } - } - - context("type with name only") { - it("should not match the pattern") { - let type = "CustomCell" - let matches = type.matches(of: pattern) - expect(matches).to(beEmpty()) - } - } - } - - describe("reuse identifier") { - context("custom type") { - it("should be the type name") { - let identifier = CustomCell.reuseIdentifier - expect(identifier) == "CustomCell" - } - } - - context("type in the module") { - it("should be the type name") { - let identifier = SwitchCell.reuseIdentifier - expect(identifier) == "SwitchCell" - } - } - } + private let pattern = String.typeDescriptionPattern + + func testTypeString_withInvalidPattern() { + // Given + let typeString = String(describing: type(of: self)) + + // When + let matches = typeString.matches(of: "\\") + + // Then it should return an empty array + XCTAssert(matches.isEmpty) + } + + func testTypeString_withSpecialFormat() { + // Given + let typeString = "(CustomCell in _B5334F301B8CC6AA00C64A6D)" + + // When + let matches = typeString.matches(of: pattern) + + // Then it should match the pattern + XCTAssertEqual(matches.count, 2) + } + + func testTypeString_withNameOnly() { + // Given + let typeString = "CustomCell" + + // When + let matches = typeString.matches(of: pattern) + + // Then it should not match the pattern + XCTAssert(matches.isEmpty) + } + + func testReuseIdentifier_withCustomType() { + // When + let identifier = CustomCell.reuseIdentifier + + // Then + XCTAssertEqual(identifier, "CustomCell") + } + + func testReuseIdentifier_withTypeInModule() { + // When + let identifier = SwitchCell.reuseIdentifier + + // Then + XCTAssertEqual(identifier, "SwitchCell") } } From 620fd13f1a1b611f8c173b3d37a03794fc1d8d27 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 17 Feb 2020 22:56:07 +0000 Subject: [PATCH 4/5] Convert ViewController specs to XCTests --- .../QuickTableViewControllerSpec.swift | 55 +- .../QuickTableViewDataSourceSpec.swift | 581 +++++++++--------- .../QuickTableViewDelegateSpec.swift | 534 ++++++++-------- 3 files changed, 601 insertions(+), 569 deletions(-) diff --git a/Tests/ViewController/QuickTableViewControllerSpec.swift b/Tests/ViewController/QuickTableViewControllerSpec.swift index bd37f761..db98a8a6 100644 --- a/Tests/ViewController/QuickTableViewControllerSpec.swift +++ b/Tests/ViewController/QuickTableViewControllerSpec.swift @@ -1,5 +1,5 @@ // -// QuickTableViewControllerSpec.swift +// QuickTableViewControllerTests.swift // QuickTableViewControllerTests // // Created by Ben on 21/01/2016. @@ -24,44 +24,39 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest -internal final class QuickTableViewControllerSpec: QuickSpec { +internal final class QuickTableViewControllerTests: XCTestCase { - override func spec() { + func testInitialization() { + // When + let controller = QuickTableViewController() - // MARK: - Initializer - - describe("init(style:)") { - it("should set up table view with style") { - expect(QuickTableViewController().tableView.style) == UITableView.Style.grouped - expect(QuickTableViewController(style: .plain).tableView.style) == UITableView.Style.plain - } - } + // Then it should set up table view with style + XCTAssertEqual(controller.tableView.style, .grouped) + } - // MARK: - UIViewController + func testInitialization_withStyle() { + // When + let controller = QuickTableViewController(style: .plain) - describe("lifecycle") { - var tableView: UITableView! // swiftlint:disable:this implicitly_unwrapped_optional + // Then it should set up table view with style + XCTAssertEqual(controller.tableView.style, .plain) + } - it("should set up table view") { - let controller = QuickTableViewController(style: .grouped) - let view = controller.view - tableView = controller.tableView + func testViewConfiguration() { + // Given + let controller = QuickTableViewController(style: .grouped) - expect(view?.subviews).to(contain(tableView)) - expect(tableView.dataSource as? QuickTableViewController) == controller - expect(tableView.delegate as? QuickTableViewController) == controller - } + // When + let view = controller.view + let tableView = controller.tableView - it("should nullify the references after controller is gone") { - expect(tableView).notTo(beNil()) - expect(tableView.dataSource).toEventually(beNil()) - expect(tableView.delegate).toEventually(beNil()) - } - } + // Than it should set up table view + XCTAssert(try XCTUnwrap(view?.subviews.contains(tableView))) + XCTAssertEqual(tableView.dataSource as? QuickTableViewController, controller) + XCTAssertEqual(tableView.delegate as? QuickTableViewController, controller) } } diff --git a/Tests/ViewController/QuickTableViewDataSourceSpec.swift b/Tests/ViewController/QuickTableViewDataSourceSpec.swift index e5138380..c7512ec3 100644 --- a/Tests/ViewController/QuickTableViewDataSourceSpec.swift +++ b/Tests/ViewController/QuickTableViewDataSourceSpec.swift @@ -1,5 +1,5 @@ // -// QuickTableViewDataSourceSpec.swift +// QuickTableViewDataSourceTests.swift // QuickTableViewControllerTests // // Created by Ben on 31/12/2017. @@ -24,302 +24,325 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest -internal final class QuickTableViewDataSourceSpec: QuickSpec { +internal final class QuickTableViewDataSourceTests: XCTestCase { - override func spec() { + private var controller: QuickTableViewController! - // MARK: - numberOfSectionsInTableView(_:) + override func setUp() { + super.setUp() + controller = QuickTableViewController() + _ = controller.view + } - describe("numberOfSectionsInTableView(_:)") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: nil, rows: []), - Section(title: nil, rows: []), - Section(title: nil, rows: []) - ] - it("should return the number of sections") { - expect(controller.numberOfSections(in: controller.tableView)) == 3 - } + func testNumberOfSectionsInTableView() { + // Given + controller.tableContents = [ + Section(title: nil, rows: []), + Section(title: nil, rows: []), + Section(title: nil, rows: []) + ] + + // When + let numberOfSections = controller.numberOfSections(in: controller.tableView) + + // Then + XCTAssertEqual(numberOfSections, 3) + } + + func testTableViewNumberOfRowsInSection() { + // Given + controller.tableContents = [ + Section(title: nil, rows: []), + Section(title: nil, rows: [ + NavigationRow(text: "", detailText: .none), + NavigationRow(text: "", detailText: .none) + ]), + RadioSection(title: nil, options: []), + RadioSection(title: nil, options: [ + OptionRow(text: "", isSelected: false, action: { _ in }), + OptionRow(text: "", isSelected: false, action: { _ in }) + ]) + ] + + // When + let numberOfRowsInSection: [Int] = (0...3).map { + controller.tableView(controller.tableView, numberOfRowsInSection: $0) } - // MARK: - tableView(_:numberOfRowsInSection:) - - describe("tableView(_:numberOfRowsInSection:)") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: nil, rows: []), - Section(title: nil, rows: [ - NavigationRow(text: "", detailText: .none), - NavigationRow(text: "", detailText: .none) - ]), - RadioSection(title: nil, options: []), - RadioSection(title: nil, options: [ - OptionRow(text: "", isSelected: false, action: { _ in }), - OptionRow(text: "", isSelected: false, action: { _ in }) - ]) - ] - it("should return the number of sections") { - expect(controller.tableView(controller.tableView, numberOfRowsInSection: 0)) == 0 - expect(controller.tableView(controller.tableView, numberOfRowsInSection: 1)) == 2 - expect(controller.tableView(controller.tableView, numberOfRowsInSection: 2)) == 0 - expect(controller.tableView(controller.tableView, numberOfRowsInSection: 3)) == 2 - } + // Then + XCTAssertEqual(numberOfRowsInSection[0], 0) + XCTAssertEqual(numberOfRowsInSection[1], 2) + XCTAssertEqual(numberOfRowsInSection[2], 0) + XCTAssertEqual(numberOfRowsInSection[3], 2) + } + + func testTableViewTitleForHeaderInSection() { + // Given + controller.tableContents = [ + Section(title: nil, rows: []), + Section(title: "title", rows: []), + RadioSection(title: "radio", options: []) + ] + + // When + let titleForHeaderInSection: [String?] = (0...2).map { + controller.tableView(controller.tableView, titleForHeaderInSection: $0) } - // MARK: - tableView(_:titleForHeaderInSection:) - - describe("tableView(_:titleForHeaderInSection:)") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: nil, rows: []), - Section(title: "title", rows: []), - RadioSection(title: "radio", options: []) - ] - it("should return the title in sections") { - expect(controller.tableView(controller.tableView, titleForHeaderInSection: 0)).to(beNil()) - expect(controller.tableView(controller.tableView, titleForHeaderInSection: 1)) == "title" - expect(controller.tableView(controller.tableView, titleForHeaderInSection: 2)) == "radio" - } + // Then + XCTAssertNil(titleForHeaderInSection[0]) + XCTAssertEqual(titleForHeaderInSection[1], "title") + XCTAssertEqual(titleForHeaderInSection[2], "radio") + } + + func testTableViewTitleForFooterInSection() { + // Given + controller.tableContents = [ + Section(title: nil, rows: []), + Section(title: nil, rows: [], footer: "footer"), + RadioSection(title: nil, options: [], footer: "radio") + ] + + // When + let titleForFooterInSection: [String?] = (0...2).map { + controller.tableView(controller.tableView, titleForFooterInSection: $0) } - // MARK: - tableView(_:titleForFooterInSection:) - - describe("tableView(_:titleForFooterInSection:)") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: nil, rows: []), - Section(title: nil, rows: [], footer: "footer"), - RadioSection(title: nil, options: [], footer: "radio") - ] - it("should return the title in sections") { - expect(controller.tableView(controller.tableView, titleForFooterInSection: 0)).to(beNil()) - expect(controller.tableView(controller.tableView, titleForFooterInSection: 1)) == "footer" - expect(controller.tableView(controller.tableView, titleForFooterInSection: 2)) == "radio" - } + // Then + XCTAssertNil(titleForFooterInSection[0]) + XCTAssertEqual(titleForFooterInSection[1], "footer") + XCTAssertEqual(titleForFooterInSection[2], "radio") + } + + // MARK: - tableView(_:cellForRowAt:) + + func testTableViewCellForRowAt_navigationRow() { + // Given + controller.tableContents = [ + Section(title: "Cell Styles", rows: [ + CustomNavigationRow(text: "CellStyle.default", detailText: .none), + CustomNavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle")), + CustomNavigationRow(text: "CellStyle", detailText: .value1(".value1")), + CustomNavigationRow(text: "CellStyle", detailText: .value2(".value2")) + ]) + ] + + // When + let cells: [UITableViewCell] = (0...3).map { + controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: $0, section: 0)) } - // MARK: - tableView(_:cellForRowAt:) - - describe("tableView(_:cellForRowAt:)") { - - // MARK: NavigationRow - - context("NavigationRow") { - context("style") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: "Cell Styles", rows: [ - CustomNavigationRow(text: "CellStyle.default", detailText: .none), - CustomNavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle")), - CustomNavigationRow(text: "CellStyle", detailText: .value1(".value1")), - CustomNavigationRow(text: "CellStyle", detailText: .value2(".value2")) - ]) - ] - let a = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 0)) - let b = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 1, section: 0)) - let c = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 2, section: 0)) - let d = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 3, section: 0)) - - it("should match the reusable identifier") { - expect(a.reuseIdentifier) == "CustomCell.default" - expect(b.reuseIdentifier) == "CustomCell.subtitle" - expect(c.reuseIdentifier) == "CustomCell.value1" - expect(d.reuseIdentifier) == "CustomCell.value2" - } - - it("should match the texts in labels") { - expect(a.textLabel?.text) == "CellStyle.default" - expect(b.textLabel?.text) == "CellStyle" - expect(c.textLabel?.text) == "CellStyle" - expect(d.textLabel?.text) == "CellStyle" - } - - it("should match the texts in detail labels") { - expect(a.detailTextLabel?.text).to(beNil()) - expect(b.detailTextLabel?.text) == ".subtitle" - expect(c.detailTextLabel?.text) == ".value1" - expect(d.detailTextLabel?.text) == ".value2" - } - } - - context("icon") { - let controller = QuickTableViewController() - let resourcePath = Bundle(for: QuickTableViewControllerSpec.self).resourcePath as NSString? - let imagePath = resourcePath?.appendingPathComponent("icon.png") ?? "" - let highlightedImagePath = resourcePath?.appendingPathComponent("icon.png") ?? "" - - let image = UIImage(contentsOfFile: imagePath)! - let highlightedImage = UIImage(contentsOfFile: highlightedImagePath)! - - controller.tableContents = [ - Section(title: "NavigationRow", rows: [ - CustomNavigationRow(text: "CellStyle.default", detailText: .none, icon: .named("icon")), - CustomNavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), icon: .image(image)), - CustomNavigationRow(text: "CellStyle", detailText: .value1(".value1"), icon: .images(normal: image, highlighted: highlightedImage)), - CustomNavigationRow(text: "CellStyle", detailText: .value2(".value2"), icon: .image(image)) - ]), - Section(title: "SwitchRow", rows: [ - CustomSwitchRow(text: "imageName", switchValue: true, icon: .named("icon"), action: nil), - CustomSwitchRow(text: "image", switchValue: true, icon: .image(image), action: nil), - CustomSwitchRow(text: "image + highlightedImage", switchValue: true, icon: .images(normal: image, highlighted: highlightedImage), action: nil) - ]) - ] - - it("does not work with images in the test bundle") { - let navigationCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 0)) - expect(navigationCell.imageView?.image).to(beNil()) - expect(navigationCell.imageView?.highlightedImage).to(beNil()) - - let switchCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 0, section: 1)) - expect(switchCell.imageView?.image).to(beNil()) - expect(switchCell.imageView?.highlightedImage).to(beNil()) - } - - it("should have the image set") { - let navigationCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 1, section: 0)) - expect(navigationCell.imageView?.image) == image - expect(navigationCell.imageView?.highlightedImage).to(beNil()) - - let switchCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 1, section: 1)) - expect(switchCell.imageView?.image).notTo(beNil()) - expect(switchCell.imageView?.highlightedImage).to(beNil()) - } - - it("should have the image and highlightedImage set") { - let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 2, section: 0)) - expect(cell.imageView?.image).notTo(beNil()) - expect(cell.imageView?.highlightedImage).notTo(beNil()) - - let switchCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 2, section: 1)) - expect(switchCell.imageView?.image).notTo(beNil()) - expect(switchCell.imageView?.highlightedImage).notTo(beNil()) - } - - it("should not have an image with UITableViewCellStyle.value2") { - let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: 3, section: 0)) - expect(cell.imageView?.image).to(beNil()) - expect(cell.imageView?.highlightedImage).to(beNil()) - } - } - - context("indicator") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: "Navigation", rows: [ - CustomNavigationRow(text: "", detailText: .none, action: { _ in }), - CustomNavigationRow(text: "", detailText: .subtitle(""), action: { _ in }), - CustomNavigationRow(text: "", detailText: .value1(""), action: { _ in }), - CustomNavigationRow(text: "", detailText: .value2(""), action: { _ in }) - ]) - ] - - it("should have the disclosure indicator") { - for row in 0...3 { - let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 0)) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.disclosureIndicator - } - } - } - } + // Then + XCTAssertEqual(cells[0].reuseIdentifier, "CustomCell.default") + XCTAssertEqual(cells[1].reuseIdentifier, "CustomCell.subtitle") + XCTAssertEqual(cells[2].reuseIdentifier, "CustomCell.value1") + XCTAssertEqual(cells[3].reuseIdentifier, "CustomCell.value2") - // MARK: SwitchRow - - context("SwitchRow") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: "SwitchRow", rows: [ - SwitchRow(text: "Setting 0", switchValue: true, action: nil), - CustomSwitchRow(text: "Setting 1", switchValue: true, action: nil), - SwitchRow(text: "Setting 2", switchValue: true, action: nil), - CustomSwitchRow(text: "Setting 3", switchValue: true, action: nil) - ]) - ] - - for index in 0...3 { - let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: index, section: 0)) - - it("should return cell type at \(index)") { - let type = index < 2 ? SwitchCell.self : CustomSwitchCell.self - expect(cell).to(beAKindOf(type)) - } - - it("should match the text at \(index)") { - expect(cell.textLabel?.text) == "Setting \(index)" - expect(cell.detailTextLabel?.text).to(beNil()) - } - - it("should match the switch value at \(index)") { - #if os(iOS) - expect((cell as? SwitchCell)?.switchControl.isOn) == true - #elseif os(tvOS) - expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark - #endif - } - } - } + XCTAssertEqual(cells[0].textLabel?.text, "CellStyle.default") + XCTAssertEqual(cells[1].textLabel?.text, "CellStyle") + XCTAssertEqual(cells[2].textLabel?.text, "CellStyle") + XCTAssertEqual(cells[3].textLabel?.text, "CellStyle") + + XCTAssertNil(cells[0].detailTextLabel?.text) + XCTAssertEqual(cells[1].detailTextLabel?.text, ".subtitle") + XCTAssertEqual(cells[2].detailTextLabel?.text, ".value1") + XCTAssertEqual(cells[3].detailTextLabel?.text, ".value2") + + cells.forEach { + XCTAssertEqual($0.accessoryType, .none) + } + } + + func testTableViewCellForRowAt_navigationRowWithAction() { + // Given + controller.tableContents = [ + Section(title: "Navigation", rows: [ + CustomNavigationRow(text: "", detailText: .none, action: { _ in }), + CustomNavigationRow(text: "", detailText: .subtitle(""), action: { _ in }), + CustomNavigationRow(text: "", detailText: .value1(""), action: { _ in }), + CustomNavigationRow(text: "", detailText: .value2(""), action: { _ in }) + ]) + ] + + // When + let cells: [UITableViewCell] = (0...3).map { + controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: $0, section: 0)) + } + + // Then + cells.forEach { + XCTAssertEqual($0.accessoryType, .disclosureIndicator) + } + } - // MARK: TapActionRow - - context("TapActionRow") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: "TapActionRow", rows: [ - TapActionRow(text: "0", action: { _ in }), - CustomTapActionRow(text: "1", action: { _ in }), - TapActionRow(text: "2", action: { _ in }), - CustomTapActionRow(text: "3", action: { _ in }) - ]) - ] - - for index in 0...3 { - let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: index, section: 0)) - - it("should return cell type at \(index)") { - let type = index < 2 ? TapActionCell.self : CustomTapActionCell.self - expect(cell).to(beAKindOf(type)) - } - - it("should match the text at \(index)") { - expect(cell.textLabel?.text) == "\(index)" - expect(cell.detailTextLabel?.text).to(beNil()) - } - } + func testTableViewCellForRowAt_switchRow() { + // Given + controller.tableContents = [ + Section(title: "SwitchRow", rows: [ + SwitchRow(text: "Setting 0", switchValue: true, action: nil), + CustomSwitchRow(text: "Setting 1", switchValue: true, action: nil), + SwitchRow(text: "Setting 2", switchValue: true, action: nil), + CustomSwitchRow(text: "Setting 3", switchValue: true, action: nil) + ]) + ] + + for index in 0...3 { + // When + let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: index, section: 0)) + + // Then it should match the cell type + if index < 2 { + XCTAssert(cell is SwitchCell) + } else { + XCTAssert(cell is CustomSwitchCell) } - // MARK: OptionRow - - context("OptionRow") { - let controller = QuickTableViewController() - controller.tableContents = [ - Section(title: "OptionRow", rows: [ - OptionRow(text: "0", isSelected: true, action: { _ in }), - CustomOptionRow(text: "1", isSelected: true, action: { _ in }), - OptionRow(text: "2", isSelected: true, action: { _ in }), - CustomOptionRow(text: "3", isSelected: true, action: { _ in }) - ]) - ] - - for index in 0...3 { - let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: index, section: 0)) - - it("should return cell type at \(index)") { - let type = index < 2 ? UITableViewCell.self : CustomCell.self - expect(cell).to(beAKindOf(type)) - } - - it("should match the text at \(index)") { - expect(cell.textLabel?.text) == "\(index)" - } - - it("should match the selection at \(index)") { - expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark - } - } + // Then it should match the text + XCTAssertEqual(cell.textLabel?.text, "Setting \(index)") + XCTAssertNil(cell.detailTextLabel?.text) + + // Then it should match the switch value + #if os(iOS) + XCTAssertEqual((cell as? SwitchCell)?.switchControl.isOn, true) + #elseif os(tvOS) + XCTAssertEqual(cell.accessoryType, .checkmark) + #endif + } + } + + func testTableViewCellForRowAt_tapActionRow() { + // Given + controller.tableContents = [ + Section(title: "TapActionRow", rows: [ + TapActionRow(text: "0", action: { _ in }), + CustomTapActionRow(text: "1", action: { _ in }), + TapActionRow(text: "2", action: { _ in }), + CustomTapActionRow(text: "3", action: { _ in }) + ]) + ] + + for index in 0...3 { + // When + let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: index, section: 0)) + + // Then it should match the cell type + if index < 2 { + XCTAssert(cell is TapActionCell) + } else { + XCTAssert(cell is CustomTapActionCell) } + + // Then it should match the configuration + XCTAssertEqual(cell.textLabel?.text, "\(index)") + XCTAssertNil(cell.detailTextLabel?.text) + } + } + + func testTableViewCellForRowAt_optionRow() { + // Given + controller.tableContents = [ + Section(title: "OptionRow", rows: [ + OptionRow(text: "0", isSelected: true, action: { _ in }), + CustomOptionRow(text: "1", isSelected: true, action: { _ in }), + OptionRow(text: "2", isSelected: true, action: { _ in }), + CustomOptionRow(text: "3", isSelected: true, action: { _ in }) + ]) + ] + + for index in [2, 3] { + // When + let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: index, section: 0)) + + // Then it should match the cell type + XCTAssert(cell is CustomCell) + } + + for index in 0...3 { + // When + let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: index, section: 0)) + + // Then it should match the configuration + XCTAssertEqual(cell.textLabel?.text, "\(index)") + XCTAssertEqual(cell.accessoryType, .checkmark) + } + } + + func testTableViewCellForRowAt_rowWithIcon() { + // Given + let resourcePath = Bundle(for: QuickTableViewDataSourceTests.self).resourcePath as NSString? + let imagePath = resourcePath!.appendingPathComponent("icon.png") + let highlightedImagePath = resourcePath!.appendingPathComponent("icon-highlighted.png") + + let image = UIImage(contentsOfFile: imagePath)! + let highlightedImage = UIImage(contentsOfFile: highlightedImagePath)! + + controller.tableContents = [ + Section(title: "NavigationRow", rows: [ + CustomNavigationRow(text: "CellStyle.default", detailText: .none, icon: .named("icon")), + CustomNavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), icon: .image(image)), + CustomNavigationRow(text: "CellStyle", detailText: .value1(".value1"), icon: .images(normal: image, highlighted: highlightedImage)), + CustomNavigationRow(text: "CellStyle", detailText: .value2(".value2"), icon: .image(image)) + ]), + Section(title: "SwitchRow", rows: [ + CustomSwitchRow(text: "imageName", switchValue: true, icon: .named("icon"), action: nil), + CustomSwitchRow(text: "image", switchValue: true, icon: .image(image), action: nil), + CustomSwitchRow(text: "image + highlightedImage", switchValue: true, icon: .images(normal: image, highlighted: highlightedImage), action: nil) + ]) + ] + + do { + // When + let row = 0 + let navigationCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 0)) + let switchCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 1)) + + // Then it does not work with images in the test bundle + XCTAssertNil(navigationCell.imageView?.image) + XCTAssertNil(navigationCell.imageView?.highlightedImage) + + XCTAssertNil(switchCell.imageView?.image) + XCTAssertNil(switchCell.imageView?.highlightedImage) + } + + do { + // When + let row = 1 + let navigationCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 0)) + let switchCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 1)) + + // Then it should have the image set + XCTAssertEqual(navigationCell.imageView?.image, image) + XCTAssertNil(navigationCell.imageView?.highlightedImage) + + XCTAssertEqual(switchCell.imageView?.image, image) + XCTAssertNil(switchCell.imageView?.highlightedImage) + } + + do { + // When + let row = 2 + let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 0)) + let switchCell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 1)) + + // Then it should have the image and highlightedImage set + XCTAssertEqual(cell.imageView?.image, image) + XCTAssertEqual(cell.imageView?.highlightedImage, highlightedImage) + + XCTAssertEqual(switchCell.imageView?.image, image) + XCTAssertEqual(switchCell.imageView?.highlightedImage, highlightedImage) + } + + do { + // When + let row = 3 + let cell = controller.tableView(controller.tableView, cellForRowAt: IndexPath(row: row, section: 0)) + + // Then it should not have an image with UITableViewCellStyle.value2" + XCTAssertNil(cell.imageView?.image) + XCTAssertNil(cell.imageView?.highlightedImage) } } diff --git a/Tests/ViewController/QuickTableViewDelegateSpec.swift b/Tests/ViewController/QuickTableViewDelegateSpec.swift index 14e59812..66f1e4b2 100644 --- a/Tests/ViewController/QuickTableViewDelegateSpec.swift +++ b/Tests/ViewController/QuickTableViewDelegateSpec.swift @@ -1,5 +1,5 @@ // -// QuickTableViewDelegateSpec.swift +// QuickTableViewDelegateTests.swift // QuickTableViewControllerTests // // Created by Ben on 31/12/2017. @@ -24,275 +24,289 @@ // SOFTWARE. // -import Nimble -import Quick @testable import QuickTableViewController +import XCTest -internal final class QuickTableViewDelegateSpec: QuickSpec { - - override func spec() { - - // MARK: tableView(_:shouldHighlightRowAt:) - - describe("tableView(_:shouldHighlightRowAt:)") { - let controller = QuickTableViewController() - _ = controller.view - - controller.tableContents = [ - Section(title: "NavigationRow", rows: [ - NavigationRow(text: "", detailText: .none), - CustomNavigationRow(text: "", detailText: .none), - NavigationRow(text: "", detailText: .none), - CustomNavigationRow(text: "", detailText: .none) - ]), - - Section(title: "NavigationRow", rows: [ - NavigationRow(text: "", detailText: .none, action: { _ in }), - CustomNavigationRow(text: "", detailText: .none, action: { _ in }), - NavigationRow(text: "", detailText: .none, action: { _ in }), - CustomNavigationRow(text: "", detailText: .none, action: { _ in }) - ]), - - Section(title: "SwitchRow", rows: [ - SwitchRow(text: "", switchValue: true, action: nil), - CustomSwitchRow(text: "", switchValue: true, action: nil), - SwitchRow(text: "", switchValue: true, action: nil), - CustomSwitchRow(text: "", switchValue: true, action: nil) - ]), - - Section(title: "TapActionRow", rows: [ - TapActionRow(text: "", action: { _ in }), - CustomTapActionRow(text: "", action: { _ in }), - TapActionRow(text: "", action: { _ in }), - CustomTapActionRow(text: "", action: { _ in }) - ]), - - Section(title: "OptionRow", rows: [ - OptionRow(text: "", isSelected: false, action: nil), - CustomOptionRow(text: "", isSelected: false, action: nil), - OptionRow(text: "", isSelected: false, action: nil), - CustomOptionRow(text: "", isSelected: false, action: nil) - ]), - - RadioSection(title: "RadioSection", options: [ - OptionRow(text: "", isSelected: false, action: { _ in }), - CustomOptionRow(text: "", isSelected: false, action: { _ in }), - OptionRow(text: "", isSelected: false, action: { _ in }), - CustomOptionRow(text: "", isSelected: false, action: { _ in }) - ]) - ] - - it("should not highlight NavigationRow without an action") { - for index in 0...3 { - let highlight = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: index, section: 0)) - expect(highlight) == false - } - } - - it("should highlight NavigationRow with an action") { - for index in 0...3 { - let highlight = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: index, section: 1)) - expect(highlight) == true - } - } - - it("should not highlight SwitchRow") { - for index in 0...3 { - let highlight = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: index, section: 2)) - #if os(iOS) - expect(highlight) == false - #elseif os(tvOS) - expect(highlight) == true - #endif - } - } - - it("should highlight TapActionRow") { - for index in 0...3 { - let highlight = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: index, section: 3)) - expect(highlight) == true - } - } - - it("should highlight OptionRow without an action") { - for index in 0...3 { - let highlight = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: index, section: 4)) - expect(highlight) == true - } - } - - it("should highlight OptionRow with an action") { - for index in 0...3 { - let highlight = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: index, section: 5)) - expect(highlight) == true - } - } +internal final class QuickTableViewDelegateTests: XCTestCase { + + private var controller: QuickTableViewController! + + override func setUp() { + super.setUp() + controller = QuickTableViewController() + _ = controller.view + } + + // MARK: - tableView(_:shouldHighlightRowAt:) + + func testTableViewShouldHighlightRowAt_navigationRow() { + // Given + controller.tableContents = [ + Section(title: "NavigationRow without actions", rows: [ + NavigationRow(text: "", detailText: .none), + CustomNavigationRow(text: "", detailText: .none), + NavigationRow(text: "", detailText: .none), + CustomNavigationRow(text: "", detailText: .none) + ]), + + Section(title: "NavigationRow with actions", rows: [ + NavigationRow(text: "", detailText: .none, action: { _ in }), + CustomNavigationRow(text: "", detailText: .none, action: { _ in }), + NavigationRow(text: "", detailText: .none, action: { _ in }), + CustomNavigationRow(text: "", detailText: .none, action: { _ in }) + ]) + ] + + for row in 0...3 { + let section = 0 + + // When + let highlighted = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: row, section: section)) + + // Then it should not highlight NavigationRow without an action + XCTAssertEqual(highlighted, false) } - // MARK: - tableView(_:didSelectRowAt:) - - describe("tableView(_:didSelectRowAt:)") { - - // MARK: Section - - context("Section") { - context("NavigationRow") { - let controller = QuickTableViewController() - _ = controller.view - var selectedIndex = -1 - - controller.tableContents = [ - Section(title: "NavigationRow", rows: [ - NavigationRow(text: "", detailText: .none, action: { _ in selectedIndex = 0 }), - CustomNavigationRow(text: "", detailText: .none, action: { _ in selectedIndex = 1 }), - NavigationRow(text: "", detailText: .none, action: { _ in selectedIndex = 2 }), - CustomNavigationRow(text: "", detailText: .none, action: { _ in selectedIndex = 3 }) - ]) - ] - - for index in 0...3 { - it("should invoke action when \(index) is selected") { - controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) - expect(selectedIndex).toEventually(equal(index)) - } - } - } - - context("TapActionRow") { - let controller = QuickTableViewController() - _ = controller.view - var selectedIndex = -1 - - controller.tableContents = [ - Section(title: "TapActionRow", rows: [ - TapActionRow(text: "", action: { _ in selectedIndex = 0 }), - CustomTapActionRow(text: "", action: { _ in selectedIndex = 1 }), - TapActionRow(text: "", action: { _ in selectedIndex = 2 }), - CustomTapActionRow(text: "", action: { _ in selectedIndex = 3 }) - ]) - ] - - for index in 0...3 { - it("should invoke action when \(index) is selected") { - controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) - expect(selectedIndex).toEventually(equal(index)) - } - } - } - - context("OptionRow") { - let controller = QuickTableViewController() - _ = controller.view - var toggledIndex = -1 - - let section = Section(title: "OptionRow", rows: [ - OptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 0 }), - CustomOptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 1 }), - OptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 2 }), - CustomOptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 3 }) - ]) - controller.tableContents = [section] - - for index in 0...3 { - it("should invoke action when \(index) is selected") { - controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) - expect(toggledIndex).toEventually(equal(index)) - - let option = section.rows[index] as? OptionRowCompatible - expect(option?.isSelected) == true - } - } - } - } - - // MARK: Radio Section - - context("RadioSection") { - context("default") { - let controller = QuickTableViewController() - _ = controller.view - var toggledIndex = -1 - - let radio = RadioSection(title: "alwaysSelectsOneOption = false", options: [ - OptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 0 }), - CustomOptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 1 }), - OptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 2 }), - CustomOptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 3 }) - ]) - controller.tableContents = [radio] - - for index in 0...3 { - it("should invoke action when \(index) is selected") { - controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) - expect(toggledIndex).toEventually(equal(index)) - - let option = radio.rows[index] as? OptionRowCompatible - expect(option?.isSelected) == true - - controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) - expect(option?.isSelected) == false - } - } - } - - context("alwaysSelectsOneOption") { - let controller = QuickTableViewController() - _ = controller.view - var toggledIndex = -1 - - let radio = RadioSection(title: "alwaysSelectsOneOption = true", options: [ - OptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 0 }), - CustomOptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 1 }), - OptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 2 }), - CustomOptionRow(text: "", isSelected: false, action: { _ in toggledIndex = 3 }) - ]) - radio.alwaysSelectsOneOption = true - controller.tableContents = [radio] - - for index in 0...3 { - it("should invoke action when \(index) is selected") { - controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) - expect(toggledIndex).toEventually(equal(index)) - - let option = controller.tableContents[0].rows[index] as? OptionRowCompatible - expect(option?.isSelected) == true - - controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) - expect(option?.isSelected) == true - expect(radio.indexOfSelectedOption) == index - } - } - } - } + for row in 0...3 { + let section = 1 - #if os(iOS) + // When + let highlighted = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: row, section: section)) - // MARK: - tableView(_:accessoryButtonTappedForRowWith:) - describe("tableView(_:accessoryButtonTappedForRowWith:)") { - let controller = QuickTableViewController() - _ = controller.view - var selectedIndex = -1 - - controller.tableContents = [ - Section(title: "NavigationRow", rows: [ - NavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in selectedIndex = 0 }), - CustomNavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in selectedIndex = 1 }), - NavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in selectedIndex = 2 }), - CustomNavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in selectedIndex = 3 }) - ]) - ] - - for index in 0...3 { - it("should invoke action when accessory button at \(index) is selected") { - controller.tableView(controller.tableView, accessoryButtonTappedForRowWith: IndexPath(row: index, section: 0)) - expect(selectedIndex).toEventually(equal(index)) - } - } - } + // Then it should highlight NavigationRow with an action + XCTAssertEqual(highlighted, true) + } + } + func testTableViewShouldHighlightRowAt_switchRow() { + // Given + controller.tableContents = [ + Section(title: "SwitchRow", rows: [ + SwitchRow(text: "", switchValue: true, action: nil), + CustomSwitchRow(text: "", switchValue: true, action: nil), + SwitchRow(text: "", switchValue: true, action: nil), + CustomSwitchRow(text: "", switchValue: true, action: nil) + ]) + ] + + for row in 0...3 { + // When + let highlighted = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: row, section: 0)) + + // Then + #if os(iOS) + XCTAssertEqual(highlighted, false) + #elseif os(tvOS) + XCTAssertEqual(highlighted, true) #endif + } + } + + func testTableViewShouldHighlightRowAt_tapActionRow() { + // Given + controller.tableContents = [ + Section(title: "TapActionRow", rows: [ + TapActionRow(text: "", action: { _ in }), + CustomTapActionRow(text: "", action: { _ in }), + TapActionRow(text: "", action: { _ in }), + CustomTapActionRow(text: "", action: { _ in }) + ]) + ] + + for row in 0...3 { + // When + let highlighted = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: row, section: 0)) + + // Then + XCTAssertEqual(highlighted, true) + } + } + + func testTableViewShouldHighlightRowAt_optionRow() { + // Given + controller.tableContents = [ + Section(title: "OptionRow withou actions", rows: [ + OptionRow(text: "", isSelected: false, action: nil), + CustomOptionRow(text: "", isSelected: false, action: nil), + OptionRow(text: "", isSelected: false, action: nil), + CustomOptionRow(text: "", isSelected: false, action: nil) + ]), + + RadioSection(title: "RadioSection with actions", options: [ + OptionRow(text: "", isSelected: false, action: { _ in }), + CustomOptionRow(text: "", isSelected: false, action: { _ in }), + OptionRow(text: "", isSelected: false, action: { _ in }), + CustomOptionRow(text: "", isSelected: false, action: { _ in }) + ]) + ] + + for row in 0...3 { + let section = 0 + + // When + let highlighted = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: row, section: section)) + + // Then it should highlight OptionRow without an action + XCTAssertEqual(highlighted, true) + } + + for row in 0...3 { + let section = 1 + + // When + let highlighted = controller.tableView(controller.tableView, shouldHighlightRowAt: IndexPath(row: row, section: section)) + + // Then it should highlight OptionRow with an action + XCTAssertEqual(highlighted, true) + } + } + + // MARK: - tableView(_:didSelectRowAt:) + func testTableViewDidSelectRowAt_sectionWithNavigationRow() { + // Given + let expectations = (0...3).map { expectation(description: "it should invoke the action closure at index \($0)") } + + controller.tableContents = [ + Section(title: "NavigationRow", rows: [ + NavigationRow(text: "", detailText: .none, action: { _ in expectations[0].fulfill() }), + CustomNavigationRow(text: "", detailText: .none, action: { _ in expectations[1].fulfill() }), + NavigationRow(text: "", detailText: .none, action: { _ in expectations[2].fulfill() }), + CustomNavigationRow(text: "", detailText: .none, action: { _ in expectations[3].fulfill() }) + ]) + ] + + // When + for row in 0...3 { + controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: row, section: 0)) + } + + // Then it should invoke the action when row is selected + waitForExpectations(timeout: 1, handler: nil) + } + + func testTableViewDidSelectRowAt_sectionWithTapActionRow() { + // Given + let expectations = (0...3).map { expectation(description: "it should invoke the action closure at index \($0)") } + + controller.tableContents = [ + Section(title: "TapActionRow", rows: [ + TapActionRow(text: "", action: { _ in expectations[0].fulfill() }), + CustomTapActionRow(text: "", action: { _ in expectations[1].fulfill() }), + TapActionRow(text: "", action: { _ in expectations[2].fulfill() }), + CustomTapActionRow(text: "", action: { _ in expectations[3].fulfill() }) + ]) + ] + + // When + for row in 0...3 { + controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: row, section: 0)) } + + // Then it should invoke the action when row is selected + waitForExpectations(timeout: 1, handler: nil) + } + + func testTableViewDidSelectRowAt_sectionWithOptionRow() { + // Given + let expectations = (0...3).map { expectation(description: "it should invoke the action closure at index \($0)") } + + controller.tableContents = [ + Section(title: "OptionRow", rows: [ + OptionRow(text: "", isSelected: false, action: { _ in expectations[0].fulfill() }), + CustomOptionRow(text: "", isSelected: false, action: { _ in expectations[1].fulfill() }), + OptionRow(text: "", isSelected: false, action: { _ in expectations[2].fulfill() }), + CustomOptionRow(text: "", isSelected: false, action: { _ in expectations[3].fulfill() }) + ]) + ] + + // When + for row in 0...3 { + controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: row, section: 0)) + } + + // Then it should invoke the action when row is selected + waitForExpectations(timeout: 1, handler: nil) + } + + func testTableViewDidSelectRowAt_radioSectionWithOptionRow() { + // Given + let radio = RadioSection(title: "alwaysSelectsOneOption = false", options: [ + OptionRow(text: "", isSelected: false, action: nil), + CustomOptionRow(text: "", isSelected: false, action: nil), + OptionRow(text: "", isSelected: false, action: nil), + CustomOptionRow(text: "", isSelected: false, action: nil) + ]) + controller.tableContents = [radio] + + for index in 0...3 { + // When + controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) + + // Then the row should be selected + let option = radio.rows[index] as? OptionRowCompatible + XCTAssertEqual(option?.isSelected, true) + + // When + controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) + + // The selection should be toggled when selected again + XCTAssertEqual(option?.isSelected, false) + } + } + + func testTableViewDidSelectRowAt_radioSectionThatAlwaysSelectsOneOption() { + // Given + let radio = RadioSection(title: "alwaysSelectsOneOption = true", options: [ + OptionRow(text: "", isSelected: false, action: nil), + CustomOptionRow(text: "", isSelected: false, action: nil), + OptionRow(text: "", isSelected: false, action: nil), + CustomOptionRow(text: "", isSelected: false, action: nil) + ]) + radio.alwaysSelectsOneOption = true + controller.tableContents = [radio] + + for index in 0...3 { + // When + controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) + + // The row should be selected + let option = radio.rows[index] as? OptionRowCompatible + XCTAssertEqual(option?.isSelected, true) + + // When + controller.tableView(controller.tableView, didSelectRowAt: IndexPath(row: index, section: 0)) + + // The row should not be deselected + XCTAssertEqual(option?.isSelected, true) + XCTAssertEqual(radio.indexOfSelectedOption, index) + } + } + + // MARK: - + + #if os(iOS) + func testTableViewAccessoryButtonTappedForRowWith() { + // Given + let expectations = (0...3).map { expectation(description: "it should invoke the action closure at index \($0)") } + + controller.tableContents = [ + Section(title: "NavigationRow", rows: [ + NavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in expectations[0].fulfill() }), + CustomNavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in expectations[1].fulfill() }), + NavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in expectations[2].fulfill() }), + CustomNavigationRow(text: "", detailText: .none, accessoryButtonAction: { _ in expectations[3].fulfill() }) + ]) + ] + + // When + for index in 0...3 { + controller.tableView(controller.tableView, accessoryButtonTappedForRowWith: IndexPath(row: index, section: 0)) + } + + // Then it should invoke action when accessory button is selected + waitForExpectations(timeout: 1, handler: nil) } + #endif } From 3517f4057779cf0ca44a1c71253693b5007282bc Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 17 Feb 2020 22:49:18 +0000 Subject: [PATCH 5/5] Remove Quick framework --- Gemfile.lock | 41 +++++----- Podfile | 11 --- Podfile.lock | 22 +----- .../project.pbxproj | 75 ------------------- 4 files changed, 23 insertions(+), 126 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a5518773..4b41dcfe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: http://rubygems.org/ specs: - CFPropertyList (3.0.1) + CFPropertyList (3.0.2) activesupport (4.2.11.1) i18n (~> 0.7) minitest (~> 5.1) @@ -44,7 +44,7 @@ GEM fuzzy_match (~> 2.0.4) nap (~> 1.0) cocoapods-deintegrate (1.0.4) - cocoapods-downloader (1.2.2) + cocoapods-downloader (1.3.0) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) @@ -54,36 +54,37 @@ GEM netrc (~> 0.11) cocoapods-try (1.1.0) colored2 (3.1.2) - concurrent-ruby (1.1.5) + concurrent-ruby (1.1.6) cork (0.3.0) colored2 (~> 3.1) - danger (6.1.0) + danger (6.2.2) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) cork (~> 0.1) faraday (~> 0.9) faraday-http-cache (~> 2.0) - git (~> 1.5) + git (~> 1.6) kramdown (~> 2.0) kramdown-parser-gfm (~> 1.0) no_proxy_fix octokit (~> 4.7) terminal-table (~> 1) escape (0.0.4) - faraday (0.17.0) + faraday (0.17.3) multipart-post (>= 1.2, < 3) faraday-http-cache (2.0.0) faraday (~> 0.8) - ffi (1.11.1) + ffi (1.12.2) fourflusher (2.3.1) fuzzy_match (2.0.4) gh_inspector (1.1.3) - git (1.5.0) + git (1.6.0) + rchardet (~> 1.8) httpclient (2.8.3) i18n (0.9.5) concurrent-ruby (~> 1.0) - jazzy (0.11.2) + jazzy (0.13.1) cocoapods (~> 1.5) mustache (~> 1.1) open4 @@ -92,24 +93,26 @@ GEM sassc (~> 2.1) sqlite3 (~> 1.3) xcinvoke (~> 0.3.0) - json (2.2.0) + json (2.3.0) kramdown (2.1.0) kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) liferaft (0.0.6) - minitest (5.12.2) + minitest (5.14.0) molinillo (0.6.6) multipart-post (2.1.1) - mustache (1.1.0) + mustache (1.1.1) nanaimo (0.2.6) nap (1.1.0) netrc (0.11.0) no_proxy_fix (0.1.2) - octokit (4.14.0) + octokit (4.16.0) + faraday (>= 0.9) sawyer (~> 0.8.0, >= 0.5.3) open4 (1.3.4) - public_suffix (4.0.1) - rake (13.0.0) + public_suffix (4.0.3) + rake (13.0.1) + rchardet (1.8.0) redcarpet (3.5.0) rouge (2.0.7) ruby-macho (1.4.0) @@ -118,16 +121,16 @@ GEM sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) - sqlite3 (1.4.1) + sqlite3 (1.4.2) terminal-table (1.8.0) unicode-display_width (~> 1.1, >= 1.1.1) thread_safe (0.3.6) - tzinfo (1.2.5) + tzinfo (1.2.6) thread_safe (~> 0.1) - unicode-display_width (1.6.0) + unicode-display_width (1.6.1) xcinvoke (0.3.0) liferaft (~> 0.0.6) - xcodeproj (1.13.0) + xcodeproj (1.15.0) CFPropertyList (>= 2.3.3, < 4.0) atomos (~> 0.1.3) claide (>= 1.0.2, < 2.0) diff --git a/Podfile b/Podfile index 46c0165b..d09db514 100644 --- a/Podfile +++ b/Podfile @@ -5,22 +5,11 @@ use_frameworks! workspace "QuickTableViewController" project "QuickTableViewController" -def testing_frameworks - pod "Nimble", git: "https://github.com/Quick/Nimble.git", tag: "v8.0.4" - pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v2.2.0" -end - def linter pod "SwiftLint", podspec: "https://raw.githubusercontent.com/CocoaPods/Specs/master/Specs/4/0/1/SwiftLint/0.32.0/SwiftLint.podspec.json" end target "QuickTableViewController-iOSTests" do platform :ios, "8.0" - testing_frameworks linter end - -target "QuickTableViewController-tvOSTests" do - platform :tvos, "9.0" - testing_frameworks -end diff --git a/Podfile.lock b/Podfile.lock index 2f829fac..5ff2ded3 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,36 +1,16 @@ PODS: - - Nimble (8.0.4) - - Quick (2.2.0) - SwiftLint (0.32.0) DEPENDENCIES: - - Nimble (from `https://github.com/Quick/Nimble.git`, tag `v8.0.4`) - - Quick (from `https://github.com/Quick/Quick.git`, tag `v2.2.0`) - SwiftLint (from `https://raw.githubusercontent.com/CocoaPods/Specs/master/Specs/4/0/1/SwiftLint/0.32.0/SwiftLint.podspec.json`) EXTERNAL SOURCES: - Nimble: - :git: https://github.com/Quick/Nimble.git - :tag: v8.0.4 - Quick: - :git: https://github.com/Quick/Quick.git - :tag: v2.2.0 SwiftLint: :podspec: https://raw.githubusercontent.com/CocoaPods/Specs/master/Specs/4/0/1/SwiftLint/0.32.0/SwiftLint.podspec.json -CHECKOUT OPTIONS: - Nimble: - :git: https://github.com/Quick/Nimble.git - :tag: v8.0.4 - Quick: - :git: https://github.com/Quick/Quick.git - :tag: v2.2.0 - SPEC CHECKSUMS: - Nimble: 56d5e29d71c1c13ef008401760edca09974e8903 - Quick: 8bf351656d824b9cc6e292b41494c8f18562a5e9 SwiftLint: 009a898ef2a1c851f45e1b59349bf6ff2ddc990d -PODFILE CHECKSUM: 6ab4719ee6c875770594be660db985ea59d39e68 +PODFILE CHECKSUM: 96aa123a793662bd2268447e11f25f81eafaaaef COCOAPODS: 1.8.4 diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index f0f20296..77172481 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ 136DD300216A367B00F554F0 /* ExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136DD2FF216A367B00F554F0 /* ExampleUITests.swift */; }; 136DD307216A36FA00F554F0 /* QuickTableViewController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B54A24262088816D00EEBA26 /* QuickTableViewController.framework */; }; 136DD308216A36FA00F554F0 /* QuickTableViewController.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B54A24262088816D00EEBA26 /* QuickTableViewController.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 2E72C6FDAAB1ACD925E74017 /* Pods_QuickTableViewController_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A468C1C7F21AF005E793AB39 /* Pods_QuickTableViewController_tvOSTests.framework */; }; 3E45597A21DA81B100FC0C76 /* DetailText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E45597921DA81B100FC0C76 /* DetailText.swift */; }; 3E45597F21DA8B5F00FC0C76 /* DetailTextSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E45597D21DA8B3400FC0C76 /* DetailTextSpec.swift */; }; 3E45598021DA8B6000FC0C76 /* DetailTextSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E45597D21DA8B3400FC0C76 /* DetailTextSpec.swift */; }; @@ -178,14 +177,11 @@ 136DD2FD216A367B00F554F0 /* Example-tvOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Example-tvOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 136DD2FF216A367B00F554F0 /* ExampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleUITests.swift; sourceTree = ""; }; 136DD301216A367B00F554F0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 1F0BC6B8F7C674D42151AF6E /* Pods-QuickTableViewController-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickTableViewController-tvOSTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-QuickTableViewController-tvOSTests/Pods-QuickTableViewController-tvOSTests.debug.xcconfig"; sourceTree = ""; }; 3E45597921DA81B100FC0C76 /* DetailText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailText.swift; sourceTree = ""; }; 3E45597D21DA8B3400FC0C76 /* DetailTextSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailTextSpec.swift; sourceTree = ""; }; 3E45598121DC134800FC0C76 /* Deprecated.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Deprecated.swift; sourceTree = ""; }; - 78AB2AB635DD585665C8299B /* Pods-QuickTableViewController-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickTableViewController-tvOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-QuickTableViewController-tvOSTests/Pods-QuickTableViewController-tvOSTests.release.xcconfig"; sourceTree = ""; }; 8003A1058E05F7C13D280A70 /* Pods-QuickTableViewController-iOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickTableViewController-iOSTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-QuickTableViewController-iOSTests/Pods-QuickTableViewController-iOSTests.debug.xcconfig"; sourceTree = ""; }; 8F762195FA5E16AA5B27D4E8 /* Pods_QuickTableViewController_iOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QuickTableViewController_iOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - A468C1C7F21AF005E793AB39 /* Pods_QuickTableViewController_tvOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_QuickTableViewController_tvOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B50E73841F2E1BC900481910 /* RowStyle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowStyle.swift; sourceTree = ""; }; B51F21A21F417037009BC2C9 /* Example-iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-iOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; B51F21A41F417037009BC2C9 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -301,7 +297,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 2E72C6FDAAB1ACD925E74017 /* Pods_QuickTableViewController_tvOSTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -330,8 +325,6 @@ children = ( 8003A1058E05F7C13D280A70 /* Pods-QuickTableViewController-iOSTests.debug.xcconfig */, 037DFCD4BDF28ECB615D80A8 /* Pods-QuickTableViewController-iOSTests.release.xcconfig */, - 1F0BC6B8F7C674D42151AF6E /* Pods-QuickTableViewController-tvOSTests.debug.xcconfig */, - 78AB2AB635DD585665C8299B /* Pods-QuickTableViewController-tvOSTests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -565,7 +558,6 @@ isa = PBXGroup; children = ( 8F762195FA5E16AA5B27D4E8 /* Pods_QuickTableViewController_iOSTests.framework */, - A468C1C7F21AF005E793AB39 /* Pods_QuickTableViewController_tvOSTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -675,7 +667,6 @@ B5334F1A1B8CC5BD00C64A6D /* Sources */, B5334F1B1B8CC5BD00C64A6D /* Frameworks */, B5334F1C1B8CC5BD00C64A6D /* Resources */, - F7FFC04098F120999A1188C5 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -709,12 +700,10 @@ isa = PBXNativeTarget; buildConfigurationList = B54A243C2088816E00EEBA26 /* Build configuration list for PBXNativeTarget "QuickTableViewController-tvOSTests" */; buildPhases = ( - 9A0C27E207AFCC00990C91F3 /* [CP] Check Pods Manifest.lock */, B51EE1432177EB3C0039C9B2 /* SwiftLint */, B54A242A2088816E00EEBA26 /* Sources */, B54A242B2088816E00EEBA26 /* Frameworks */, B54A242C2088816E00EEBA26 /* Resources */, - 2BFDF0ADB176B8E5F9EA1B30 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -894,26 +883,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 2BFDF0ADB176B8E5F9EA1B30 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-QuickTableViewController-tvOSTests/Pods-QuickTableViewController-tvOSTests-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Nimble-tvOS/Nimble.framework", - "${BUILT_PRODUCTS_DIR}/Quick-tvOS/Quick.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-QuickTableViewController-tvOSTests/Pods-QuickTableViewController-tvOSTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; 836E5B7438A64BC9CFF69C6F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -936,28 +905,6 @@ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 9A0C27E207AFCC00990C91F3 /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-QuickTableViewController-tvOSTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; B51EE1432177EB3C0039C9B2 /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -1018,26 +965,6 @@ shellPath = /bin/sh; shellScript = "ruby scripts/swiftlint.rb\n"; }; - F7FFC04098F120999A1188C5 /* [CP] Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-QuickTableViewController-iOSTests/Pods-QuickTableViewController-iOSTests-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Nimble-iOS/Nimble.framework", - "${BUILT_PRODUCTS_DIR}/Quick-iOS/Quick.framework", - ); - name = "[CP] Embed Pods Frameworks"; - outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Nimble.framework", - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Quick.framework", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-QuickTableViewController-iOSTests/Pods-QuickTableViewController-iOSTests-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1627,7 +1554,6 @@ }; B54A24392088816E00EEBA26 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1F0BC6B8F7C674D42151AF6E /* Pods-QuickTableViewController-tvOSTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; CLANG_ANALYZER_NONNULL = YES; @@ -1653,7 +1579,6 @@ }; B54A243A2088816E00EEBA26 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 78AB2AB635DD585665C8299B /* Pods-QuickTableViewController-tvOSTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = "$(inherited)"; CLANG_ANALYZER_NONNULL = YES;