diff --git a/CleanStore.xcodeproj/project.pbxproj b/CleanStore.xcodeproj/project.pbxproj index 181c085..c4b2507 100644 --- a/CleanStore.xcodeproj/project.pbxproj +++ b/CleanStore.xcodeproj/project.pbxproj @@ -391,14 +391,16 @@ attributes = { LastSwiftMigration = 0700; LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = "Raymond Law"; TargetAttributes = { 710475311B882CA000D72E3C = { CreatedOnToolsVersion = 6.4; + LastSwiftMigration = 0800; }; 710475461B882CA000D72E3C = { CreatedOnToolsVersion = 6.4; + LastSwiftMigration = 0800; TestTargetID = 710475311B882CA000D72E3C; }; }; @@ -546,8 +548,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -591,8 +595,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -611,6 +617,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -620,9 +627,11 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = CleanStore/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.clean-swift.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -631,9 +640,11 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; INFOPLIST_FILE = CleanStore/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.clean-swift.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -650,6 +661,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.clean-swift.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CleanStore.app/CleanStore"; }; name = Debug; @@ -663,6 +675,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.clean-swift.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CleanStore.app/CleanStore"; }; name = Release; diff --git a/CleanStore.xcodeproj/xcshareddata/xcschemes/CleanStore.xcscheme b/CleanStore.xcodeproj/xcshareddata/xcschemes/CleanStore.xcscheme index 4aedc95..1200a84 100644 --- a/CleanStore.xcodeproj/xcshareddata/xcschemes/CleanStore.xcscheme +++ b/CleanStore.xcodeproj/xcshareddata/xcschemes/CleanStore.xcscheme @@ -1,6 +1,6 @@ Bool + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - func applicationWillResignActive(application: UIApplication) + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/CleanStore/Base.lproj/Main.storyboard b/CleanStore/Base.lproj/Main.storyboard index 96932cb..541c885 100644 --- a/CleanStore/Base.lproj/Main.storyboard +++ b/CleanStore/Base.lproj/Main.storyboard @@ -1,8 +1,9 @@ - + - + + @@ -12,7 +13,7 @@ - + @@ -20,17 +21,15 @@ - + - @@ -54,17 +53,15 @@ - + - @@ -88,17 +85,15 @@ - + - @@ -122,17 +117,15 @@ - + - @@ -160,17 +153,15 @@ - + - @@ -194,17 +185,15 @@ - + - @@ -228,17 +217,15 @@ - + - @@ -262,17 +249,15 @@ - + - @@ -296,17 +281,15 @@ - + - @@ -334,17 +317,15 @@ - + - @@ -372,17 +353,15 @@ - + - @@ -406,17 +385,15 @@ - + - @@ -440,17 +417,15 @@ - + - @@ -478,18 +453,15 @@ - + - - - + @@ -503,17 +475,15 @@ - + - @@ -537,17 +507,15 @@ - + - @@ -571,17 +539,15 @@ - + - @@ -605,17 +571,15 @@ - + - @@ -639,17 +603,15 @@ - + - @@ -727,36 +689,36 @@ - + - + - + - + - + @@ -792,41 +754,35 @@ - + - - + + - - @@ -871,7 +821,7 @@ - + diff --git a/CleanStore/Models/ManagedOrder+CoreDataProperties.swift b/CleanStore/Models/ManagedOrder+CoreDataProperties.swift index 0f705ba..4825e0d 100644 --- a/CleanStore/Models/ManagedOrder+CoreDataProperties.swift +++ b/CleanStore/Models/ManagedOrder+CoreDataProperties.swift @@ -14,7 +14,7 @@ import CoreData extension ManagedOrder { - @NSManaged var date: NSDate? + @NSManaged var date: Date? @NSManaged var email: String? @NSManaged var firstName: String? @NSManaged var id: String? diff --git a/CleanStore/Models/Order.swift b/CleanStore/Models/Order.swift index 2c95c72..bf3bce0 100644 --- a/CleanStore/Models/Order.swift +++ b/CleanStore/Models/Order.swift @@ -3,7 +3,7 @@ import Foundation struct Order: Equatable { var id: String? - var date: NSDate? + var date: Date? var email: String? var firstName: String? var lastName: String? @@ -13,8 +13,8 @@ struct Order: Equatable func ==(lhs: Order, rhs: Order) -> Bool { var dateEqual = false - if let lhsDate = lhs.date, rhsDate = rhs.date { - dateEqual = lhsDate.timeIntervalSinceDate(rhsDate) < 1.0 + if let lhsDate = lhs.date, let rhsDate = rhs.date { + dateEqual = lhsDate.timeIntervalSince(rhsDate) < 1.0 } return lhs.id == rhs.id && dateEqual diff --git a/CleanStore/Scenes/CreateOrder/CreateOrderConfigurator.swift b/CleanStore/Scenes/CreateOrder/CreateOrderConfigurator.swift index fa0370f..3c59a5e 100644 --- a/CleanStore/Scenes/CreateOrder/CreateOrderConfigurator.swift +++ b/CleanStore/Scenes/CreateOrder/CreateOrderConfigurator.swift @@ -15,7 +15,7 @@ import UIKit extension CreateOrderViewController: CreateOrderPresenterOutput { - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { router.passDataToNextScene(segue) } @@ -32,24 +32,13 @@ extension CreateOrderPresenter: CreateOrderInteractorOutput class CreateOrderConfigurator { // MARK: Object lifecycle - - class var sharedInstance: CreateOrderConfigurator - { - struct Static { - static var instance: CreateOrderConfigurator? - static var token: dispatch_once_t = 0 - } - - dispatch_once(&Static.token) { - Static.instance = CreateOrderConfigurator() - } - - return Static.instance! - } + + static let shared = CreateOrderConfigurator() + private init() {} //This prevents others from using the default '()' initializer for this class. // MARK: Configuration - func configure(viewController: CreateOrderViewController) + func configure(_ viewController: CreateOrderViewController) { let router = CreateOrderRouter() router.viewController = viewController diff --git a/CleanStore/Scenes/CreateOrder/CreateOrderInteractor.swift b/CleanStore/Scenes/CreateOrder/CreateOrderInteractor.swift index ccf8fe5..289baf0 100644 --- a/CleanStore/Scenes/CreateOrder/CreateOrderInteractor.swift +++ b/CleanStore/Scenes/CreateOrder/CreateOrderInteractor.swift @@ -14,12 +14,12 @@ import UIKit protocol CreateOrderInteractorInput { var shippingMethods: [String] { get } - func formatExpirationDate(request: CreateOrder.FormatExpirationDate.Request) + func formatExpirationDate(_ request: CreateOrder.FormatExpirationDate.Request) } protocol CreateOrderInteractorOutput { - func presentExpirationDate(response: CreateOrder.FormatExpirationDate.Response) + func presentExpirationDate(_ response: CreateOrder.FormatExpirationDate.Response) } class CreateOrderInteractor: CreateOrderInteractorInput @@ -34,7 +34,7 @@ class CreateOrderInteractor: CreateOrderInteractorInput // MARK: Expiration date - func formatExpirationDate(request: CreateOrder.FormatExpirationDate.Request) + func formatExpirationDate(_ request: CreateOrder.FormatExpirationDate.Request) { let response = CreateOrder.FormatExpirationDate.Response(date: request.date) output.presentExpirationDate(response) diff --git a/CleanStore/Scenes/CreateOrder/CreateOrderModels.swift b/CleanStore/Scenes/CreateOrder/CreateOrderModels.swift index be82e35..0a902b7 100644 --- a/CleanStore/Scenes/CreateOrder/CreateOrderModels.swift +++ b/CleanStore/Scenes/CreateOrder/CreateOrderModels.swift @@ -17,11 +17,11 @@ struct CreateOrder { struct Request { - var date: NSDate + var date: Date } struct Response { - var date: NSDate + var date: Date } struct ViewModel { diff --git a/CleanStore/Scenes/CreateOrder/CreateOrderPresenter.swift b/CleanStore/Scenes/CreateOrder/CreateOrderPresenter.swift index 38a20c0..ef36580 100644 --- a/CleanStore/Scenes/CreateOrder/CreateOrderPresenter.swift +++ b/CleanStore/Scenes/CreateOrder/CreateOrderPresenter.swift @@ -13,29 +13,29 @@ import UIKit protocol CreateOrderPresenterInput { - func presentExpirationDate(response: CreateOrder.FormatExpirationDate.Response) + func presentExpirationDate(_ response: CreateOrder.FormatExpirationDate.Response) } protocol CreateOrderPresenterOutput: class { - func displayExpirationDate(viewModel: CreateOrder.FormatExpirationDate.ViewModel) + func displayExpirationDate(_ viewModel: CreateOrder.FormatExpirationDate.ViewModel) } class CreateOrderPresenter: CreateOrderPresenterInput { weak var output: CreateOrderPresenterOutput! - let dateFormatter: NSDateFormatter = { - let dateFormatter = NSDateFormatter() - dateFormatter.dateStyle = .ShortStyle - dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle + let dateFormatter: DateFormatter = { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .short + dateFormatter.timeStyle = DateFormatter.Style.none return dateFormatter }() // MARK: Expiration date - func presentExpirationDate(response: CreateOrder.FormatExpirationDate.Response) + func presentExpirationDate(_ response: CreateOrder.FormatExpirationDate.Response) { - let date = dateFormatter.stringFromDate(response.date) + let date = dateFormatter.string(from: response.date as Date) let viewModel = CreateOrder.FormatExpirationDate.ViewModel(date: date) output.displayExpirationDate(viewModel) } diff --git a/CleanStore/Scenes/CreateOrder/CreateOrderRouter.swift b/CleanStore/Scenes/CreateOrder/CreateOrderRouter.swift index 6d74990..2e8df11 100644 --- a/CleanStore/Scenes/CreateOrder/CreateOrderRouter.swift +++ b/CleanStore/Scenes/CreateOrder/CreateOrderRouter.swift @@ -43,7 +43,7 @@ class CreateOrderRouter // MARK: Communication - func passDataToNextScene(segue: UIStoryboardSegue) + func passDataToNextScene(_ segue: UIStoryboardSegue) { // NOTE: Teach the router which scenes it can communicate with @@ -52,7 +52,7 @@ class CreateOrderRouter } } - func passDataToSomewhereScene(segue: UIStoryboardSegue) + func passDataToSomewhereScene(_ segue: UIStoryboardSegue) { // NOTE: Teach the router how to pass data to the next scene diff --git a/CleanStore/Scenes/CreateOrder/CreateOrderViewController.swift b/CleanStore/Scenes/CreateOrder/CreateOrderViewController.swift index a722ea5..82e6e81 100644 --- a/CleanStore/Scenes/CreateOrder/CreateOrderViewController.swift +++ b/CleanStore/Scenes/CreateOrder/CreateOrderViewController.swift @@ -13,13 +13,13 @@ import UIKit protocol CreateOrderViewControllerInput { - func displayExpirationDate(viewModel: CreateOrder.FormatExpirationDate.ViewModel) + func displayExpirationDate(_ viewModel: CreateOrder.FormatExpirationDate.ViewModel) } protocol CreateOrderViewControllerOutput { var shippingMethods: [String] { get } - func formatExpirationDate(request: CreateOrder.FormatExpirationDate.Request) + func formatExpirationDate(_ request: CreateOrder.FormatExpirationDate.Request) } class CreateOrderViewController: UITableViewController, CreateOrderViewControllerInput, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate @@ -32,7 +32,7 @@ class CreateOrderViewController: UITableViewController, CreateOrderViewControlle override func awakeFromNib() { super.awakeFromNib() - CreateOrderConfigurator.sharedInstance.configure(self) + CreateOrderConfigurator.shared.configure(self) } // MARK: View lifecycle @@ -47,10 +47,10 @@ class CreateOrderViewController: UITableViewController, CreateOrderViewControlle @IBOutlet var textFields: [UITextField]! - func textFieldShouldReturn(textField: UITextField) -> Bool + func textFieldShouldReturn(_ textField: UITextField) -> Bool { textField.resignFirstResponder() - if let index = textFields.indexOf(textField) { + if let index = textFields.index(of: textField) { if index < textFields.count - 1 { let nextTextField = textFields[index + 1] nextTextField.becomeFirstResponder() @@ -59,11 +59,11 @@ class CreateOrderViewController: UITableViewController, CreateOrderViewControlle return true } - override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if let cell = tableView.cellForRowAtIndexPath(indexPath) { + if let cell = tableView.cellForRow(at: indexPath) { for textField in textFields { - if textField.isDescendantOfView(cell) { + if textField.isDescendant(of: cell) { textField.becomeFirstResponder() } } @@ -81,22 +81,22 @@ class CreateOrderViewController: UITableViewController, CreateOrderViewControlle expirationDateTextField.inputView = expirationDatePicker } - func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int + func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 } - func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return output.shippingMethods.count } - func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return output.shippingMethods[row] } - func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { shippingMethodTextField.text = output.shippingMethods[row] } @@ -106,14 +106,14 @@ class CreateOrderViewController: UITableViewController, CreateOrderViewControlle @IBOutlet weak var expirationDateTextField: UITextField! @IBOutlet var expirationDatePicker: UIDatePicker! - @IBAction func expirationDatePickerValueChanged(sender: AnyObject) + @IBAction func expirationDatePickerValueChanged(_ sender: AnyObject) { let date = expirationDatePicker.date let request = CreateOrder.FormatExpirationDate.Request(date: date) output.formatExpirationDate(request) } - func displayExpirationDate(viewModel: CreateOrder.FormatExpirationDate.ViewModel) + func displayExpirationDate(_ viewModel: CreateOrder.FormatExpirationDate.ViewModel) { let date = viewModel.date expirationDateTextField.text = date diff --git a/CleanStore/Scenes/ListOrders/ListOrdersConfigurator.swift b/CleanStore/Scenes/ListOrders/ListOrdersConfigurator.swift index fb3e3cd..b14a8d7 100644 --- a/CleanStore/Scenes/ListOrders/ListOrdersConfigurator.swift +++ b/CleanStore/Scenes/ListOrders/ListOrdersConfigurator.swift @@ -15,7 +15,7 @@ import UIKit extension ListOrdersViewController: ListOrdersPresenterOutput { - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { router.passDataToNextScene(segue) } @@ -32,24 +32,13 @@ extension ListOrdersPresenter: ListOrdersInteractorOutput class ListOrdersConfigurator { // MARK: Object lifecycle - - class var sharedInstance: ListOrdersConfigurator - { - struct Static { - static var instance: ListOrdersConfigurator? - static var token: dispatch_once_t = 0 - } - - dispatch_once(&Static.token) { - Static.instance = ListOrdersConfigurator() - } - - return Static.instance! - } + + static let shared = ListOrdersConfigurator() + private init() {} //This prevents others from using the default '()' initializer for this class. // MARK: Configuration - func configure(viewController: ListOrdersViewController) + func configure(_ viewController: ListOrdersViewController) { let router = ListOrdersRouter() router.viewController = viewController diff --git a/CleanStore/Scenes/ListOrders/ListOrdersInteractor.swift b/CleanStore/Scenes/ListOrders/ListOrdersInteractor.swift index 206918b..6629698 100644 --- a/CleanStore/Scenes/ListOrders/ListOrdersInteractor.swift +++ b/CleanStore/Scenes/ListOrders/ListOrdersInteractor.swift @@ -13,13 +13,13 @@ import UIKit protocol ListOrdersInteractorInput { - func fetchOrders(request: ListOrders.FetchOrders.Request) + func fetchOrders(_ request: ListOrders.FetchOrders.Request) var orders: [Order]? { get } } protocol ListOrdersInteractorOutput { - func presentFetchedOrders(response: ListOrders.FetchOrders.Response) + func presentFetchedOrders(_ response: ListOrders.FetchOrders.Response) } class ListOrdersInteractor: ListOrdersInteractorInput @@ -31,7 +31,7 @@ class ListOrdersInteractor: ListOrdersInteractorInput // MARK: Business logic - func fetchOrders(request: ListOrders.FetchOrders.Request) + func fetchOrders(_ request: ListOrders.FetchOrders.Request) { ordersWorker.fetchOrders { (orders) -> Void in self.orders = orders diff --git a/CleanStore/Scenes/ListOrders/ListOrdersPresenter.swift b/CleanStore/Scenes/ListOrders/ListOrdersPresenter.swift index 3adcf53..7007188 100644 --- a/CleanStore/Scenes/ListOrders/ListOrdersPresenter.swift +++ b/CleanStore/Scenes/ListOrders/ListOrdersPresenter.swift @@ -13,37 +13,37 @@ import UIKit protocol ListOrdersPresenterInput { - func presentFetchedOrders(response: ListOrders.FetchOrders.Response) + func presentFetchedOrders(_ response: ListOrders.FetchOrders.Response) } protocol ListOrdersPresenterOutput: class { - func displayFetchedOrders(viewModel: ListOrders.FetchOrders.ViewModel) + func displayFetchedOrders(_ viewModel: ListOrders.FetchOrders.ViewModel) } class ListOrdersPresenter: ListOrdersPresenterInput { weak var output: ListOrdersPresenterOutput! - let dateFormatter: NSDateFormatter = { - let dateFormatter = NSDateFormatter() - dateFormatter.dateStyle = .ShortStyle - dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle + let dateFormatter: DateFormatter = { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .short + dateFormatter.timeStyle = DateFormatter.Style.none return dateFormatter }() - let currencyFormatter: NSNumberFormatter = { - let currencyFormatter = NSNumberFormatter() - currencyFormatter.numberStyle = .CurrencyStyle + let currencyFormatter: NumberFormatter = { + let currencyFormatter = NumberFormatter() + currencyFormatter.numberStyle = .currency return currencyFormatter }() // MARK: Presentation logic - func presentFetchedOrders(response: ListOrders.FetchOrders.Response) + func presentFetchedOrders(_ response: ListOrders.FetchOrders.Response) { var displayedOrders: [ListOrders.FetchOrders.ViewModel.DisplayedOrder] = [] for order in response.orders { - let date = dateFormatter.stringFromDate(order.date!) - let total = currencyFormatter.stringFromNumber(order.total!) + let date = dateFormatter.string(from: order.date! as Date) + let total = currencyFormatter.string(from: order.total!) let displayedOrder = ListOrders.FetchOrders.ViewModel.DisplayedOrder(id: order.id!, date: date, email: order.email!, name: "\(order.firstName!) \(order.lastName!)", total: total!) displayedOrders.append(displayedOrder) } diff --git a/CleanStore/Scenes/ListOrders/ListOrdersRouter.swift b/CleanStore/Scenes/ListOrders/ListOrdersRouter.swift index ad4b427..3b5574c 100644 --- a/CleanStore/Scenes/ListOrders/ListOrdersRouter.swift +++ b/CleanStore/Scenes/ListOrders/ListOrdersRouter.swift @@ -43,7 +43,7 @@ class ListOrdersRouter // MARK: Communication - func passDataToNextScene(segue: UIStoryboardSegue) + func passDataToNextScene(_ segue: UIStoryboardSegue) { // NOTE: Teach the router which scenes it can communicate with @@ -54,7 +54,7 @@ class ListOrdersRouter } } - func passDataToSomewhereScene(segue: UIStoryboardSegue) + func passDataToSomewhereScene(_ segue: UIStoryboardSegue) { // NOTE: Teach the router how to pass data to the next scene @@ -62,11 +62,11 @@ class ListOrdersRouter // someWhereViewController.output.name = viewController.output.name } - func passDataToShowOrderScene(segue: UIStoryboardSegue) + func passDataToShowOrderScene(_ segue: UIStoryboardSegue) { if let selectedIndexPath = viewController.tableView.indexPathForSelectedRow { - if let selectedOrder = viewController.output.orders?[selectedIndexPath.row] { - let showOrderViewController = segue.destinationViewController as! ShowOrderViewController + if let selectedOrder = viewController.output.orders?[(selectedIndexPath as NSIndexPath).row] { + let showOrderViewController = segue.destination as! ShowOrderViewController showOrderViewController.output.order = selectedOrder } } diff --git a/CleanStore/Scenes/ListOrders/ListOrdersViewController.swift b/CleanStore/Scenes/ListOrders/ListOrdersViewController.swift index ab4192b..f21ce61 100644 --- a/CleanStore/Scenes/ListOrders/ListOrdersViewController.swift +++ b/CleanStore/Scenes/ListOrders/ListOrdersViewController.swift @@ -13,12 +13,12 @@ import UIKit protocol ListOrdersViewControllerInput { - func displayFetchedOrders(viewModel: ListOrders.FetchOrders.ViewModel) + func displayFetchedOrders(_ viewModel: ListOrders.FetchOrders.ViewModel) } protocol ListOrdersViewControllerOutput { - func fetchOrders(request: ListOrders.FetchOrders.Request) + func fetchOrders(_ request: ListOrders.FetchOrders.Request) var orders: [Order]? { get } } @@ -33,7 +33,7 @@ class ListOrdersViewController: UITableViewController, ListOrdersViewControllerI override func awakeFromNib() { super.awakeFromNib() - ListOrdersConfigurator.sharedInstance.configure(self) + ListOrdersConfigurator.shared.configure(self) } // MARK: View lifecycle @@ -54,7 +54,7 @@ class ListOrdersViewController: UITableViewController, ListOrdersViewControllerI // MARK: Display logic - func displayFetchedOrders(viewModel: ListOrders.FetchOrders.ViewModel) + func displayFetchedOrders(_ viewModel: ListOrders.FetchOrders.ViewModel) { displayedOrders = viewModel.displayedOrders tableView.reloadData() @@ -62,22 +62,22 @@ class ListOrdersViewController: UITableViewController, ListOrdersViewControllerI // MARK: Table view data source - override func numberOfSectionsInTableView(tableView: UITableView) -> Int + override func numberOfSections(in tableView: UITableView) -> Int { return 1 } - override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return displayedOrders.count } - override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let displayedOrder = displayedOrders[indexPath.row] - var cell = tableView.dequeueReusableCellWithIdentifier("OrderTableViewCell") + let displayedOrder = displayedOrders[(indexPath as NSIndexPath).row] + var cell = tableView.dequeueReusableCell(withIdentifier: "OrderTableViewCell") if cell == nil { - cell = UITableViewCell(style: .Value1, reuseIdentifier: "OrderTableViewCell") + cell = UITableViewCell(style: .value1, reuseIdentifier: "OrderTableViewCell") } cell?.textLabel?.text = displayedOrder.date cell?.detailTextLabel?.text = displayedOrder.total diff --git a/CleanStore/Scenes/ShowOrder/ShowOrderConfigurator.swift b/CleanStore/Scenes/ShowOrder/ShowOrderConfigurator.swift index cff989f..8e0f209 100644 --- a/CleanStore/Scenes/ShowOrder/ShowOrderConfigurator.swift +++ b/CleanStore/Scenes/ShowOrder/ShowOrderConfigurator.swift @@ -15,7 +15,7 @@ import UIKit extension ShowOrderViewController: ShowOrderPresenterOutput { - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { router.passDataToNextScene(segue) } @@ -33,23 +33,12 @@ class ShowOrderConfigurator { // MARK: Object lifecycle - class var sharedInstance: ShowOrderConfigurator - { - struct Static { - static var instance: ShowOrderConfigurator? - static var token: dispatch_once_t = 0 - } - - dispatch_once(&Static.token) { - Static.instance = ShowOrderConfigurator() - } - - return Static.instance! - } + static let shared = ShowOrderConfigurator() + private init() {} //This prevents others from using the default '()' initializer for this class. // MARK: Configuration - func configure(viewController: ShowOrderViewController) + func configure(_ viewController: ShowOrderViewController) { let router = ShowOrderRouter() router.viewController = viewController diff --git a/CleanStore/Scenes/ShowOrder/ShowOrderInteractor.swift b/CleanStore/Scenes/ShowOrder/ShowOrderInteractor.swift index 3cfab8e..ae3b0b8 100644 --- a/CleanStore/Scenes/ShowOrder/ShowOrderInteractor.swift +++ b/CleanStore/Scenes/ShowOrder/ShowOrderInteractor.swift @@ -13,13 +13,13 @@ import UIKit protocol ShowOrderInteractorInput { - func getOrder(request: ShowOrder.GetOrder.Request) + func getOrder(_ request: ShowOrder.GetOrder.Request) var order: Order! { get set } } protocol ShowOrderInteractorOutput { - func presentOrder(response: ShowOrder.GetOrder.Response) + func presentOrder(_ response: ShowOrder.GetOrder.Response) } class ShowOrderInteractor: ShowOrderInteractorInput @@ -31,7 +31,7 @@ class ShowOrderInteractor: ShowOrderInteractorInput // MARK: Business logic - func getOrder(request: ShowOrder.GetOrder.Request) + func getOrder(_ request: ShowOrder.GetOrder.Request) { let response = ShowOrder.GetOrder.Response(order: order) output.presentOrder(response) diff --git a/CleanStore/Scenes/ShowOrder/ShowOrderPresenter.swift b/CleanStore/Scenes/ShowOrder/ShowOrderPresenter.swift index 9994a87..79ea405 100644 --- a/CleanStore/Scenes/ShowOrder/ShowOrderPresenter.swift +++ b/CleanStore/Scenes/ShowOrder/ShowOrderPresenter.swift @@ -13,39 +13,39 @@ import UIKit protocol ShowOrderPresenterInput { - func presentOrder(response: ShowOrder.GetOrder.Response) + func presentOrder(_ response: ShowOrder.GetOrder.Response) } protocol ShowOrderPresenterOutput: class { - func displayOrder(viewModel: ShowOrder.GetOrder.ViewModel) + func displayOrder(_ viewModel: ShowOrder.GetOrder.ViewModel) } class ShowOrderPresenter: ShowOrderPresenterInput { weak var output: ShowOrderPresenterOutput! - let dateFormatter: NSDateFormatter = { - let dateFormatter = NSDateFormatter() - dateFormatter.dateStyle = .ShortStyle - dateFormatter.timeStyle = NSDateFormatterStyle.NoStyle + let dateFormatter: DateFormatter = { + let dateFormatter = DateFormatter() + dateFormatter.dateStyle = .short + dateFormatter.timeStyle = DateFormatter.Style.none return dateFormatter }() - let currencyFormatter: NSNumberFormatter = { - let currencyFormatter = NSNumberFormatter() - currencyFormatter.numberStyle = .CurrencyStyle + let currencyFormatter: NumberFormatter = { + let currencyFormatter = NumberFormatter() + currencyFormatter.numberStyle = .currency return currencyFormatter }() // MARK: Presentation logic - func presentOrder(response: ShowOrder.GetOrder.Response) + func presentOrder(_ response: ShowOrder.GetOrder.Response) { let order = response.order - let date = dateFormatter.stringFromDate(order.date!) - let total = currencyFormatter.stringFromNumber(order.total!) + let date = dateFormatter.string(from: order.date! as Date) + let total = currencyFormatter.string(from: order.total!) let displayedOrder = ShowOrder.GetOrder.ViewModel.DisplayedOrder(id: order.id!, date: date, email: order.email!, name: "\(order.firstName!) \(order.lastName!)", total: total!) let viewModel = ShowOrder.GetOrder.ViewModel(displayedOrder: displayedOrder) diff --git a/CleanStore/Scenes/ShowOrder/ShowOrderRouter.swift b/CleanStore/Scenes/ShowOrder/ShowOrderRouter.swift index 7b164dd..172dd59 100644 --- a/CleanStore/Scenes/ShowOrder/ShowOrderRouter.swift +++ b/CleanStore/Scenes/ShowOrder/ShowOrderRouter.swift @@ -43,7 +43,7 @@ class ShowOrderRouter: ShowOrderRouterInput // MARK: Communication - func passDataToNextScene(segue: UIStoryboardSegue) + func passDataToNextScene(_ segue: UIStoryboardSegue) { // NOTE: Teach the router which scenes it can communicate with @@ -52,7 +52,7 @@ class ShowOrderRouter: ShowOrderRouterInput } } - func passDataToSomewhereScene(segue: UIStoryboardSegue) + func passDataToSomewhereScene(_ segue: UIStoryboardSegue) { // NOTE: Teach the router how to pass data to the next scene diff --git a/CleanStore/Scenes/ShowOrder/ShowOrderViewController.swift b/CleanStore/Scenes/ShowOrder/ShowOrderViewController.swift index 604f76a..98007ac 100644 --- a/CleanStore/Scenes/ShowOrder/ShowOrderViewController.swift +++ b/CleanStore/Scenes/ShowOrder/ShowOrderViewController.swift @@ -13,12 +13,12 @@ import UIKit protocol ShowOrderViewControllerInput { - func displayOrder(viewModel: ShowOrder.GetOrder.ViewModel) + func displayOrder(_ viewModel: ShowOrder.GetOrder.ViewModel) } protocol ShowOrderViewControllerOutput { - func getOrder(request: ShowOrder.GetOrder.Request) + func getOrder(_ request: ShowOrder.GetOrder.Request) var order: Order! { get set } } @@ -38,7 +38,7 @@ class ShowOrderViewController: UIViewController, ShowOrderViewControllerInput override func awakeFromNib() { super.awakeFromNib() - ShowOrderConfigurator.sharedInstance.configure(self) + ShowOrderConfigurator.shared.configure(self) } // MARK: View lifecycle @@ -61,7 +61,7 @@ class ShowOrderViewController: UIViewController, ShowOrderViewControllerInput // MARK: Display logic - func displayOrder(viewModel: ShowOrder.GetOrder.ViewModel) + func displayOrder(_ viewModel: ShowOrder.GetOrder.ViewModel) { let displayedOrder = viewModel.displayedOrder orderIDLabel.text = displayedOrder.id diff --git a/CleanStore/Services/OrdersAPI.swift b/CleanStore/Services/OrdersAPI.swift index f21a7cd..c768be4 100644 --- a/CleanStore/Services/OrdersAPI.swift +++ b/CleanStore/Services/OrdersAPI.swift @@ -4,67 +4,67 @@ class OrdersAPI: OrdersStoreProtocol { // MARK: - CRUD operations - Optional error - func fetchOrders(completionHandler: (orders: [Order], error: OrdersStoreError?) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: [Order], _ error: OrdersStoreError?) -> Void) { } - func fetchOrder(id: String, completionHandler: (order: Order?, error: OrdersStoreError?) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: Order?, _ error: OrdersStoreError?) -> Void) { } - func createOrder(orderToCreate: Order, completionHandler: (error: OrdersStoreError?) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { } - func updateOrder(orderToUpdate: Order, completionHandler: (error: OrdersStoreError?) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { } - func deleteOrder(id: String, completionHandler: (error: OrdersStoreError?) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { } // MARK: - CRUD operations - Generic enum result type - func fetchOrders(completionHandler: OrdersStoreFetchOrdersCompletionHandler) + func fetchOrders(_ completionHandler: @escaping OrdersStoreFetchOrdersCompletionHandler) { } - func fetchOrder(id: String, completionHandler: OrdersStoreFetchOrderCompletionHandler) + func fetchOrder(_ id: String, completionHandler: @escaping OrdersStoreFetchOrderCompletionHandler) { } - func createOrder(orderToCreate: Order, completionHandler: OrdersStoreCreateOrderCompletionHandler) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping OrdersStoreCreateOrderCompletionHandler) { } - func updateOrder(orderToUpdate: Order, completionHandler: OrdersStoreUpdateOrderCompletionHandler) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping OrdersStoreUpdateOrderCompletionHandler) { } - func deleteOrder(id: String, completionHandler: OrdersStoreDeleteOrderCompletionHandler) + func deleteOrder(_ id: String, completionHandler: @escaping OrdersStoreDeleteOrderCompletionHandler) { } // MARK: - CRUD operations - Inner closure - func fetchOrders(completionHandler: (orders: () throws -> [Order]) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: () throws -> [Order]) -> Void) { } - func fetchOrder(id: String, completionHandler: (order: () throws -> Order?) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: () throws -> Order?) -> Void) { } - func createOrder(orderToCreate: Order, completionHandler: (done: () throws -> Void) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { } - func updateOrder(orderToUpdate: Order, completionHandler: (done: () throws -> Void) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { } - func deleteOrder(id: String, completionHandler: (done: () throws -> Void) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { } } diff --git a/CleanStore/Services/OrdersCoreDataStore.swift b/CleanStore/Services/OrdersCoreDataStore.swift index 6d7b0e6..53f8f85 100644 --- a/CleanStore/Services/OrdersCoreDataStore.swift +++ b/CleanStore/Services/OrdersCoreDataStore.swift @@ -12,33 +12,33 @@ class OrdersCoreDataStore: OrdersStoreProtocol init() { // This resource is the same name as your xcdatamodeld contained in your project. - guard let modelURL = NSBundle.mainBundle().URLForResource("CleanStore", withExtension:"momd") else { + guard let modelURL = Bundle.main.url(forResource: "CleanStore", withExtension:"momd") else { fatalError("Error loading model from bundle") } // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. - guard let mom = NSManagedObjectModel(contentsOfURL: modelURL) else { + guard let mom = NSManagedObjectModel(contentsOf: modelURL) else { fatalError("Error initializing mom from: \(modelURL)") } let psc = NSPersistentStoreCoordinator(managedObjectModel: mom) - mainManagedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) + mainManagedObjectContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) mainManagedObjectContext.persistentStoreCoordinator = psc - let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) + let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let docURL = urls[urls.endIndex-1] /* The directory the application uses to store the Core Data store file. This code uses a file named "DataModel.sqlite" in the application's documents directory. */ - let storeURL = docURL.URLByAppendingPathComponent("CleanStore.sqlite") + let storeURL = docURL.appendingPathComponent("CleanStore.sqlite") do { - try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil) + try psc.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: storeURL, options: nil) } catch { fatalError("Error migrating store: \(error)") } - privateManagedObjectContext = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType) - privateManagedObjectContext.parentContext = mainManagedObjectContext + privateManagedObjectContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) + privateManagedObjectContext.parent = mainManagedObjectContext } deinit @@ -52,43 +52,43 @@ class OrdersCoreDataStore: OrdersStoreProtocol // MARK: - CRUD operations - Optional error - func fetchOrders(completionHandler: (orders: [Order], error: OrdersStoreError?) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: [Order], _ error: OrdersStoreError?) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] let orders = results.map { $0.toOrder() } - completionHandler(orders: orders, error: nil) + completionHandler(orders, nil) } catch { - completionHandler(orders: [], error: OrdersStoreError.CannotFetch("Cannot fetch orders")) + completionHandler([], OrdersStoreError.cannotFetch("Cannot fetch orders")) } } } - func fetchOrder(id: String, completionHandler: (order: Order?, error: OrdersStoreError?) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: Order?, _ error: OrdersStoreError?) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", id) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let order = results.first?.toOrder() { - completionHandler(order: order, error: nil) + completionHandler(order, nil) } else { - completionHandler(order: nil, error: OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)")) + completionHandler(nil, OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)")) } } catch { - completionHandler(order: nil, error: OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)")) + completionHandler(nil, OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)")) } } } - func createOrder(orderToCreate: Order, completionHandler: (error: OrdersStoreError?) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let managedOrder = NSEntityDescription.insertNewObjectForEntityForName("ManagedOrder", inManagedObjectContext: self.privateManagedObjectContext) as! ManagedOrder + let managedOrder = NSEntityDescription.insertNewObject(forEntityName: "ManagedOrder", into: self.privateManagedObjectContext) as! ManagedOrder managedOrder.id = orderToCreate.id managedOrder.date = orderToCreate.date managedOrder.email = orderToCreate.email @@ -96,20 +96,20 @@ class OrdersCoreDataStore: OrdersStoreProtocol managedOrder.lastName = orderToCreate.lastName managedOrder.total = orderToCreate.total try self.privateManagedObjectContext.save() - completionHandler(error: nil) + completionHandler(nil) } catch { - completionHandler(error: OrdersStoreError.CannotCreate("Cannot create order with id \(orderToCreate.id)")) + completionHandler(OrdersStoreError.cannotCreate("Cannot create order with id \(orderToCreate.id)")) } } } - func updateOrder(orderToUpdate: Order, completionHandler: (error: OrdersStoreError?) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", orderToUpdate.id!) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let managedOrder = results.first { do { managedOrder.id = orderToUpdate.id @@ -119,80 +119,80 @@ class OrdersCoreDataStore: OrdersStoreProtocol managedOrder.lastName = orderToUpdate.lastName managedOrder.total = orderToUpdate.total try self.privateManagedObjectContext.save() - completionHandler(error: nil) + completionHandler(nil) } catch { - completionHandler(error: OrdersStoreError.CannotUpdate("Cannot update order with id \(orderToUpdate.id)")) + completionHandler(OrdersStoreError.cannotUpdate("Cannot update order with id \(orderToUpdate.id)")) } } } catch { - completionHandler(error: OrdersStoreError.CannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update")) + completionHandler(OrdersStoreError.cannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update")) } } } - func deleteOrder(id: String, completionHandler: (error: OrdersStoreError?) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", id) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let managedOrder = results.first { - self.privateManagedObjectContext.deleteObject(managedOrder) + self.privateManagedObjectContext.delete(managedOrder) do { try self.privateManagedObjectContext.save() - completionHandler(error: nil) + completionHandler(nil) } catch { - completionHandler(error: OrdersStoreError.CannotDelete("Cannot delete order with id \(id)")) + completionHandler(OrdersStoreError.cannotDelete("Cannot delete order with id \(id)")) } } else { - throw OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete") + throw OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete") } } catch { - completionHandler(error: OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete")) + completionHandler(OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete")) } } } // MARK: - CRUD operations - Generic enum result type - func fetchOrders(completionHandler: OrdersStoreFetchOrdersCompletionHandler) + func fetchOrders(_ completionHandler: @escaping OrdersStoreFetchOrdersCompletionHandler) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] let orders = results.map { $0.toOrder() } - completionHandler(result: OrdersStoreResult.Success(result: orders)) + completionHandler(OrdersStoreResult.success(result: orders)) } catch { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotFetch("Cannot fetch orders"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotFetch("Cannot fetch orders"))) } } } - func fetchOrder(id: String, completionHandler: OrdersStoreFetchOrderCompletionHandler) + func fetchOrder(_ id: String, completionHandler: @escaping OrdersStoreFetchOrderCompletionHandler) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", id) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let order = results.first?.toOrder() { - completionHandler(result: OrdersStoreResult.Success(result: order)) + completionHandler(OrdersStoreResult.success(result: order)) } else { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)"))) } } catch { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)"))) } } } - func createOrder(orderToCreate: Order, completionHandler: OrdersStoreCreateOrderCompletionHandler) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping OrdersStoreCreateOrderCompletionHandler) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let managedOrder = NSEntityDescription.insertNewObjectForEntityForName("ManagedOrder", inManagedObjectContext: self.privateManagedObjectContext) as! ManagedOrder + let managedOrder = NSEntityDescription.insertNewObject(forEntityName: "ManagedOrder", into: self.privateManagedObjectContext) as! ManagedOrder managedOrder.id = orderToCreate.id managedOrder.date = orderToCreate.date managedOrder.email = orderToCreate.email @@ -200,21 +200,21 @@ class OrdersCoreDataStore: OrdersStoreProtocol managedOrder.lastName = orderToCreate.lastName managedOrder.total = orderToCreate.total try self.privateManagedObjectContext.save() - completionHandler(result: OrdersStoreResult.Success(result: ())) + completionHandler(OrdersStoreResult.success(result: ())) } catch { - let error = OrdersStoreError.CannotCreate("Cannot create order with id \(orderToCreate.id)") - completionHandler(result: OrdersStoreResult.Failure(error: error)) + let error = OrdersStoreError.cannotCreate("Cannot create order with id \(orderToCreate.id)") + completionHandler(OrdersStoreResult.failure(error: error)) } } } - func updateOrder(orderToUpdate: Order, completionHandler: OrdersStoreUpdateOrderCompletionHandler) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping OrdersStoreUpdateOrderCompletionHandler) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", orderToUpdate.id!) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let managedOrder = results.first { do { managedOrder.id = orderToUpdate.id @@ -224,80 +224,80 @@ class OrdersCoreDataStore: OrdersStoreProtocol managedOrder.lastName = orderToUpdate.lastName managedOrder.total = orderToUpdate.total try self.privateManagedObjectContext.save() - completionHandler(result: OrdersStoreResult.Success(result: ())) + completionHandler(OrdersStoreResult.success(result: ())) } catch { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotUpdate("Cannot update order with id \(orderToUpdate.id)"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotUpdate("Cannot update order with id \(orderToUpdate.id)"))) } } } catch { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update"))) } } } - func deleteOrder(id: String, completionHandler: OrdersStoreDeleteOrderCompletionHandler) + func deleteOrder(_ id: String, completionHandler: @escaping OrdersStoreDeleteOrderCompletionHandler) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", id) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let managedOrder = results.first { - self.privateManagedObjectContext.deleteObject(managedOrder) + self.privateManagedObjectContext.delete(managedOrder) do { try self.privateManagedObjectContext.save() - completionHandler(result: OrdersStoreResult.Success(result: ())) + completionHandler(OrdersStoreResult.success(result: ())) } catch { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotDelete("Cannot delete order with id \(id)"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotDelete("Cannot delete order with id \(id)"))) } } else { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete"))) } } catch { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete"))) } } } // MARK: - CRUD operations - Inner closure - func fetchOrders(completionHandler: (orders: () throws -> [Order]) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: () throws -> [Order]) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] let orders = results.map { $0.toOrder() } completionHandler { return orders } } catch { - completionHandler { throw OrdersStoreError.CannotFetch("Cannot fetch orders") } + completionHandler { throw OrdersStoreError.cannotFetch("Cannot fetch orders") } } } } - func fetchOrder(id: String, completionHandler: (order: () throws -> Order?) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: () throws -> Order?) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", id) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let order = results.first?.toOrder() { completionHandler { return order } } else { - throw OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)") + throw OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)") } } catch { - completionHandler { throw OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)") } + completionHandler { throw OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)") } } } } - func createOrder(orderToCreate: Order, completionHandler: (done: () throws -> Void) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let managedOrder = NSEntityDescription.insertNewObjectForEntityForName("ManagedOrder", inManagedObjectContext: self.privateManagedObjectContext) as! ManagedOrder + let managedOrder = NSEntityDescription.insertNewObject(forEntityName: "ManagedOrder", into: self.privateManagedObjectContext) as! ManagedOrder managedOrder.id = orderToCreate.id managedOrder.date = orderToCreate.date managedOrder.email = orderToCreate.email @@ -307,18 +307,18 @@ class OrdersCoreDataStore: OrdersStoreProtocol try self.privateManagedObjectContext.save() completionHandler { return } } catch { - completionHandler { throw OrdersStoreError.CannotCreate("Cannot create order with id \(orderToCreate.id)") } + completionHandler { throw OrdersStoreError.cannotCreate("Cannot create order with id \(orderToCreate.id)") } } } } - func updateOrder(orderToUpdate: Order, completionHandler: (done: () throws -> Void) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", orderToUpdate.id!) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let managedOrder = results.first { do { managedOrder.id = orderToUpdate.id @@ -330,35 +330,35 @@ class OrdersCoreDataStore: OrdersStoreProtocol try self.privateManagedObjectContext.save() completionHandler { return } } catch { - completionHandler { throw OrdersStoreError.CannotUpdate("Cannot update order with id \(orderToUpdate.id)") } + completionHandler { throw OrdersStoreError.cannotUpdate("Cannot update order with id \(orderToUpdate.id)") } } } } catch { - completionHandler { throw OrdersStoreError.CannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update") } + completionHandler { throw OrdersStoreError.cannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update") } } } } - func deleteOrder(id: String, completionHandler: (done: () throws -> Void) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { - privateManagedObjectContext.performBlock { + privateManagedObjectContext.perform { do { - let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") + let fetchRequest = NSFetchRequest(entityName: "ManagedOrder") fetchRequest.predicate = NSPredicate(format: "id == %@", id) - let results = try self.privateManagedObjectContext.executeFetchRequest(fetchRequest) as! [ManagedOrder] + let results = try self.privateManagedObjectContext.fetch(fetchRequest) as! [ManagedOrder] if let managedOrder = results.first { - self.privateManagedObjectContext.deleteObject(managedOrder) + self.privateManagedObjectContext.delete(managedOrder) do { try self.privateManagedObjectContext.save() completionHandler { return } } catch { - completionHandler { throw OrdersStoreError.CannotDelete("Cannot delete order with id \(id)") } + completionHandler { throw OrdersStoreError.cannotDelete("Cannot delete order with id \(id)") } } } else { - throw OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete") + throw OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete") } } catch { - completionHandler { throw OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete") } + completionHandler { throw OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete") } } } } diff --git a/CleanStore/Services/OrdersMemStore.swift b/CleanStore/Services/OrdersMemStore.swift index 71a16cd..cd71c5e 100644 --- a/CleanStore/Services/OrdersMemStore.swift +++ b/CleanStore/Services/OrdersMemStore.swift @@ -5,158 +5,158 @@ class OrdersMemStore: OrdersStoreProtocol // MARK: - Data var orders = [ - Order(id: "abc123", date: NSDate(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), - Order(id: "def456", date: NSDate(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) + Order(id: "abc123", date: Date(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), + Order(id: "def456", date: Date(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) ] // MARK: - CRUD operations - Optional error - func fetchOrders(completionHandler: (orders: [Order], error: OrdersStoreError?) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: [Order], _ error: OrdersStoreError?) -> Void) { - completionHandler(orders: orders, error: nil) + completionHandler(orders, nil) } - func fetchOrder(id: String, completionHandler: (order: Order?, error: OrdersStoreError?) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: Order?, _ error: OrdersStoreError?) -> Void) { let order = orders.filter { (order: Order) -> Bool in return order.id == id }.first if let _ = order { - completionHandler(order: order, error: nil) + completionHandler(order, nil) } else { - completionHandler(order: nil, error: OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)")) + completionHandler(nil, OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)")) } } - func createOrder(order: Order, completionHandler: (error: OrdersStoreError?) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { - orders.append(order) - completionHandler(error: nil) + orders.append(orderToCreate) + completionHandler(nil) } - func updateOrder(orderToUpdate: Order, completionHandler: (error: OrdersStoreError?) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { for var order in orders { if order.id == orderToUpdate.id { order = orderToUpdate - completionHandler(error: nil) + completionHandler(nil) return } } - completionHandler(error: OrdersStoreError.CannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update")) + completionHandler(OrdersStoreError.cannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update")) } - func deleteOrder(id: String, completionHandler: (error: OrdersStoreError?) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) { - let index = orders.indexOf { (order: Order) -> Bool in + let index = orders.index { (order: Order) -> Bool in return order.id == id } if let index = index { - orders.removeAtIndex(index) - completionHandler(error: nil) + orders.remove(at: index) + completionHandler(nil) return } - completionHandler(error: OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete")) + completionHandler(OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete")) } // MARK: - CRUD operations - Generic enum result type - func fetchOrders(completionHandler: OrdersStoreFetchOrdersCompletionHandler) + func fetchOrders(_ completionHandler: @escaping OrdersStoreFetchOrdersCompletionHandler) { - completionHandler(result: OrdersStoreResult.Success(result: orders)) + completionHandler(OrdersStoreResult.success(result: orders)) } - func fetchOrder(id: String, completionHandler: OrdersStoreFetchOrderCompletionHandler) + func fetchOrder(_ id: String, completionHandler: @escaping OrdersStoreFetchOrderCompletionHandler) { let order = orders.filter { (order: Order) -> Bool in return order.id == id }.first if let order = order { - completionHandler(result: OrdersStoreResult.Success(result: order)) + completionHandler(OrdersStoreResult.success(result: order)) } else { - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)"))) } } - func createOrder(order: Order, completionHandler: OrdersStoreCreateOrderCompletionHandler) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping OrdersStoreCreateOrderCompletionHandler) { - orders.append(order) - completionHandler(result: OrdersStoreResult.Success(result: ())) + orders.append(orderToCreate) + completionHandler(OrdersStoreResult.success(result: ())) } - func updateOrder(orderToUpdate: Order, completionHandler: OrdersStoreUpdateOrderCompletionHandler) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping OrdersStoreUpdateOrderCompletionHandler) { for var order in orders { if order.id == orderToUpdate.id { order = orderToUpdate - completionHandler(result: OrdersStoreResult.Success(result: ())) + completionHandler(OrdersStoreResult.success(result: ())) return } } - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotUpdate("Cannot update order with id \(orderToUpdate.id) to update"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotUpdate("Cannot update order with id \(orderToUpdate.id) to update"))) } - func deleteOrder(id: String, completionHandler: OrdersStoreDeleteOrderCompletionHandler) + func deleteOrder(_ id: String, completionHandler: @escaping OrdersStoreDeleteOrderCompletionHandler) { - let index = orders.indexOf { (order: Order) -> Bool in + let index = orders.index { (order: Order) -> Bool in return order.id == id } if let index = index { - orders.removeAtIndex(index) - completionHandler(result: OrdersStoreResult.Success(result: ())) + orders.remove(at: index) + completionHandler(OrdersStoreResult.success(result: ())) return } - completionHandler(result: OrdersStoreResult.Failure(error: OrdersStoreError.CannotDelete("Cannot delete order with id \(id) to delete"))) + completionHandler(OrdersStoreResult.failure(error: OrdersStoreError.cannotDelete("Cannot delete order with id \(id) to delete"))) } // MARK: - CRUD operations - Inner closure - func fetchOrders(completionHandler: (orders: () throws -> [Order]) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: () throws -> [Order]) -> Void) { completionHandler { return self.orders } } - func fetchOrder(id: String, completionHandler: (order: () throws -> Order?) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: () throws -> Order?) -> Void) { - let index = orders.indexOf { (order: Order) -> Bool in + let index = orders.index { (order: Order) -> Bool in return order.id == id } if let index = index { completionHandler { return self.orders[index] } } else { - completionHandler { throw OrdersStoreError.CannotFetch("Cannot fetch order with id \(id)") } + completionHandler { throw OrdersStoreError.cannotFetch("Cannot fetch order with id \(id)") } } } - func createOrder(order: Order, completionHandler: (done: () throws -> Void) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { - orders.append(order) + orders.append(orderToCreate) completionHandler { return } } - func updateOrder(orderToUpdate: Order, completionHandler: (done: () throws -> Void) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { - let index = orders.indexOf { (order: Order) -> Bool in + let index = orders.index { (order: Order) -> Bool in return order.id == orderToUpdate.id } if let index = index { orders[index] = orderToUpdate completionHandler { return } } else { - completionHandler { throw OrdersStoreError.CannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update") } + completionHandler { throw OrdersStoreError.cannotUpdate("Cannot fetch order with id \(orderToUpdate.id) to update") } } } - func deleteOrder(id: String, completionHandler: (done: () throws -> Void) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ done: () throws -> Void) -> Void) { - let index = orders.indexOf { (order: Order) -> Bool in + let index = orders.index { (order: Order) -> Bool in return order.id == id } if let index = index { - orders.removeAtIndex(index) + orders.remove(at: index) completionHandler { return } } else { - completionHandler { throw OrdersStoreError.CannotDelete("Cannot fetch order with id \(id) to delete") } + completionHandler { throw OrdersStoreError.cannotDelete("Cannot fetch order with id \(id) to delete") } } } } diff --git a/CleanStore/Workers/OrdersWorker.swift b/CleanStore/Workers/OrdersWorker.swift index e288346..8df3928 100644 --- a/CleanStore/Workers/OrdersWorker.swift +++ b/CleanStore/Workers/OrdersWorker.swift @@ -11,14 +11,14 @@ class OrdersWorker self.ordersStore = ordersStore } - func fetchOrders(completionHandler: (orders: [Order]) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: [Order]) -> Void) { ordersStore.fetchOrders { (orders: () throws -> [Order]) -> Void in do { let orders = try orders() - completionHandler(orders: orders) + completionHandler(orders) } catch { - completionHandler(orders: []) + completionHandler([]) } } } @@ -30,60 +30,60 @@ protocol OrdersStoreProtocol { // MARK: CRUD operations - Optional error - func fetchOrders(completionHandler: (orders: [Order], error: OrdersStoreError?) -> Void) - func fetchOrder(id: String, completionHandler: (order: Order?, error: OrdersStoreError?) -> Void) - func createOrder(orderToCreate: Order, completionHandler: (error: OrdersStoreError?) -> Void) - func updateOrder(orderToUpdate: Order, completionHandler: (error: OrdersStoreError?) -> Void) - func deleteOrder(id: String, completionHandler: (error: OrdersStoreError?) -> Void) - + func fetchOrders(_ completionHandler: @escaping (_ orders: [Order], _ error: OrdersStoreError?) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: Order?, _ error: OrdersStoreError?) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ error: OrdersStoreError?) -> Void) + // MARK: CRUD operations - Generic enum result type - func fetchOrders(completionHandler: OrdersStoreFetchOrdersCompletionHandler) - func fetchOrder(id: String, completionHandler: OrdersStoreFetchOrderCompletionHandler) - func createOrder(orderToCreate: Order, completionHandler: OrdersStoreCreateOrderCompletionHandler) - func updateOrder(orderToUpdate: Order, completionHandler: OrdersStoreUpdateOrderCompletionHandler) - func deleteOrder(id: String, completionHandler: OrdersStoreDeleteOrderCompletionHandler) + func fetchOrders(_ completionHandler: @escaping OrdersStoreFetchOrdersCompletionHandler) + func fetchOrder(_ id: String, completionHandler: @escaping OrdersStoreFetchOrderCompletionHandler) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping OrdersStoreCreateOrderCompletionHandler) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping OrdersStoreUpdateOrderCompletionHandler) + func deleteOrder(_ id: String, completionHandler: @escaping OrdersStoreDeleteOrderCompletionHandler) // MARK: CRUD operations - Inner closure - func fetchOrders(completionHandler: (orders: () throws -> [Order]) -> Void) - func fetchOrder(id: String, completionHandler: (order: () throws -> Order?) -> Void) - func createOrder(orderToCreate: Order, completionHandler: (done: () throws -> Void) -> Void) - func updateOrder(orderToUpdate: Order, completionHandler: (done: () throws -> Void) -> Void) - func deleteOrder(id: String, completionHandler: (done: () throws -> Void) -> Void) + func fetchOrders(_ completionHandler: @escaping (_ orders: () throws -> [Order]) -> Void) + func fetchOrder(_ id: String, completionHandler: @escaping (_ order: () throws -> Order?) -> Void) + func createOrder(_ orderToCreate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) + func updateOrder(_ orderToUpdate: Order, completionHandler: @escaping (_ done: () throws -> Void) -> Void) + func deleteOrder(_ id: String, completionHandler: @escaping (_ done: () throws -> Void) -> Void) } // MARK: - Orders store CRUD operation results -typealias OrdersStoreFetchOrdersCompletionHandler = (result: OrdersStoreResult<[Order]>) -> Void -typealias OrdersStoreFetchOrderCompletionHandler = (result: OrdersStoreResult) -> Void -typealias OrdersStoreCreateOrderCompletionHandler = (result: OrdersStoreResult) -> Void -typealias OrdersStoreUpdateOrderCompletionHandler = (result: OrdersStoreResult) -> Void -typealias OrdersStoreDeleteOrderCompletionHandler = (result: OrdersStoreResult) -> Void +typealias OrdersStoreFetchOrdersCompletionHandler = (_ result: OrdersStoreResult<[Order]>) -> Void +typealias OrdersStoreFetchOrderCompletionHandler = (_ result: OrdersStoreResult) -> Void +typealias OrdersStoreCreateOrderCompletionHandler = (_ result: OrdersStoreResult) -> Void +typealias OrdersStoreUpdateOrderCompletionHandler = (_ result: OrdersStoreResult) -> Void +typealias OrdersStoreDeleteOrderCompletionHandler = (_ result: OrdersStoreResult) -> Void enum OrdersStoreResult { - case Success(result: U) - case Failure(error: OrdersStoreError) + case success(result: U) + case failure(error: OrdersStoreError) } // MARK: - Orders store CRUD operation errors -enum OrdersStoreError: Equatable, ErrorType +enum OrdersStoreError: Equatable, Error { - case CannotFetch(String) - case CannotCreate(String) - case CannotUpdate(String) - case CannotDelete(String) + case cannotFetch(String) + case cannotCreate(String) + case cannotUpdate(String) + case cannotDelete(String) } func ==(lhs: OrdersStoreError, rhs: OrdersStoreError) -> Bool { switch (lhs, rhs) { - case (.CannotFetch(let a), .CannotFetch(let b)) where a == b: return true - case (.CannotCreate(let a), .CannotCreate(let b)) where a == b: return true - case (.CannotUpdate(let a), .CannotUpdate(let b)) where a == b: return true - case (.CannotDelete(let a), .CannotDelete(let b)) where a == b: return true + case (.cannotFetch(let a), .cannotFetch(let b)) where a == b: return true + case (.cannotCreate(let a), .cannotCreate(let b)) where a == b: return true + case (.cannotUpdate(let a), .cannotUpdate(let b)) where a == b: return true + case (.cannotDelete(let a), .cannotDelete(let b)) where a == b: return true default: return false } } diff --git a/CleanStoreTests/CleanStoreTests.swift b/CleanStoreTests/CleanStoreTests.swift index 7e9a45a..fb90636 100644 --- a/CleanStoreTests/CleanStoreTests.swift +++ b/CleanStoreTests/CleanStoreTests.swift @@ -28,7 +28,7 @@ class CleanStoreTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } } diff --git a/CleanStoreTests/Scenes/CreateOrder/CreateOrderInteractorTests.swift b/CleanStoreTests/Scenes/CreateOrder/CreateOrderInteractorTests.swift index 871f9af..b79bf9d 100644 --- a/CleanStoreTests/Scenes/CreateOrder/CreateOrderInteractorTests.swift +++ b/CleanStoreTests/Scenes/CreateOrder/CreateOrderInteractorTests.swift @@ -34,7 +34,7 @@ class CreateOrderInteractorTests: XCTestCase { var presentExpirationDateCalled = false - func presentExpirationDate(response: CreateOrder.FormatExpirationDate.Response) + func presentExpirationDate(_ response: CreateOrder.FormatExpirationDate.Response) { presentExpirationDateCalled = true } @@ -47,7 +47,7 @@ class CreateOrderInteractorTests: XCTestCase // Given let createOrderInteractorOutputSpy = CreateOrderInteractorOutputSpy() createOrderInteractor.output = createOrderInteractorOutputSpy - let request = CreateOrder.FormatExpirationDate.Request(date: NSDate()) + let request = CreateOrder.FormatExpirationDate.Request(date: Date()) // When createOrderInteractor.formatExpirationDate(request) diff --git a/CleanStoreTests/Scenes/CreateOrder/CreateOrderPresenterTests.swift b/CleanStoreTests/Scenes/CreateOrder/CreateOrderPresenterTests.swift index 7624a70..0b71967 100644 --- a/CleanStoreTests/Scenes/CreateOrder/CreateOrderPresenterTests.swift +++ b/CleanStoreTests/Scenes/CreateOrder/CreateOrderPresenterTests.swift @@ -39,7 +39,7 @@ class CreateOrderPresenterTests: XCTestCase var viewModel: CreateOrder.FormatExpirationDate.ViewModel! // MARK: Spied methods - func displayExpirationDate(viewModel: CreateOrder.FormatExpirationDate.ViewModel) + func displayExpirationDate(_ viewModel: CreateOrder.FormatExpirationDate.ViewModel) { displayExpirationDateCalled = true self.viewModel = viewModel @@ -55,7 +55,7 @@ class CreateOrderPresenterTests: XCTestCase var viewModel: CreateOrder.FormatExpirationDate.ViewModel! // MARK: Spied methods - func displayExpirationDate(viewModel: CreateOrder.FormatExpirationDate.ViewModel) + func displayExpirationDate(_ viewModel: CreateOrder.FormatExpirationDate.ViewModel) { displayExpirationDateCalled = true self.viewModel = viewModel @@ -67,7 +67,7 @@ class CreateOrderPresenterTests: XCTestCase return displayExpirationDateCalled } - func verifyExpirationDateIsFormattedAs(date: String) -> Bool + func verifyExpirationDateIsFormattedAs(_ date: String) -> Bool { return viewModel.date == date } @@ -81,11 +81,11 @@ class CreateOrderPresenterTests: XCTestCase let createOrderPresenterOutputSpy = CreateOrderPresenterOutputSpy() createOrderPresenter.output = createOrderPresenterOutputSpy - let dateComponents = NSDateComponents() + var dateComponents = DateComponents() dateComponents.year = 2007 dateComponents.month = 6 dateComponents.day = 29 - let date = NSCalendar.currentCalendar().dateFromComponents(dateComponents)! + let date = Calendar.current.date(from: dateComponents)! let response = CreateOrder.FormatExpirationDate.Response(date: date) // When @@ -102,7 +102,7 @@ class CreateOrderPresenterTests: XCTestCase // Given let createOrderPresenterOutputSpy = CreateOrderPresenterOutputSpy() createOrderPresenter.output = createOrderPresenterOutputSpy - let response = CreateOrder.FormatExpirationDate.Response(date: NSDate()) + let response = CreateOrder.FormatExpirationDate.Response(date: Date()) // When createOrderPresenter.presentExpirationDate(response) @@ -117,11 +117,11 @@ class CreateOrderPresenterTests: XCTestCase let createOrderPresenterOutputMock = CreateOrderPresenterOutputMock() createOrderPresenter.output = createOrderPresenterOutputMock - let dateComponents = NSDateComponents() + var dateComponents = DateComponents() dateComponents.year = 2007 dateComponents.month = 6 dateComponents.day = 29 - let date = NSCalendar.currentCalendar().dateFromComponents(dateComponents)! + let date = Calendar.current.date(from: dateComponents)! let response = CreateOrder.FormatExpirationDate.Response(date: date) // When @@ -137,7 +137,7 @@ class CreateOrderPresenterTests: XCTestCase // Given let createOrderPresenterOutputMock = CreateOrderPresenterOutputMock() createOrderPresenter.output = createOrderPresenterOutputMock - let response = CreateOrder.FormatExpirationDate.Response(date: NSDate()) + let response = CreateOrder.FormatExpirationDate.Response(date: Date()) // When createOrderPresenter.presentExpirationDate(response) diff --git a/CleanStoreTests/Scenes/CreateOrder/CreateOrderViewControllerTests.swift b/CleanStoreTests/Scenes/CreateOrder/CreateOrderViewControllerTests.swift index e9eddce..1344557 100644 --- a/CleanStoreTests/Scenes/CreateOrder/CreateOrderViewControllerTests.swift +++ b/CleanStoreTests/Scenes/CreateOrder/CreateOrderViewControllerTests.swift @@ -28,9 +28,9 @@ class CreateOrderViewControllerTests: XCTestCase func setupCreateOrderViewController() { - let bundle = NSBundle.mainBundle() + let bundle = Bundle.main let storyboard = UIStoryboard(name: "Main", bundle: bundle) - createOrderViewController = storyboard.instantiateViewControllerWithIdentifier("CreateOrderViewController") as! CreateOrderViewController + createOrderViewController = storyboard.instantiateViewController(withIdentifier: "CreateOrderViewController") as! CreateOrderViewController _ = createOrderViewController.view addViewToWindow() } @@ -38,7 +38,7 @@ class CreateOrderViewControllerTests: XCTestCase func addViewToWindow() { window.addSubview(createOrderViewController.view) - NSRunLoop.currentRunLoop().runUntilDate(NSDate()) + RunLoop.current.run(until: Date()) } // MARK: Test doubles @@ -55,7 +55,7 @@ class CreateOrderViewControllerTests: XCTestCase var shippingMethods = [String]() // MARK: Spied methods - func formatExpirationDate(request: CreateOrder.FormatExpirationDate.Request) + func formatExpirationDate(_ request: CreateOrder.FormatExpirationDate.Request) { formatExpirationDateCalled = true self.request = request @@ -83,11 +83,11 @@ class CreateOrderViewControllerTests: XCTestCase let createOrderViewControllerOutputSpy = CreateOrderViewControllerOutputSpy() createOrderViewController.output = createOrderViewControllerOutputSpy - let dateComponents = NSDateComponents() + var dateComponents = DateComponents() dateComponents.year = 2007 dateComponents.month = 6 dateComponents.day = 29 - let selectedDate = NSCalendar.currentCalendar().dateFromComponents(dateComponents)! + let selectedDate = Calendar.current.date(from: dateComponents)! // When createOrderViewController.expirationDatePicker.date = selectedDate @@ -107,7 +107,7 @@ class CreateOrderViewControllerTests: XCTestCase let pickerView = createOrderViewController.shippingMethodPicker // When - let numberOfComponents = createOrderViewController.numberOfComponentsInPickerView(pickerView) + let numberOfComponents = createOrderViewController.numberOfComponents(in: pickerView!) // Then XCTAssertEqual(numberOfComponents, 1, "The number of components in the shipping method picker should be 1") @@ -119,7 +119,7 @@ class CreateOrderViewControllerTests: XCTestCase let pickerView = createOrderViewController.shippingMethodPicker // When - let numberOfRows = createOrderViewController.pickerView(pickerView, numberOfRowsInComponent: 0) + let numberOfRows = createOrderViewController.pickerView(pickerView!, numberOfRowsInComponent: 0) // Then let numberOfAvailableShippingtMethods = createOrderViewController.output.shippingMethods.count @@ -133,9 +133,9 @@ class CreateOrderViewControllerTests: XCTestCase // When let returnedTitles = [ - createOrderViewController.pickerView(pickerView, titleForRow: 0, forComponent: 0), - createOrderViewController.pickerView(pickerView, titleForRow: 1, forComponent: 0), - createOrderViewController.pickerView(pickerView, titleForRow: 2, forComponent: 0) + createOrderViewController.pickerView(pickerView!, titleForRow: 0, forComponent: 0), + createOrderViewController.pickerView(pickerView!, titleForRow: 1, forComponent: 0), + createOrderViewController.pickerView(pickerView!, titleForRow: 2, forComponent: 0) ] // Then @@ -155,7 +155,7 @@ class CreateOrderViewControllerTests: XCTestCase let pickerView = createOrderViewController.shippingMethodPicker // When - createOrderViewController.pickerView(pickerView, didSelectRow: 1, inComponent: 0) + createOrderViewController.pickerView(pickerView!, didSelectRow: 1, inComponent: 0) // Then let expectedShippingMethod = "Two-Day Shipping" @@ -176,8 +176,8 @@ class CreateOrderViewControllerTests: XCTestCase createOrderViewController.textFieldShouldReturn(currentTextField) // Then - XCTAssert(!currentTextField.isFirstResponder(), "Current text field should lose keyboard focus") - XCTAssert(nextTextField.isFirstResponder(), "Next text field should gain keyboard focus") + XCTAssert(!currentTextField.isFirstResponder, "Current text field should lose keyboard focus") + XCTAssert(nextTextField.isFirstResponder, "Next text field should gain keyboard focus") } func testKeyboardShouldBeDismissedWhenUserTapsReturnKeyWhenFocusIsInLastTextField() @@ -186,8 +186,8 @@ class CreateOrderViewControllerTests: XCTestCase // Scroll to the bottom of table view so the last text field is visible and its gesture recognizer is set up let lastSectionIndex = createOrderViewController.tableView.numberOfSections - 1 - let lastRowIndex = createOrderViewController.tableView.numberOfRowsInSection(lastSectionIndex) - 1 - createOrderViewController.tableView.scrollToRowAtIndexPath(NSIndexPath(forRow: lastRowIndex, inSection: lastSectionIndex), atScrollPosition: .Bottom, animated: false) + let lastRowIndex = createOrderViewController.tableView.numberOfRows(inSection: lastSectionIndex) - 1 + createOrderViewController.tableView.scrollToRow(at: IndexPath(row: lastRowIndex, section: lastSectionIndex), at: .bottom, animated: false) // Show keyboard for the last text field let numTextFields = createOrderViewController.textFields.count @@ -198,7 +198,7 @@ class CreateOrderViewControllerTests: XCTestCase createOrderViewController.textFieldShouldReturn(lastTextField) // Then - XCTAssert(!lastTextField.isFirstResponder(), "Last text field should lose keyboard focus") + XCTAssert(!lastTextField.isFirstResponder, "Last text field should lose keyboard focus") } func testTextFieldShouldHaveFocusWhenUserTapsOnTableViewRow() @@ -206,12 +206,12 @@ class CreateOrderViewControllerTests: XCTestCase // Given // When - let indexPath = NSIndexPath(forRow: 0, inSection: 0) - createOrderViewController.tableView(createOrderViewController.tableView, didSelectRowAtIndexPath: indexPath) + let indexPath = IndexPath(row: 0, section: 0) + createOrderViewController.tableView(createOrderViewController.tableView, didSelectRowAt: indexPath) // Then let textField = createOrderViewController.textFields[0] - XCTAssert(textField.isFirstResponder(), "The text field should have keyboard focus when user taps on the corresponding table view row") + XCTAssert(textField.isFirstResponder, "The text field should have keyboard focus when user taps on the corresponding table view row") } // MARK: Test picker configs when view is loaded diff --git a/CleanStoreTests/Scenes/ListOrders/ListOrdersInteractorTests.swift b/CleanStoreTests/Scenes/ListOrders/ListOrdersInteractorTests.swift index 74429d4..c24ccd1 100644 --- a/CleanStoreTests/Scenes/ListOrders/ListOrdersInteractorTests.swift +++ b/CleanStoreTests/Scenes/ListOrders/ListOrdersInteractorTests.swift @@ -46,7 +46,7 @@ class ListOrdersInteractorTests: XCTestCase var presentFetchedOrdersCalled = false // MARK: Spied methods - func presentFetchedOrders(response: ListOrders.FetchOrders.Response) + func presentFetchedOrders(_ response: ListOrders.FetchOrders.Response) { presentFetchedOrdersCalled = true } @@ -58,10 +58,10 @@ class ListOrdersInteractorTests: XCTestCase var fetchOrdersCalled = false // MARK: Spied methods - override func fetchOrders(completionHandler: (orders: [Order]) -> Void) + override func fetchOrders(_ completionHandler: @escaping (_ orders: [Order]) -> Void) { fetchOrdersCalled = true - completionHandler(orders: []) + completionHandler([]) } } diff --git a/CleanStoreTests/Scenes/ListOrders/ListOrdersPresenterTests.swift b/CleanStoreTests/Scenes/ListOrders/ListOrdersPresenterTests.swift index b4b0647..e8d5a9a 100644 --- a/CleanStoreTests/Scenes/ListOrders/ListOrdersPresenterTests.swift +++ b/CleanStoreTests/Scenes/ListOrders/ListOrdersPresenterTests.swift @@ -49,7 +49,7 @@ class ListOrdersPresenterTests: XCTestCase var viewModel: ListOrders.FetchOrders.ViewModel! // MARK: Spied methods - func displayFetchedOrders(viewModel: ListOrders.FetchOrders.ViewModel) + func displayFetchedOrders(_ viewModel: ListOrders.FetchOrders.ViewModel) { displayFetchedOrdersCalled = true self.viewModel = viewModel @@ -64,11 +64,11 @@ class ListOrdersPresenterTests: XCTestCase let listOrdersPresenterOutputSpy = ListOrdersPresenterOutputSpy() sut.output = listOrdersPresenterOutputSpy - let dateComponents = NSDateComponents() + var dateComponents = DateComponents() dateComponents.year = 2007 dateComponents.month = 6 dateComponents.day = 29 - let date = NSCalendar.currentCalendar().dateFromComponents(dateComponents)! + let date = Calendar.current.date(from: dateComponents)! let orders = [Order(id: "abc123", date: date, email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23"))] let response = ListOrders.FetchOrders.Response(orders: orders) @@ -93,7 +93,7 @@ class ListOrdersPresenterTests: XCTestCase let listOrdersPresenterOutputSpy = ListOrdersPresenterOutputSpy() sut.output = listOrdersPresenterOutputSpy - let orders = [Order(id: "abc123", date: NSDate(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23"))] + let orders = [Order(id: "abc123", date: Date(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23"))] let response = ListOrders.FetchOrders.Response(orders: orders) // When diff --git a/CleanStoreTests/Scenes/ListOrders/ListOrdersViewControllerTests.swift b/CleanStoreTests/Scenes/ListOrders/ListOrdersViewControllerTests.swift index 998bd9e..1acd9a8 100644 --- a/CleanStoreTests/Scenes/ListOrders/ListOrdersViewControllerTests.swift +++ b/CleanStoreTests/Scenes/ListOrders/ListOrdersViewControllerTests.swift @@ -38,15 +38,15 @@ class ListOrdersViewControllerTests: XCTestCase func setupListOrdersViewController() { - let bundle = NSBundle.mainBundle() + let bundle = Bundle.main let storyboard = UIStoryboard(name: "Main", bundle: bundle) - sut = storyboard.instantiateViewControllerWithIdentifier("ListOrdersViewController") as! ListOrdersViewController + sut = storyboard.instantiateViewController(withIdentifier: "ListOrdersViewController") as! ListOrdersViewController } func loadView() { window.addSubview(sut.view) - NSRunLoop.currentRunLoop().runUntilDate(NSDate()) + RunLoop.current.run(until: Date()) } // MARK: Test doubles @@ -59,7 +59,7 @@ class ListOrdersViewControllerTests: XCTestCase var fetchOrdersCalled = false // MARK: Spied methods - func fetchOrders(request: ListOrders.FetchOrders.Request) + func fetchOrders(_ request: ListOrders.FetchOrders.Request) { fetchOrdersCalled = true } @@ -114,7 +114,7 @@ class ListOrdersViewControllerTests: XCTestCase let tableView = sut.tableView // When - let numberOfSections = sut.numberOfSectionsInTableView(tableView) + let numberOfSections = sut.numberOfSections(in: tableView!) // Then XCTAssertEqual(numberOfSections, 1, "The number of table view sections should always be 1") @@ -128,7 +128,7 @@ class ListOrdersViewControllerTests: XCTestCase sut.displayedOrders = testDisplayedOrders // When - let numberOfRows = sut.tableView(tableView, numberOfRowsInSection: 0) + let numberOfRows = sut.tableView(tableView!, numberOfRowsInSection: 0) // Then XCTAssertEqual(numberOfRows, testDisplayedOrders.count, "The number of table view rows should equal the number of orders to display") @@ -142,8 +142,8 @@ class ListOrdersViewControllerTests: XCTestCase sut.displayedOrders = testDisplayedOrders // When - let indexPath = NSIndexPath(forRow: 0, inSection: 0) - let cell = sut.tableView(tableView, cellForRowAtIndexPath: indexPath) + let indexPath = IndexPath(row: 0, section: 0) + let cell = sut.tableView(tableView!, cellForRowAt: indexPath) // Then XCTAssertEqual(cell.textLabel?.text, "6/29/07", "A properly configured table view cell should display the order date") diff --git a/CleanStoreTests/Scenes/ShowOrder/ShowOrderViewControllerTests.swift b/CleanStoreTests/Scenes/ShowOrder/ShowOrderViewControllerTests.swift index 043d4cd..170410f 100644 --- a/CleanStoreTests/Scenes/ShowOrder/ShowOrderViewControllerTests.swift +++ b/CleanStoreTests/Scenes/ShowOrder/ShowOrderViewControllerTests.swift @@ -38,15 +38,15 @@ class ShowOrderViewControllerTests: XCTestCase func setupShowOrderViewController() { - let bundle = NSBundle.mainBundle() + let bundle = Bundle.main let storyboard = UIStoryboard(name: "Main", bundle: bundle) - sut = storyboard.instantiateViewControllerWithIdentifier("ShowOrderViewController") as! ShowOrderViewController + sut = storyboard.instantiateViewController(withIdentifier: "ShowOrderViewController") as! ShowOrderViewController } func loadView() { window.addSubview(sut.view) - NSRunLoop.currentRunLoop().runUntilDate(NSDate()) + RunLoop.current.run(until: Date()) } // MARK: Test doubles diff --git a/CleanStoreTests/Services/OrdersAPITests.swift b/CleanStoreTests/Services/OrdersAPITests.swift index 0bd08d7..d0a375c 100644 --- a/CleanStoreTests/Services/OrdersAPITests.swift +++ b/CleanStoreTests/Services/OrdersAPITests.swift @@ -27,8 +27,8 @@ class OrdersAPITests: XCTestCase { sut = OrdersAPI() testOrders = [ - Order(id: "abc123", date: NSDate(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), - Order(id: "def456", date: NSDate(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) + Order(id: "abc123", date: Date(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), + Order(id: "def456", date: Date(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) ] } diff --git a/CleanStoreTests/Services/OrdersCoreDataStoreTests.swift b/CleanStoreTests/Services/OrdersCoreDataStoreTests.swift index 69a94df..fbad272 100644 --- a/CleanStoreTests/Services/OrdersCoreDataStoreTests.swift +++ b/CleanStoreTests/Services/OrdersCoreDataStoreTests.swift @@ -32,16 +32,16 @@ class OrdersCoreDataStoreTests: XCTestCase deleteAllOrdersInOrdersCoreDataStore() testOrders = [ - Order(id: "abc123", date: NSDate(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), - Order(id: "def456", date: NSDate(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) + Order(id: "abc123", date: Date(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), + Order(id: "def456", date: Date(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) ] for order in testOrders { - let expectation = expectationWithDescription("Wait for createOrder() to return") + let expectation = self.expectation(description: "Wait for createOrder() to return") sut.createOrder(order) { (done: () throws -> Void) -> Void in expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } } } @@ -49,20 +49,20 @@ class OrdersCoreDataStoreTests: XCTestCase func deleteAllOrdersInOrdersCoreDataStore() { var allOrders = [Order]() - let fetchOrdersExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrdersExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrders { (orders: () throws -> [Order]) -> Void in allOrders = try! orders() fetchOrdersExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } for order in allOrders { - let deleteOrderExpectation = expectationWithDescription("Wait for deleteOrder() to return") + let deleteOrderExpectation = expectation(description: "Wait for deleteOrder() to return") self.sut.deleteOrder(order.id!) { (done: () throws -> Void) -> Void in deleteOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } } } @@ -75,12 +75,12 @@ class OrdersCoreDataStoreTests: XCTestCase // When var returnedOrders = [Order]() - let expectation = expectationWithDescription("Wait for fetchOrders() to return") + let expectation = self.expectation(description: "Wait for fetchOrders() to return") sut.fetchOrders { (orders: [Order], error: OrdersStoreError?) -> Void in returnedOrders = orders expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -97,12 +97,12 @@ class OrdersCoreDataStoreTests: XCTestCase // When var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToFetch.id!) { (order: Order?, error: OrdersStoreError?) -> Void in returnedOrder = order expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -112,24 +112,24 @@ class OrdersCoreDataStoreTests: XCTestCase func testCreateOrderShouldCreateNewOrder_OptionalError() { // Given - let orderToCreate = Order(id: "ghi789", date: NSDate(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) + let orderToCreate = Order(id: "ghi789", date: Date(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) // When - let createOrderExpectation = expectationWithDescription("Wait for createOrder() to return") + let createOrderExpectation = self.expectation(description: "Wait for createOrder() to return") sut.createOrder(orderToCreate) { (error: OrdersStoreError?) -> Void in createOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToCreate.id!) { (order: () throws -> Order?) -> Void in returnedOrder = try! order() expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(returnedOrder, orderToCreate, "createOrder() should create a new order") @@ -139,25 +139,25 @@ class OrdersCoreDataStoreTests: XCTestCase { // Given var orderToUpdate = testOrders.first! - let tomorrow = NSDate(timeIntervalSinceNow: 24*60*60) + let tomorrow = Date(timeIntervalSinceNow: 24*60*60) orderToUpdate.date = tomorrow // When - let updateOrderExpectation = expectationWithDescription("Wait for updateOrder() to return") + let updateOrderExpectation = expectation(description: "Wait for updateOrder() to return") sut.updateOrder(orderToUpdate) { (error: OrdersStoreError?) -> Void in updateOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var updatedOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToUpdate.id!) { (order: Order?, error: OrdersStoreError?) -> Void in updatedOrder = order fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(updatedOrder, orderToUpdate, "updateOrder() should update an existing order") @@ -169,27 +169,27 @@ class OrdersCoreDataStoreTests: XCTestCase let orderToDelete = testOrders.first! // When - let deleteOrderExpectation = expectationWithDescription("Wait for deleteOrder() to return") + let deleteOrderExpectation = expectation(description: "Wait for deleteOrder() to return") sut.deleteOrder(orderToDelete.id!) { (error: OrdersStoreError?) -> Void in deleteOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var deletedOrder: Order? var deleteOrderError: OrdersStoreError? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToDelete.id!) { (order: Order?, error: OrdersStoreError?) -> Void in deletedOrder = order deleteOrderError = error fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertNil(deletedOrder, "deleteOrder() should delete an existing order") - XCTAssertEqual(deleteOrderError, OrdersStoreError.CannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") + XCTAssertEqual(deleteOrderError, OrdersStoreError.cannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") } // MARK: - Test CRUD operations - Generic enum result type @@ -200,17 +200,17 @@ class OrdersCoreDataStoreTests: XCTestCase // When var returnedOrders = [Order]() - let expectation = expectationWithDescription("Wait for fetchOrders() to return") + let expectation = self.expectation(description: "Wait for fetchOrders() to return") sut.fetchOrders { (result: OrdersStoreResult<[Order]>) -> Void in switch (result) { - case .Success(let orders): + case .success(let orders): returnedOrders = orders - case .Failure(let error): + case .failure(let error): XCTFail("fetchOrders() should not return an error: \(error)") } expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -227,17 +227,17 @@ class OrdersCoreDataStoreTests: XCTestCase // When var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToFetch.id!) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success(let order): + case .success(let order): returnedOrder = order - case .Failure(let error): + case .failure(let error): XCTFail("fetchOrder() should not return an error: \(error)") } expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -247,24 +247,24 @@ class OrdersCoreDataStoreTests: XCTestCase func testCreateOrderShouldCreateNewOrder_GenericEnumResultType() { // Given - let orderToCreate = Order(id: "ghi789", date: NSDate(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) + let orderToCreate = Order(id: "ghi789", date: Date(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) // When - let createOrderExpectation = expectationWithDescription("Wait for createOrder() to return") + let createOrderExpectation = self.expectation(description: "Wait for createOrder() to return") sut.createOrder(orderToCreate) { (result: OrdersStoreResult) -> Void in createOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToCreate.id!) { (order: () throws -> Order?) -> Void in returnedOrder = try! order() expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(returnedOrder, orderToCreate, "createOrder() should create a new order") @@ -274,36 +274,36 @@ class OrdersCoreDataStoreTests: XCTestCase { // Given var orderToUpdate = testOrders.first! - let tomorrow = NSDate(timeIntervalSinceNow: 24*60*60) + let tomorrow = Date(timeIntervalSinceNow: 24*60*60) orderToUpdate.date = tomorrow // When - let updateOrderExpectation = expectationWithDescription("Wait for updateOrder() to return") + let updateOrderExpectation = expectation(description: "Wait for updateOrder() to return") sut.updateOrder(orderToUpdate) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success: + case .success: break; - case .Failure(let error): + case .failure(let error): XCTFail("updateOrder() should not return an error: \(error)") } updateOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var updatedOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToUpdate.id!) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success(let order): + case .success(let order): updatedOrder = order - case .Failure(let error): + case .failure(let error): XCTFail("fetchOrder() should not return an error: \(error)") } fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(updatedOrder, orderToUpdate, "updateOrder() should update an existing order") @@ -315,31 +315,31 @@ class OrdersCoreDataStoreTests: XCTestCase let orderToDelete = testOrders.first! // When - let deleteOrderExpectation = expectationWithDescription("Wait for deleteOrder() to return") + let deleteOrderExpectation = expectation(description: "Wait for deleteOrder() to return") sut.deleteOrder(orderToDelete.id!) { (result: OrdersStoreResult) -> Void in deleteOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var deletedOrder: Order? var deleteOrderError: OrdersStoreError? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToDelete.id!) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success(let order): + case .success(let order): deletedOrder = order - case .Failure(let error): + case .failure(let error): deleteOrderError = error } fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertNil(deletedOrder, "deleteOrder() should delete an existing order") - XCTAssertEqual(deleteOrderError, OrdersStoreError.CannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") + XCTAssertEqual(deleteOrderError, OrdersStoreError.cannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") } // MARK: - Test CRUD operations - Inner closure @@ -350,12 +350,12 @@ class OrdersCoreDataStoreTests: XCTestCase // When var returnedOrders = [Order]() - let expectation = expectationWithDescription("Wait for fetchOrders() to return") + let expectation = self.expectation(description: "Wait for fetchOrders() to return") sut.fetchOrders { (orders: () throws -> [Order]) -> Void in returnedOrders = try! orders() expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -372,12 +372,12 @@ class OrdersCoreDataStoreTests: XCTestCase // When var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToFetch.id!) { (order: () throws -> Order?) -> Void in returnedOrder = try! order() expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -387,25 +387,25 @@ class OrdersCoreDataStoreTests: XCTestCase func testCreateOrderShouldCreateNewOrder_InnerClosure() { // Given - let orderToCreate = Order(id: "ghi789", date: NSDate(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) + let orderToCreate = Order(id: "ghi789", date: Date(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) // When - let createOrderExpectation = expectationWithDescription("Wait for createOrder() to return") + let createOrderExpectation = self.expectation(description: "Wait for createOrder() to return") sut.createOrder(orderToCreate) { (done: () throws -> Void) -> Void in try! done() createOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToCreate.id!) { (order: () throws -> Order?) -> Void in returnedOrder = try! order() expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(returnedOrder, orderToCreate, "createOrder() should create a new order") @@ -415,26 +415,26 @@ class OrdersCoreDataStoreTests: XCTestCase { // Given var orderToUpdate = testOrders.first! - let tomorrow = NSDate(timeIntervalSinceNow: 24*60*60) + let tomorrow = Date(timeIntervalSinceNow: 24*60*60) orderToUpdate.date = tomorrow // When - let updateOrderExpectation = expectationWithDescription("Wait for updateOrder() to return") + let updateOrderExpectation = expectation(description: "Wait for updateOrder() to return") sut.updateOrder(orderToUpdate) { (done: () throws -> Void) -> Void in try! done() updateOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var updatedOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToUpdate.id!) { (order: () throws -> Order?) -> Void in updatedOrder = try! order() fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(updatedOrder, orderToUpdate, "updateOrder() should update an existing order") @@ -446,18 +446,18 @@ class OrdersCoreDataStoreTests: XCTestCase let orderToDelete = testOrders.first! // When - let deleteOrderExpectation = expectationWithDescription("Wait for deleteOrder() to return") + let deleteOrderExpectation = expectation(description: "Wait for deleteOrder() to return") sut.deleteOrder(orderToDelete.id!) { (done: () throws -> Void) -> Void in try! done() deleteOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var deletedOrder: Order? var deleteOrderError: OrdersStoreError? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToDelete.id!) { (order: () throws -> Order?) -> Void in do { deletedOrder = try order() @@ -467,10 +467,10 @@ class OrdersCoreDataStoreTests: XCTestCase } fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertNil(deletedOrder, "deleteOrder() should delete an existing order") - XCTAssertEqual(deleteOrderError, OrdersStoreError.CannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") + XCTAssertEqual(deleteOrderError, OrdersStoreError.cannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") } } diff --git a/CleanStoreTests/Services/OrdersMemStoreTests.swift b/CleanStoreTests/Services/OrdersMemStoreTests.swift index 9eecbdc..2707f09 100644 --- a/CleanStoreTests/Services/OrdersMemStoreTests.swift +++ b/CleanStoreTests/Services/OrdersMemStoreTests.swift @@ -29,8 +29,8 @@ class OrdersMemStoreTests: XCTestCase sut = OrdersMemStore() testOrders = [ - Order(id: "abc123", date: NSDate(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), - Order(id: "def456", date: NSDate(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) + Order(id: "abc123", date: Date(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), + Order(id: "def456", date: Date(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) ] sut.orders = testOrders @@ -50,12 +50,12 @@ class OrdersMemStoreTests: XCTestCase // When var returnedOrders = [Order]() - let expectation = expectationWithDescription("Wait for fetchOrders() to return") + let expectation = self.expectation(description: "Wait for fetchOrders() to return") sut.fetchOrders { (orders: [Order], error: OrdersStoreError?) -> Void in returnedOrders = orders expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -72,12 +72,12 @@ class OrdersMemStoreTests: XCTestCase // When var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToFetch.id!) { (order: Order?, error: OrdersStoreError?) -> Void in returnedOrder = order expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -87,24 +87,24 @@ class OrdersMemStoreTests: XCTestCase func testCreateOrderShouldCreateNewOrder_OptionalError() { // Given - let orderToCreate = Order(id: "ghi789", date: NSDate(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) + let orderToCreate = Order(id: "ghi789", date: Date(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) // When - let createOrderExpectation = expectationWithDescription("Wait for createOrder() to return") + let createOrderExpectation = expectation(description: "Wait for createOrder() to return") sut.createOrder(orderToCreate) { (error: OrdersStoreError?) -> Void in createOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var createdOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToCreate.id!) { (order: Order?, error: OrdersStoreError?) -> Void in createdOrder = order fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(createdOrder, orderToCreate, "createOrder() should create a new order") @@ -114,25 +114,25 @@ class OrdersMemStoreTests: XCTestCase { // Given var orderToUpdate = testOrders.first! - let tomorrow = NSDate(timeIntervalSinceNow: 24*60*60) + let tomorrow = Date(timeIntervalSinceNow: 24*60*60) orderToUpdate.date = tomorrow // When - let updateOrderExpectation = expectationWithDescription("Wait for updateOrder() to return") + let updateOrderExpectation = expectation(description: "Wait for updateOrder() to return") sut.updateOrder(orderToUpdate) { (error: OrdersStoreError?) -> Void in updateOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var updatedOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToUpdate.id!) { (order: Order?, error: OrdersStoreError?) -> Void in updatedOrder = order fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(updatedOrder, orderToUpdate, "updateOrder() should update an existing order") @@ -144,27 +144,27 @@ class OrdersMemStoreTests: XCTestCase let orderToDelete = testOrders.first! // When - let deleteOrderExpectation = expectationWithDescription("Wait for deleteOrder() to return") + let deleteOrderExpectation = expectation(description: "Wait for deleteOrder() to return") sut.deleteOrder(orderToDelete.id!) { (error: OrdersStoreError?) -> Void in deleteOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var deletedOrder: Order? var deleteOrderError: OrdersStoreError? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToDelete.id!) { (order: Order?, error: OrdersStoreError?) -> Void in deletedOrder = order deleteOrderError = error fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertNil(deletedOrder, "deleteOrder() should delete an existing order") - XCTAssertEqual(deleteOrderError, OrdersStoreError.CannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") + XCTAssertEqual(deleteOrderError, OrdersStoreError.cannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") } // MARK: - Test CRUD operations - Generic enum result type @@ -175,17 +175,17 @@ class OrdersMemStoreTests: XCTestCase // When var returnedOrders = [Order]() - let expectation = expectationWithDescription("Wait for fetchOrders() to return") + let expectation = self.expectation(description: "Wait for fetchOrders() to return") sut.fetchOrders { (result: OrdersStoreResult<[Order]>) -> Void in switch (result) { - case .Success(let orders): + case .success(let orders): returnedOrders = orders - case .Failure(let error): + case .failure(let error): XCTFail("fetchOrders() should not return an error: \(error)") } expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -202,17 +202,17 @@ class OrdersMemStoreTests: XCTestCase // When var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToFetch.id!) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success(let order): + case .success(let order): returnedOrder = order - case .Failure(let error): + case .failure(let error): XCTFail("fetchOrder() should not return an error: \(error)") } expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -222,35 +222,35 @@ class OrdersMemStoreTests: XCTestCase func testCreateOrderShouldCreateNewOrder_GenericEnumResultType() { // Given - let orderToCreate = Order(id: "ghi789", date: NSDate(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) + let orderToCreate = Order(id: "ghi789", date: Date(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) // When - let createOrderExpectation = expectationWithDescription("Wait for createOrder() to return") + let createOrderExpectation = expectation(description: "Wait for createOrder() to return") sut.createOrder(orderToCreate) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success: + case .success: break; - case .Failure(let error): + case .failure(let error): XCTFail("createOrder() should not return an error: \(error)") } createOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var createdOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToCreate.id!) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success(let order): + case .success(let order): createdOrder = order - case .Failure(let error): + case .failure(let error): XCTFail("fetchOrder() should not return an error: \(error)") } fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(createdOrder, orderToCreate, "createOrder() should create a new order") @@ -260,36 +260,36 @@ class OrdersMemStoreTests: XCTestCase { // Given var orderToUpdate = testOrders.first! - let tomorrow = NSDate(timeIntervalSinceNow: 24*60*60) + let tomorrow = Date(timeIntervalSinceNow: 24*60*60) orderToUpdate.date = tomorrow // When - let updateOrderExpectation = expectationWithDescription("Wait for updateOrder() to return") + let updateOrderExpectation = expectation(description: "Wait for updateOrder() to return") sut.updateOrder(orderToUpdate) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success: + case .success: break; - case .Failure(let error): + case .failure(let error): XCTFail("updateOrder() should not return an error: \(error)") } updateOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var updatedOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToUpdate.id!) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success(let order): + case .success(let order): updatedOrder = order - case .Failure(let error): + case .failure(let error): XCTFail("fetchOrder() should not return an error: \(error)") } fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(updatedOrder, orderToUpdate, "updateOrder() should update an existing order") @@ -301,31 +301,31 @@ class OrdersMemStoreTests: XCTestCase let orderToDelete = testOrders.first! // When - let deleteOrderExpectation = expectationWithDescription("Wait for deleteOrder() to return") + let deleteOrderExpectation = expectation(description: "Wait for deleteOrder() to return") sut.deleteOrder(orderToDelete.id!) { (result: OrdersStoreResult) -> Void in deleteOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var deletedOrder: Order? var deleteOrderError: OrdersStoreError? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToDelete.id!) { (result: OrdersStoreResult) -> Void in switch (result) { - case .Success(let order): + case .success(let order): deletedOrder = order - case .Failure(let error): + case .failure(let error): deleteOrderError = error } fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertNil(deletedOrder, "deleteOrder() should delete an existing order") - XCTAssertEqual(deleteOrderError, OrdersStoreError.CannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") + XCTAssertEqual(deleteOrderError, OrdersStoreError.cannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") } // MARK: - Test CRUD operations - Inner closure @@ -336,12 +336,12 @@ class OrdersMemStoreTests: XCTestCase // When var returnedOrders = [Order]() - let expectation = expectationWithDescription("Wait for fetchOrders() to return") + let expectation = self.expectation(description: "Wait for fetchOrders() to return") sut.fetchOrders { (orders: () throws -> [Order]) -> Void in returnedOrders = try! orders() expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -358,12 +358,12 @@ class OrdersMemStoreTests: XCTestCase // When var returnedOrder: Order? - let expectation = expectationWithDescription("Wait for fetchOrder() to return") + let expectation = self.expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToFetch.id!) { (order: () throws -> Order?) -> Void in returnedOrder = try! order() expectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then @@ -373,25 +373,25 @@ class OrdersMemStoreTests: XCTestCase func testCreateOrderShouldCreateNewOrder_InnerClosure() { // Given - let orderToCreate = Order(id: "ghi789", date: NSDate(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) + let orderToCreate = Order(id: "ghi789", date: Date(), email: "colin.code@clean-swift.com", firstName: "Colin", lastName: "Code", total: NSDecimalNumber(string: "7.89")) // When - let createOrderExpectation = expectationWithDescription("Wait for createOrder() to return") + let createOrderExpectation = expectation(description: "Wait for createOrder() to return") sut.createOrder(orderToCreate) { (done: () throws -> Void) -> Void in try! done() createOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var createdOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToCreate.id!) { (order: () throws -> Order?) -> Void in createdOrder = try! order() fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(createdOrder, orderToCreate, "createOrder() should create a new order") @@ -401,26 +401,26 @@ class OrdersMemStoreTests: XCTestCase { // Given var orderToUpdate = testOrders.first! - let tomorrow = NSDate(timeIntervalSinceNow: 24*60*60) + let tomorrow = Date(timeIntervalSinceNow: 24*60*60) orderToUpdate.date = tomorrow // When - let updateOrderExpectation = expectationWithDescription("Wait for updateOrder() to return") + let updateOrderExpectation = expectation(description: "Wait for updateOrder() to return") sut.updateOrder(orderToUpdate) { (done: () throws -> Void) -> Void in try! done() updateOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var updatedOrder: Order? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToUpdate.id!) { (order: () throws -> Order?) -> Void in updatedOrder = try! order() fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertEqual(updatedOrder, orderToUpdate, "updateOrder() should update an existing order") @@ -432,18 +432,18 @@ class OrdersMemStoreTests: XCTestCase let orderToDelete = testOrders.first! // When - let deleteOrderExpectation = expectationWithDescription("Wait for deleteOrder() to return") + let deleteOrderExpectation = expectation(description: "Wait for deleteOrder() to return") sut.deleteOrder(orderToDelete.id!) { (done: () throws -> Void) -> Void in try! done() deleteOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } // Then var deletedOrder: Order? var deleteOrderError: OrdersStoreError? - let fetchOrderExpectation = expectationWithDescription("Wait for fetchOrder() to return") + let fetchOrderExpectation = expectation(description: "Wait for fetchOrder() to return") sut.fetchOrder(orderToDelete.id!) { (order: () throws -> Order?) -> Void in do { deletedOrder = try order() @@ -452,10 +452,10 @@ class OrdersMemStoreTests: XCTestCase } catch {} fetchOrderExpectation.fulfill() } - waitForExpectationsWithTimeout(1.0) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.0) { (error) -> Void in } XCTAssertNil(deletedOrder, "deleteOrder() should delete an existing order") - XCTAssertEqual(deleteOrderError, OrdersStoreError.CannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") + XCTAssertEqual(deleteOrderError, OrdersStoreError.cannotFetch("Cannot fetch order with id \(orderToDelete.id!)"), "Deleted order should not exist") } } diff --git a/CleanStoreTests/TheLittleMocker.swift b/CleanStoreTests/TheLittleMocker.swift index 2e061a3..c9a2923 100644 --- a/CleanStoreTests/TheLittleMocker.swift +++ b/CleanStoreTests/TheLittleMocker.swift @@ -11,12 +11,12 @@ import XCTest protocol Authorizer { - func authorize(username: String, password: String) -> Bool? + func authorize(_ username: String, password: String) -> Bool? } class DummyAuthorizer: Authorizer { - func authorize(username: String, password: String) -> Bool? + func authorize(_ username: String, password: String) -> Bool? { return nil } @@ -24,7 +24,7 @@ class DummyAuthorizer: Authorizer class AcceptingAuthorizerStub: Authorizer { - func authorize(username: String, password: String) -> Bool? + func authorize(_ username: String, password: String) -> Bool? { return true } @@ -34,7 +34,7 @@ class AcceptingAuthorizerSpy: Authorizer { var authorizeWasCalled = false - func authorize(username: String, password: String) -> Bool? + func authorize(_ username: String, password: String) -> Bool? { authorizeWasCalled = true return true @@ -45,7 +45,7 @@ class AcceptingAuthorizerVerificationMock: Authorizer { var authorizeWasCalled = false - func authorize(username: String, password: String) -> Bool? + func authorize(_ username: String, password: String) -> Bool? { authorizeWasCalled = true return true @@ -59,7 +59,7 @@ class AcceptingAuthorizerVerificationMock: Authorizer class AcceptingAuthorizerFake: Authorizer { - func authorize(username: String, password: String) -> Bool? + func authorize(_ username: String, password: String) -> Bool? { return username == "Bob" } diff --git a/CleanStoreTests/Workers/OrdersWorkerTests.swift b/CleanStoreTests/Workers/OrdersWorkerTests.swift index 4a77866..364a9f5 100644 --- a/CleanStoreTests/Workers/OrdersWorkerTests.swift +++ b/CleanStoreTests/Workers/OrdersWorkerTests.swift @@ -35,15 +35,15 @@ class OrdersWorkerTests: XCTestCase var fetchedOrdersCalled = false // MARK: Spied methods - override func fetchOrders(completionHandler: (orders: () throws -> [Order]) -> Void) + override func fetchOrders(_ completionHandler: @escaping (_ orders: () throws -> [Order]) -> Void) { fetchedOrdersCalled = true - let oneSecond = dispatch_time(dispatch_time_t(DISPATCH_TIME_NOW), 1 * Int64(NSEC_PER_SEC)) - dispatch_after(oneSecond, dispatch_get_main_queue(), { + let oneSecond = DispatchTime.now() + Double(1 * Int64(NSEC_PER_SEC)) / Double(NSEC_PER_SEC) + DispatchQueue.main.asyncAfter(deadline: oneSecond, execute: { completionHandler { return [ - Order(id: "abc123", date: NSDate(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), - Order(id: "def456", date: NSDate(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) + Order(id: "abc123", date: Date(), email: "amy.apple@clean-swift.com", firstName: "Amy", lastName: "Apple", total: NSDecimalNumber(string: "1.23")), + Order(id: "def456", date: Date(), email: "bob.battery@clean-swift.com", firstName: "Bob", lastName: "Battery", total: NSDecimalNumber(string: "4.56")) ] } }) @@ -58,14 +58,14 @@ class OrdersWorkerTests: XCTestCase let ordersMemStoreSpy = sut.ordersStore as! OrdersMemStoreSpy // When - let expectation = expectationWithDescription("Wait for fetchOrders() to return") + let expectation = self.expectation(description: "Wait for fetchOrders() to return") sut.fetchOrders { (orders: [Order]) -> Void in expectation.fulfill() } // Then XCTAssert(ordersMemStoreSpy.fetchedOrdersCalled, "Calling fetchOrders() should ask the data store for a list of orders") - waitForExpectationsWithTimeout(1.1) { (error: NSError?) -> Void in + waitForExpectations(timeout: 1.1) { (error) -> Void in XCTAssert(true, "Calling fetchOrders() should result in the completion handler being called with the fetched orders result") } }