From 8ba7bf4514de74af7403e83c1acca2d14b4fa733 Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sat, 29 Sep 2018 18:30:38 -0700 Subject: [PATCH 01/35] Update to Swift 4.2 --- Example-iOS/AppDelegate.swift | 2 +- Gemfile.lock | 2 +- .../project.pbxproj | 24 +++++++------------ Source/Model/Section.swift | 2 +- Source/Model/Subtitle.swift | 4 ++-- Source/Protocol/RowStyle.swift | 4 ++-- Source/QuickTableViewController.swift | 4 ++-- Source/Rows/NavigationRow.swift | 4 ++-- Source/Rows/OptionRow.swift | 4 ++-- Source/Rows/SwitchRow.swift | 4 ++-- Source/Rows/TapActionRow.swift | 4 ++-- Source/Views/SwitchCell.swift | 2 +- Source/Views/TapActionCell.swift | 2 +- 13 files changed, 28 insertions(+), 34 deletions(-) diff --git a/Example-iOS/AppDelegate.swift b/Example-iOS/AppDelegate.swift index f3b02381..c780991a 100644 --- a/Example-iOS/AppDelegate.swift +++ b/Example-iOS/AppDelegate.swift @@ -31,7 +31,7 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { if #available(iOS 9.0, *) { // See AppearanceViewController for the setups. diff --git a/Gemfile.lock b/Gemfile.lock index 488d0253..183884fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -105,7 +105,7 @@ GEM ffi (>= 0.5.0, < 2) redcarpet (3.4.0) rouge (2.0.7) - ruby-macho (1.2.0) + ruby-macho (1.3.0) sass (3.5.7) sass-listen (~> 4.0.0) sass-listen (4.0.0) diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index 672fede2..ab6a1097 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -703,18 +703,18 @@ TargetAttributes = { B51F21A11F417037009BC2C9 = { CreatedOnToolsVersion = 8.3.3; - LastSwiftMigration = 0900; + LastSwiftMigration = 1000; ProvisioningStyle = Manual; }; B51F21BF1F41E600009BC2C9 = { CreatedOnToolsVersion = 8.3.3; - LastSwiftMigration = 0900; + LastSwiftMigration = 1000; ProvisioningStyle = Manual; TestTargetID = B51F21A11F417037009BC2C9; }; B5334F121B8CC5BD00C64A6D = { CreatedOnToolsVersion = 6.4; - LastSwiftMigration = 0900; + LastSwiftMigration = 1000; }; B5334F1D1B8CC5BD00C64A6D = { CreatedOnToolsVersion = 6.4; @@ -1160,8 +1160,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -1182,8 +1181,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Release; }; @@ -1206,8 +1204,7 @@ PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TEST_TARGET_NAME = "Example-iOS"; }; name = Debug; @@ -1230,8 +1227,7 @@ PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TEST_TARGET_NAME = "Example-iOS"; }; name = Release; @@ -1375,8 +1371,7 @@ PRODUCT_NAME = QuickTableViewController; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -1397,8 +1392,7 @@ PRODUCT_NAME = QuickTableViewController; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; }; name = Release; }; diff --git a/Source/Model/Section.swift b/Source/Model/Section.swift index 543fc874..4a40f252 100644 --- a/Source/Model/Section.swift +++ b/Source/Model/Section.swift @@ -41,7 +41,7 @@ open class Section { // MARK: - Properties /// The text of the section title. - open let title: String? + public let title: String? /// The array of rows in the section. open var rows: [Row & RowStyle] diff --git a/Source/Model/Subtitle.swift b/Source/Model/Subtitle.swift index 286f51fb..5a3cb5eb 100644 --- a/Source/Model/Subtitle.swift +++ b/Source/Model/Subtitle.swift @@ -39,7 +39,7 @@ public enum Subtitle: Equatable { case leftAligned(String) /// Returns the corresponding table view cell style. - public var style: UITableViewCellStyle { + public var style: UITableViewCell.CellStyle { switch self { case .none: return .default case .belowTitle: return .subtitle @@ -79,7 +79,7 @@ public enum Subtitle: Equatable { } -internal extension UITableViewCellStyle { +internal extension UITableViewCell.CellStyle { var stringValue: String { switch self { diff --git a/Source/Protocol/RowStyle.swift b/Source/Protocol/RowStyle.swift index 427b8cb9..5d8ee262 100644 --- a/Source/Protocol/RowStyle.swift +++ b/Source/Protocol/RowStyle.swift @@ -36,13 +36,13 @@ public protocol RowStyle { var cellReuseIdentifier: String { get } /// The style of the table view cell to display the row. - var cellStyle: UITableViewCellStyle { get } + var cellStyle: UITableViewCell.CellStyle { get } /// The icon of the row. var icon: Icon? { get } /// The type of standard accessory view the cell should use. - var accessoryType: UITableViewCellAccessoryType { get } + var accessoryType: UITableViewCell.AccessoryType { get } /// The flag that indicates whether the table view cell should trigger the action when selected. var isSelectable: Bool { get } diff --git a/Source/QuickTableViewController.swift b/Source/QuickTableViewController.swift index 6f43e473..e413d76e 100644 --- a/Source/QuickTableViewController.swift +++ b/Source/QuickTableViewController.swift @@ -51,7 +51,7 @@ open class QuickTableViewController: UIViewController, UITableViewDataSource, UI - returns: An initialized `QuickTableViewController` object. */ - public convenience init(style: UITableViewStyle) { + public convenience init(style: UITableView.Style) { self.init(nibName: nil, bundle: nil) tableView = UITableView(frame: .zero, style: style) } @@ -68,7 +68,7 @@ open class QuickTableViewController: UIViewController, UITableViewDataSource, UI view.addSubview(tableView) tableView.frame = view.bounds tableView.autoresizingMask = [.flexibleWidth, .flexibleHeight] - tableView.rowHeight = UITableViewAutomaticDimension + tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 44 tableView.dataSource = self tableView.delegate = self diff --git a/Source/Rows/NavigationRow.swift b/Source/Rows/NavigationRow.swift index 5b1195d7..03a73c77 100644 --- a/Source/Rows/NavigationRow.swift +++ b/Source/Rows/NavigationRow.swift @@ -69,7 +69,7 @@ open class NavigationRow: NavigationRowCompatible, Equatable } /// Returns the table view cell style for the specified subtitle. - public var cellStyle: UITableViewCellStyle { + public var cellStyle: UITableViewCell.CellStyle { return subtitle?.style ?? .default } @@ -77,7 +77,7 @@ open class NavigationRow: NavigationRowCompatible, Equatable public let icon: Icon? /// Returns `.disclosureIndicator` when action is not nil, otherwise returns `.none`. - public var accessoryType: UITableViewCellAccessoryType { + public var accessoryType: UITableViewCell.AccessoryType { return (action == nil) ? .none : .disclosureIndicator } diff --git a/Source/Rows/OptionRow.swift b/Source/Rows/OptionRow.swift index dbb0572d..222c4a2e 100644 --- a/Source/Rows/OptionRow.swift +++ b/Source/Rows/OptionRow.swift @@ -81,13 +81,13 @@ open class OptionRow: OptionRowCompatible, Equatable { public let cellReuseIdentifier: String = T.reuseIdentifier /// The cell style is `.default`. - public let cellStyle: UITableViewCellStyle = .default + public let cellStyle: UITableViewCell.CellStyle = .default /// The icon of the row. public let icon: Icon? /// Returns `.checkmark` when the row is selected, otherwise returns `.none`. - public var accessoryType: UITableViewCellAccessoryType { + public var accessoryType: UITableViewCell.AccessoryType { return isSelected ? .checkmark : .none } diff --git a/Source/Rows/SwitchRow.swift b/Source/Rows/SwitchRow.swift index fc8e3bc9..55bfef96 100644 --- a/Source/Rows/SwitchRow.swift +++ b/Source/Rows/SwitchRow.swift @@ -81,7 +81,7 @@ open class SwitchRow: SwitchRowCompatible, Equatable { public let cellReuseIdentifier: String = T.reuseIdentifier /// The cell style is `.default`. - public let cellStyle: UITableViewCellStyle = .default + public let cellStyle: UITableViewCell.CellStyle = .default /// The icon of the row. public let icon: Icon? @@ -89,7 +89,7 @@ open class SwitchRow: SwitchRowCompatible, Equatable { #if os(iOS) /// The default accessory type is `.none`. - public let accessoryType: UITableViewCellAccessoryType = .none + public let accessoryType: UITableViewCell.AccessoryType = .none /// The `SwitchRow` should not be selectable. public let isSelectable: Bool = false diff --git a/Source/Rows/TapActionRow.swift b/Source/Rows/TapActionRow.swift index e8aaaf01..7b8d5e41 100644 --- a/Source/Rows/TapActionRow.swift +++ b/Source/Rows/TapActionRow.swift @@ -63,13 +63,13 @@ open class TapActionRow: TapActionRowCompatible, Equatable { public let cellReuseIdentifier: String = T.reuseIdentifier /// The cell style is `.default`. - public let cellStyle: UITableViewCellStyle = .default + public let cellStyle: UITableViewCell.CellStyle = .default /// The default icon is nil. public let icon: Icon? = nil /// The default accessory type is `.none`. - public let accessoryType: UITableViewCellAccessoryType = .none + public let accessoryType: UITableViewCell.AccessoryType = .none /// The `TapActionRow` is selectable when action is not nil. public var isSelectable: Bool { diff --git a/Source/Views/SwitchCell.swift b/Source/Views/SwitchCell.swift index fa809145..f85bb06a 100644 --- a/Source/Views/SwitchCell.swift +++ b/Source/Views/SwitchCell.swift @@ -63,7 +63,7 @@ open class SwitchCell: UITableViewCell, Configurable { - returns: An initialized `SwitchCell` object. */ - public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setUpAppearance() } diff --git a/Source/Views/TapActionCell.swift b/Source/Views/TapActionCell.swift index 972f4b8b..88f01ee2 100644 --- a/Source/Views/TapActionCell.swift +++ b/Source/Views/TapActionCell.swift @@ -42,7 +42,7 @@ open class TapActionCell: UITableViewCell { - returns: An initialized `TapActionCell` object. */ - public override init(style: UITableViewCellStyle, reuseIdentifier: String?) { + public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: .default, reuseIdentifier: reuseIdentifier) setUpAppearance() } From 92e6a069465758627247fac35e093d4f57a53444 Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sat, 6 Oct 2018 09:08:47 +0800 Subject: [PATCH 02/35] Update Travis osx_image and Podspec swift_version --- .travis.yml | 2 +- QuickTableViewController.podspec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index e1cfedc3..eacc8a4d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode9.3beta +osx_image: xcode10 matrix: include: - env: VERSION=latest diff --git a/QuickTableViewController.podspec b/QuickTableViewController.podspec index e8cc8628..48f13465 100644 --- a/QuickTableViewController.podspec +++ b/QuickTableViewController.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.license = { type: "MIT", file: "LICENSE" } s.author = "bcylin" - s.swift_version = "4.0" + s.swift_version = "4.2" s.ios.deployment_target = "8.0" s.tvos.deployment_target = "9.0" From 06997a19444e77e40f1744123b3358a29a14acc3 Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sat, 6 Oct 2018 09:10:39 +0800 Subject: [PATCH 03/35] Add Swiftlint fix --- Example-iOS/AppDelegate.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Example-iOS/AppDelegate.swift b/Example-iOS/AppDelegate.swift index c780991a..782d60e6 100644 --- a/Example-iOS/AppDelegate.swift +++ b/Example-iOS/AppDelegate.swift @@ -31,7 +31,9 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? + // swiftlint:disable line_length func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { + // swiftlint:enable line_length if #available(iOS 9.0, *) { // See AppearanceViewController for the setups. From 907e2224c879a7ac002043c1f36ac3820275603a Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sat, 6 Oct 2018 09:23:00 +0800 Subject: [PATCH 04/35] Open simulator with -a instead of -b --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index eacc8a4d..e731bc6d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ cache: before_install: - export LANG=en_US.UTF-8 - xcrun instruments -s devices - - open -b com.apple.iphonesimulator + - open -a /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app install: - bundle install --without development --deployment --jobs=3 --retry=3 - bundle exec pod install From e954f5f53b8f1acbae2b5f11110153611caaa233 Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sat, 6 Oct 2018 09:28:32 +0800 Subject: [PATCH 05/35] Update SWIFT_VERSION in build script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e731bc6d..6d1e0e0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ before_script: - if [ -n "$DANGER_GITHUB_API_TOKEN" ]; then bundle exec danger; fi script: - set -o pipefail - - xcodebuild clean build -workspace QuickTableViewController.xcworkspace -scheme QuickTableViewController-iOS -sdk iphonesimulator SWIFT_VERSION=3.0 | bundle exec xcpretty -c + - xcodebuild clean build -workspace QuickTableViewController.xcworkspace -scheme QuickTableViewController-iOS -sdk iphonesimulator SWIFT_VERSION=4.2 | bundle exec xcpretty -c - bundle exec rake "test:ios[QuickTableViewController-iOS]" - bundle exec rake "test:tvos[QuickTableViewController-tvOS]" - bash <(curl -s https://codecov.io/bash) -cF ios -J "QuickTableViewController" From 426e3523ce1c585a94df54539108fbbf588885e5 Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sat, 6 Oct 2018 09:42:28 +0800 Subject: [PATCH 06/35] tvOS update --- Example-iOS/AppDelegate.swift | 2 -- Example-tvOS/AppDelegate.swift | 2 +- QuickTableViewController.xcodeproj/project.pbxproj | 10 ++++++---- Source/Rows/SwitchRow.swift | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Example-iOS/AppDelegate.swift b/Example-iOS/AppDelegate.swift index 782d60e6..c780991a 100644 --- a/Example-iOS/AppDelegate.swift +++ b/Example-iOS/AppDelegate.swift @@ -31,9 +31,7 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - // swiftlint:disable line_length func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { - // swiftlint:enable line_length if #available(iOS 9.0, *) { // See AppearanceViewController for the setups. diff --git a/Example-tvOS/AppDelegate.swift b/Example-tvOS/AppDelegate.swift index 9b0f0ef9..57dbadf6 100644 --- a/Example-tvOS/AppDelegate.swift +++ b/Example-tvOS/AppDelegate.swift @@ -31,7 +31,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = UINavigationController(rootViewController: TableViewController()) window?.makeKeyAndVisible() diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index ab6a1097..0c712b9f 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -722,6 +722,7 @@ }; B54A24252088816D00EEBA26 = { CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 1000; ProvisioningStyle = Automatic; }; B54A242D2088816E00EEBA26 = { @@ -730,6 +731,7 @@ }; B54A24522088D44A00EEBA26 = { CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 1000; ProvisioningStyle = Automatic; }; }; @@ -1462,7 +1464,7 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1492,7 +1494,7 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1570,7 +1572,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1596,7 +1598,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; diff --git a/Source/Rows/SwitchRow.swift b/Source/Rows/SwitchRow.swift index 55bfef96..d6804ce7 100644 --- a/Source/Rows/SwitchRow.swift +++ b/Source/Rows/SwitchRow.swift @@ -97,7 +97,7 @@ open class SwitchRow: SwitchRowCompatible, Equatable { #elseif os(tvOS) /// Returns `.checkmark` when the `switchValue` is on, otherwise returns `.none`. - public var accessoryType: UITableViewCellAccessoryType { + public var accessoryType: UITableViewCell.AccessoryType { return switchValue ? .checkmark : .none } From ad972df7bcb6bb6036de4a02c3a9aa692e0d457d Mon Sep 17 00:00:00 2001 From: Aaron Brager Date: Sat, 6 Oct 2018 09:43:47 +0800 Subject: [PATCH 07/35] Add Swiftlint fix back in --- Example-iOS/AppDelegate.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Example-iOS/AppDelegate.swift b/Example-iOS/AppDelegate.swift index c780991a..782d60e6 100644 --- a/Example-iOS/AppDelegate.swift +++ b/Example-iOS/AppDelegate.swift @@ -31,7 +31,9 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? + // swiftlint:disable line_length func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { + // swiftlint:enable line_length if #available(iOS 9.0, *) { // See AppearanceViewController for the setups. From a492658575b01671f154cf0d985878a9c6511422 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 6 Oct 2018 11:29:44 +0100 Subject: [PATCH 08/35] Disable SwiftLint:line_length rule --- .swiftlint.yml | 2 +- Example-iOS/AppDelegate.swift | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 5cad63dc..13e5771b 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -3,6 +3,7 @@ disabled_rules: - force_cast - function_body_length - identifier_name + - line_length - vertical_whitespace opt_in_rules: - closure_end_indentation @@ -36,4 +37,3 @@ included: excluded: - Carthage - Pods -line_length: 192 diff --git a/Example-iOS/AppDelegate.swift b/Example-iOS/AppDelegate.swift index 782d60e6..c780991a 100644 --- a/Example-iOS/AppDelegate.swift +++ b/Example-iOS/AppDelegate.swift @@ -31,9 +31,7 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - // swiftlint:disable line_length func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool { - // swiftlint:enable line_length if #available(iOS 9.0, *) { // See AppearanceViewController for the setups. From 9f3a52d4cb58024133c2ddbf319a1dc198836e06 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 6 Oct 2018 11:40:34 +0100 Subject: [PATCH 09/35] Remove the duplicate test command from .travis.yml --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6d1e0e0e..b505eb26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,5 @@ language: objective-c osx_image: xcode10 -matrix: - include: - - env: VERSION=latest cache: - bundler - cocoapods @@ -17,7 +14,6 @@ before_script: - if [ -n "$DANGER_GITHUB_API_TOKEN" ]; then bundle exec danger; fi script: - set -o pipefail - - xcodebuild clean build -workspace QuickTableViewController.xcworkspace -scheme QuickTableViewController-iOS -sdk iphonesimulator SWIFT_VERSION=4.2 | bundle exec xcpretty -c - bundle exec rake "test:ios[QuickTableViewController-iOS]" - bundle exec rake "test:tvos[QuickTableViewController-tvOS]" - bash <(curl -s https://codecov.io/bash) -cF ios -J "QuickTableViewController" From 8eb0d08b122038aa030a9a61f5a487984f7b5809 Mon Sep 17 00:00:00 2001 From: mttcrsp Date: Sun, 7 Oct 2018 14:46:37 +0200 Subject: [PATCH 10/35] Bump Swift version to 4.2 for all targets --- .../project.pbxproj | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index 0c712b9f..3f7a6848 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -1162,7 +1162,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -1183,7 +1182,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.2; }; name = Release; }; @@ -1206,7 +1204,6 @@ PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.2; TEST_TARGET_NAME = "Example-iOS"; }; name = Debug; @@ -1229,7 +1226,6 @@ PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.2; TEST_TARGET_NAME = "Example-iOS"; }; name = Release; @@ -1292,7 +1288,7 @@ SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1348,7 +1344,7 @@ MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; + SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1373,7 +1369,6 @@ PRODUCT_NAME = QuickTableViewController; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.2; }; name = Debug; }; @@ -1394,7 +1389,6 @@ PRODUCT_NAME = QuickTableViewController; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.2; }; name = Release; }; @@ -1416,7 +1410,6 @@ PRODUCT_BUNDLE_IDENTIFIER = io.github.bcylin.QuickTableViewControllerTests; PRODUCT_NAME = QuickTableViewControllerTests; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -1435,7 +1428,6 @@ PRODUCT_NAME = QuickTableViewControllerTests; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_SWIFT3_OBJC_INFERENCE = Default; - SWIFT_VERSION = 4.0; }; name = Release; }; @@ -1464,7 +1456,6 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1494,7 +1485,6 @@ SDKROOT = appletvos; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1520,7 +1510,6 @@ PRODUCT_NAME = QuickTableViewControllerTests; SDKROOT = appletvos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 11.3; }; @@ -1545,7 +1534,6 @@ PRODUCT_NAME = QuickTableViewControllerTests; SDKROOT = appletvos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 11.3; }; @@ -1572,7 +1560,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; @@ -1598,7 +1585,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SDKROOT = appletvos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 4.2; TARGETED_DEVICE_FAMILY = 3; TVOS_DEPLOYMENT_TARGET = 9.0; }; From 0e3bd8865559c06ffd802550ac3d0594602caee8 Mon Sep 17 00:00:00 2001 From: mttcrsp Date: Sun, 7 Oct 2018 14:46:53 +0200 Subject: [PATCH 11/35] Migrate the iOS tests target to Swift 4.2 --- Tests/Row/OptionRowSpec.swift | 8 ++++---- Tests/ViewController/QuickTableViewControllerSpec.swift | 4 ++-- Tests/ViewController/QuickTableViewDataSourceSpec.swift | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Tests/Row/OptionRowSpec.swift b/Tests/Row/OptionRowSpec.swift index 1bc917f2..b3664e55 100644 --- a/Tests/Row/OptionRowSpec.swift +++ b/Tests/Row/OptionRowSpec.swift @@ -48,9 +48,9 @@ internal final class OptionRowSpec: QuickSpec { // RowStyle expect(row.cellReuseIdentifier) == "UITableViewCell" - expect(row.cellStyle) == UITableViewCellStyle.default + expect(row.cellStyle) == UITableViewCell.CellStyle.default expect(row.icon) == icon - expect(row.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(row.accessoryType) == UITableViewCell.AccessoryType.checkmark expect(row.isSelectable) == true expect(row.customize).to(beNil()) } @@ -106,7 +106,7 @@ internal final class OptionRowSpec: QuickSpec { it("should invoke the action closure") { row.isSelected = true - expect(row.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(row.accessoryType) == UITableViewCell.AccessoryType.checkmark expect(invoked).toEventually(beTrue()) } } @@ -117,7 +117,7 @@ internal final class OptionRowSpec: QuickSpec { it("should not invoke the action closure") { row.isSelected = false - expect(row.accessoryType) == UITableViewCellAccessoryType.none + expect(row.accessoryType) == UITableViewCell.AccessoryType.none expect(invoked).toEventually(beFalse()) } } diff --git a/Tests/ViewController/QuickTableViewControllerSpec.swift b/Tests/ViewController/QuickTableViewControllerSpec.swift index 1c1bde67..bd37f761 100644 --- a/Tests/ViewController/QuickTableViewControllerSpec.swift +++ b/Tests/ViewController/QuickTableViewControllerSpec.swift @@ -36,8 +36,8 @@ internal final class QuickTableViewControllerSpec: QuickSpec { describe("init(style:)") { it("should set up table view with style") { - expect(QuickTableViewController().tableView.style) == UITableViewStyle.grouped - expect(QuickTableViewController(style: .plain).tableView.style) == UITableViewStyle.plain + expect(QuickTableViewController().tableView.style) == UITableView.Style.grouped + expect(QuickTableViewController(style: .plain).tableView.style) == UITableView.Style.plain } } diff --git a/Tests/ViewController/QuickTableViewDataSourceSpec.swift b/Tests/ViewController/QuickTableViewDataSourceSpec.swift index 0d46c188..9fc80fb5 100644 --- a/Tests/ViewController/QuickTableViewDataSourceSpec.swift +++ b/Tests/ViewController/QuickTableViewDataSourceSpec.swift @@ -220,7 +220,7 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { 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) == UITableViewCellAccessoryType.disclosureIndicator + expect(cell.accessoryType) == UITableViewCell.AccessoryType.disclosureIndicator } } } @@ -316,7 +316,7 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { } it("should match the selection at \(index)") { - expect(cell.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark } } } From 92c05241bf8a1bb6b9ec145f1558025852642c26 Mon Sep 17 00:00:00 2001 From: mttcrsp Date: Sun, 7 Oct 2018 14:47:02 +0200 Subject: [PATCH 12/35] Migrate the tvOS tests target to Swift 4.2 --- Tests/View/ConfigurableSpec.swift | 16 ++++++++-------- .../QuickTableViewDataSourceSpec.swift | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Tests/View/ConfigurableSpec.swift b/Tests/View/ConfigurableSpec.swift index 3251838d..b33cbccb 100644 --- a/Tests/View/ConfigurableSpec.swift +++ b/Tests/View/ConfigurableSpec.swift @@ -42,7 +42,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == true #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark #endif } @@ -55,7 +55,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == false #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.none + expect(cell.accessoryType) == UITableViewCell.AccessoryType.none #endif } } @@ -70,7 +70,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == true #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark #endif } @@ -83,7 +83,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == false #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.none + expect(cell.accessoryType) == UITableViewCell.AccessoryType.none #endif } } @@ -98,7 +98,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == true #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark #endif } @@ -111,7 +111,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == false #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.none + expect(cell.accessoryType) == UITableViewCell.AccessoryType.none #endif } } @@ -126,7 +126,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == true #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark #endif } @@ -139,7 +139,7 @@ internal final class ConfigurableSpec: QuickSpec { expect(cell.switchControl.isOn) == false #elseif os(tvOS) expect(cell.accessoryView).to(beNil()) - expect(cell.accessoryType) == UITableViewCellAccessoryType.none + expect(cell.accessoryType) == UITableViewCell.AccessoryType.none #endif } } diff --git a/Tests/ViewController/QuickTableViewDataSourceSpec.swift b/Tests/ViewController/QuickTableViewDataSourceSpec.swift index 9fc80fb5..b2cce0ac 100644 --- a/Tests/ViewController/QuickTableViewDataSourceSpec.swift +++ b/Tests/ViewController/QuickTableViewDataSourceSpec.swift @@ -256,7 +256,7 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { #if os(iOS) expect((cell as? SwitchCell)?.switchControl.isOn) == true #elseif os(tvOS) - expect(cell.accessoryType) == UITableViewCellAccessoryType.checkmark + expect(cell.accessoryType) == UITableViewCell.AccessoryType.checkmark #endif } } From f1d888b63f0ee6ed3f6d8f37b2a7b751c863ea8f Mon Sep 17 00:00:00 2001 From: mttcrsp Date: Sun, 7 Oct 2018 14:47:09 +0200 Subject: [PATCH 13/35] Update workspace to Xcode 10 recommended settings --- .../xcshareddata/xcschemes/Example-iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/Example-tvOS.xcscheme | 2 +- .../xcschemes/QuickTableViewController-iOS.xcscheme | 2 +- .../xcschemes/QuickTableViewController-tvOS.xcscheme | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme b/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme index 6d7797e0..fae8fcd3 100644 --- a/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme +++ b/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme @@ -1,6 +1,6 @@ Date: Mon, 8 Oct 2018 21:08:34 +0200 Subject: [PATCH 14/35] Inhibit Quick warnings for test targets At this time the Quick testing framework hasn't yet been updated to Swift 4.2. This causing some compilation warnings to be generated by the compiler. While discussing #26, it was decided to solve this issue by inhibiting warnings generated by the Quick pod for tests target. --- Podfile | 4 ++-- Podfile.lock | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Podfile b/Podfile index d6075681..3ee73041 100644 --- a/Podfile +++ b/Podfile @@ -6,13 +6,13 @@ project "QuickTableViewController" target "QuickTableViewController-iOSTests" do platform :ios, "8.0" pod "Nimble", git: "https://github.com/Quick/Nimble.git", tag: "v7.1.3" - pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1" + pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1", :inhibit_warnings => true end target "QuickTableViewController-tvOSTests" do platform :tvos, "9.0" pod "Nimble", git: "https://github.com/Quick/Nimble.git", tag: "v7.1.3" - pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1" + pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1", :inhibit_warnings => true end target "Example-iOS" do diff --git a/Podfile.lock b/Podfile.lock index 4cda9f7a..ee5ffcba 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -31,6 +31,6 @@ SPEC CHECKSUMS: Quick: d17304d58d0d169dd0bd1c6e5c28e3318de32a1a SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073 -PODFILE CHECKSUM: 6dedfd3b564540ea44d6f3f3bf311afc936ee83a +PODFILE CHECKSUM: 209aaba56acbe1a7575f449d1faebf22752c3f27 COCOAPODS: 1.5.3 From d4d8fcee26dfd977d9233e306e3549efa9a6562b Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 10 Oct 2018 21:56:40 +0100 Subject: [PATCH 15/35] Update .hound.yml [ci skip] https://intercom.help/hound/configuration/swiftlint --- .hound.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.hound.yml b/.hound.yml index 65fa0c85..3f75e0bf 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1,3 +1,3 @@ -swift: +swiftlint: enabled: true config_file: .swiftlint.yml From 88eb745bd3b5f62b763b58d7b6f74ee77bf6b8eb Mon Sep 17 00:00:00 2001 From: Francesco Deliro Date: Sun, 7 Oct 2018 14:42:12 +0200 Subject: [PATCH 16/35] Added tvOSUITestsTarget --- Example-tvOSUITests/Example_tvOSUITests.swift | 34 +++++ Example-tvOSUITests/Info.plist | 22 +++ .../project.pbxproj | 139 +++++++++++++++++- .../xcschemes/Example-tvOS.xcscheme | 10 ++ 4 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 Example-tvOSUITests/Example_tvOSUITests.swift create mode 100644 Example-tvOSUITests/Info.plist diff --git a/Example-tvOSUITests/Example_tvOSUITests.swift b/Example-tvOSUITests/Example_tvOSUITests.swift new file mode 100644 index 00000000..51f7637e --- /dev/null +++ b/Example-tvOSUITests/Example_tvOSUITests.swift @@ -0,0 +1,34 @@ +// +// Example_tvOSUITests.swift +// Example-tvOSUITests +// +// Created by Francesco on 07/10/2018. +// Copyright © 2018 bcylin. All rights reserved. +// + +import XCTest + +class Example_tvOSUITests: XCTestCase { + + override func setUp() { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + XCUIApplication().launch() + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + +} diff --git a/Example-tvOSUITests/Info.plist b/Example-tvOSUITests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/Example-tvOSUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index 3f7a6848..a367dabf 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -8,6 +8,7 @@ /* Begin PBXBuildFile section */ 0313D389A7BCE29502848262 /* Pods_Example_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA2A67F5AE20173B6E17FFBE /* Pods_Example_tvOS.framework */; }; + 136DD300216A367B00F554F0 /* Example_tvOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136DD2FF216A367B00F554F0 /* Example_tvOSUITests.swift */; }; 1DF796C7F4630ACDCE1DE189 /* Pods_QuickTableViewController_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51571B6D4B25D0BCCCFFBCF5 /* Pods_QuickTableViewController_iOSTests.framework */; }; A3895BA2FCD4633B9297CB06 /* Pods_QuickTableViewController_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73EFDFBFA59BFFF7C494F9AE /* Pods_QuickTableViewController_tvOSTests.framework */; }; A7A26A71AB271F9D402D1A12 /* Pods_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF3454E57819285B32968564 /* Pods_Example_iOS.framework */; }; @@ -98,6 +99,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 136DD302216A367B00F554F0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B5334F0A1B8CC5BD00C64A6D /* Project object */; + proxyType = 1; + remoteGlobalIDString = B54A24522088D44A00EEBA26; + remoteInfo = "Example-tvOS"; + }; B51A0E912069360500F42693 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B5334F0A1B8CC5BD00C64A6D /* Project object */; @@ -150,6 +158,9 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 136DD2FD216A367B00F554F0 /* Example-tvOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Example-tvOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 136DD2FF216A367B00F554F0 /* Example_tvOSUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example_tvOSUITests.swift; sourceTree = ""; }; + 136DD301216A367B00F554F0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 466DB8C8ACDE64B9E0EF8D74 /* Pods-QuickTableViewController-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickTableViewController-iOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-QuickTableViewController-iOSTests/Pods-QuickTableViewController-iOSTests.release.xcconfig"; sourceTree = ""; }; 4AAC8E26F072FAB5027928F8 /* Pods-Example-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS.debug.xcconfig"; sourceTree = ""; }; 4D38F5DD6F45D1136A106B9F /* 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 = ""; }; @@ -229,6 +240,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 136DD2FA216A367B00F554F0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; B51F219F1F417037009BC2C9 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -287,6 +305,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 136DD2FE216A367B00F554F0 /* Example-tvOSUITests */ = { + isa = PBXGroup; + children = ( + 136DD2FF216A367B00F554F0 /* Example_tvOSUITests.swift */, + 136DD301216A367B00F554F0 /* Info.plist */, + ); + path = "Example-tvOSUITests"; + sourceTree = ""; + }; 942C1FAD68407A74DB056C2B /* Pods */ = { isa = PBXGroup; children = ( @@ -415,6 +442,7 @@ B51F21A31F417037009BC2C9 /* Example-iOS */, B51F21C11F41E600009BC2C9 /* Example-iOSUITests */, B54A24542088D44A00EEBA26 /* Example-tvOS */, + 136DD2FE216A367B00F554F0 /* Example-tvOSUITests */, B5DB7D241C4A4BEC007B84D2 /* Frameworks */, 942C1FAD68407A74DB056C2B /* Pods */, B5334F141B8CC5BD00C64A6D /* Products */, @@ -440,6 +468,7 @@ B54A24262088816D00EEBA26 /* QuickTableViewController.framework */, B54A242E2088816E00EEBA26 /* QuickTableViewControllerTests.xctest */, B5334F1E1B8CC5BD00C64A6D /* QuickTableViewControllerTests.xctest */, + 136DD2FD216A367B00F554F0 /* Example-tvOSUITests.xctest */, ); name = Products; sourceTree = ""; @@ -555,6 +584,24 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 136DD2FC216A367B00F554F0 /* Example-tvOSUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 136DD306216A367B00F554F0 /* Build configuration list for PBXNativeTarget "Example-tvOSUITests" */; + buildPhases = ( + 136DD2F9216A367B00F554F0 /* Sources */, + 136DD2FA216A367B00F554F0 /* Frameworks */, + 136DD2FB216A367B00F554F0 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 136DD303216A367B00F554F0 /* PBXTargetDependency */, + ); + name = "Example-tvOSUITests"; + productName = "Example-tvOSUITests"; + productReference = 136DD2FD216A367B00F554F0 /* Example-tvOSUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; B51F21A11F417037009BC2C9 /* Example-iOS */ = { isa = PBXNativeTarget; buildConfigurationList = B51F21B31F417037009BC2C9 /* Build configuration list for PBXNativeTarget "Example-iOS" */; @@ -697,10 +744,16 @@ B5334F0A1B8CC5BD00C64A6D /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0930; + LastSwiftUpdateCheck = 1000; LastUpgradeCheck = 0930; ORGANIZATIONNAME = bcylin; TargetAttributes = { + 136DD2FC216A367B00F554F0 = { + CreatedOnToolsVersion = 10.0; + DevelopmentTeam = NQU669U9J9; + ProvisioningStyle = Automatic; + TestTargetID = B54A24522088D44A00EEBA26; + }; B51F21A11F417037009BC2C9 = { CreatedOnToolsVersion = 8.3.3; LastSwiftMigration = 1000; @@ -756,11 +809,19 @@ B51F21A11F417037009BC2C9 /* Example-iOS */, B51F21BF1F41E600009BC2C9 /* Example-iOSUITests */, B54A24522088D44A00EEBA26 /* Example-tvOS */, + 136DD2FC216A367B00F554F0 /* Example-tvOSUITests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 136DD2FB216A367B00F554F0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; B51F21A01F417037009BC2C9 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -985,6 +1046,14 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 136DD2F9216A367B00F554F0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 136DD300216A367B00F554F0 /* Example_tvOSUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; B51F219E1F417037009BC2C9 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1105,6 +1174,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 136DD303216A367B00F554F0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = B54A24522088D44A00EEBA26 /* Example-tvOS */; + targetProxy = 136DD302216A367B00F554F0 /* PBXContainerItemProxy */; + }; B51A0E922069360500F42693 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = B51F21A11F417037009BC2C9 /* Example-iOS */; @@ -1144,6 +1218,60 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 136DD304216A367B00F554F0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = NQU669U9J9; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "Example-tvOSUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "io.github.bcylin.QuickTableViewController.Example-tvOSUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "Example-tvOS"; + TVOS_DEPLOYMENT_TARGET = 12.0; + }; + name = Debug; + }; + 136DD305216A367B00F554F0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = NQU669U9J9; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "Example-tvOSUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "io.github.bcylin.QuickTableViewController.Example-tvOSUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = 3; + TEST_TARGET_NAME = "Example-tvOS"; + TVOS_DEPLOYMENT_TARGET = 12.0; + }; + name = Release; + }; B51F21B11F417037009BC2C9 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = A57FEA19A020A7DE44AE8BCE /* Pods-Example-iOS.debug.xcconfig */; @@ -1593,6 +1721,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 136DD306216A367B00F554F0 /* Build configuration list for PBXNativeTarget "Example-tvOSUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 136DD304216A367B00F554F0 /* Debug */, + 136DD305216A367B00F554F0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; B51F21B31F417037009BC2C9 /* Build configuration list for PBXNativeTarget "Example-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme b/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme index f3334099..0757fbad 100644 --- a/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme +++ b/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-tvOS.xcscheme @@ -28,6 +28,16 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + Date: Sun, 7 Oct 2018 14:45:52 +0200 Subject: [PATCH 17/35] Implemented testInteractions function --- Example-tvOSUITests/Example_tvOSUITests.swift | 114 +++++++++++++++--- .../project.pbxproj | 17 +++ 2 files changed, 115 insertions(+), 16 deletions(-) diff --git a/Example-tvOSUITests/Example_tvOSUITests.swift b/Example-tvOSUITests/Example_tvOSUITests.swift index 51f7637e..f94713dd 100644 --- a/Example-tvOSUITests/Example_tvOSUITests.swift +++ b/Example-tvOSUITests/Example_tvOSUITests.swift @@ -2,33 +2,115 @@ // Example_tvOSUITests.swift // Example-tvOSUITests // -// Created by Francesco on 07/10/2018. +// Created by Francesco Deliro on 07/10/2018. // Copyright © 2018 bcylin. All rights reserved. // +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// import XCTest class Example_tvOSUITests: XCTestCase { - override func setUp() { - // Put setup code here. This method is called before the invocation of each test method in the class. + private lazy var app: XCUIApplication = XCUIApplication() + + override func setUp() { + super.setUp() + continueAfterFailure = false + app.launch() + } + + func testInteractions() { + + let tables = XCUIApplication().tables + let existance = NSPredicate(format: "exists == true") + let hasFocus = NSPredicate(format: "hasFocus == true") + + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Setting 1").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) + + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Setting 2").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) + + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Tap action").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) + + expectation(for: hasFocus, evaluatedWith: app.alerts["Tap action"].otherElements["OK"], handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) + + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Tap action").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"CellStyle.default").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) + + expectation(for: existance, evaluatedWith: app.otherElements.containing(.staticText, identifier:"CellStyle.default").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.menu) + + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"CellStyle.default").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".subtitle").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) + + expectation(for: existance, evaluatedWith: app.otherElements.containing(.staticText, identifier:"CellStyle.subtitle").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.menu) + + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".subtitle").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) - // In UI tests it is usually best to stop immediately when a failure occurs. - continueAfterFailure = false + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".value1").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) - // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. - XCUIApplication().launch() + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".value2").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) - // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. - } + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Option 1").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) - override func tearDown() { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Option 2").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) - func testExample() { - // Use recording to get started writing UI tests. - // Use XCTAssert and related functions to verify your tests produce the correct results. - } + XCUIRemote.shared.press(.down) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Option 3").element, handler: nil) + waitForExpectations(timeout: 5, handler: nil) + XCUIRemote.shared.press(.select) + } } diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index a367dabf..e950feba 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -9,6 +9,8 @@ /* Begin PBXBuildFile section */ 0313D389A7BCE29502848262 /* Pods_Example_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA2A67F5AE20173B6E17FFBE /* Pods_Example_tvOS.framework */; }; 136DD300216A367B00F554F0 /* Example_tvOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136DD2FF216A367B00F554F0 /* Example_tvOSUITests.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, ); }; }; 1DF796C7F4630ACDCE1DE189 /* Pods_QuickTableViewController_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51571B6D4B25D0BCCCFFBCF5 /* Pods_QuickTableViewController_iOSTests.framework */; }; A3895BA2FCD4633B9297CB06 /* Pods_QuickTableViewController_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73EFDFBFA59BFFF7C494F9AE /* Pods_QuickTableViewController_tvOSTests.framework */; }; A7A26A71AB271F9D402D1A12 /* Pods_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF3454E57819285B32968564 /* Pods_Example_iOS.framework */; }; @@ -144,6 +146,17 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 136DD309216A36FA00F554F0 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 136DD308216A36FA00F554F0 /* QuickTableViewController.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; B51F21CE1F41F32D009BC2C9 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -298,6 +311,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 136DD307216A36FA00F554F0 /* QuickTableViewController.framework in Frameworks */, 0313D389A7BCE29502848262 /* Pods_Example_tvOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -727,6 +741,7 @@ B54A244F2088D44A00EEBA26 /* Sources */, B54A24502088D44A00EEBA26 /* Frameworks */, B54A24512088D44A00EEBA26 /* Resources */, + 136DD309216A36FA00F554F0 /* Embed Frameworks */, ); buildRules = ( ); @@ -1671,6 +1686,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 4AAC8E26F072FAB5027928F8 /* Pods-Example-tvOS.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ANALYZER_NONNULL = YES; @@ -1697,6 +1713,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = C846A13C763FF2B7B3A6029A /* Pods-Example-tvOS.release.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; CLANG_ANALYZER_NONNULL = YES; From 11cb83f6575da13ce4baf6d6ed7ab102fc356e8c Mon Sep 17 00:00:00 2001 From: Francesco Deliro Date: Sun, 7 Oct 2018 14:50:17 +0200 Subject: [PATCH 18/35] Set Example_tvOSUITests class as internal final --- Example-tvOSUITests/Example_tvOSUITests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Example-tvOSUITests/Example_tvOSUITests.swift b/Example-tvOSUITests/Example_tvOSUITests.swift index f94713dd..9f631894 100644 --- a/Example-tvOSUITests/Example_tvOSUITests.swift +++ b/Example-tvOSUITests/Example_tvOSUITests.swift @@ -26,7 +26,7 @@ import XCTest -class Example_tvOSUITests: XCTestCase { +internal final class Example_tvOSUITests: XCTestCase { private lazy var app: XCUIApplication = XCUIApplication() From b248e0b10c2f4ccbc7d861f894ffd7bc18434796 Mon Sep 17 00:00:00 2001 From: Francesco Deliro Date: Tue, 9 Oct 2018 21:20:35 +0200 Subject: [PATCH 19/35] Add-tvOSUITests: code review required changes --- .travis.yml | 2 +- ...tvOSUITests.swift => ExampleUITests.swift} | 2 +- .../project.pbxproj | 21 ++++++++++--------- 3 files changed, 13 insertions(+), 12 deletions(-) rename Example-tvOSUITests/{Example_tvOSUITests.swift => ExampleUITests.swift} (98%) diff --git a/.travis.yml b/.travis.yml index b505eb26..4b2e59cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,7 @@ script: - bundle exec rake "test:tvos[QuickTableViewController-tvOS]" - bash <(curl -s https://codecov.io/bash) -cF ios -J "QuickTableViewController" - bundle exec rake "test:ios[Example-iOS]" - - bundle exec rake "build:tvos[Example-tvOS]" + - bundle exec rake "test:tvos[Example-tvOS]" - make -B carthage - make -B docs after_success: diff --git a/Example-tvOSUITests/Example_tvOSUITests.swift b/Example-tvOSUITests/ExampleUITests.swift similarity index 98% rename from Example-tvOSUITests/Example_tvOSUITests.swift rename to Example-tvOSUITests/ExampleUITests.swift index 9f631894..cce13147 100644 --- a/Example-tvOSUITests/Example_tvOSUITests.swift +++ b/Example-tvOSUITests/ExampleUITests.swift @@ -26,7 +26,7 @@ import XCTest -internal final class Example_tvOSUITests: XCTestCase { +internal final class ExampleUITests: XCTestCase { private lazy var app: XCUIApplication = XCUIApplication() diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index e950feba..e265717e 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -8,7 +8,7 @@ /* Begin PBXBuildFile section */ 0313D389A7BCE29502848262 /* Pods_Example_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CA2A67F5AE20173B6E17FFBE /* Pods_Example_tvOS.framework */; }; - 136DD300216A367B00F554F0 /* Example_tvOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 136DD2FF216A367B00F554F0 /* Example_tvOSUITests.swift */; }; + 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, ); }; }; 1DF796C7F4630ACDCE1DE189 /* Pods_QuickTableViewController_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51571B6D4B25D0BCCCFFBCF5 /* Pods_QuickTableViewController_iOSTests.framework */; }; @@ -172,7 +172,7 @@ /* Begin PBXFileReference section */ 136DD2FD216A367B00F554F0 /* Example-tvOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Example-tvOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 136DD2FF216A367B00F554F0 /* Example_tvOSUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Example_tvOSUITests.swift; sourceTree = ""; }; + 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 = ""; }; 466DB8C8ACDE64B9E0EF8D74 /* Pods-QuickTableViewController-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickTableViewController-iOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-QuickTableViewController-iOSTests/Pods-QuickTableViewController-iOSTests.release.xcconfig"; sourceTree = ""; }; 4AAC8E26F072FAB5027928F8 /* Pods-Example-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS.debug.xcconfig"; sourceTree = ""; }; @@ -322,7 +322,7 @@ 136DD2FE216A367B00F554F0 /* Example-tvOSUITests */ = { isa = PBXGroup; children = ( - 136DD2FF216A367B00F554F0 /* Example_tvOSUITests.swift */, + 136DD2FF216A367B00F554F0 /* ExampleUITests.swift */, 136DD301216A367B00F554F0 /* Info.plist */, ); path = "Example-tvOSUITests"; @@ -765,8 +765,7 @@ TargetAttributes = { 136DD2FC216A367B00F554F0 = { CreatedOnToolsVersion = 10.0; - DevelopmentTeam = NQU669U9J9; - ProvisioningStyle = Automatic; + ProvisioningStyle = Manual; TestTargetID = B54A24522088D44A00EEBA26; }; B51F21A11F417037009BC2C9 = { @@ -1065,7 +1064,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 136DD300216A367B00F554F0 /* Example_tvOSUITests.swift in Sources */, + 136DD300216A367B00F554F0 /* ExampleUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1242,9 +1241,9 @@ CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_TEAM = NQU669U9J9; + DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = "Example-tvOSUITests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1252,6 +1251,7 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.github.bcylin.QuickTableViewController.Example-tvOSUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = appletvos; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_VERSION = 4.2; @@ -1270,14 +1270,15 @@ CLANG_ENABLE_OBJC_WEAK = YES; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = NQU669U9J9; + CODE_SIGN_STYLE = Manual; + DEVELOPMENT_TEAM = ""; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = "Example-tvOSUITests/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = "io.github.bcylin.QuickTableViewController.Example-tvOSUITests"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; SDKROOT = appletvos; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SWIFT_VERSION = 4.2; From 8786e6e730d8eef6c93814cd47a51d31490ac595 Mon Sep 17 00:00:00 2001 From: Francesco Deliro Date: Fri, 12 Oct 2018 12:48:24 +0200 Subject: [PATCH 20/35] Add-tvOSUITests: fixed swift lint warnings --- Example-tvOSUITests/ExampleUITests.swift | 31 ++++++++++++------------ 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/Example-tvOSUITests/ExampleUITests.swift b/Example-tvOSUITests/ExampleUITests.swift index cce13147..d2bd4ab1 100644 --- a/Example-tvOSUITests/ExampleUITests.swift +++ b/Example-tvOSUITests/ExampleUITests.swift @@ -36,23 +36,24 @@ internal final class ExampleUITests: XCTestCase { app.launch() } +// swiftlint:disable function_body_length line_length func testInteractions() { let tables = XCUIApplication().tables let existance = NSPredicate(format: "exists == true") let hasFocus = NSPredicate(format: "hasFocus == true") - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Setting 1").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "Setting 1").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Setting 2").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "Setting 2").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Tap action").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "Tap action").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) @@ -60,55 +61,55 @@ internal final class ExampleUITests: XCTestCase { waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Tap action").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "Tap action").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"CellStyle.default").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "CellStyle.default").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) - expectation(for: existance, evaluatedWith: app.otherElements.containing(.staticText, identifier:"CellStyle.default").element, handler: nil) + expectation(for: existance, evaluatedWith: app.otherElements.containing(.staticText, identifier: "CellStyle.default").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.menu) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"CellStyle.default").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "CellStyle.default").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".subtitle").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: ".subtitle").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) - expectation(for: existance, evaluatedWith: app.otherElements.containing(.staticText, identifier:"CellStyle.subtitle").element, handler: nil) + expectation(for: existance, evaluatedWith: app.otherElements.containing(.staticText, identifier: "CellStyle.subtitle").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.menu) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".subtitle").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: ".subtitle").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".value1").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: ".value1").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:".value2").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: ".value2").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Option 1").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "Option 1").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Option 2").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "Option 2").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) XCUIRemote.shared.press(.down) - expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier:"Option 3").element, handler: nil) + expectation(for: hasFocus, evaluatedWith: tables.cells.containing(.staticText, identifier: "Option 3").element, handler: nil) waitForExpectations(timeout: 5, handler: nil) XCUIRemote.shared.press(.select) } From 69dd55e0197b2e459e9c333d616184bc14961a70 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 17 Oct 2018 23:13:54 +0100 Subject: [PATCH 21/35] Run SwiftLint in the example and testing targets --- .swiftlint.yml | 5 ++-- Example-tvOS/AppDelegate.swift | 2 +- Example-tvOS/TableViewController.swift | 2 +- Example-tvOSUITests/ExampleUITests.swift | 1 - Podfile | 4 +-- Podfile.lock | 2 +- .../project.pbxproj | 25 ++++++++++++++++--- Tests/Model/RadioSectionSpec.swift | 2 +- scripts/swiftlint.sh | 7 ++++++ 9 files changed, 38 insertions(+), 12 deletions(-) create mode 100644 scripts/swiftlint.sh diff --git a/.swiftlint.yml b/.swiftlint.yml index 13e5771b..64d70f32 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -31,9 +31,10 @@ opt_in_rules: included: - "Example-iOS" - "Example-iOSUITests" - - "QuickTableViewController-iOS" - - "QuickTableViewController-iOSTests" + - "Example-tvOS" + - "Example-tvOSUITests" - "Source" + - "Tests" excluded: - Carthage - Pods diff --git a/Example-tvOS/AppDelegate.swift b/Example-tvOS/AppDelegate.swift index 57dbadf6..112ea76f 100644 --- a/Example-tvOS/AppDelegate.swift +++ b/Example-tvOS/AppDelegate.swift @@ -27,7 +27,7 @@ import UIKit @UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { +internal final class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? diff --git a/Example-tvOS/TableViewController.swift b/Example-tvOS/TableViewController.swift index 899f12d8..a7f046ac 100644 --- a/Example-tvOS/TableViewController.swift +++ b/Example-tvOS/TableViewController.swift @@ -27,7 +27,7 @@ import UIKit import QuickTableViewController -final class TableViewController: QuickTableViewController { +internal final class TableViewController: QuickTableViewController { override func viewDidLoad() { super.viewDidLoad() diff --git a/Example-tvOSUITests/ExampleUITests.swift b/Example-tvOSUITests/ExampleUITests.swift index d2bd4ab1..e43fb07a 100644 --- a/Example-tvOSUITests/ExampleUITests.swift +++ b/Example-tvOSUITests/ExampleUITests.swift @@ -36,7 +36,6 @@ internal final class ExampleUITests: XCTestCase { app.launch() } -// swiftlint:disable function_body_length line_length func testInteractions() { let tables = XCUIApplication().tables diff --git a/Podfile b/Podfile index 3ee73041..a91f754a 100644 --- a/Podfile +++ b/Podfile @@ -6,13 +6,13 @@ project "QuickTableViewController" target "QuickTableViewController-iOSTests" do platform :ios, "8.0" pod "Nimble", git: "https://github.com/Quick/Nimble.git", tag: "v7.1.3" - pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1", :inhibit_warnings => true + pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1", inhibit_warnings: true end target "QuickTableViewController-tvOSTests" do platform :tvos, "9.0" pod "Nimble", git: "https://github.com/Quick/Nimble.git", tag: "v7.1.3" - pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1", :inhibit_warnings => true + pod "Quick", git: "https://github.com/Quick/Quick.git", tag: "v1.3.1", inhibit_warnings: true end target "Example-iOS" do diff --git a/Podfile.lock b/Podfile.lock index ee5ffcba..4c085e98 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -31,6 +31,6 @@ SPEC CHECKSUMS: Quick: d17304d58d0d169dd0bd1c6e5c28e3318de32a1a SwiftLint: 3207c1faa2240bf8973b191820a116113cd11073 -PODFILE CHECKSUM: 209aaba56acbe1a7575f449d1faebf22752c3f27 +PODFILE CHECKSUM: e7ef9cc37da1ecd814713ea6beccac0b452a5ae4 COCOAPODS: 1.5.3 diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index e265717e..a0671e91 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -717,6 +717,7 @@ buildConfigurationList = B54A243C2088816E00EEBA26 /* Build configuration list for PBXNativeTarget "QuickTableViewController-tvOSTests" */; buildPhases = ( E5D972CCDEB057DA678D5651 /* [CP] Check Pods Manifest.lock */, + B51EE1432177EB3C0039C9B2 /* SwiftLint */, B54A242A2088816E00EEBA26 /* Sources */, B54A242B2088816E00EEBA26 /* Frameworks */, B54A242C2088816E00EEBA26 /* Resources */, @@ -979,6 +980,24 @@ 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; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = SwiftLint; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "sh scripts/swiftlint.sh\n"; + }; B51F21BB1F417269009BC2C9 /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -991,7 +1010,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "${PODS_ROOT}/SwiftLint/swiftlint"; + shellScript = "sh scripts/swiftlint.sh\n"; }; B54582FB212D7F89004376C8 /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; @@ -1005,7 +1024,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "${PODS_ROOT}/SwiftLint/swiftlint"; + shellScript = "sh scripts/swiftlint.sh\n"; }; B5C335A91D07CBD000C706A4 /* Swift Lint */ = { isa = PBXShellScriptBuildPhase; @@ -1019,7 +1038,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "${PODS_ROOT}/SwiftLint/swiftlint --config .swiftlint.yml"; + shellScript = "sh scripts/swiftlint.sh\n"; }; D6A5837800B2AEA91500816C /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; diff --git a/Tests/Model/RadioSectionSpec.swift b/Tests/Model/RadioSectionSpec.swift index 2a7e51ad..007451d7 100644 --- a/Tests/Model/RadioSectionSpec.swift +++ b/Tests/Model/RadioSectionSpec.swift @@ -158,7 +158,7 @@ internal final class RadioSectionSpec: QuickSpec { describe("toggle options") { let mock = { - return RadioSection(title: "Radio", options: [ + RadioSection(title: "Radio", options: [ OptionRow(title: "Option 1", isSelected: true, action: nil), OptionRow(title: "Option 2", isSelected: false, action: nil), OptionRow(title: "Option 3", isSelected: false, action: nil) diff --git a/scripts/swiftlint.sh b/scripts/swiftlint.sh new file mode 100644 index 00000000..7ac7186a --- /dev/null +++ b/scripts/swiftlint.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ -z "${TRAVIS}"]; then + ${PODS_ROOT}/SwiftLint/swiftlint --config .swiftlint.yml +else + echo "Skip SwiftLint" +fi From e98325cb17f59a9e4d34662e160820bfdd5f1778 Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 31 Dec 2018 17:55:53 +0000 Subject: [PATCH 22/35] Add a Subtitle compatible DetailText --- .../project.pbxproj | 16 ++- Source/Model/DetailText.swift | 61 ++++++++++ Source/Model/Subtitle.swift | 30 ++++- Source/Rows/NavigationRow.swift | 14 +++ Tests/Model/DetailTextSpec.swift | 108 ++++++++++++++++++ Tests/Model/SubtitleSpec.swift | 13 +-- 6 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 Source/Model/DetailText.swift create mode 100644 Tests/Model/DetailTextSpec.swift diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index a0671e91..246e44cc 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -12,6 +12,10 @@ 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, ); }; }; 1DF796C7F4630ACDCE1DE189 /* Pods_QuickTableViewController_iOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51571B6D4B25D0BCCCFFBCF5 /* Pods_QuickTableViewController_iOSTests.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 */; }; + 3E45598421DC181600FC0C76 /* DetailText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E45597921DA81B100FC0C76 /* DetailText.swift */; }; A3895BA2FCD4633B9297CB06 /* Pods_QuickTableViewController_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73EFDFBFA59BFFF7C494F9AE /* Pods_QuickTableViewController_tvOSTests.framework */; }; A7A26A71AB271F9D402D1A12 /* Pods_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF3454E57819285B32968564 /* Pods_Example_iOS.framework */; }; B50E73851F2E1BC900481910 /* RowStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50E73841F2E1BC900481910 /* RowStyle.swift */; }; @@ -174,6 +178,8 @@ 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 = ""; }; + 3E45597921DA81B100FC0C76 /* DetailText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailText.swift; sourceTree = ""; }; + 3E45597D21DA8B3400FC0C76 /* DetailTextSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailTextSpec.swift; sourceTree = ""; }; 466DB8C8ACDE64B9E0EF8D74 /* Pods-QuickTableViewController-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickTableViewController-iOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-QuickTableViewController-iOSTests/Pods-QuickTableViewController-iOSTests.release.xcconfig"; sourceTree = ""; }; 4AAC8E26F072FAB5027928F8 /* Pods-Example-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS.debug.xcconfig"; sourceTree = ""; }; 4D38F5DD6F45D1136A106B9F /* 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 = ""; }; @@ -311,8 +317,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 136DD307216A36FA00F554F0 /* QuickTableViewController.framework in Frameworks */, 0313D389A7BCE29502848262 /* Pods_Example_tvOS.framework in Frameworks */, + 136DD307216A36FA00F554F0 /* QuickTableViewController.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -367,6 +373,7 @@ B51A0E2E20692B1100F42693 /* Model */ = { isa = PBXGroup; children = ( + 3E45597D21DA8B3400FC0C76 /* DetailTextSpec.swift */, B5DB7D251C4B7F0E007B84D2 /* IconSpec.swift */, B5E619D61F4589F7005200E1 /* RadioSectionSpec.swift */, B5DB7D341C4CBB74007B84D2 /* SectionSpec.swift */, @@ -478,11 +485,11 @@ B51F21A21F417037009BC2C9 /* Example-iOS.app */, B51F21C01F41E600009BC2C9 /* Example-iOSUITests.xctest */, B54A24532088D44A00EEBA26 /* Example-tvOS.app */, + 136DD2FD216A367B00F554F0 /* Example-tvOSUITests.xctest */, B5334F131B8CC5BD00C64A6D /* QuickTableViewController.framework */, B54A24262088816D00EEBA26 /* QuickTableViewController.framework */, B54A242E2088816E00EEBA26 /* QuickTableViewControllerTests.xctest */, B5334F1E1B8CC5BD00C64A6D /* QuickTableViewControllerTests.xctest */, - 136DD2FD216A367B00F554F0 /* Example-tvOSUITests.xctest */, ); name = Products; sourceTree = ""; @@ -526,6 +533,7 @@ B55475721F2DC29B0027F7C1 /* Model */ = { isa = PBXGroup; children = ( + 3E45597921DA81B100FC0C76 /* DetailText.swift */, B5E029221DC8B3EC00B5C90E /* Icon.swift */, B5E619CE1F454CF0005200E1 /* RadioSection.swift */, B5E029201DC7A39200B5C90E /* Section.swift */, @@ -1112,6 +1120,7 @@ buildActionMask = 2147483647; files = ( B55475751F2DC3C00027F7C1 /* Configurable.swift in Sources */, + 3E45597A21DA81B100FC0C76 /* DetailText.swift in Sources */, B5E029231DC8B3EC00B5C90E /* Icon.swift in Sources */, B5F0FFE81E9CC6E8007BF1C9 /* NavigationRow.swift in Sources */, B5E619D21F454EEF005200E1 /* OptionRow.swift in Sources */, @@ -1136,6 +1145,7 @@ files = ( B5824E8C1FF3BA0A009666C8 /* ConfigurableSpec.swift in Sources */, B52677711FF7EA7500DC1362 /* CustomTypes.swift in Sources */, + 3E45597F21DA8B5F00FC0C76 /* DetailTextSpec.swift in Sources */, B5DB7D271C4B7F74007B84D2 /* IconSpec.swift in Sources */, B5DB7D2D1C4B8294007B84D2 /* NavigationRowSpec.swift in Sources */, B5E619D51F45744B005200E1 /* OptionRowSpec.swift in Sources */, @@ -1156,6 +1166,7 @@ buildActionMask = 2147483647; files = ( B54A2443208883A300EEBA26 /* Configurable.swift in Sources */, + 3E45598421DC181600FC0C76 /* DetailText.swift in Sources */, B54A243F208883A300EEBA26 /* Icon.swift in Sources */, B54A2448208883A300EEBA26 /* NavigationRow.swift in Sources */, B54A2449208883A300EEBA26 /* OptionRow.swift in Sources */, @@ -1180,6 +1191,7 @@ files = ( B5C9174F20B1831800C7999C /* ConfigurableSpec.swift in Sources */, B5C9175420B1831800C7999C /* CustomTypes.swift in Sources */, + 3E45598021DA8B6000FC0C76 /* DetailTextSpec.swift in Sources */, B5C9174720B1831800C7999C /* IconSpec.swift in Sources */, B5C9174B20B1831800C7999C /* NavigationRowSpec.swift in Sources */, B5C9174C20B1831800C7999C /* OptionRowSpec.swift in Sources */, diff --git a/Source/Model/DetailText.swift b/Source/Model/DetailText.swift new file mode 100644 index 00000000..c1cdd07a --- /dev/null +++ b/Source/Model/DetailText.swift @@ -0,0 +1,61 @@ +// +// DetailText.swift +// QuickTableViewController +// +// Created by bcylin on 31/12/2018. +// Copyright © 2018 bcylin. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import UIKit + +/// An enum that represents a detail text with `UITableViewCell.CellStyle`. +public enum DetailText: Equatable { + + /// Does not show a detail text in `UITableViewCell.CellStyle.default`. + case none + /// Shows the detail text in `UITableViewCell.CellStyle.subtitle`. + case subtitle(String) + /// Shows the detail text in `UITableViewCell.CellStyle.value1`. + case value1(String) + /// Shows the detail text in `UITableViewCell.CellStyle.value2`. + case value2(String) + + /// Returns the corresponding table view cell style. + public var style: UITableViewCell.CellStyle { + switch self { + case .none: return .default + case .subtitle: return .subtitle + case .value1: return .value1 + case .value2: return .value2 + } + } + + /// Returns the associated text of the case. + public var text: String? { + switch self { + case .none: + return nil + case let .subtitle(text), let .value1(text), let .value2(text): + return text + } + } + +} diff --git a/Source/Model/Subtitle.swift b/Source/Model/Subtitle.swift index 5a3cb5eb..ed11ad5c 100644 --- a/Source/Model/Subtitle.swift +++ b/Source/Model/Subtitle.swift @@ -78,15 +78,33 @@ public enum Subtitle: Equatable { } +//////////////////////////////////////////////////////////////////////////////// -internal extension UITableViewCell.CellStyle { +internal extension Subtitle { - var stringValue: String { + /// The conversion between Subtitle and DetailText. + internal var detailText: DetailText { switch self { - case .default: return ".default" - case .subtitle: return ".subtitle" - case .value1: return ".value1" - case .value2: return ".value2" + case .none: return .none + case let .belowTitle(text): return .subtitle(text) + case let .rightAligned(text): return .value1(text) + case let .leftAligned(text): return .value2(text) + } + } + +} + +//////////////////////////////////////////////////////////////////////////////// + +internal extension DetailText { + + /// The conversion between DetailText and Subtitle. + internal var subtitle: Subtitle { + switch self { + case .none: return .none + case let .subtitle(text): return .belowTitle(text) + case let .value1(text): return .rightAligned(text) + case let .value2(text): return .leftAligned(text) } } diff --git a/Source/Rows/NavigationRow.swift b/Source/Rows/NavigationRow.swift index 03a73c77..f50ba175 100644 --- a/Source/Rows/NavigationRow.swift +++ b/Source/Rows/NavigationRow.swift @@ -100,3 +100,17 @@ open class NavigationRow: NavigationRowCompatible, Equatable } } + + +private extension UITableViewCell.CellStyle { + + var stringValue: String { + switch self { + case .default: return ".default" + case .subtitle: return ".subtitle" + case .value1: return ".value1" + case .value2: return ".value2" + } + } + +} diff --git a/Tests/Model/DetailTextSpec.swift b/Tests/Model/DetailTextSpec.swift new file mode 100644 index 00000000..d6733058 --- /dev/null +++ b/Tests/Model/DetailTextSpec.swift @@ -0,0 +1,108 @@ +// +// DetailTextSpec.swift +// QuickTableViewController +// +// Created by bcylin on 31/12/2018. +// Copyright © 2018 bcylin. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Nimble +import Quick +@testable import QuickTableViewController + +internal final class DetailTextSpec: QuickSpec { + + 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 + } + } + + 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" + } + } + + describe("equatable") { + context(".none") { + it("should be equal when both are .none") { + let a = DetailText.none + let b = DetailText.none + expect(a) == b + } + } + + 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 + + it("should be equal only when type and associated value match") { + expect(a) == b + expect(a) != c + expect(a) != d + expect(a) != e + } + } + + 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 + + it("should be equal only when type and associated value match") { + expect(a) == b + expect(a) != c + expect(a) != d + expect(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 + + it("should be equal only when type and associated value match") { + expect(a) == b + expect(a) != c + expect(a) != d + expect(a) != e + } + } + } + } + +} diff --git a/Tests/Model/SubtitleSpec.swift b/Tests/Model/SubtitleSpec.swift index ec83a90b..6ad7d31b 100644 --- a/Tests/Model/SubtitleSpec.swift +++ b/Tests/Model/SubtitleSpec.swift @@ -23,7 +23,6 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. // - import Nimble import Quick @testable import QuickTableViewController @@ -31,12 +30,12 @@ import Quick internal final class SubtitleSpec: QuickSpec { override func spec() { - describe("subtitle style") { - it("should return the descriptive name of the style") { - expect(Subtitle.none.style.stringValue) == ".default" - expect(Subtitle.belowTitle("text").style.stringValue) == ".subtitle" - expect(Subtitle.rightAligned("text").style.stringValue) == ".value1" - expect(Subtitle.leftAligned("text").style.stringValue) == ".value2" + 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") } } From 7a403bce8e66643f80061244d14e9e6623b492d3 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 1 Jan 2019 20:47:48 +0000 Subject: [PATCH 23/35] Replace Subtitle with DetailTex in Rows --- .../DefaultViewController.swift | 2 +- .../project.pbxproj | 6 + Source/Model/Deprecated.swift | 128 ++++++++++++++++++ Source/Model/Subtitle.swift | 40 +----- Source/Protocol/Configurable.swift | 4 +- Source/Protocol/Row.swift | 8 +- Source/Rows/NavigationRow.swift | 28 ++-- Source/Rows/OptionRow.swift | 23 ++-- Source/Rows/SwitchRow.swift | 21 +-- Source/Rows/TapActionRow.swift | 20 +-- Tests/Model/SubtitleSpec.swift | 69 ---------- 11 files changed, 193 insertions(+), 156 deletions(-) create mode 100644 Source/Model/Deprecated.swift diff --git a/Example-iOS/ViewControllers/DefaultViewController.swift b/Example-iOS/ViewControllers/DefaultViewController.swift index 50007d88..a219142b 100644 --- a/Example-iOS/ViewControllers/DefaultViewController.swift +++ b/Example-iOS/ViewControllers/DefaultViewController.swift @@ -110,7 +110,7 @@ internal final class DefaultViewController: QuickTableViewController { private func showDetail() -> (Row) -> Void { return { [weak self] in - let detail = $0.title + ($0.subtitle?.text ?? "") + let detail = $0.title + ($0.detailText?.text ?? "") let controller = UIViewController() controller.view.backgroundColor = .white controller.title = detail diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index 246e44cc..66c7ce8f 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -15,7 +15,9 @@ 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 */; }; + 3E45598221DC134800FC0C76 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E45598121DC134800FC0C76 /* Deprecated.swift */; }; 3E45598421DC181600FC0C76 /* DetailText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E45597921DA81B100FC0C76 /* DetailText.swift */; }; + 3E45598521DC184800FC0C76 /* Deprecated.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E45598121DC134800FC0C76 /* Deprecated.swift */; }; A3895BA2FCD4633B9297CB06 /* Pods_QuickTableViewController_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 73EFDFBFA59BFFF7C494F9AE /* Pods_QuickTableViewController_tvOSTests.framework */; }; A7A26A71AB271F9D402D1A12 /* Pods_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF3454E57819285B32968564 /* Pods_Example_iOS.framework */; }; B50E73851F2E1BC900481910 /* RowStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50E73841F2E1BC900481910 /* RowStyle.swift */; }; @@ -180,6 +182,7 @@ 136DD301216A367B00F554F0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; 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 = ""; }; 466DB8C8ACDE64B9E0EF8D74 /* Pods-QuickTableViewController-iOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-QuickTableViewController-iOSTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-QuickTableViewController-iOSTests/Pods-QuickTableViewController-iOSTests.release.xcconfig"; sourceTree = ""; }; 4AAC8E26F072FAB5027928F8 /* Pods-Example-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Example-tvOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Example-tvOS/Pods-Example-tvOS.debug.xcconfig"; sourceTree = ""; }; 4D38F5DD6F45D1136A106B9F /* 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 = ""; }; @@ -533,6 +536,7 @@ B55475721F2DC29B0027F7C1 /* Model */ = { isa = PBXGroup; children = ( + 3E45598121DC134800FC0C76 /* Deprecated.swift */, 3E45597921DA81B100FC0C76 /* DetailText.swift */, B5E029221DC8B3EC00B5C90E /* Icon.swift */, B5E619CE1F454CF0005200E1 /* RadioSection.swift */, @@ -1120,6 +1124,7 @@ buildActionMask = 2147483647; files = ( B55475751F2DC3C00027F7C1 /* Configurable.swift in Sources */, + 3E45598221DC134800FC0C76 /* Deprecated.swift in Sources */, 3E45597A21DA81B100FC0C76 /* DetailText.swift in Sources */, B5E029231DC8B3EC00B5C90E /* Icon.swift in Sources */, B5F0FFE81E9CC6E8007BF1C9 /* NavigationRow.swift in Sources */, @@ -1166,6 +1171,7 @@ buildActionMask = 2147483647; files = ( B54A2443208883A300EEBA26 /* Configurable.swift in Sources */, + 3E45598521DC184800FC0C76 /* Deprecated.swift in Sources */, 3E45598421DC181600FC0C76 /* DetailText.swift in Sources */, B54A243F208883A300EEBA26 /* Icon.swift in Sources */, B54A2448208883A300EEBA26 /* NavigationRow.swift in Sources */, diff --git a/Source/Model/Deprecated.swift b/Source/Model/Deprecated.swift new file mode 100644 index 00000000..a3bdebcf --- /dev/null +++ b/Source/Model/Deprecated.swift @@ -0,0 +1,128 @@ +// +// Deprecated.swift +// QuickTableViewController +// +// Created by bcylin on 01/01/2019. +// Copyright © 2019 bcylin. +// +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import Foundation + +public extension Row { + + public var title: String { + return text + } + + public var subtitle: Subtitle? { + return detailText?.subtitle + } + +} + +//////////////////////////////////////////////////////////////////////////////// + +public extension NavigationRow { + + public convenience init( + title: String, + subtitle: Subtitle, + icon: Icon? = nil, + customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, + action: ((Row) -> Void)? = nil + ) { + self.init( + text: title, + detailText: subtitle.detailText, + icon: icon, + customization: customization, + action: action + ) + } + +} + +//////////////////////////////////////////////////////////////////////////////// + +public extension OptionRow { + + public convenience init( + title: String, + subtitle: Subtitle? = nil, + isSelected: Bool, + icon: Icon? = nil, + customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, + action: ((Row) -> Void)? + ) { + self.init( + text: title, + detailText: subtitle?.detailText, + isSelected: isSelected, + icon: icon, + customization: customization, + action: action + ) + } + +} + +//////////////////////////////////////////////////////////////////////////////// + +public extension SwitchRow { + + public convenience init( + title: String, + subtitle: Subtitle? = nil, + switchValue: Bool, + icon: Icon? = nil, + customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, + action: ((Row) -> Void)? + ) { + self.init( + text: title, + detailText: subtitle?.detailText, + switchValue: switchValue, + icon: icon, + customization: customization, + action: action + ) + } + +} + +//////////////////////////////////////////////////////////////////////////////// + +public extension TapActionRow { + + public convenience init( + title: String, + customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, + action: ((Row) -> Void)? + ) { + self.init( + text: title, + customization: customization, + action: action + ) + } + +} diff --git a/Source/Model/Subtitle.swift b/Source/Model/Subtitle.swift index ed11ad5c..75e1a20b 100644 --- a/Source/Model/Subtitle.swift +++ b/Source/Model/Subtitle.swift @@ -26,7 +26,6 @@ import UIKit -/// An enum that represents a subtitle text with `UITableViewCellStyle`. public enum Subtitle: Equatable { /// Does not show a subtitle as `UITableViewCellStyle.default`. @@ -40,48 +39,14 @@ public enum Subtitle: Equatable { /// Returns the corresponding table view cell style. public var style: UITableViewCell.CellStyle { - switch self { - case .none: return .default - case .belowTitle: return .subtitle - case .rightAligned: return .value1 - case .leftAligned: return .value2 - } + return detailText.style } /// Returns the associated text of the case. public var text: String? { - switch self { - case let .belowTitle(text): return text - case let .rightAligned(text): return text - case let .leftAligned(text): return text - default: return nil - } - } - - // MARK: Equatable - - /// Returns true iff `lhs` and `rhs` have equal texts in the same `Subtitle`. - public static func == (lhs: Subtitle, rhs: Subtitle) -> Bool { - switch (lhs, rhs) { - case (.none, .none): - return true - case let (.belowTitle(a), .belowTitle(b)): - return a == b - case let (.rightAligned(a), .rightAligned(b)): - return a == b - case let (.leftAligned(a), .leftAligned(b)): - return a == b - default: - return false - } + return detailText.text } -} - -//////////////////////////////////////////////////////////////////////////////// - -internal extension Subtitle { - /// The conversion between Subtitle and DetailText. internal var detailText: DetailText { switch self { @@ -94,7 +59,6 @@ internal extension Subtitle { } -//////////////////////////////////////////////////////////////////////////////// internal extension DetailText { diff --git a/Source/Protocol/Configurable.swift b/Source/Protocol/Configurable.swift index 47a7af6f..d743e86d 100644 --- a/Source/Protocol/Configurable.swift +++ b/Source/Protocol/Configurable.swift @@ -36,8 +36,8 @@ public protocol Configurable { extension UITableViewCell { internal func defaultSetUp(with row: Row & RowStyle) { - textLabel?.text = row.title - detailTextLabel?.text = row.subtitle?.text + textLabel?.text = row.text + detailTextLabel?.text = row.detailText?.text // Reset the accessory view in case the cell is reused. accessoryView = nil diff --git a/Source/Protocol/Row.swift b/Source/Protocol/Row.swift index 1a018f58..99b6d3d6 100644 --- a/Source/Protocol/Row.swift +++ b/Source/Protocol/Row.swift @@ -29,11 +29,11 @@ import Foundation /// Any type that conforms to this protocol is capable of representing a row in a table view. public protocol Row: class { - /// The title text of the row. - var title: String { get } + /// The text of the row. + var text: String { get } - /// The subtitle text of the row. - var subtitle: Subtitle? { get } + /// The detail text of the row. + var detailText: DetailText? { get } /// A closure related to the action of the row. var action: ((Row) -> Void)? { get } diff --git a/Source/Rows/NavigationRow.swift b/Source/Rows/NavigationRow.swift index f50ba175..793c7959 100644 --- a/Source/Rows/NavigationRow.swift +++ b/Source/Rows/NavigationRow.swift @@ -31,17 +31,17 @@ open class NavigationRow: NavigationRowCompatible, Equatable // MARK: - Initializer - /// Initializes a `NavigationRow` with a title and a subtitle. + /// Initializes a `NavigationRow` with a text and a detail text. /// The icon, customization and action closures are optional. public init( - title: String, - subtitle: Subtitle, + text: String, + detailText: DetailText, icon: Icon? = nil, customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, action: ((Row) -> Void)? = nil ) { - self.title = title - self.subtitle = subtitle + self.text = text + self.detailText = detailText self.icon = icon self.customize = customization self.action = action @@ -49,11 +49,11 @@ open class NavigationRow: NavigationRowCompatible, Equatable // MARK: - Row - /// The title text of the row. - public let title: String + /// The text of the row. + public let text: String - /// The subtitle text of the row. - public let subtitle: Subtitle? + /// The detail text of the row. + public let detailText: DetailText? /// A closure that will be invoked when the row is selected. public let action: ((Row) -> Void)? @@ -65,12 +65,12 @@ open class NavigationRow: NavigationRowCompatible, Equatable /// Returns the reuse identifier of the table view cell to display the row. public var cellReuseIdentifier: String { - return T.reuseIdentifier + (subtitle?.style.stringValue ?? "") + return T.reuseIdentifier + (detailText?.style.stringValue ?? "") } /// Returns the table view cell style for the specified subtitle. public var cellStyle: UITableViewCell.CellStyle { - return subtitle?.style ?? .default + return detailText?.style ?? .default } /// The icon of the row. @@ -91,11 +91,11 @@ open class NavigationRow: NavigationRowCompatible, Equatable // MARK: Equatable - /// Returns true iff `lhs` and `rhs` have equal titles, subtitles and icons. + /// Returns true iff `lhs` and `rhs` have equal titles, detail texts and icons. public static func == (lhs: NavigationRow, rhs: NavigationRow) -> Bool { return - lhs.title == rhs.title && - lhs.subtitle == rhs.subtitle && + lhs.text == rhs.text && + lhs.detailText == rhs.detailText && lhs.icon == rhs.icon } diff --git a/Source/Rows/OptionRow.swift b/Source/Rows/OptionRow.swift index 222c4a2e..9db0eb2d 100644 --- a/Source/Rows/OptionRow.swift +++ b/Source/Rows/OptionRow.swift @@ -31,16 +31,18 @@ open class OptionRow: OptionRowCompatible, Equatable { // MARK: - Initializer - /// Initializes an `OptionRow` with a title, a selection state and an action closure. - /// The icon and the customization closure are optional. + /// Initializes an `OptionRow` with a text, a selection state and an action closure. + /// The detail text, icon, and the customization closure are optional. public init( - title: String, + text: String, + detailText: DetailText? = nil, isSelected: Bool, icon: Icon? = nil, customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, action: ((Row) -> Void)? ) { - self.title = title + self.text = text + self.detailText = detailText self.isSelected = isSelected self.icon = icon self.customize = customization @@ -63,11 +65,11 @@ open class OptionRow: OptionRowCompatible, Equatable { // MARK: - Row - /// The title text of the row. - public let title: String + /// The text of the row. + public let text: String - /// Subtitle is disabled in `OptionRow`. - public let subtitle: Subtitle? = nil + /// The detail text of the row. + public let detailText: DetailText? /// A closure that will be invoked when the `isSelected` is changed. public let action: ((Row) -> Void)? @@ -99,10 +101,11 @@ open class OptionRow: OptionRowCompatible, Equatable { // MARK: - Equatable - /// Returns true iff `lhs` and `rhs` have equal titles, selection states, and icons. + /// Returns true iff `lhs` and `rhs` have equal titles, detail texts, selection states, and icons. public static func == (lhs: OptionRow, rhs: OptionRow) -> Bool { return - lhs.title == rhs.title && + lhs.text == rhs.text && + lhs.detailText == rhs.detailText && lhs.isSelected == rhs.isSelected && lhs.icon == rhs.icon } diff --git a/Source/Rows/SwitchRow.swift b/Source/Rows/SwitchRow.swift index d6804ce7..bcbbded1 100644 --- a/Source/Rows/SwitchRow.swift +++ b/Source/Rows/SwitchRow.swift @@ -32,15 +32,17 @@ open class SwitchRow: SwitchRowCompatible, Equatable { // MARK: - Initializer /// Initializes a `SwitchRow` with a title, a switch state and an action closure. - /// The icon and the customization closure are optional. + /// The detail text, icon and the customization closure are optional. public init( - title: String, + text: String, + detailText: DetailText? = nil, switchValue: Bool, icon: Icon? = nil, customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, action: ((Row) -> Void)? ) { - self.title = title + self.text = text + self.detailText = detailText self.switchValue = switchValue self.icon = icon self.customize = customization @@ -63,11 +65,11 @@ open class SwitchRow: SwitchRowCompatible, Equatable { // MARK: - Row - /// The title text of the row. - public let title: String + /// The text of the row. + public let text: String - /// The subtitle is disabled in `SwitchRow`. - public let subtitle: Subtitle? = nil + /// The detail text of the row. + public let detailText: DetailText? /// A closure that will be invoked when the `switchValue` is changed. public let action: ((Row) -> Void)? @@ -111,10 +113,11 @@ open class SwitchRow: SwitchRowCompatible, Equatable { // MARK: - Equatable - /// Returns true iff `lhs` and `rhs` have equal titles, switch values, and icons. + /// Returns true iff `lhs` and `rhs` have equal titles, detail texts, switch values, and icons. public static func == (lhs: SwitchRow, rhs: SwitchRow) -> Bool { return - lhs.title == rhs.title && + lhs.text == rhs.text && + lhs.detailText == rhs.detailText && lhs.switchValue == rhs.switchValue && lhs.icon == rhs.icon } diff --git a/Source/Rows/TapActionRow.swift b/Source/Rows/TapActionRow.swift index 7b8d5e41..e1ae71b1 100644 --- a/Source/Rows/TapActionRow.swift +++ b/Source/Rows/TapActionRow.swift @@ -31,25 +31,25 @@ open class TapActionRow: TapActionRowCompatible, Equatable { // MARK: - Initializer - /// Initializes a `TapActionRow` with a title, an action closure, + /// Initializes a `TapActionRow` with a text, an action closure, /// and an optional customization closure. public init( - title: String, + text: String, customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, action: ((Row) -> Void)? ) { - self.title = title + self.text = text self.customize = customization self.action = action } // MARK: - Row - /// The title text of the row. - public let title: String + /// The text of the row. + public let text: String - /// The subtitle is disabled in `TapActionRow`. - public let subtitle: Subtitle? = nil + /// The detail text is disabled in `TapActionRow`. + public let detailText: DetailText? = nil /// A closure that will be invoked when the row is selected. public let action: ((Row) -> Void)? @@ -81,9 +81,11 @@ open class TapActionRow: TapActionRowCompatible, Equatable { // MARK: - Equatable - /// Returns true iff `lhs` and `rhs` have equal titles and subtitles. + /// Returns true iff `lhs` and `rhs` have equal titles and detail texts. public static func == (lhs: TapActionRow, rhs: TapActionRow) -> Bool { - return lhs.title == rhs.title && lhs.subtitle == rhs.subtitle + return + lhs.text == rhs.text && + lhs.detailText == rhs.detailText } } diff --git a/Tests/Model/SubtitleSpec.swift b/Tests/Model/SubtitleSpec.swift index 6ad7d31b..0b088c48 100644 --- a/Tests/Model/SubtitleSpec.swift +++ b/Tests/Model/SubtitleSpec.swift @@ -38,75 +38,6 @@ internal final class SubtitleSpec: QuickSpec { expect(Subtitle.leftAligned("text").detailText) == .value2("text") } } - - describe("associtated value") { - let none = Subtitle.none - let belowTitle = Subtitle.belowTitle("text") - let rightAligned = Subtitle.rightAligned("text") - let leftAligned = Subtitle.leftAligned("text") - - it("should return the associated text") { - expect(none.text).to(beNil()) - expect(belowTitle.text) == "text" - expect(rightAligned.text) == "text" - expect(leftAligned.text) == "text" - } - } - - describe("equatable") { - context(".none") { - it("should be equal when both are .none") { - let a = Subtitle.none - let b = Subtitle.none - expect(a) == b - } - } - - context(".belowTitle") { - let a = Subtitle.belowTitle("Same") - let b = Subtitle.belowTitle("Same") - let c = Subtitle.belowTitle("Different") - let d = Subtitle.rightAligned("Same") - let e = Subtitle.none - - it("should be equal only when type and associated value match") { - expect(a) == b - expect(a) != c - expect(a) != d - expect(a) != e - } - } - - context(".rightAligned") { - let a = Subtitle.rightAligned("Same") - let b = Subtitle.rightAligned("Same") - let c = Subtitle.rightAligned("Different") - let d = Subtitle.leftAligned("Same") - let e = Subtitle.none - - it("should be equal only when type and associated value match") { - expect(a) == b - expect(a) != c - expect(a) != d - expect(a) != e - } - } - - context(".leftAligned") { - let a = Subtitle.leftAligned("Same") - let b = Subtitle.leftAligned("Same") - let c = Subtitle.leftAligned("Different") - let d = Subtitle.belowTitle("Same") - let e = Subtitle.none - - it("should be equal only when type and associated value match") { - expect(a) == b - expect(a) != c - expect(a) != d - expect(a) != e - } - } - } } } From 3f8a71e9456254b6f53df2f648a0b2ddb5961fca Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 1 Jan 2019 21:39:33 +0000 Subject: [PATCH 24/35] Deprecate Subtitle and related Row properties --- CHANGELOG.md | 7 +++++++ Source/Model/Deprecated.swift | 2 ++ Source/Model/Icon.swift | 14 -------------- Source/Model/Subtitle.swift | 5 +++-- Tests/Row/NavigationRowSpec.swift | 8 ++++---- Tests/Row/OptionRowSpec.swift | 7 ++++--- Tests/Row/SwitchRowSpec.swift | 2 +- Tests/Row/TapActionRowSpec.swift | 2 +- 8 files changed, 22 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d18cf83..5ffe9707 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Change Log +## v1.1.0 + +#### Enhancements + +* Rename `Row`'s title and subtitle to text and detail text to align with `UITableViewCell`'s naming +* `Subtitle` is deprecated and will be removed in **v2.0.0** + ## v1.0.0 #### Enhancements diff --git a/Source/Model/Deprecated.swift b/Source/Model/Deprecated.swift index a3bdebcf..38b06291 100644 --- a/Source/Model/Deprecated.swift +++ b/Source/Model/Deprecated.swift @@ -29,10 +29,12 @@ import Foundation public extension Row { + @available(*, deprecated, message: "Use `text` instead.") public var title: String { return text } + @available(*, deprecated, message: "Use `detailText` instead.") public var subtitle: Subtitle? { return detailText?.subtitle } diff --git a/Source/Model/Icon.swift b/Source/Model/Icon.swift index a931c5b5..7691c87f 100644 --- a/Source/Model/Icon.swift +++ b/Source/Model/Icon.swift @@ -61,18 +61,4 @@ public enum Icon: Equatable { } } - // MARK: Equatable - - /// Returns true iff `lhs` and `rhs` have equal images and highlighted images. - public static func == (lhs: Icon, rhs: Icon) -> Bool { - switch (lhs, rhs) { - case let (.named(left), .named(right)): - return left == right - default: - return - lhs.image == rhs.image && - lhs.highlightedImage == rhs.highlightedImage - } - } - } diff --git a/Source/Model/Subtitle.swift b/Source/Model/Subtitle.swift index 75e1a20b..1021bcf2 100644 --- a/Source/Model/Subtitle.swift +++ b/Source/Model/Subtitle.swift @@ -26,6 +26,7 @@ import UIKit +@available(*, deprecated, message: "Use `DetailText` instead.") public enum Subtitle: Equatable { /// Does not show a subtitle as `UITableViewCellStyle.default`. @@ -47,7 +48,7 @@ public enum Subtitle: Equatable { return detailText.text } - /// The conversion between Subtitle and DetailText. + @available(*, deprecated, message: "The conversion between Subtitle and DetailText.") internal var detailText: DetailText { switch self { case .none: return .none @@ -62,7 +63,7 @@ public enum Subtitle: Equatable { internal extension DetailText { - /// The conversion between DetailText and Subtitle. + @available(*, deprecated, message: "The conversion between DetailText and Subtitle.") internal var subtitle: Subtitle { switch self { case .none: return .none diff --git a/Tests/Row/NavigationRowSpec.swift b/Tests/Row/NavigationRowSpec.swift index 63ead340..6ba09131 100644 --- a/Tests/Row/NavigationRowSpec.swift +++ b/Tests/Row/NavigationRowSpec.swift @@ -32,15 +32,15 @@ internal final class NavigationRowSpec: QuickSpec { override func spec() { describe("initialization") { - let subtitle = Subtitle.belowTitle("subtitle") + let detailText = DetailText.subtitle("subtitle") let icon = Icon.named("icon") var invoked = false - let row = NavigationRow(title: "title", subtitle: subtitle, icon: icon, action: { _ in invoked = true }) + let row = NavigationRow(text: "title", detailText: detailText, icon: icon, action: { _ in invoked = true }) it("should initialize with given parameters") { - expect(row.title) == "title" - expect(row.subtitle) == subtitle + expect(row.text) == "title" + expect(row.detailText) == detailText expect(row.icon) == icon expect(row.cellReuseIdentifier) == "UITableViewCell.subtitle" diff --git a/Tests/Row/OptionRowSpec.swift b/Tests/Row/OptionRowSpec.swift index b3664e55..cd08e865 100644 --- a/Tests/Row/OptionRowSpec.swift +++ b/Tests/Row/OptionRowSpec.swift @@ -32,15 +32,16 @@ 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(title: "title", isSelected: true, icon: icon) { _ in invoked = true } + let row = OptionRow(text: "title", detailText: detailText, isSelected: true, icon: icon) { _ in invoked = true } it("should initialize with given parameters") { // Row - expect(row.title) == "title" - expect(row.subtitle).to(beNil()) + expect(row.text) == "title" + expect(row.detailText) == detailText expect(row.isSelected) == true row.action?(row) diff --git a/Tests/Row/SwitchRowSpec.swift b/Tests/Row/SwitchRowSpec.swift index de084785..786382b4 100644 --- a/Tests/Row/SwitchRowSpec.swift +++ b/Tests/Row/SwitchRowSpec.swift @@ -36,7 +36,7 @@ internal final class SwitchRowSpec: QuickSpec { let row = SwitchRow(title: "title", switchValue: true) { _ in invoked = true } it("should initialize with given parameters") { - expect(row.title) == "title" + expect(row.text) == "title" expect(row.switchValue) == true expect(row.cellReuseIdentifier) == "SwitchCell" diff --git a/Tests/Row/TapActionRowSpec.swift b/Tests/Row/TapActionRowSpec.swift index f6678e30..254cc6af 100644 --- a/Tests/Row/TapActionRowSpec.swift +++ b/Tests/Row/TapActionRowSpec.swift @@ -36,7 +36,7 @@ internal final class TapActionRowSpec: QuickSpec { let row = TapActionRow(title: "title") { _ in invoked = true } it("should initialize with given parameters") { - expect(row.title) == "title" + expect(row.text) == "title" expect(row.cellReuseIdentifier) == "TapActionCell" row.action?(row) From dec28422ccafe88206f361a72002458979bed880 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 1 Jan 2019 21:49:46 +0000 Subject: [PATCH 25/35] Deprecate the previous initializers --- .../AppearanceViewController.swift | 8 +- .../CustomizationViewController.swift | 36 ++++---- .../DefaultViewController.swift | 30 +++---- .../ViewControllers/RootViewController.swift | 6 +- Example-tvOS/TableViewController.swift | 30 +++---- README.md | 36 ++++---- Source/Model/Deprecated.swift | 4 + Tests/Model/RadioSectionSpec.swift | 36 ++++---- Tests/Model/SectionSpec.swift | 2 +- Tests/Row/NavigationRowSpec.swift | 20 ++--- Tests/Row/OptionRowSpec.swift | 16 ++-- Tests/Row/SwitchRowSpec.swift | 18 ++-- Tests/Row/TapActionRowSpec.swift | 10 +-- Tests/View/ConfigurableSpec.swift | 16 ++-- .../QuickTableViewDataSourceSpec.swift | 62 ++++++------- .../QuickTableViewDelegateSpec.swift | 88 +++++++++---------- 16 files changed, 211 insertions(+), 207 deletions(-) diff --git a/Example-iOS/ViewControllers/AppearanceViewController.swift b/Example-iOS/ViewControllers/AppearanceViewController.swift index 71cc5344..5881db4b 100644 --- a/Example-iOS/ViewControllers/AppearanceViewController.swift +++ b/Example-iOS/ViewControllers/AppearanceViewController.swift @@ -41,19 +41,19 @@ internal final class AppearanceViewController: QuickTableViewController { tableContents = [ Section(title: "Switch", rows: [ - SwitchRow(title: "SwitchCell", switchValue: true, action: { _ in }) + SwitchRow(text: "SwitchCell", switchValue: true, action: { _ in }) ]), Section(title: "Tap Action", rows: [ - TapActionRow(title: "TapActionCell", action: { _ in }) + TapActionRow(text: "TapActionCell", action: { _ in }) ]), Section(title: "Navigation", rows: [ - NavigationRow(title: "UITableViewCell", subtitle: .belowTitle(".subtitle"), action: { _ in }) + NavigationRow(text: "UITableViewCell", detailText: .subtitle(".subtitle"), action: { _ in }) ]), RadioSection(title: "Radio Buttons", options: [ - OptionRow(title: "UITableViewCell", isSelected: true, action: { _ in }) + OptionRow(text: "UITableViewCell", isSelected: true, action: { _ in }) ]) ] } diff --git a/Example-iOS/ViewControllers/CustomizationViewController.swift b/Example-iOS/ViewControllers/CustomizationViewController.swift index ee1b1708..f70bdd11 100644 --- a/Example-iOS/ViewControllers/CustomizationViewController.swift +++ b/Example-iOS/ViewControllers/CustomizationViewController.swift @@ -41,7 +41,7 @@ internal final class CustomizationViewController: QuickTableViewController { private let debugging = Section( title: nil, - rows: [NavigationRow(title: "", subtitle: .none)], + rows: [NavigationRow(text: "", detailText: .none)], footer: "Select or toggle each row to show their cell reuse identifiers." ) @@ -56,13 +56,13 @@ internal final class CustomizationViewController: QuickTableViewController { Section(title: "Switch", rows: [ SwitchRow( - title: "SwitchRow\n", + text: "SwitchRow\n", switchValue: true, customization: set(label: "0-0"), action: showLog() ), CustomSwitchRow( - title: "CustomSwitchRow\n", + text: "CustomSwitchRow\n", switchValue: false, customization: set(label: "0-1"), action: showLog() @@ -71,12 +71,12 @@ internal final class CustomizationViewController: QuickTableViewController { Section(title: "Tap Action", rows: [ TapActionRow( - title: "TapActionRow\n", + text: "TapActionRow\n", customization: set(label: "1-0"), action: showLog() ), CustomTapActionRow( - title: "CustomTapActionRow\n", + text: "CustomTapActionRow\n", customization: set(label: "1-1"), action: showLog() ) @@ -84,26 +84,26 @@ internal final class CustomizationViewController: QuickTableViewController { Section(title: "Navigation", rows: [ NavigationRow( - title: "NavigationRow", - subtitle: .none, + text: "NavigationRow", + detailText: .none, customization: set(label: "2-0"), action: showLog() ), NavigationRow( - title: "NavigationRow", - subtitle: .belowTitle(".subtitle"), + text: "NavigationRow", + detailText: .subtitle(".subtitle"), customization: set(label: "2-1"), action: showLog() ), CustomNavigationRow( - title: "CustomNavigationRow", - subtitle: .rightAligned(".value1"), + text: "CustomNavigationRow", + detailText: .value1(".value1"), customization: set(label: "2-2"), action: showLog() ), CustomNavigationRow( - title: "CustomNavigationRow", - subtitle: .leftAligned(".value2"), + text: "CustomNavigationRow", + detailText: .value2(".value2"), customization: set(label: "2-3"), action: showLog() ) @@ -111,19 +111,19 @@ internal final class CustomizationViewController: QuickTableViewController { RadioSection(title: "Radio Buttons", options: [ OptionRow( - title: "OptionRow", + text: "OptionRow", isSelected: false, customization: set(label: "3-0"), action: showLog() ), CustomOptionRow( - title: "CustomOptionRow", + text: "CustomOptionRow", isSelected: false, customization: set(label: "3-1"), action: showLog() ), CustomOptionRow( - title: "CustomOptionRow", + text: "CustomOptionRow", isSelected: false, customization: set(label: "3-2"), action: showLog() @@ -131,7 +131,7 @@ internal final class CustomizationViewController: QuickTableViewController { ]), Section(title: nil, rows: [ - NavigationRow(title: "Customization closure", subtitle: .none, customization: { cell, _ in + NavigationRow(text: "Customization closure", detailText: .none, customization: { cell, _ in cell.accessibilityLabel = "4-0" cell.accessoryView = UIImageView(image: #imageLiteral(resourceName: "iconmonstr-x-mark")) }) @@ -162,7 +162,7 @@ internal final class CustomizationViewController: QuickTableViewController { } let identifier = ($0 as! RowStyle).cellReuseIdentifier self?.debugging.rows = [ - NavigationRow(title: identifier, subtitle: .none, customization: self?.set(label: "debug")) + NavigationRow(text: identifier, detailText: .none, customization: self?.set(label: "debug")) ] print(identifier) DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in diff --git a/Example-iOS/ViewControllers/DefaultViewController.swift b/Example-iOS/ViewControllers/DefaultViewController.swift index a219142b..e604fad1 100644 --- a/Example-iOS/ViewControllers/DefaultViewController.swift +++ b/Example-iOS/ViewControllers/DefaultViewController.swift @@ -31,7 +31,7 @@ internal final class DefaultViewController: QuickTableViewController { // MARK: - Properties - private let debugging = Section(title: nil, rows: [NavigationRow(title: "", subtitle: .none)]) + private let debugging = Section(title: nil, rows: [NavigationRow(text: "", detailText: .none)]) // MARK: - UIViewController @@ -45,25 +45,25 @@ internal final class DefaultViewController: QuickTableViewController { tableContents = [ Section(title: "Switch", rows: [ - SwitchRow(title: "Setting 1", switchValue: true, icon: .image(globe), action: didToggleSwitch()), - SwitchRow(title: "Setting 2", switchValue: false, icon: .image(time), action: didToggleSwitch()) + SwitchRow(text: "Setting 1", switchValue: true, icon: .image(globe), action: didToggleSwitch()), + SwitchRow(text: "Setting 2", switchValue: false, icon: .image(time), action: didToggleSwitch()) ]), Section(title: "Tap Action", rows: [ - TapActionRow(title: "Tap action", action: showAlert()) + TapActionRow(text: "Tap action", action: showAlert()) ]), Section(title: "Navigation", rows: [ - NavigationRow(title: "CellStyle.default", subtitle: .none, icon: .image(gear)), - NavigationRow(title: "CellStyle", subtitle: .belowTitle(".subtitle"), icon: .image(globe)), - NavigationRow(title: "CellStyle", subtitle: .rightAligned(".value1"), icon: .image(time), action: showDetail()), - NavigationRow(title: "CellStyle", subtitle: .leftAligned(".value2")) + NavigationRow(text: "CellStyle.default", detailText: .none, icon: .image(gear)), + NavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), icon: .image(globe)), + NavigationRow(text: "CellStyle", detailText: .value1(".value1"), icon: .image(time), action: showDetail()), + NavigationRow(text: "CellStyle", detailText: .value2(".value2")) ], footer: "UITableViewCellStyle.Value2 hides the image view."), RadioSection(title: "Radio Buttons", options: [ - OptionRow(title: "Option 1", isSelected: true, action: didToggleSelection()), - OptionRow(title: "Option 2", isSelected: false, action: didToggleSelection()), - OptionRow(title: "Option 3", isSelected: false, action: didToggleSelection()) + OptionRow(text: "Option 1", isSelected: true, action: didToggleSelection()), + OptionRow(text: "Option 2", isSelected: false, action: didToggleSelection()), + OptionRow(text: "Option 3", isSelected: false, action: didToggleSelection()) ], footer: "See RadioSection for more details."), debugging @@ -83,7 +83,7 @@ internal final class DefaultViewController: QuickTableViewController { private func didToggleSelection() -> (Row) -> Void { return { [weak self] in if let option = $0 as? OptionRowCompatible { - let state = "\(option.title) is " + (option.isSelected ? "selected" : "deselected") + let state = "\(option.text) is " + (option.isSelected ? "selected" : "deselected") self?.showDebuggingText(state) } } @@ -92,7 +92,7 @@ internal final class DefaultViewController: QuickTableViewController { private func didToggleSwitch() -> (Row) -> Void { return { [weak self] in if let row = $0 as? SwitchRowCompatible { - let state = "\(row.title) = \(row.switchValue)" + let state = "\(row.text) = \(row.switchValue)" self?.showDebuggingText(state) } } @@ -110,7 +110,7 @@ internal final class DefaultViewController: QuickTableViewController { private func showDetail() -> (Row) -> Void { return { [weak self] in - let detail = $0.title + ($0.detailText?.text ?? "") + let detail = $0.text + ($0.detailText?.text ?? "") let controller = UIViewController() controller.view.backgroundColor = .white controller.title = detail @@ -121,7 +121,7 @@ internal final class DefaultViewController: QuickTableViewController { private func showDebuggingText(_ text: String) { print(text) - debugging.rows = [NavigationRow(title: text, subtitle: .none)] + debugging.rows = [NavigationRow(text: text, detailText: .none)] DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in self?.tableView.reloadData() } diff --git a/Example-iOS/ViewControllers/RootViewController.swift b/Example-iOS/ViewControllers/RootViewController.swift index 4b9e7390..8b7cdb77 100644 --- a/Example-iOS/ViewControllers/RootViewController.swift +++ b/Example-iOS/ViewControllers/RootViewController.swift @@ -40,19 +40,19 @@ internal final class RootViewController: QuickTableViewController { tableContents = [ Section(title: "Default", rows: [ - NavigationRow(title: "Use default cell types", subtitle: .none, action: { [weak self] _ in + NavigationRow(text: "Use default cell types", detailText: .none, action: { [weak self] _ in self?.navigationController?.pushViewController(DefaultViewController(), animated: true) }) ]), Section(title: "Customization", rows: [ - NavigationRow(title: "Use custom cell types", subtitle: .none, action: { [weak self] _ in + NavigationRow(text: "Use custom cell types", detailText: .none, action: { [weak self] _ in self?.navigationController?.pushViewController(CustomizationViewController(), animated: true) }) ]), Section(title: "UIAppearance", rows: [ - NavigationRow(title: "UILabel customization", subtitle: .none, action: { [weak self] _ in + NavigationRow(text: "UILabel customization", detailText: .none, action: { [weak self] _ in self?.navigationController?.pushViewController(AppearanceViewController(), animated: true) }) ]) diff --git a/Example-tvOS/TableViewController.swift b/Example-tvOS/TableViewController.swift index a7f046ac..5f304f04 100644 --- a/Example-tvOS/TableViewController.swift +++ b/Example-tvOS/TableViewController.swift @@ -35,25 +35,25 @@ internal final class TableViewController: QuickTableViewController { tableContents = [ Section(title: "Switch", rows: [ - SwitchRow(title: "Setting 1", switchValue: true, action: showLog()), - SwitchRow(title: "Setting 2", switchValue: false, action: showLog()) + SwitchRow(text: "Setting 1", switchValue: true, action: showLog()), + SwitchRow(text: "Setting 2", switchValue: false, action: showLog()) ]), Section(title: "Tap Action", rows: [ - TapActionRow(title: "Tap action", action: showAlert()) + TapActionRow(text: "Tap action", action: showAlert()) ]), Section(title: "Navigation", rows: [ - NavigationRow(title: "CellStyle.default", subtitle: .none, action: showDetail()), - NavigationRow(title: "CellStyle", subtitle: .belowTitle(".subtitle"), action: showDetail()), - NavigationRow(title: "CellStyle", subtitle: .rightAligned(".value1")), - NavigationRow(title: "CellStyle", subtitle: .leftAligned(".value2")) + NavigationRow(text: "CellStyle.default", detailText: .none, action: showDetail()), + NavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), action: showDetail()), + NavigationRow(text: "CellStyle", detailText: .value1(".value1")), + NavigationRow(text: "CellStyle", detailText: .value2(".value2")) ]), RadioSection(title: "Radio Buttons", options: [ - OptionRow(title: "Option 1", isSelected: true, action: showLog()), - OptionRow(title: "Option 2", isSelected: false, action: showLog()), - OptionRow(title: "Option 3", isSelected: false, action: showLog()) + OptionRow(text: "Option 1", isSelected: true, action: showLog()), + OptionRow(text: "Option 2", isSelected: false, action: showLog()), + OptionRow(text: "Option 3", isSelected: false, action: showLog()) ], footer: "See RadioSection for more details.") ] } @@ -63,8 +63,8 @@ internal final class TableViewController: QuickTableViewController { private func showAlert() -> (Row) -> Void { return { [weak self] row in let alert = UIAlertController( - title: row.title, - message: row.subtitle.flatMap({ $0.text }), + title: row.text, + message: row.detailText.flatMap({ $0.text }), preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil)) @@ -75,7 +75,7 @@ internal final class TableViewController: QuickTableViewController { private func showDetail() -> (Row) -> Void { return { [weak self] row in let controller = UIViewController() - controller.title = row.title + (row.subtitle?.text ?? "") + controller.title = row.text + (row.detailText?.text ?? "") self?.navigationController?.pushViewController(controller, animated: true) } } @@ -84,9 +84,9 @@ internal final class TableViewController: QuickTableViewController { return { switch $0 { case let row as SwitchRowCompatible: - print("\(row.title) = \(row.switchValue)") + print("\(row.text) = \(row.switchValue)") case let option as OptionRowCompatible where option.isSelected: - print("\(option.title) is selected") + print("\(option.text) is selected") default: break } diff --git a/README.md b/README.md index f79443f9..ad7cd1a1 100644 --- a/README.md +++ b/README.md @@ -31,25 +31,25 @@ class ViewController: QuickTableViewController { tableContents = [ Section(title: "Switch", rows: [ - SwitchRow(title: "Setting 1", switchValue: true, action: { _ in }), - SwitchRow(title: "Setting 2", switchValue: false, action: { _ in }), + SwitchRow(text: "Setting 1", switchValue: true, action: { _ in }), + SwitchRow(text: "Setting 2", switchValue: false, action: { _ in }), ]), Section(title: "Tap Action", rows: [ - TapActionRow(title: "Tap action", action: { [weak self] in self?.showAlert($0) }) + TapActionRow(text: "Tap action", action: { [weak self] in self?.showAlert($0) }) ]), Section(title: "Navigation", rows: [ - NavigationRow(title: "CellStyle.default", subtitle: .none, icon: .named("gear")), - NavigationRow(title: "CellStyle", subtitle: .belowTitle(".subtitle"), icon: .named("globe")), - NavigationRow(title: "CellStyle", subtitle: .rightAligned(".value1"), icon: .named("time"), action: { _ in }), - NavigationRow(title: "CellStyle", subtitle: .leftAligned(".value2")) + NavigationRow(text: "CellStyle.default", subtitle: .none, icon: .named("gear")), + NavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), icon: .named("globe")), + NavigationRow(text: "CellStyle", subtitle: .rightAligned(".value1"), icon: .named("time"), action: { _ in }), + NavigationRow(text: "CellStyle", subtitle: .leftAligned(".value2")) ]), RadioSection(title: "Radio Buttons", options: [ - OptionRow(title: "Option 1", isSelected: true, action: didToggleOption()), - OptionRow(title: "Option 2", isSelected: false, action: didToggleOption()), - OptionRow(title: "Option 3", isSelected: false, action: didToggleOption()) + OptionRow(text: "Option 1", isSelected: true, action: didToggleOption()), + OptionRow(text: "Option 2", isSelected: false, action: didToggleOption()), + OptionRow(text: "Option 3", isSelected: false, action: didToggleOption()) ], footer: "See RadioSection for more details.") ] } @@ -74,10 +74,10 @@ class ViewController: QuickTableViewController { #### Subtitle Styles ```swift -NavigationRow(title: "UITableViewCellStyle.default", subtitle: .none) -NavigationRow(title: "UITableViewCellStyle", subtitle: .belowTitle(".subtitle") -NavigationRow(title: "UITableViewCellStyle", subtitle: .rightAligned(".value1") -NavigationRow(title: "UITableViewCellStyle", subtitle: .leftAligned(".value2")) +NavigationRow(text: "UITableViewCellStyle.default", subtitle: .none) +NavigationRow(text: "UITableViewCellStyle", detailText: .subtitle(".subtitle") +NavigationRow(text: "UITableViewCellStyle", subtitle: .rightAligned(".value1") +NavigationRow(text: "UITableViewCellStyle", subtitle: .leftAligned(".value2")) ``` #### Disclosure Indicator @@ -146,16 +146,16 @@ A customized table view cell type can be specified to rows during initialization ```swift // Default is UITableViewCell. -NavigationRow(title: "Navigation", subtitle: .none) +NavigationRow(text: "Navigation", subtitle: .none) // Default is SwitchCell. -SwitchRow(title: "Switch", switchValue: true, action: { _ in }) +SwitchRow(text: "Switch", switchValue: true, action: { _ in }) // Default is TapActionCell. -TapActionRow(title: "Tap", action: { _ in }) +TapActionRow(text: "Tap", action: { _ in }) // Default is UITableViewCell. -OptionRow(title: "Option", isSelected: true, action: { _ in }) +OptionRow(text: "Option", isSelected: true, action: { _ in }) ``` Since the rows carry different cell types, they can be matched using either the concrete types or the related protocol: diff --git a/Source/Model/Deprecated.swift b/Source/Model/Deprecated.swift index 38b06291..6793d67a 100644 --- a/Source/Model/Deprecated.swift +++ b/Source/Model/Deprecated.swift @@ -45,6 +45,7 @@ public extension Row { public extension NavigationRow { + @available(*, deprecated, message: "Use `init(text:detailText:icon:customization:action:)` instead.") public convenience init( title: String, subtitle: Subtitle, @@ -67,6 +68,7 @@ public extension NavigationRow { public extension OptionRow { + @available(*, deprecated, message: "Use `init(text:detailText:isSelected:icon:customization:action:)` instead.") public convenience init( title: String, subtitle: Subtitle? = nil, @@ -91,6 +93,7 @@ public extension OptionRow { public extension SwitchRow { + @available(*, deprecated, message: "Use `init(text:detailText:switchValue:icon:customization:action:)` instead.") public convenience init( title: String, subtitle: Subtitle? = nil, @@ -115,6 +118,7 @@ public extension SwitchRow { public extension TapActionRow { + @available(*, deprecated, message: "Use `init(text:customization:action:)` instead.") public convenience init( title: String, customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, diff --git a/Tests/Model/RadioSectionSpec.swift b/Tests/Model/RadioSectionSpec.swift index 007451d7..c3a6eb55 100644 --- a/Tests/Model/RadioSectionSpec.swift +++ b/Tests/Model/RadioSectionSpec.swift @@ -32,7 +32,7 @@ internal final class RadioSectionSpec: QuickSpec { override func spec() { describe("initialization") { - let row = OptionRow(title: "", isSelected: false, action: nil) + let row = OptionRow(text: "", isSelected: false, action: nil) let section = RadioSection(title: "title", options: [row], footer: "footer") it("should initialize with given parameters") { @@ -48,8 +48,8 @@ internal final class RadioSectionSpec: QuickSpec { describe("rows") { context("getter") { let options = [ - OptionRow(title: "0", isSelected: false, action: nil), - OptionRow(title: "1", isSelected: true, action: nil) + OptionRow(text: "0", isSelected: false, action: nil), + OptionRow(text: "1", isSelected: true, action: nil) ] let section = RadioSection(title: "", options: options) @@ -62,7 +62,7 @@ internal final class RadioSectionSpec: QuickSpec { context("setter") { context("given empty array") { let section = RadioSection(title: "", options: [ - OptionRow(title: "", isSelected: true, action: nil) + OptionRow(text: "", isSelected: true, action: nil) ]) it("should change rows") { @@ -73,14 +73,14 @@ internal final class RadioSectionSpec: QuickSpec { } context("given incompatible type") { - let options = [OptionRow(title: "0", isSelected: false, action: nil)] + 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(title: "", subtitle: .none), - NavigationRow(title: "", subtitle: .none) + NavigationRow(text: "", detailText: .none), + NavigationRow(text: "", detailText: .none) ] expect(section.rows).to(haveCount(1)) expect(section.rows as? [OptionRow]) == options @@ -89,8 +89,8 @@ internal final class RadioSectionSpec: QuickSpec { context("given compatible type") { let options = [ - OptionRow(title: "0", isSelected: false, action: nil), - OptionRow(title: "1", isSelected: true, action: nil) + OptionRow(text: "0", isSelected: false, action: nil), + OptionRow(text: "1", isSelected: true, action: nil) ] let section = RadioSection(title: "", options: []) @@ -107,7 +107,7 @@ internal final class RadioSectionSpec: QuickSpec { describe("always selects one option") { context("when set to false") { let section = RadioSection(title: "title", options: [ - OptionRow(title: "Option 1", isSelected: false, action: nil) + OptionRow(text: "Option 1", isSelected: false, action: nil) ]) section.alwaysSelectsOneOption = false @@ -129,8 +129,8 @@ internal final class RadioSectionSpec: QuickSpec { context("when set to true with nothing selected") { let section = RadioSection(title: "title", options: [ - OptionRow(title: "Option 1", isSelected: false, action: nil), - OptionRow(title: "Option 2", isSelected: false, action: nil) + OptionRow(text: "Option 1", isSelected: false, action: nil), + OptionRow(text: "Option 2", isSelected: false, action: nil) ]) section.alwaysSelectsOneOption = true @@ -143,8 +143,8 @@ internal final class RadioSectionSpec: QuickSpec { context("when set to true with something selected") { let section = RadioSection(title: "title", options: [ - OptionRow(title: "Option 1", isSelected: false, action: nil), - OptionRow(title: "Option 2", isSelected: true, action: nil) + OptionRow(text: "Option 1", isSelected: false, action: nil), + OptionRow(text: "Option 2", isSelected: true, action: nil) ]) section.alwaysSelectsOneOption = true @@ -159,15 +159,15 @@ internal final class RadioSectionSpec: QuickSpec { describe("toggle options") { let mock = { RadioSection(title: "Radio", options: [ - OptionRow(title: "Option 1", isSelected: true, action: nil), - OptionRow(title: "Option 2", isSelected: false, action: nil), - OptionRow(title: "Option 3", isSelected: false, action: nil) + 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(title: "", isSelected: true, action: nil) + let option = OptionRow(text: "", isSelected: true, action: nil) let result = section.toggle(option) it("should return an empty index set") { diff --git a/Tests/Model/SectionSpec.swift b/Tests/Model/SectionSpec.swift index e5243497..02473f1a 100644 --- a/Tests/Model/SectionSpec.swift +++ b/Tests/Model/SectionSpec.swift @@ -32,7 +32,7 @@ internal final class SectionSpec: QuickSpec { override func spec() { describe("initialization") { - let row = NavigationRow(title: "", subtitle: .none) + 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" diff --git a/Tests/Row/NavigationRowSpec.swift b/Tests/Row/NavigationRowSpec.swift index 6ba09131..5eedd094 100644 --- a/Tests/Row/NavigationRowSpec.swift +++ b/Tests/Row/NavigationRowSpec.swift @@ -54,10 +54,10 @@ internal final class NavigationRowSpec: QuickSpec { } describe("cellReuseIdentifier") { - let a = NavigationRow(title: "", subtitle: .none) - let b = NavigationRow(title: "", subtitle: .belowTitle("")) - let c = NavigationRow(title: "", subtitle: .rightAligned("")) - let d = NavigationRow(title: "", subtitle: .leftAligned("")) + 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" @@ -69,38 +69,38 @@ internal final class NavigationRowSpec: QuickSpec { describe("equatable") { let image = UIImage() - let a = NavigationRow(title: "Same", subtitle: .belowTitle("Same"), icon: .image(image), action: nil) + let a = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) context("identical parameters") { - let b = NavigationRow(title: "Same", subtitle: .belowTitle("Same"), icon: .image(image), action: nil) + let b = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) it("should be equal") { expect(a) == b } } context("different titles") { - let c = NavigationRow(title: "Different", subtitle: .belowTitle("Same"), icon: .image(image), action: nil) + let c = NavigationRow(text: "Different", detailText: .subtitle("Same"), icon: .image(image), action: nil) it("should not be equal") { expect(a) != c } } context("different subtitles") { - let d = NavigationRow(title: "Same", subtitle: .belowTitle("Different"), icon: .image(image), action: nil) + let d = NavigationRow(text: "Same", detailText: .subtitle("Different"), icon: .image(image), action: nil) it("should not be equal") { expect(a) != d } } context("different icons") { - let e = NavigationRow(title: "Same", subtitle: .belowTitle("Same"), icon: .image(UIImage()), action: nil) + let e = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(UIImage()), action: nil) it("should not be equal") { expect(a) != e } } context("different actions") { - let f = NavigationRow(title: "Same", subtitle: .belowTitle("Same"), icon: .image(image), action: { _ in }) + let f = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: { _ in }) it("should be equal regardless of the actions attached") { expect(a) == f } diff --git a/Tests/Row/OptionRowSpec.swift b/Tests/Row/OptionRowSpec.swift index cd08e865..f4c29888 100644 --- a/Tests/Row/OptionRowSpec.swift +++ b/Tests/Row/OptionRowSpec.swift @@ -62,38 +62,38 @@ internal final class OptionRowSpec: QuickSpec { } describe("equatable") { - let a = OptionRow(title: "Same", isSelected: true, action: nil) + let a = OptionRow(text: "Same", isSelected: true, action: nil) context("identical parameters") { - let b = OptionRow(title: "Same", isSelected: true, action: nil) + let b = OptionRow(text: "Same", isSelected: true, action: nil) it("should be qeaul") { expect(a) == b } } context("different titles") { - let c = OptionRow(title: "Different", isSelected: true, action: nil) + let c = OptionRow(text: "Different", isSelected: true, action: nil) it("should not be eqaul") { expect(a) != c } } context("different selection state") { - let d = OptionRow(title: "Same", isSelected: false, action: nil) + let d = OptionRow(text: "Same", isSelected: false, action: nil) it("should not be equal") { expect(a) != d } } context("different icons") { - let e = OptionRow(title: "Same", isSelected: true, icon: .image(UIImage()), action: nil) + let e = OptionRow(text: "Same", isSelected: true, icon: .image(UIImage()), action: nil) it("should not be equal") { expect(a) != e } } context("different actions") { - let f = OptionRow(title: "Same", isSelected: true, action: { _ in }) + let f = OptionRow(text: "Same", isSelected: true, action: { _ in }) it("should be equal regardless of the actions attached") { expect(a) == f } @@ -103,7 +103,7 @@ internal final class OptionRowSpec: QuickSpec { describe("action invocation") { context("when the selection is toggled") { var invoked = false - let row = OptionRow(title: "", isSelected: false) { _ in invoked = true } + let row = OptionRow(text: "", isSelected: false) { _ in invoked = true } it("should invoke the action closure") { row.isSelected = true @@ -114,7 +114,7 @@ internal final class OptionRowSpec: QuickSpec { context("when the selection stays the same") { var invoked = false - let row = OptionRow(title: "", isSelected: false) { _ in invoked = true } + let row = OptionRow(text: "", isSelected: false) { _ in invoked = true } it("should not invoke the action closure") { row.isSelected = false diff --git a/Tests/Row/SwitchRowSpec.swift b/Tests/Row/SwitchRowSpec.swift index 786382b4..5ffa08f5 100644 --- a/Tests/Row/SwitchRowSpec.swift +++ b/Tests/Row/SwitchRowSpec.swift @@ -33,7 +33,7 @@ internal final class SwitchRowSpec: QuickSpec { override func spec() { describe("initialization") { var invoked = false - let row = SwitchRow(title: "title", switchValue: true) { _ in invoked = true } + let row = SwitchRow(text: "title", switchValue: true) { _ in invoked = true } it("should initialize with given parameters") { expect(row.text) == "title" @@ -50,38 +50,38 @@ internal final class SwitchRowSpec: QuickSpec { } describe("equatable") { - let a = SwitchRow(title: "Same", switchValue: true, action: nil) + let a = SwitchRow(text: "Same", switchValue: true, action: nil) context("identical parameters") { - let b = SwitchRow(title: "Same", switchValue: true, action: nil) + let b = SwitchRow(text: "Same", switchValue: true, action: nil) it("should be qeaul") { expect(a) == b } } context("different titles") { - let c = SwitchRow(title: "Different", switchValue: true, action: nil) + let c = SwitchRow(text: "Different", switchValue: true, action: nil) it("should not be eqaul") { expect(a) != c } } context("different switch values") { - let d = SwitchRow(title: "Same", switchValue: false, action: nil) + let d = SwitchRow(text: "Same", switchValue: false, action: nil) it("should not be equal") { expect(a) != d } } context("different icons") { - let e = SwitchRow(title: "Same", switchValue: true, icon: .image(UIImage()), action: nil) + let e = SwitchRow(text: "Same", switchValue: true, icon: .image(UIImage()), action: nil) it("should not be equal") { expect(a) != e } } context("different actions") { - let f = SwitchRow(title: "Same", switchValue: true, action: { _ in }) + let f = SwitchRow(text: "Same", switchValue: true, action: { _ in }) it("should be equal regardless of the actions attached") { expect(a) == f } @@ -91,7 +91,7 @@ internal final class SwitchRowSpec: QuickSpec { describe("action invocation") { context("when the switch value is changed") { var invoked = false - let row = SwitchRow(title: "", switchValue: false) { _ in invoked = true } + let row = SwitchRow(text: "", switchValue: false) { _ in invoked = true } it("should invoke the action closure") { row.switchValue = true @@ -101,7 +101,7 @@ internal final class SwitchRowSpec: QuickSpec { context("when the switch value stays the same") { var invoked = false - let row = SwitchRow(title: "", switchValue: false) { _ in invoked = true } + let row = SwitchRow(text: "", switchValue: false) { _ in invoked = true } it("should not invoke the action closure") { row.switchValue = false diff --git a/Tests/Row/TapActionRowSpec.swift b/Tests/Row/TapActionRowSpec.swift index 254cc6af..8be381b8 100644 --- a/Tests/Row/TapActionRowSpec.swift +++ b/Tests/Row/TapActionRowSpec.swift @@ -33,7 +33,7 @@ internal final class TapActionRowSpec: QuickSpec { override func spec() { describe("initialization") { var invoked = false - let row = TapActionRow(title: "title") { _ in invoked = true } + let row = TapActionRow(text: "title") { _ in invoked = true } it("should initialize with given parameters") { expect(row.text) == "title" @@ -49,24 +49,24 @@ internal final class TapActionRowSpec: QuickSpec { } describe("equatable") { - let a = TapActionRow(title: "Same", action: nil) + let a = TapActionRow(text: "Same", action: nil) context("identical titles") { - let b = TapActionRow(title: "Same", action: nil) + let b = TapActionRow(text: "Same", action: nil) it("should be equal") { expect(a) == b } } context("different titles") { - let c = TapActionRow(title: "Different", action: nil) + let c = TapActionRow(text: "Different", action: nil) it("should not be equal") { expect(a) != c } } context("different actions") { - let d = TapActionRow(title: "Same", action: { _ in }) + let d = TapActionRow(text: "Same", action: { _ in }) it("should be equal regardless of the actions attached") { expect(a) == d } diff --git a/Tests/View/ConfigurableSpec.swift b/Tests/View/ConfigurableSpec.swift index b33cbccb..98abe10d 100644 --- a/Tests/View/ConfigurableSpec.swift +++ b/Tests/View/ConfigurableSpec.swift @@ -35,7 +35,7 @@ internal final class ConfigurableSpec: QuickSpec { context("default row and cell") { it("should set the switch to true") { let cell = SwitchCell() - let row = SwitchRow(title: "", switchValue: true, action: nil) + let row = SwitchRow(text: "", switchValue: true, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl @@ -48,7 +48,7 @@ internal final class ConfigurableSpec: QuickSpec { it("should set the switch to false") { let cell = SwitchCell() - let row = SwitchRow(title: "", switchValue: false, action: nil) + let row = SwitchRow(text: "", switchValue: false, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl @@ -63,7 +63,7 @@ internal final class ConfigurableSpec: QuickSpec { context("custom row") { it("should set the switch to true") { let cell = SwitchCell() - let row = CustomSwitchRow(title: "", switchValue: true, action: nil) + let row = CustomSwitchRow(text: "", switchValue: true, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl @@ -76,7 +76,7 @@ internal final class ConfigurableSpec: QuickSpec { it("should set the switch to false") { let cell = SwitchCell() - let row = CustomSwitchRow(title: "", switchValue: false, action: nil) + let row = CustomSwitchRow(text: "", switchValue: false, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl @@ -91,7 +91,7 @@ internal final class ConfigurableSpec: QuickSpec { context("custom cell") { it("should set the switch to true") { let cell = CustomSwitchCell() - let row = SwitchRow(title: "", switchValue: true, action: nil) + let row = SwitchRow(text: "", switchValue: true, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl @@ -104,7 +104,7 @@ internal final class ConfigurableSpec: QuickSpec { it("should set the switch to false") { let cell = CustomSwitchCell() - let row = SwitchRow(title: "", switchValue: false, action: nil) + let row = SwitchRow(text: "", switchValue: false, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl @@ -119,7 +119,7 @@ internal final class ConfigurableSpec: QuickSpec { context("custom row and cell") { it("should set the switch to true") { let cell = CustomSwitchCell() - let row = CustomSwitchRow(title: "", switchValue: true, action: nil) + let row = CustomSwitchRow(text: "", switchValue: true, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl @@ -132,7 +132,7 @@ internal final class ConfigurableSpec: QuickSpec { it("should set the switch to false") { let cell = CustomSwitchCell() - let row = CustomSwitchRow(title: "", switchValue: false, action: nil) + let row = CustomSwitchRow(text: "", switchValue: false, action: nil) cell.configure(with: row) #if os(iOS) expect(cell.accessoryView) == cell.switchControl diff --git a/Tests/ViewController/QuickTableViewDataSourceSpec.swift b/Tests/ViewController/QuickTableViewDataSourceSpec.swift index b2cce0ac..e5138380 100644 --- a/Tests/ViewController/QuickTableViewDataSourceSpec.swift +++ b/Tests/ViewController/QuickTableViewDataSourceSpec.swift @@ -53,13 +53,13 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { controller.tableContents = [ Section(title: nil, rows: []), Section(title: nil, rows: [ - NavigationRow(title: "", subtitle: .none), - NavigationRow(title: "", subtitle: .none) + NavigationRow(text: "", detailText: .none), + NavigationRow(text: "", detailText: .none) ]), RadioSection(title: nil, options: []), RadioSection(title: nil, options: [ - OptionRow(title: "", isSelected: false, action: { _ in }), - OptionRow(title: "", isSelected: false, action: { _ in }) + OptionRow(text: "", isSelected: false, action: { _ in }), + OptionRow(text: "", isSelected: false, action: { _ in }) ]) ] it("should return the number of sections") { @@ -113,10 +113,10 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { let controller = QuickTableViewController() controller.tableContents = [ Section(title: "Cell Styles", rows: [ - CustomNavigationRow(title: "CellStyle.default", subtitle: .none), - CustomNavigationRow(title: "CellStyle", subtitle: .belowTitle(".subtitle")), - CustomNavigationRow(title: "CellStyle", subtitle: .rightAligned(".value1")), - CustomNavigationRow(title: "CellStyle", subtitle: .leftAligned(".value2")) + 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)) @@ -157,15 +157,15 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { controller.tableContents = [ Section(title: "NavigationRow", rows: [ - CustomNavigationRow(title: "CellStyle.default", subtitle: .none, icon: .named("icon")), - CustomNavigationRow(title: "CellStyle", subtitle: .belowTitle(".subtitle"), icon: .image(image)), - CustomNavigationRow(title: "CellStyle", subtitle: .rightAligned(".value1"), icon: .images(normal: image, highlighted: highlightedImage)), - CustomNavigationRow(title: "CellStyle", subtitle: .leftAligned(".value2"), icon: .image(image)) + 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(title: "imageName", switchValue: true, icon: .named("icon"), action: nil), - CustomSwitchRow(title: "image", switchValue: true, icon: .image(image), action: nil), - CustomSwitchRow(title: "image + highlightedImage", switchValue: true, icon: .images(normal: image, highlighted: highlightedImage), action: nil) + 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) ]) ] @@ -210,10 +210,10 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { let controller = QuickTableViewController() controller.tableContents = [ Section(title: "Navigation", rows: [ - CustomNavigationRow(title: "", subtitle: .none, action: { _ in }), - CustomNavigationRow(title: "", subtitle: .belowTitle(""), action: { _ in }), - CustomNavigationRow(title: "", subtitle: .rightAligned(""), action: { _ in }), - CustomNavigationRow(title: "", subtitle: .leftAligned(""), action: { _ in }) + CustomNavigationRow(text: "", detailText: .none, action: { _ in }), + CustomNavigationRow(text: "", detailText: .subtitle(""), action: { _ in }), + CustomNavigationRow(text: "", detailText: .value1(""), action: { _ in }), + CustomNavigationRow(text: "", detailText: .value2(""), action: { _ in }) ]) ] @@ -232,10 +232,10 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { let controller = QuickTableViewController() controller.tableContents = [ Section(title: "SwitchRow", rows: [ - SwitchRow(title: "Setting 0", switchValue: true, action: nil), - CustomSwitchRow(title: "Setting 1", switchValue: true, action: nil), - SwitchRow(title: "Setting 2", switchValue: true, action: nil), - CustomSwitchRow(title: "Setting 3", switchValue: true, action: nil) + 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) ]) ] @@ -268,10 +268,10 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { let controller = QuickTableViewController() controller.tableContents = [ Section(title: "TapActionRow", rows: [ - TapActionRow(title: "0", action: { _ in }), - CustomTapActionRow(title: "1", action: { _ in }), - TapActionRow(title: "2", action: { _ in }), - CustomTapActionRow(title: "3", action: { _ in }) + TapActionRow(text: "0", action: { _ in }), + CustomTapActionRow(text: "1", action: { _ in }), + TapActionRow(text: "2", action: { _ in }), + CustomTapActionRow(text: "3", action: { _ in }) ]) ] @@ -296,10 +296,10 @@ internal final class QuickTableViewDataSourceSpec: QuickSpec { let controller = QuickTableViewController() controller.tableContents = [ Section(title: "OptionRow", rows: [ - OptionRow(title: "0", isSelected: true, action: { _ in }), - CustomOptionRow(title: "1", isSelected: true, action: { _ in }), - OptionRow(title: "2", isSelected: true, action: { _ in }), - CustomOptionRow(title: "3", isSelected: true, action: { _ in }) + 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 }) ]) ] diff --git a/Tests/ViewController/QuickTableViewDelegateSpec.swift b/Tests/ViewController/QuickTableViewDelegateSpec.swift index 1c2135f0..404e93f5 100644 --- a/Tests/ViewController/QuickTableViewDelegateSpec.swift +++ b/Tests/ViewController/QuickTableViewDelegateSpec.swift @@ -40,45 +40,45 @@ internal final class QuickTableViewDelegateSpec: QuickSpec { controller.tableContents = [ Section(title: "NavigationRow", rows: [ - NavigationRow(title: "", subtitle: .none), - CustomNavigationRow(title: "", subtitle: .none), - NavigationRow(title: "", subtitle: .none), - CustomNavigationRow(title: "", subtitle: .none) + NavigationRow(text: "", detailText: .none), + CustomNavigationRow(text: "", detailText: .none), + NavigationRow(text: "", detailText: .none), + CustomNavigationRow(text: "", detailText: .none) ]), Section(title: "NavigationRow", rows: [ - NavigationRow(title: "", subtitle: .none, action: { _ in }), - CustomNavigationRow(title: "", subtitle: .none, action: { _ in }), - NavigationRow(title: "", subtitle: .none, action: { _ in }), - CustomNavigationRow(title: "", subtitle: .none, action: { _ in }) + 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(title: "", switchValue: true, action: nil), - CustomSwitchRow(title: "", switchValue: true, action: nil), - SwitchRow(title: "", switchValue: true, action: nil), - CustomSwitchRow(title: "", switchValue: true, action: nil) + 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(title: "", action: { _ in }), - CustomTapActionRow(title: "", action: { _ in }), - TapActionRow(title: "", action: { _ in }), - CustomTapActionRow(title: "", action: { _ in }) + TapActionRow(text: "", action: { _ in }), + CustomTapActionRow(text: "", action: { _ in }), + TapActionRow(text: "", action: { _ in }), + CustomTapActionRow(text: "", action: { _ in }) ]), Section(title: "OptionRow", rows: [ - OptionRow(title: "", isSelected: false, action: nil), - CustomOptionRow(title: "", isSelected: false, action: nil), - OptionRow(title: "", isSelected: false, action: nil), - CustomOptionRow(title: "", isSelected: false, action: nil) + 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(title: "", isSelected: false, action: { _ in }), - CustomOptionRow(title: "", isSelected: false, action: { _ in }), - OptionRow(title: "", isSelected: false, action: { _ in }), - CustomOptionRow(title: "", isSelected: false, action: { _ in }) + OptionRow(text: "", isSelected: false, action: { _ in }), + CustomOptionRow(text: "", isSelected: false, action: { _ in }), + OptionRow(text: "", isSelected: false, action: { _ in }), + CustomOptionRow(text: "", isSelected: false, action: { _ in }) ]) ] @@ -143,10 +143,10 @@ internal final class QuickTableViewDelegateSpec: QuickSpec { controller.tableContents = [ Section(title: "NavigationRow", rows: [ - NavigationRow(title: "", subtitle: .none, action: { _ in selectedIndex = 0 }), - CustomNavigationRow(title: "", subtitle: .none, action: { _ in selectedIndex = 1 }), - NavigationRow(title: "", subtitle: .none, action: { _ in selectedIndex = 2 }), - CustomNavigationRow(title: "", subtitle: .none, action: { _ in selectedIndex = 3 }) + 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 }) ]) ] @@ -165,10 +165,10 @@ internal final class QuickTableViewDelegateSpec: QuickSpec { controller.tableContents = [ Section(title: "TapActionRow", rows: [ - TapActionRow(title: "", action: { _ in selectedIndex = 0 }), - CustomTapActionRow(title: "", action: { _ in selectedIndex = 1 }), - TapActionRow(title: "", action: { _ in selectedIndex = 2 }), - CustomTapActionRow(title: "", action: { _ in selectedIndex = 3 }) + TapActionRow(text: "", action: { _ in selectedIndex = 0 }), + CustomTapActionRow(text: "", action: { _ in selectedIndex = 1 }), + TapActionRow(text: "", action: { _ in selectedIndex = 2 }), + CustomTapActionRow(text: "", action: { _ in selectedIndex = 3 }) ]) ] @@ -186,10 +186,10 @@ internal final class QuickTableViewDelegateSpec: QuickSpec { var toggledIndex = -1 let section = Section(title: "OptionRow", rows: [ - OptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 0 }), - CustomOptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 1 }), - OptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 2 }), - CustomOptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 3 }) + 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] @@ -214,10 +214,10 @@ internal final class QuickTableViewDelegateSpec: QuickSpec { var toggledIndex = -1 let radio = RadioSection(title: "alwaysSelectsOneOption = false", options: [ - OptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 0 }), - CustomOptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 1 }), - OptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 2 }), - CustomOptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 3 }) + 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] @@ -241,10 +241,10 @@ internal final class QuickTableViewDelegateSpec: QuickSpec { var toggledIndex = -1 let radio = RadioSection(title: "alwaysSelectsOneOption = true", options: [ - OptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 0 }), - CustomOptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 1 }), - OptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 2 }), - CustomOptionRow(title: "", isSelected: false, action: { _ in toggledIndex = 3 }) + 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] From 98c19ccadf8ce058e8307cb1ac150aaf57d57a28 Mon Sep 17 00:00:00 2001 From: Ben Date: Tue, 1 Jan 2019 22:46:43 +0000 Subject: [PATCH 26/35] Add tests for the detail text in OptionRow and SwitchRow --- CHANGELOG.md | 1 + Tests/Row/NavigationRowSpec.swift | 26 ++++++++++----------- Tests/Row/OptionRowSpec.swift | 31 +++++++++++++++---------- Tests/Row/SwitchRowSpec.swift | 38 ++++++++++++++++++++----------- Tests/Row/TapActionRowSpec.swift | 16 ++++++------- 5 files changed, 66 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ffe9707..ac09b8ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ * Rename `Row`'s title and subtitle to text and detail text to align with `UITableViewCell`'s naming * `Subtitle` is deprecated and will be removed in **v2.0.0** +* Enable **detailText** in `OptionRow` and `SwitchRow` ## v1.0.0 diff --git a/Tests/Row/NavigationRowSpec.swift b/Tests/Row/NavigationRowSpec.swift index 5eedd094..0420c7dc 100644 --- a/Tests/Row/NavigationRowSpec.swift +++ b/Tests/Row/NavigationRowSpec.swift @@ -69,40 +69,40 @@ internal final class NavigationRowSpec: QuickSpec { describe("equatable") { let image = UIImage() - let a = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) + let row = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) context("identical parameters") { - let b = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) + let this = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: nil) it("should be equal") { - expect(a) == b + expect(this) == row } } - context("different titles") { - let c = NavigationRow(text: "Different", detailText: .subtitle("Same"), icon: .image(image), action: nil) + context("different texts") { + let this = NavigationRow(text: "Different", detailText: .subtitle("Same"), icon: .image(image), action: nil) it("should not be equal") { - expect(a) != c + expect(this) != row } } - context("different subtitles") { - let d = NavigationRow(text: "Same", detailText: .subtitle("Different"), icon: .image(image), action: nil) + context("different detail texts") { + let this = NavigationRow(text: "Same", detailText: .subtitle("Different"), icon: .image(image), action: nil) it("should not be equal") { - expect(a) != d + expect(this) != row } } context("different icons") { - let e = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(UIImage()), action: nil) + let this = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(UIImage()), action: nil) it("should not be equal") { - expect(a) != e + expect(this) != row } } context("different actions") { - let f = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: { _ in }) + let this = NavigationRow(text: "Same", detailText: .subtitle("Same"), icon: .image(image), action: { _ in }) it("should be equal regardless of the actions attached") { - expect(a) == f + expect(this) == row } } } diff --git a/Tests/Row/OptionRowSpec.swift b/Tests/Row/OptionRowSpec.swift index f4c29888..ef46af1e 100644 --- a/Tests/Row/OptionRowSpec.swift +++ b/Tests/Row/OptionRowSpec.swift @@ -62,40 +62,47 @@ internal final class OptionRowSpec: QuickSpec { } describe("equatable") { - let a = OptionRow(text: "Same", isSelected: true, action: nil) + let row = OptionRow(text: "Same", isSelected: true, action: nil) context("identical parameters") { - let b = OptionRow(text: "Same", isSelected: true, action: nil) + let this = OptionRow(text: "Same", isSelected: true, action: nil) it("should be qeaul") { - expect(a) == b + expect(this) == row } } - context("different titles") { - let c = OptionRow(text: "Different", isSelected: true, action: nil) + context("different texts") { + let this = OptionRow(text: "Different", isSelected: true, action: nil) it("should not be eqaul") { - expect(a) != c + 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 d = OptionRow(text: "Same", isSelected: false, action: nil) + let this = OptionRow(text: "Same", isSelected: false, action: nil) it("should not be equal") { - expect(a) != d + expect(this) != row } } context("different icons") { - let e = OptionRow(text: "Same", isSelected: true, icon: .image(UIImage()), action: nil) + let this = OptionRow(text: "Same", isSelected: true, icon: .image(UIImage()), action: nil) it("should not be equal") { - expect(a) != e + expect(this) != row } } context("different actions") { - let f = OptionRow(text: "Same", isSelected: true, action: { _ in }) + let this = OptionRow(text: "Same", isSelected: true, action: { _ in }) it("should be equal regardless of the actions attached") { - expect(a) == f + expect(this) == row } } } diff --git a/Tests/Row/SwitchRowSpec.swift b/Tests/Row/SwitchRowSpec.swift index 5ffa08f5..38533512 100644 --- a/Tests/Row/SwitchRowSpec.swift +++ b/Tests/Row/SwitchRowSpec.swift @@ -32,11 +32,16 @@ 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", switchValue: true) { _ in invoked = true } + 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" @@ -50,40 +55,47 @@ internal final class SwitchRowSpec: QuickSpec { } describe("equatable") { - let a = SwitchRow(text: "Same", switchValue: true, action: nil) + let row = SwitchRow(text: "Same", switchValue: true, action: nil) context("identical parameters") { - let b = SwitchRow(text: "Same", switchValue: true, action: nil) + let this = SwitchRow(text: "Same", switchValue: true, action: nil) it("should be qeaul") { - expect(a) == b + expect(this) == row } } - context("different titles") { - let c = SwitchRow(text: "Different", switchValue: true, action: nil) + context("different texts") { + let this = SwitchRow(text: "Different", switchValue: true, action: nil) it("should not be eqaul") { - expect(a) != c + 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 d = SwitchRow(text: "Same", switchValue: false, action: nil) + let this = SwitchRow(text: "Same", switchValue: false, action: nil) it("should not be equal") { - expect(a) != d + expect(this) != row } } context("different icons") { - let e = SwitchRow(text: "Same", switchValue: true, icon: .image(UIImage()), action: nil) + let this = SwitchRow(text: "Same", switchValue: true, icon: .image(UIImage()), action: nil) it("should not be equal") { - expect(a) != e + expect(this) != row } } context("different actions") { - let f = SwitchRow(text: "Same", switchValue: true, action: { _ in }) + let this = SwitchRow(text: "Same", switchValue: true, action: { _ in }) it("should be equal regardless of the actions attached") { - expect(a) == f + expect(this) == row } } } diff --git a/Tests/Row/TapActionRowSpec.swift b/Tests/Row/TapActionRowSpec.swift index 8be381b8..ff7d6925 100644 --- a/Tests/Row/TapActionRowSpec.swift +++ b/Tests/Row/TapActionRowSpec.swift @@ -49,26 +49,26 @@ internal final class TapActionRowSpec: QuickSpec { } describe("equatable") { - let a = TapActionRow(text: "Same", action: nil) + let row = TapActionRow(text: "Same", action: nil) context("identical titles") { - let b = TapActionRow(text: "Same", action: nil) + let this = TapActionRow(text: "Same", action: nil) it("should be equal") { - expect(a) == b + expect(this) == row } } - context("different titles") { - let c = TapActionRow(text: "Different", action: nil) + context("different texts") { + let this = TapActionRow(text: "Different", action: nil) it("should not be equal") { - expect(a) != c + expect(this) != row } } context("different actions") { - let d = TapActionRow(text: "Same", action: { _ in }) + let this = TapActionRow(text: "Same", action: { _ in }) it("should be equal regardless of the actions attached") { - expect(a) == d + expect(this) == row } } } From 16e6fce3a7f9c9f446f584110b74320f70b01492 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 5 Jan 2019 16:37:20 +0000 Subject: [PATCH 27/35] Add tests for backward compatible initializers --- Source/Model/Deprecated.swift | 7 +-- Tests/Model/SubtitleSpec.swift | 93 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 5 deletions(-) diff --git a/Source/Model/Deprecated.swift b/Source/Model/Deprecated.swift index 6793d67a..fe9bf752 100644 --- a/Source/Model/Deprecated.swift +++ b/Source/Model/Deprecated.swift @@ -5,7 +5,6 @@ // Created by bcylin on 01/01/2019. // Copyright © 2019 bcylin. // -// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights @@ -71,7 +70,6 @@ public extension OptionRow { @available(*, deprecated, message: "Use `init(text:detailText:isSelected:icon:customization:action:)` instead.") public convenience init( title: String, - subtitle: Subtitle? = nil, isSelected: Bool, icon: Icon? = nil, customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, @@ -79,7 +77,7 @@ public extension OptionRow { ) { self.init( text: title, - detailText: subtitle?.detailText, + detailText: nil, isSelected: isSelected, icon: icon, customization: customization, @@ -96,7 +94,6 @@ public extension SwitchRow { @available(*, deprecated, message: "Use `init(text:detailText:switchValue:icon:customization:action:)` instead.") public convenience init( title: String, - subtitle: Subtitle? = nil, switchValue: Bool, icon: Icon? = nil, customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, @@ -104,7 +101,7 @@ public extension SwitchRow { ) { self.init( text: title, - detailText: subtitle?.detailText, + detailText: nil, switchValue: switchValue, icon: icon, customization: customization, diff --git a/Tests/Model/SubtitleSpec.swift b/Tests/Model/SubtitleSpec.swift index 0b088c48..266071c0 100644 --- a/Tests/Model/SubtitleSpec.swift +++ b/Tests/Model/SubtitleSpec.swift @@ -37,6 +37,99 @@ internal final class SubtitleSpec: QuickSpec { 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()) + } + } } } From 5e2eaad759db3bc04aa2496ab87f4decd4e4f7cf Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 5 Jan 2019 20:37:29 +0000 Subject: [PATCH 28/35] Suppress deprecation warnings in the tests --- Tests/Model/SubtitleSpec.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/Model/SubtitleSpec.swift b/Tests/Model/SubtitleSpec.swift index 266071c0..1f9eaadd 100644 --- a/Tests/Model/SubtitleSpec.swift +++ b/Tests/Model/SubtitleSpec.swift @@ -27,6 +27,7 @@ import Nimble import Quick @testable import QuickTableViewController +@available(*, deprecated, message: "Compatibility tests") internal final class SubtitleSpec: QuickSpec { override func spec() { From 44ecf42488b0ab4ae6d28050ea84a3e3a5a7898f Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 5 Jan 2019 17:01:09 +0000 Subject: [PATCH 29/35] Add accessoryButtonAction to NavigationRow --- Source/Rows/NavigationRow.swift | 45 ++++++++++++++++++++- Tests/Row/NavigationRowSpec.swift | 65 +++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 2 deletions(-) diff --git a/Source/Rows/NavigationRow.swift b/Source/Rows/NavigationRow.swift index 793c7959..b8878a52 100644 --- a/Source/Rows/NavigationRow.swift +++ b/Source/Rows/NavigationRow.swift @@ -31,6 +31,28 @@ open class NavigationRow: NavigationRowCompatible, Equatable // MARK: - Initializer + #if os(iOS) + + /// Initializes a `NavigationRow` with a text and a detail text. + /// The icon, customization, action and accessory button action closures are optional. + public init( + text: String, + detailText: DetailText, + icon: Icon? = nil, + customization: ((UITableViewCell, Row & RowStyle) -> Void)? = nil, + action: ((Row) -> Void)? = nil, + accessoryButtonAction: ((Row) -> Void)? = nil + ) { + self.text = text + self.detailText = detailText + self.icon = icon + self.customize = customization + self.action = action + self.accessoryButtonAction = accessoryButtonAction + } + + #elseif os(tvOS) + /// Initializes a `NavigationRow` with a text and a detail text. /// The icon, customization and action closures are optional. public init( @@ -47,6 +69,8 @@ open class NavigationRow: NavigationRowCompatible, Equatable self.action = action } + #endif + // MARK: - Row /// The text of the row. @@ -58,6 +82,13 @@ open class NavigationRow: NavigationRowCompatible, Equatable /// A closure that will be invoked when the row is selected. public let action: ((Row) -> Void)? + #if os(iOS) + + /// A closure that will be invoked when the accessory button is selected. + public let accessoryButtonAction: ((Row) -> Void)? + + #endif + // MARK: - RowStyle /// The type of the table view cell to display the row. @@ -76,9 +107,19 @@ open class NavigationRow: NavigationRowCompatible, Equatable /// The icon of the row. public let icon: Icon? - /// Returns `.disclosureIndicator` when action is not nil, otherwise returns `.none`. + /// Returns the accessory type with the disclosure indicator when `action` is not nil, + /// and with the detail button when `accessoryButtonAction` is not nil. public var accessoryType: UITableViewCell.AccessoryType { - return (action == nil) ? .none : .disclosureIndicator + #if os(iOS) + switch (action, accessoryButtonAction) { + case (nil, nil): return .none + case (.some, nil): return .disclosureIndicator + case (nil, .some): return .detailButton + case (.some, .some): return .detailDisclosureButton + } + #elseif os(tvOS) + return (action == nil) ? .none : .disclosureIndicator + #endif } /// The `NavigationRow` is selectable when action is not nil. diff --git a/Tests/Row/NavigationRowSpec.swift b/Tests/Row/NavigationRowSpec.swift index 0420c7dc..adde1f1a 100644 --- a/Tests/Row/NavigationRowSpec.swift +++ b/Tests/Row/NavigationRowSpec.swift @@ -31,6 +31,39 @@ import Quick 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") @@ -53,6 +86,8 @@ internal final class NavigationRowSpec: QuickSpec { } } +#endif + describe("cellReuseIdentifier") { let a = NavigationRow(text: "", detailText: .none) let b = NavigationRow(text: "", detailText: .subtitle("")) @@ -67,6 +102,36 @@ internal final class NavigationRowSpec: QuickSpec { } } + #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) From 7a1bd3dae0128316b7099eb68765db0d6c3bfcfc Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 5 Jan 2019 17:11:09 +0000 Subject: [PATCH 30/35] Implement tableView(_:accessoryButtonTappedForRowWith:) --- Source/Protocol/RowCompatible.swift | 7 ++++- Source/QuickTableViewController.swift | 11 ++++++++ .../QuickTableViewDelegateSpec.swift | 28 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/Source/Protocol/RowCompatible.swift b/Source/Protocol/RowCompatible.swift index 95826f5c..69a08169 100644 --- a/Source/Protocol/RowCompatible.swift +++ b/Source/Protocol/RowCompatible.swift @@ -27,7 +27,12 @@ import Foundation /// This protocol defines the compatible interface of a `NavigationRow` regardless of its associated cell type. -public protocol NavigationRowCompatible: Row, RowStyle {} +public protocol NavigationRowCompatible: Row, RowStyle { + #if os(iOS) + /// A closure that will be invoked when the accessory button is selected. + var accessoryButtonAction: ((Row) -> Void)? { get } + #endif +} /// This protocol defines the compatible interface of a `TapActionRow` regardless of its associated cell type. diff --git a/Source/QuickTableViewController.swift b/Source/QuickTableViewController.swift index e413d76e..1b4183e8 100644 --- a/Source/QuickTableViewController.swift +++ b/Source/QuickTableViewController.swift @@ -165,6 +165,17 @@ open class QuickTableViewController: UIViewController, UITableViewDataSource, UI } } + #if os(iOS) + public func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) { + switch tableContents[indexPath.section].rows[indexPath.row] { + case let row as NavigationRowCompatible: + row.accessoryButtonAction?(row) + default: + break + } + } + #endif + } diff --git a/Tests/ViewController/QuickTableViewDelegateSpec.swift b/Tests/ViewController/QuickTableViewDelegateSpec.swift index 404e93f5..14e59812 100644 --- a/Tests/ViewController/QuickTableViewDelegateSpec.swift +++ b/Tests/ViewController/QuickTableViewDelegateSpec.swift @@ -264,6 +264,34 @@ internal final class QuickTableViewDelegateSpec: QuickSpec { } } } + + #if os(iOS) + + // 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)) + } + } + } + + #endif + } } From f3e351be6dd3f0badab9111f552f0672d74eab3a Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 5 Jan 2019 18:17:41 +0000 Subject: [PATCH 31/35] Update the example with accessoryButtonAction --- CHANGELOG.md | 1 + ...troller.swift => ExampleViewController.swift} | 6 +++--- .../ViewControllers/RootViewController.swift | 2 +- Example-iOSUITests/ExampleUITests.swift | 5 +++++ Example-tvOS/AppDelegate.swift | 2 +- ...troller.swift => ExampleViewController.swift} | 4 ++-- .../project.pbxproj | 16 ++++++++-------- 7 files changed, 21 insertions(+), 15 deletions(-) rename Example-iOS/ViewControllers/{DefaultViewController.swift => ExampleViewController.swift} (96%) rename Example-tvOS/{TableViewController.swift => ExampleViewController.swift} (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac09b8ca..8cdde10b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ * Rename `Row`'s title and subtitle to text and detail text to align with `UITableViewCell`'s naming * `Subtitle` is deprecated and will be removed in **v2.0.0** * Enable **detailText** in `OptionRow` and `SwitchRow` +* Add **accessoryButtonAction** to `NavigationRow` ## v1.0.0 diff --git a/Example-iOS/ViewControllers/DefaultViewController.swift b/Example-iOS/ViewControllers/ExampleViewController.swift similarity index 96% rename from Example-iOS/ViewControllers/DefaultViewController.swift rename to Example-iOS/ViewControllers/ExampleViewController.swift index e604fad1..d9c32b41 100644 --- a/Example-iOS/ViewControllers/DefaultViewController.swift +++ b/Example-iOS/ViewControllers/ExampleViewController.swift @@ -1,5 +1,5 @@ // -// DefaultViewController.swift +// ExampleViewController.swift // Example-iOS // // Created by Ben on 01/09/2015. @@ -27,7 +27,7 @@ import UIKit import QuickTableViewController -internal final class DefaultViewController: QuickTableViewController { +internal final class ExampleViewController: QuickTableViewController { // MARK: - Properties @@ -55,7 +55,7 @@ internal final class DefaultViewController: QuickTableViewController { Section(title: "Navigation", rows: [ NavigationRow(text: "CellStyle.default", detailText: .none, icon: .image(gear)), - NavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), icon: .image(globe)), + NavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), icon: .image(globe), accessoryButtonAction: showDetail()), NavigationRow(text: "CellStyle", detailText: .value1(".value1"), icon: .image(time), action: showDetail()), NavigationRow(text: "CellStyle", detailText: .value2(".value2")) ], footer: "UITableViewCellStyle.Value2 hides the image view."), diff --git a/Example-iOS/ViewControllers/RootViewController.swift b/Example-iOS/ViewControllers/RootViewController.swift index 8b7cdb77..1bcb8a9e 100644 --- a/Example-iOS/ViewControllers/RootViewController.swift +++ b/Example-iOS/ViewControllers/RootViewController.swift @@ -41,7 +41,7 @@ internal final class RootViewController: QuickTableViewController { tableContents = [ Section(title: "Default", rows: [ NavigationRow(text: "Use default cell types", detailText: .none, action: { [weak self] _ in - self?.navigationController?.pushViewController(DefaultViewController(), animated: true) + self?.navigationController?.pushViewController(ExampleViewController(), animated: true) }) ]), diff --git a/Example-iOSUITests/ExampleUITests.swift b/Example-iOSUITests/ExampleUITests.swift index 74a17b02..310aafd6 100644 --- a/Example-iOSUITests/ExampleUITests.swift +++ b/Example-iOSUITests/ExampleUITests.swift @@ -68,6 +68,11 @@ internal final class ExampleUITests: XCTestCase { return false } + tables.cells.containing(.staticText, identifier: ".subtitle").buttons["More Info"].tap() + app.navigationBars.buttons.element(boundBy: 0).tap() + expectation(for: existance, evaluatedWith: tables.staticTexts["CellStyle.subtitle is selected"], handler: nil) + waitForExpectations(timeout: 5, handler: nil) + tables.staticTexts[".value1"].tap() app.navigationBars.buttons.element(boundBy: 0).tap() expectation(for: existance, evaluatedWith: tables.staticTexts["CellStyle.value1 is selected"], handler: nil) diff --git a/Example-tvOS/AppDelegate.swift b/Example-tvOS/AppDelegate.swift index 112ea76f..28ab4ac7 100644 --- a/Example-tvOS/AppDelegate.swift +++ b/Example-tvOS/AppDelegate.swift @@ -33,7 +33,7 @@ internal final class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { window = UIWindow(frame: UIScreen.main.bounds) - window?.rootViewController = UINavigationController(rootViewController: TableViewController()) + window?.rootViewController = UINavigationController(rootViewController: ExampleViewController()) window?.makeKeyAndVisible() return true } diff --git a/Example-tvOS/TableViewController.swift b/Example-tvOS/ExampleViewController.swift similarity index 97% rename from Example-tvOS/TableViewController.swift rename to Example-tvOS/ExampleViewController.swift index 5f304f04..be0323c3 100644 --- a/Example-tvOS/TableViewController.swift +++ b/Example-tvOS/ExampleViewController.swift @@ -1,5 +1,5 @@ // -// TableViewController.swift +// ExampleViewController.swift // Example-tvOS // // Created by Ben on 19/04/2018. @@ -27,7 +27,7 @@ import UIKit import QuickTableViewController -internal final class TableViewController: QuickTableViewController { +internal final class ExampleViewController: QuickTableViewController { override func viewDidLoad() { super.viewDidLoad() diff --git a/QuickTableViewController.xcodeproj/project.pbxproj b/QuickTableViewController.xcodeproj/project.pbxproj index 66c7ce8f..e7a61a3d 100644 --- a/QuickTableViewController.xcodeproj/project.pbxproj +++ b/QuickTableViewController.xcodeproj/project.pbxproj @@ -22,7 +22,7 @@ A7A26A71AB271F9D402D1A12 /* Pods_Example_iOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF3454E57819285B32968564 /* Pods_Example_iOS.framework */; }; B50E73851F2E1BC900481910 /* RowStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B50E73841F2E1BC900481910 /* RowStyle.swift */; }; B51F21A51F417037009BC2C9 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51F21A41F417037009BC2C9 /* AppDelegate.swift */; }; - B51F21A71F417037009BC2C9 /* DefaultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51F21A61F417037009BC2C9 /* DefaultViewController.swift */; }; + B51F21A71F417037009BC2C9 /* ExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51F21A61F417037009BC2C9 /* ExampleViewController.swift */; }; B51F21AC1F417037009BC2C9 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B51F21AB1F417037009BC2C9 /* Assets.xcassets */; }; B51F21B61F41709B009BC2C9 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = B51F21B41F41709B009BC2C9 /* LaunchScreen.xib */; }; B51F21C31F41E600009BC2C9 /* ExampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51F21C21F41E600009BC2C9 /* ExampleUITests.swift */; }; @@ -54,7 +54,7 @@ B54A244D208883A300EEBA26 /* TapActionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B595627A1B9758BC00D6DAB1 /* TapActionCell.swift */; }; B54A244E208883A300EEBA26 /* QuickTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5334F2F1B8CC6AA00C64A6D /* QuickTableViewController.swift */; }; B54A24562088D44A00EEBA26 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54A24552088D44A00EEBA26 /* AppDelegate.swift */; }; - B54A24582088D44A00EEBA26 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54A24572088D44A00EEBA26 /* TableViewController.swift */; }; + B54A24582088D44A00EEBA26 /* ExampleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54A24572088D44A00EEBA26 /* ExampleViewController.swift */; }; B54A245D2088D44D00EEBA26 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B54A245C2088D44D00EEBA26 /* Assets.xcassets */; }; B55475751F2DC3C00027F7C1 /* Configurable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55475741F2DC3C00027F7C1 /* Configurable.swift */; }; B578B5091C5673240021F7C3 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = B578B5071C5673240021F7C3 /* icon.png */; }; @@ -193,7 +193,7 @@ 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 = ""; }; - B51F21A61F417037009BC2C9 /* DefaultViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultViewController.swift; sourceTree = ""; }; + B51F21A61F417037009BC2C9 /* ExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleViewController.swift; sourceTree = ""; }; B51F21AB1F417037009BC2C9 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B51F21B01F417037009BC2C9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; B51F21B51F41709B009BC2C9 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; @@ -218,7 +218,7 @@ B54A24352088816E00EEBA26 /* Info-tvOSTests.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tvOSTests.plist"; sourceTree = ""; }; B54A24532088D44A00EEBA26 /* Example-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Example-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; B54A24552088D44A00EEBA26 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - B54A24572088D44A00EEBA26 /* TableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewController.swift; sourceTree = ""; }; + B54A24572088D44A00EEBA26 /* ExampleViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleViewController.swift; sourceTree = ""; }; B54A245C2088D44D00EEBA26 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; B54A245E2088D44D00EEBA26 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; B55475741F2DC3C00027F7C1 /* Configurable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Configurable.swift; sourceTree = ""; }; @@ -527,8 +527,8 @@ children = ( B54A24552088D44A00EEBA26 /* AppDelegate.swift */, B54A245C2088D44D00EEBA26 /* Assets.xcassets */, + B54A24572088D44A00EEBA26 /* ExampleViewController.swift */, B54A245E2088D44D00EEBA26 /* Info.plist */, - B54A24572088D44A00EEBA26 /* TableViewController.swift */, ); path = "Example-tvOS"; sourceTree = ""; @@ -571,7 +571,7 @@ children = ( B5A37EAD20208EF7009C075F /* AppearanceViewController.swift */, B5A67A1120205F5C0075E0C8 /* CustomizationViewController.swift */, - B51F21A61F417037009BC2C9 /* DefaultViewController.swift */, + B51F21A61F417037009BC2C9 /* ExampleViewController.swift */, B5A67A13202069440075E0C8 /* RootViewController.swift */, ); path = ViewControllers; @@ -1106,7 +1106,7 @@ B51F21A51F417037009BC2C9 /* AppDelegate.swift in Sources */, B5A37EAE20208EF7009C075F /* AppearanceViewController.swift in Sources */, B5A67A1220205F5C0075E0C8 /* CustomizationViewController.swift in Sources */, - B51F21A71F417037009BC2C9 /* DefaultViewController.swift in Sources */, + B51F21A71F417037009BC2C9 /* ExampleViewController.swift in Sources */, B5A67A14202069440075E0C8 /* RootViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1218,7 +1218,7 @@ buildActionMask = 2147483647; files = ( B54A24562088D44A00EEBA26 /* AppDelegate.swift in Sources */, - B54A24582088D44A00EEBA26 /* TableViewController.swift in Sources */, + B54A24582088D44A00EEBA26 /* ExampleViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From f5b00a7c8c2d87e9d6b7d1ff8033b29cc0773a75 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 5 Jan 2019 21:01:05 +0000 Subject: [PATCH 32/35] Bump version to 1.1.0 --- .jazzy.yml | 2 +- Example-iOS/Info.plist | 2 +- Example-iOSUITests/Info.plist | 2 +- Example-tvOS/Info.plist | 2 +- Example-tvOSUITests/Info.plist | 2 +- QuickTableViewController.podspec | 2 +- QuickTableViewController/Info-iOS.plist | 2 +- QuickTableViewController/Info-iOSTests.plist | 2 +- QuickTableViewController/Info-tvOS.plist | 2 +- QuickTableViewController/Info-tvOSTests.plist | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.jazzy.yml b/.jazzy.yml index 8e85c336..3c1516eb 100644 --- a/.jazzy.yml +++ b/.jazzy.yml @@ -5,7 +5,7 @@ github_url: https://github.com/bcylin/QuickTableViewController github_file_prefix: https://github.com/bcylin/QuickTableViewController/blob/develop xcodebuild_arguments: [-project, QuickTableViewController.xcodeproj, -scheme, QuickTableViewController-iOS] module: QuickTableViewController -module_version: 1.0.0 +module_version: 1.1.0 output: docs/output theme: fullwidth skip_undocumented: true diff --git a/Example-iOS/Info.plist b/Example-iOS/Info.plist index 03f6f462..e2267da0 100644 --- a/Example-iOS/Info.plist +++ b/Example-iOS/Info.plist @@ -17,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleVersion 101 LSRequiresIPhoneOS diff --git a/Example-iOSUITests/Info.plist b/Example-iOSUITests/Info.plist index d02c62e0..81ba60ed 100644 --- a/Example-iOSUITests/Info.plist +++ b/Example-iOSUITests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleVersion 1 diff --git a/Example-tvOS/Info.plist b/Example-tvOS/Info.plist index 7d1408b7..3864dbac 100644 --- a/Example-tvOS/Info.plist +++ b/Example-tvOS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleVersion 101 LSRequiresIPhoneOS diff --git a/Example-tvOSUITests/Info.plist b/Example-tvOSUITests/Info.plist index 6c40a6cd..af63fea5 100644 --- a/Example-tvOSUITests/Info.plist +++ b/Example-tvOSUITests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.0 + 1.1.0 CFBundleVersion 1 diff --git a/QuickTableViewController.podspec b/QuickTableViewController.podspec index 48f13465..5d4e711a 100644 --- a/QuickTableViewController.podspec +++ b/QuickTableViewController.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "QuickTableViewController" - s.version = "1.0.0" + s.version = "1.1.0" s.summary = "A simple way to create a UITableView for settings." s.screenshots = "https://bcylin.github.io/QuickTableViewController/img/screenshot-1.png", "https://bcylin.github.io/QuickTableViewController/img/screenshot-2.png" diff --git a/QuickTableViewController/Info-iOS.plist b/QuickTableViewController/Info-iOS.plist index 60b9c008..09bc9720 100644 --- a/QuickTableViewController/Info-iOS.plist +++ b/QuickTableViewController/Info-iOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleSignature ???? CFBundleVersion diff --git a/QuickTableViewController/Info-iOSTests.plist b/QuickTableViewController/Info-iOSTests.plist index a30f7d0e..3b9aa4a6 100644 --- a/QuickTableViewController/Info-iOSTests.plist +++ b/QuickTableViewController/Info-iOSTests.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleSignature ???? CFBundleVersion diff --git a/QuickTableViewController/Info-tvOS.plist b/QuickTableViewController/Info-tvOS.plist index 4c0d2186..a5ae6f94 100644 --- a/QuickTableViewController/Info-tvOS.plist +++ b/QuickTableViewController/Info-tvOS.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleVersion $(CURRENT_PROJECT_VERSION) NSPrincipalClass diff --git a/QuickTableViewController/Info-tvOSTests.plist b/QuickTableViewController/Info-tvOSTests.plist index 5218a30c..af63fea5 100644 --- a/QuickTableViewController/Info-tvOSTests.plist +++ b/QuickTableViewController/Info-tvOSTests.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 1.0.0 + 1.1.0 CFBundleVersion 1 From 90b410ecd1316720b062c9d27e1b3091f881e639 Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 6 Jan 2019 12:14:03 +0000 Subject: [PATCH 33/35] Update README.md [ci skip] --- CHANGELOG.md | 4 +- README.md | 66 ++++++++++++++++++++------------- Source/Rows/NavigationRow.swift | 4 +- 3 files changed, 46 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cdde10b..3f20b7b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,10 @@ #### Enhancements +* Swift 4.2, [#20](https://github.com/bcylin/QuickTableViewController/pull/20) by [@getaaron](https://github.com/getaaron) and [#28](https://github.com/bcylin/QuickTableViewController/pull/28) by [@ mttcrsp](https://github.com/mttcrsp) +* tvOS UI tests, [#27](https://github.com/bcylin/QuickTableViewController/pull/27) by [@FraDeliro](https://github.com/FraDeliro) +* `Subtitle` is deprecated and will be removed in [**v2.0.0**](https://github.com/bcylin/QuickTableViewController/releases/tag/v2.0.0) * Rename `Row`'s title and subtitle to text and detail text to align with `UITableViewCell`'s naming -* `Subtitle` is deprecated and will be removed in **v2.0.0** * Enable **detailText** in `OptionRow` and `SwitchRow` * Add **accessoryButtonAction** to `NavigationRow` diff --git a/README.md b/README.md index ad7cd1a1..8a47e247 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ A simple way to create a table view for settings, including: * Table view cells with center aligned text for tap actions * A section that provides mutually exclusive options * Actions performed when the row reacts to the user interaction -* Customizable table view cell image, cell style and accessory type +* Easy to specify table view cell image, cell style and accessory type @@ -24,7 +24,7 @@ Set up `tableContents` in `viewDidLoad`: ```swift import QuickTableViewController -class ViewController: QuickTableViewController { +final class ViewController: QuickTableViewController { override func viewDidLoad() { super.viewDidLoad() @@ -32,7 +32,7 @@ class ViewController: QuickTableViewController { tableContents = [ Section(title: "Switch", rows: [ SwitchRow(text: "Setting 1", switchValue: true, action: { _ in }), - SwitchRow(text: "Setting 2", switchValue: false, action: { _ in }), + SwitchRow(text: "Setting 2", switchValue: false, action: { _ in }) ]), Section(title: "Tap Action", rows: [ @@ -40,16 +40,16 @@ class ViewController: QuickTableViewController { ]), Section(title: "Navigation", rows: [ - NavigationRow(text: "CellStyle.default", subtitle: .none, icon: .named("gear")), + NavigationRow(text: "CellStyle.default", detailText: .none, icon: .named("gear")), NavigationRow(text: "CellStyle", detailText: .subtitle(".subtitle"), icon: .named("globe")), - NavigationRow(text: "CellStyle", subtitle: .rightAligned(".value1"), icon: .named("time"), action: { _ in }), - NavigationRow(text: "CellStyle", subtitle: .leftAligned(".value2")) - ]), + NavigationRow(text: "CellStyle", detailText: .value1(".value1"), icon: .named("time"), action: { _ in }), + NavigationRow(text: "CellStyle", detailText: .value2(".value2")) + ], footer: "UITableViewCellStyle.Value2 hides the image view."), RadioSection(title: "Radio Buttons", options: [ - OptionRow(text: "Option 1", isSelected: true, action: didToggleOption()), - OptionRow(text: "Option 2", isSelected: false, action: didToggleOption()), - OptionRow(text: "Option 3", isSelected: false, action: didToggleOption()) + OptionRow(text: "Option 1", isSelected: true, action: didToggleSelection()), + OptionRow(text: "Option 2", isSelected: false, action: didToggleSelection()), + OptionRow(text: "Option 3", isSelected: false, action: didToggleSelection()) ], footer: "See RadioSection for more details.") ] } @@ -60,7 +60,7 @@ class ViewController: QuickTableViewController { // ... } - private func didToggleOption() -> (Row) -> Void { + private func didToggleSelection() -> (Row) -> Void { return { [weak self] row in // ... } @@ -71,19 +71,34 @@ class ViewController: QuickTableViewController { ### NavigationRow -#### Subtitle Styles +#### Detail Text Styles ```swift -NavigationRow(text: "UITableViewCellStyle.default", subtitle: .none) +NavigationRow(text: "UITableViewCellStyle.default", detailText: .none) NavigationRow(text: "UITableViewCellStyle", detailText: .subtitle(".subtitle") -NavigationRow(text: "UITableViewCellStyle", subtitle: .rightAligned(".value1") -NavigationRow(text: "UITableViewCellStyle", subtitle: .leftAligned(".value2")) +NavigationRow(text: "UITableViewCellStyle", detailText: .value1(".value1") +NavigationRow(text: "UITableViewCellStyle", detailText: .value2(".value2")) ``` -#### Disclosure Indicator +[`Subtitle`](https://github.com/bcylin/QuickTableViewController/blob/develop/Source/Model/Subtitle.swift) and the [initializers with title/subtitle](https://github.com/bcylin/QuickTableViewController/blob/develop/Source/Model/Deprecated.swift) are deprecated and will be removed in **v2.0.0**. + +#### Accessory Type + +* The `NavigationRow` shows with different accessory types based on the `action` and `accessoryButtonAction` closures: + +```swift +var accessoryType: UITableViewCell.AccessoryType { + switch (action, accessoryButtonAction) { + case (nil, nil): return .none + case (.some, nil): return .disclosureIndicator + case (nil, .some): return .detailButton + case (.some, .some): return .detailDisclosureButton + } +} +``` -* A `NavigationRow` with an `action` will be displayed in a table view cell with `.disclosureIndicator`. * The `action` will be invoked when the table view cell is selected. +* The `accessoryButtonAction` will be invoked when the accessory button is selected. #### Images @@ -102,32 +117,31 @@ enum Icon { * A `SwitchRow` is representing a table view cell with a `UISwitch` as its `accessoryView`. * The `action` will be invoked when the switch value changes. -* The subtitle is disabled in `SwitchRow `. ### TapActionRow * A `TapActionRow` is representing a button-like table view cell. * The `action` will be invoked when the table view cell is selected. -* The icon and subtitle are disabled in `TapActionRow`. +* The icon, detail text, and accessory type are disabled in `TapActionRow`. ### OptionRow * An `OptionRow` is representing a table view cell with `.checkmark`. -* The subtitle is disabled in `OptionRow`. * The `action` will be invoked when the selected state is toggled. ```swift -let didToggleOption: (Row) -> Void = { [weak self] in +let didToggleSelection: (Row) -> Void = { [weak self] in if let option = $0 as? OptionRowCompatible, option.isSelected { - // to exclude the option that's toggled off + // to exclude the event where the option is toggled off } } ``` ### RadioSection -* `OptionRow` can be used with or without `RadioSection`, which allows only one selected option. +* `RadioSection` allows only one selected option at a time. * Setting `alwaysSelectsOneOption` to true will keep one of the options selected. +* `OptionRow` can also be used with `Section` for multiple selections. ## Customization @@ -146,7 +160,7 @@ A customized table view cell type can be specified to rows during initialization ```swift // Default is UITableViewCell. -NavigationRow(text: "Navigation", subtitle: .none) +NavigationRow(text: "Navigation", detailText: .none) // Default is SwitchCell. SwitchRow(text: "Switch", switchValue: true, action: { _ in }) @@ -193,7 +207,7 @@ protocol RowStyle { } ``` -The `customize` closure overwrites the `Configurable` setup. +The `customize` closure [overwrites](https://github.com/bcylin/QuickTableViewController/blob/develop/Source/QuickTableViewController.swift#L104-L109) the `Configurable` setup. ### UIAppearance @@ -203,6 +217,7 @@ As discussed in issue [#12](https://github.com/bcylin/QuickTableViewController/i * `UISwitch` is replaced by a checkmark in `SwitchCell`. * `TapActionCell` does not use center aligned text. +* `NavigationRow.accessoryButtonAction` is not available. * Cell image view's left margin is 0. ## Limitation @@ -236,6 +251,7 @@ QuickTableViewController | iOS | tvOS | Xcode | Swift `~> 0.8.0` | 8.0+ | - | 9.1 | 4.0 `~> 0.9.0` | 8.0+ | - | 9.3 | 4.1 `~> 1.0.0` | 8.0+ | 9.0+ | 9.4 | 4.1 +`~> 1.1.0` | 8.0+ | 9.0+ | 10.1 | 4.2 ## Installation diff --git a/Source/Rows/NavigationRow.swift b/Source/Rows/NavigationRow.swift index b8878a52..39ab847d 100644 --- a/Source/Rows/NavigationRow.swift +++ b/Source/Rows/NavigationRow.swift @@ -33,7 +33,7 @@ open class NavigationRow: NavigationRowCompatible, Equatable #if os(iOS) - /// Initializes a `NavigationRow` with a text and a detail text. + /// Designated initializer on iOS. Returns a `NavigationRow` with a text and a detail text. /// The icon, customization, action and accessory button action closures are optional. public init( text: String, @@ -53,7 +53,7 @@ open class NavigationRow: NavigationRowCompatible, Equatable #elseif os(tvOS) - /// Initializes a `NavigationRow` with a text and a detail text. + /// Designated initializer on tvOS. Returns a `NavigationRow` with a text and a detail text. /// The icon, customization and action closures are optional. public init( text: String, From 5f9ac87e93768a94d2e5658905255eceae78046c Mon Sep 17 00:00:00 2001 From: Ben Date: Sun, 6 Jan 2019 12:14:17 +0000 Subject: [PATCH 34/35] Use Xcode 10.1 on Travis CI --- .travis.yml | 2 +- .../xcshareddata/xcschemes/Example-iOS.xcscheme | 2 +- .../xcshareddata/xcschemes/Example-tvOS.xcscheme | 2 +- .../xcschemes/QuickTableViewController-iOS.xcscheme | 2 +- .../xcschemes/QuickTableViewController-tvOS.xcscheme | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4b2e59cc..83798de6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,5 @@ language: objective-c -osx_image: xcode10 +osx_image: xcode10.1 cache: - bundler - cocoapods diff --git a/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme b/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme index fae8fcd3..d39fbe59 100644 --- a/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme +++ b/QuickTableViewController.xcodeproj/xcshareddata/xcschemes/Example-iOS.xcscheme @@ -1,6 +1,6 @@ Date: Sun, 6 Jan 2019 09:38:54 +0000 Subject: [PATCH 35/35] Update Makefile for tests --- .travis.yml | 2 +- Makefile | 21 +++++++++++++-------- scripts/{update-docs.sh => push-docs.sh} | 0 3 files changed, 14 insertions(+), 9 deletions(-) rename scripts/{update-docs.sh => push-docs.sh} (100%) diff --git a/.travis.yml b/.travis.yml index 83798de6..984479e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ script: - make -B carthage - make -B docs after_success: - - sh scripts/update-docs.sh + - sh scripts/push-docs.sh notifications: email: false slack: diff --git a/Makefile b/Makefile index 3506e051..2f6a34d3 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,18 @@ default: test -test: - xcodebuild clean build -workspace QuickTableViewController.xcworkspace -scheme QuickTableViewController-iOS -sdk iphonesimulator SWIFT_VERSION=3.0 | bundle exec xcpretty -c - bundle exec rake "test:ios[QuickTableViewController-iOS]" - bundle exec rake "test:tvos[QuickTableViewController-tvOS]" - bundle exec rake "test:ios[Example-iOS]" - bundle exec rake "build:tvos[Example-tvOS]" - -ci-test: test +test: unit-test ui-test + +unit-test: + bundle exec rake \ + "test:ios[QuickTableViewController-iOS]" \ + "test:tvos[QuickTableViewController-tvOS]" \ + +ui-test: + bundle exec rake \ + "test:ios[Example-iOS]" \ + "test:tvos[Example-tvOS]" + +ci-test: unit-test ui-test make -B carthage make -B docs diff --git a/scripts/update-docs.sh b/scripts/push-docs.sh similarity index 100% rename from scripts/update-docs.sh rename to scripts/push-docs.sh