From 91d041390ee20ea6f66009f8c9bdff9c20155eec Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sat, 28 Sep 2024 09:11:03 +1000 Subject: [PATCH 1/7] Add `.swift-version` Will use it for SwiftFormat, https://github.com/nicklockwood/SwiftFormat --- .swift-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .swift-version diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000..e0ea36f --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +6.0 From 1d0bad23fbae371207a3979627dbae6b1704ec4d Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sat, 28 Sep 2024 09:19:35 +1000 Subject: [PATCH 2/7] Set up `.git-blame-ignore-revs` file --- .git-blame-ignore-revs | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .git-blame-ignore-revs diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..1a49603 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,8 @@ +# Formatting-only commits +# +# Make `git blame` ignore the commits in this list by feeding it this file via `--ignore-revs-file` +# +# See https://git-scm.com/docs/git-blame#Documentation/git-blame.txt---ignore-revs-fileltfilegt +# +# GitHub supports this out of the box. +# See https://github.com/orgs/community/discussions/5033 From 7a7c96e1cd9889ff3221c09528a6e857feea4a61 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sat, 28 Sep 2024 09:21:40 +1000 Subject: [PATCH 3/7] Run `swiftformat .` --- 01-introduction/fizz_buzz.swift | 8 ++-- 01-introduction/test_fizz_buzz.swift | 2 +- .../0-start/AlbertosTests/AlbertosTests.swift | 6 +-- .../1-end/Albertos/AlbertosApp.swift | 1 - .../1-end/Albertos/MenuItem.swift | 2 - .../1-end/Albertos/MenuSection.swift | 2 - .../AlbertosTests/MenuGroupingTests.swift | 3 +- 05-fixtures/1-end/Albertos/MenuItem.swift | 2 - .../AlbertosTests/MenuGroupingTests.swift | 3 +- .../AlbertosTests/MenuItem+Fixture.swift | 15 ++++---- .../AlbertosTests/MenuSection+Fixture.swift | 3 +- .../0-start/Albertos/MenuItem.swift | 2 - .../AlbertosTests/MenuItem+Fixture.swift | 17 ++++----- .../1-end/Albertos/AlbertosApp.swift | 1 - .../1-end/Albertos/MenuItem.swift | 2 - .../1-end/Albertos/MenuList.ViewModel.swift | 4 +- .../1-end/Albertos/MenuList.swift | 1 - .../1-end/Albertos/MenuRow.ViewModel.swift | 2 - .../1-end/Albertos/MenuRow.swift | 1 - .../1-end/Albertos/MenuSection.swift | 2 - .../AlbertosTests/MenuGroupingTests.swift | 3 +- .../AlbertosTests/MenuItem+Fixture.swift | 17 ++++----- .../MenuList.ViewModelTests.swift | 1 - .../MenuRow.ViewModelTests.swift | 1 - .../AlbertosTests/MenuSection+Fixture.swift | 3 +- .../1-end/Albertos/AlbertosApp.swift | 1 - .../1-end/Albertos/MenuFetching.swift | 1 - .../Albertos/MenuFetchingPlaceholder.swift | 2 +- .../1-end/Albertos/MenuList.ViewModel.swift | 2 - .../MenuList.ViewModelTests.swift | 1 - .../1-end/Albertos/MenuList.ViewModel.swift | 4 +- 08-stub/1-end/Albertos/MenuList.swift | 5 +-- .../AlbertosTests/MenuFetchingStub.swift | 3 +- .../MenuList.ViewModelTests.swift | 5 +-- .../1-end/Albertos/MenuItem.swift | 2 - .../AlbertosTests/MenuItem+JSONFixture.swift | 17 ++++----- .../MenuItemAlternateJSONTests.swift | 25 ++++++------ .../1-end/AlbertosTests/MenuItemTests.swift | 2 +- .../1-end/AlbertosTests/XCTestCase+JSON.swift | 1 - .../1-end/Albertos/AlbertosApp.swift | 1 - .../1-end/Albertos/MenuFetcher.swift | 3 +- .../1-end/Albertos/NetworkFetching.swift | 1 - .../Albertos/URLSession+NetworkFetching.swift | 5 +-- .../AlbertosTests/MenuFetcherTests.swift | 13 +++---- .../MenuList.ViewModelTests.swift | 5 +-- .../AlbertosTests/NetworkFetchingStub.swift | 5 +-- .../0-start/Albertos/AlbertosApp.swift | 1 - .../0-start/Albertos/Color+Custom.swift | 1 - .../Albertos/MenuItemDetail.ViewModel.swift | 2 - .../0-start/Albertos/MenuItemDetail.swift | 1 - .../0-start/Albertos/MenuList.swift | 5 +-- .../0-start/Albertos/Order.swift | 1 - .../Albertos/OrderButton.ViewModel.swift | 2 - .../0-start/Albertos/OrderButton.swift | 3 +- .../0-start/Albertos/OrderController.swift | 5 +-- .../Albertos/OrderDetail.ViewModel.swift | 2 - .../0-start/Albertos/OrderDetail.swift | 2 - .../MenuItemDetail.ViewModelTests.swift | 1 - .../OrderButtonViewModelTests.swift | 2 - .../AlbertosTests/OrderControllerTests.swift | 1 - .../OrderDetail.ViewModelTests.swift | 1 - .../0-start/AlbertosTests/OrderTests.swift | 1 - .../1-end/Albertos/AlbertosApp.swift | 1 - .../Albertos/MenuItemDetail.ViewModel.swift | 8 ++-- .../1-end/Albertos/MenuItemDetail.swift | 1 - .../1-end/Albertos/MenuList.swift | 5 +-- .../MenuItemDetail.ViewModelTests.swift | 1 - 12-spy/0-start/Albertos/AlbertosApp.swift | 1 - .../Albertos/OrderButton.ViewModel.swift | 2 - 12-spy/0-start/Albertos/OrderButton.swift | 3 +- .../Albertos/OrderDetail.ViewModel.swift | 2 - 12-spy/0-start/Albertos/OrderDetail.swift | 1 - .../OrderButtonViewModelTests.swift | 2 - .../OrderDetail.ViewModelTests.swift | 1 - 12-spy/1-end/Albertos/AlbertosApp.swift | 1 - ...oPaymentsProcessor+PaymentProcessing.swift | 3 +- .../1-end/Albertos/Order+HippoPayments.swift | 3 +- 12-spy/1-end/Albertos/Order.swift | 1 - 12-spy/1-end/Albertos/OrderButton.swift | 3 +- .../Albertos/OrderDetail.ViewModel.swift | 2 - 12-spy/1-end/Albertos/OrderDetail.swift | 1 - 12-spy/1-end/Albertos/PaymentProcessing.swift | 1 - .../Albertos/PaymentProcessingProxy.swift | 1 - .../OrderDetail.ViewModelTests.swift | 1 - 12-spy/1-end/AlbertosTests/OrderTests.swift | 1 - .../AlbertosTests/PaymentProcessingSpy.swift | 1 - .../1-end/Albertos/Alert.ViewModel.swift | 2 - .../1-end/Albertos/OrderButton.swift | 5 +-- .../Albertos/OrderDetail.ViewModel.swift | 2 - .../1-end/Albertos/OrderDetail.swift | 1 - .../OrderDetail.ViewModelTests.swift | 1 - .../AlbertosTests/PaymentProcessingStub.swift | 5 +-- .../AlbertosTests/XCTestCase+Timeouts.swift | 1 - .../1-end/Albertos/MenuRow.ViewModel.swift | 2 - .../1-end/Albertos/OrderController.swift | 5 +-- .../Albertos/OrderDetail.ViewModel.swift | 8 ++-- .../MenuRow.ViewModelTests.swift | 1 - .../OrderDetail.ViewModelTests.swift | 1 - .../1-end/Albertos/MenuItem.swift | 2 - .../1-end/Albertos/MenuList.swift | 5 +-- 15-fake-and-dummy/1-end/Albertos/Order.swift | 1 - .../1-end/Albertos/OrderController.swift | 5 +-- .../1-end/Albertos/OrderStoring.swift | 1 - .../Albertos/UserDefaults+OrderStoring.swift | 3 +- .../MenuItemDetail.ViewModelTests.swift | 1 - .../OrderButtonViewModelTests.swift | 2 - .../AlbertosTests/OrderControllerTests.swift | 1 - .../OrderDetail.ViewModelTests.swift | 1 - .../AlbertosTests/OrderStoringFake.swift | 5 +-- .../PaymentProcessingDummy.swift | 5 +-- .../Albertos/AlbertosApp.swift | 1 - .../Albertos/Alert.ViewModel.swift | 2 - .../Albertos/Color+Custom.swift | 1 - ...oPaymentsProcessor+PaymentProcessing.swift | 3 +- .../Albertos/MenuFetcher.swift | 3 +- .../Albertos/MenuFetching.swift | 1 - .../Albertos/MenuItem.swift | 2 - .../Albertos/MenuItemDetail.ViewModel.swift | 8 ++-- .../Albertos/MenuItemDetail.swift | 1 - .../Albertos/MenuList.ViewModel.swift | 4 +- .../Albertos/MenuList.swift | 5 +-- .../Albertos/MenuRow.ViewModel.swift | 2 - .../Albertos/MenuRow.swift | 1 - .../Albertos/MenuSection.swift | 2 - .../Albertos/NetworkFetching.swift | 1 - .../Albertos/Order+HippoPayments.swift | 3 +- .../Albertos/Order.swift | 1 - .../Albertos/OrderButton.ViewModel.swift | 2 - .../Albertos/OrderButton.swift | 5 +-- .../Albertos/OrderController.swift | 5 +-- .../Albertos/OrderDetail.ViewModel.swift | 8 ++-- .../Albertos/OrderDetail.swift | 1 - .../Albertos/OrderStoring.swift | 1 - .../Albertos/PaymentProcessing.swift | 1 - .../Albertos/PaymentProcessingProxy.swift | 1 - .../Albertos/URLSession+NetworkFetching.swift | 5 +-- .../Albertos/UserDefaults+OrderStoring.swift | 3 +- .../AlbertosTests/MenuFetcherTests.swift | 13 +++---- .../AlbertosTests/MenuGroupingTests.swift | 3 +- .../MenuItemAlternateJSONTests.swift | 25 ++++++------ .../MenuItemDetail.ViewModelTests.swift | 5 +-- .../AlbertosTests/MenuItemTests.swift | 2 +- .../MenuList.ViewModelTests.swift | 5 +-- .../MenuRow.ViewModelTests.swift | 1 - .../OrderButtonViewModelTests.swift | 2 - .../AlbertosTests/OrderControllerTests.swift | 1 - .../OrderDetail.ViewModelTests.swift | 1 - .../AlbertosTests/OrderTests.swift | 1 - .../Albertos/AlbertosApp.swift | 1 - .../Albertos/Alert.ViewModel.swift | 2 - .../Albertos/Color+Custom.swift | 1 - ...oPaymentsProcessor+PaymentProcessing.swift | 3 +- .../Albertos/MenuFetcher.swift | 3 +- .../Albertos/MenuFetching.swift | 1 - .../Albertos/MenuItem.swift | 2 - .../Albertos/MenuItemDetail.ViewModel.swift | 8 ++-- .../Albertos/MenuItemDetail.swift | 1 - .../Albertos/MenuList.ViewModel.swift | 4 +- .../Albertos/MenuList.swift | 5 +-- .../Albertos/MenuRow.ViewModel.swift | 2 - .../Albertos/MenuRow.swift | 1 - .../Albertos/MenuSection.swift | 2 - .../Albertos/NetworkFetching.swift | 1 - .../Albertos/Order+HippoPayments.swift | 3 +- .../Albertos/Order.swift | 1 - .../Albertos/OrderButton.ViewModel.swift | 2 - .../Albertos/OrderButton.swift | 5 +-- .../Albertos/OrderController.swift | 5 +-- .../Albertos/OrderDetail.ViewModel.swift | 8 ++-- .../Albertos/OrderDetail.swift | 1 - .../Albertos/OrderStoring.swift | 1 - .../Albertos/PaymentProcessing.swift | 1 - .../Albertos/PaymentProcessingProxy.swift | 1 - .../Albertos/URLSession+NetworkFetching.swift | 5 +-- .../Albertos/UserDefaults+OrderStoring.swift | 3 +- .../MenuItemDetail.ViewModelSpec.swift | 13 ++----- .../Albertos/AlertViewModel.swift | 1 - .../Albertos/AppCoordinator.swift | 9 ++--- .../Albertos/AppDelegate.swift | 9 ++--- .../Albertos/MenuItemDetailView.swift | 9 ++--- .../MenuItemDetailViewController.swift | 11 +++--- .../Albertos/MenuItemDetailViewModel.swift | 9 ++--- .../MenuListTableViewDataSource.swift | 17 ++++----- .../Albertos/MenuListTableViewDelegate.swift | 7 ++-- .../Albertos/MenuListViewController.swift | 22 +++++------ .../Albertos/MenuListViewModel.swift | 3 +- .../Albertos/MenuRowViewModel.swift | 1 - .../Albertos/Order+HippoPayments.swift | 3 +- .../Albertos/OrderButton.ViewModel.swift | 1 - .../Albertos/OrderDetailViewController.swift | 38 +++++++++---------- .../Albertos/OrderDetailViewModel.swift | 7 ++-- .../Albertos/SceneDelegate.swift | 3 +- .../Albertos/UIButton+BigButtonStyle.swift | 5 +-- .../Albertos/UIColor+Custom.swift | 1 - .../Albertos/UIFont+Utils.swift | 1 - .../Albertos/UITableViewFooterLabel.swift | 4 +- .../Albertos/UIView+AutoLayout.swift | 9 ++--- .../Albertos/UIViewControllerPresenting.swift | 1 - .../AlbertosTests/AppCoordinatorTests.swift | 3 +- .../AlbertosTests/MenuFetcherTests.swift | 13 +++---- .../AlbertosTests/MenuGroupingTests.swift | 3 +- .../MenuItemAlternateJSONTests.swift | 25 ++++++------ .../MenuItemDetail.ViewModelTests.swift | 1 - .../MenuItemDetailViewControllerTests.swift | 1 - .../MenuItemDetailViewTests.swift | 1 - .../AlbertosTests/MenuItemTests.swift | 2 +- .../MenuList.ViewModelTests.swift | 5 +-- .../MenuListTableViewDataSourceTests.swift | 3 +- .../MenuListViewControllerTests.swift | 1 - .../MenuRow.ViewModelTests.swift | 1 - .../MeunListTableViewDelegateTests.swift | 1 - .../OrderButtonViewModelTests.swift | 2 - .../AlbertosTests/OrderControllerTests.swift | 1 - .../OrderDetail.ViewModelTests.swift | 1 - .../AlbertosTests/OrderTests.swift | 1 - .../AlbertosTests/SceneDelegateTests.swift | 10 ++--- Packages/CollectionSafe/Package.swift | 3 +- .../Sources/Collection+Safe.swift | 3 +- Packages/HippoAnalytics/Package.swift | 6 ++- .../HippoAnalytics/HippoAnalyticsClient.swift | 5 +-- .../HippoAnalyticsTests.swift | 2 +- Packages/HippoPayments/Package.swift | 6 ++- ...poPaymentsConfirmationViewController.swift | 3 +- .../HippoPaymentsProcessor.swift | 7 ++-- .../UIViewController+Presentation.swift | 5 +-- .../HippoPaymentsTests.swift | 2 +- 226 files changed, 298 insertions(+), 560 deletions(-) diff --git a/01-introduction/fizz_buzz.swift b/01-introduction/fizz_buzz.swift index ee46429..511d0a0 100755 --- a/01-introduction/fizz_buzz.swift +++ b/01-introduction/fizz_buzz.swift @@ -4,10 +4,10 @@ func fizzBuzz(_ number: Int) -> String { let divisibleBy3 = number % 3 == 0 let divisibleBy5 = number % 5 == 0 switch (divisibleBy3, divisibleBy5) { - case (false, false): return "\(number)" - case (true, false): return "fizz" - case (false, true): return "buzz" - case (true, true): return "fizz buzz" + case (false, false): return "\(number)" + case (true, false): return "fizz" + case (false, true): return "buzz" + case (true, true): return "fizz buzz" } } diff --git a/01-introduction/test_fizz_buzz.swift b/01-introduction/test_fizz_buzz.swift index 6ad8c9d..a34547d 100755 --- a/01-introduction/test_fizz_buzz.swift +++ b/01-introduction/test_fizz_buzz.swift @@ -32,7 +32,7 @@ func shell(_ command: String) -> String { /// Call the fizz-buzz script with a given input and return the script's output. func fizzBuzz(_ number: Int) -> String { - return shell("./fizz_buzz.swift \(number)") + shell("./fizz_buzz.swift \(number)") } /// Check if two input `String`s are equal, printing "PASSED" if true and diff --git a/04-tdd-in-the-real-world/0-start/AlbertosTests/AlbertosTests.swift b/04-tdd-in-the-real-world/0-start/AlbertosTests/AlbertosTests.swift index e9b9e46..998e31f 100644 --- a/04-tdd-in-the-real-world/0-start/AlbertosTests/AlbertosTests.swift +++ b/04-tdd-in-the-real-world/0-start/AlbertosTests/AlbertosTests.swift @@ -1,8 +1,7 @@ -import XCTest @testable import Albertos +import XCTest class AlbertosTests: XCTestCase { - override func setUpWithError() throws { // Put setup code here. This method is called before the invocation of each test method in the class. } @@ -18,9 +17,8 @@ class AlbertosTests: XCTestCase { func testPerformanceExample() throws { // This is an example of a performance test case. - self.measure { + measure { // Put the code you want to measure the time of here. } } - } diff --git a/04-tdd-in-the-real-world/1-end/Albertos/AlbertosApp.swift b/04-tdd-in-the-real-world/1-end/Albertos/AlbertosApp.swift index 4a93e1d..24a99ea 100644 --- a/04-tdd-in-the-real-world/1-end/Albertos/AlbertosApp.swift +++ b/04-tdd-in-the-real-world/1-end/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - var body: some Scene { WindowGroup { NavigationView { diff --git a/04-tdd-in-the-real-world/1-end/Albertos/MenuItem.swift b/04-tdd-in-the-real-world/1-end/Albertos/MenuItem.swift index 7d7b7d4..d8f2875 100644 --- a/04-tdd-in-the-real-world/1-end/Albertos/MenuItem.swift +++ b/04-tdd-in-the-real-world/1-end/Albertos/MenuItem.swift @@ -1,10 +1,8 @@ struct MenuItem { - let category: String let name: String } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/04-tdd-in-the-real-world/1-end/Albertos/MenuSection.swift b/04-tdd-in-the-real-world/1-end/Albertos/MenuSection.swift index 18777ef..5f36087 100644 --- a/04-tdd-in-the-real-world/1-end/Albertos/MenuSection.swift +++ b/04-tdd-in-the-real-world/1-end/Albertos/MenuSection.swift @@ -1,10 +1,8 @@ struct MenuSection { - let category: String let items: [MenuItem] } extension MenuSection: Identifiable { - var id: String { category } } diff --git a/04-tdd-in-the-real-world/1-end/AlbertosTests/MenuGroupingTests.swift b/04-tdd-in-the-real-world/1-end/AlbertosTests/MenuGroupingTests.swift index 370fc3f..f1dacb7 100644 --- a/04-tdd-in-the-real-world/1-end/AlbertosTests/MenuGroupingTests.swift +++ b/04-tdd-in-the-real-world/1-end/AlbertosTests/MenuGroupingTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuGroupingTests: XCTestCase { - func testMenuWithManyCategoriesReturnsAsManySectionsInReverseAlphabeticalOrder() { let menu = [ MenuItem(category: "pastas", name: "a pasta"), @@ -22,7 +21,7 @@ class MenuGroupingTests: XCTestCase { func testMenuWithOneCategoryReturnsOneSection() throws { let menu = [ MenuItem(category: "pastas", name: "name"), - MenuItem(category: "pastas", name: "other name") + MenuItem(category: "pastas", name: "other name"), ] let sections = groupMenuByCategory(menu) diff --git a/05-fixtures/1-end/Albertos/MenuItem.swift b/05-fixtures/1-end/Albertos/MenuItem.swift index ea0eb76..8cbebbb 100644 --- a/05-fixtures/1-end/Albertos/MenuItem.swift +++ b/05-fixtures/1-end/Albertos/MenuItem.swift @@ -1,11 +1,9 @@ struct MenuItem { - let category: String let name: String let spicy: Bool } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/05-fixtures/1-end/AlbertosTests/MenuGroupingTests.swift b/05-fixtures/1-end/AlbertosTests/MenuGroupingTests.swift index 2d05e90..1499aab 100644 --- a/05-fixtures/1-end/AlbertosTests/MenuGroupingTests.swift +++ b/05-fixtures/1-end/AlbertosTests/MenuGroupingTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuGroupingTests: XCTestCase { - func testMenuWithManyCategoriesReturnsAsManySectionsInReverseAlphabeticalOrder() { let menu: [MenuItem] = [ .fixture(category: "pastas"), @@ -22,7 +21,7 @@ class MenuGroupingTests: XCTestCase { func testMenuWithOneCategoryReturnsOneSection() throws { let menu: [MenuItem] = [ .fixture(category: "pastas", name: "name"), - .fixture(category: "pastas", name: "other name") + .fixture(category: "pastas", name: "other name"), ] let sections = groupMenuByCategory(menu) diff --git a/05-fixtures/1-end/AlbertosTests/MenuItem+Fixture.swift b/05-fixtures/1-end/AlbertosTests/MenuItem+Fixture.swift index d1bf15c..aa933d3 100644 --- a/05-fixtures/1-end/AlbertosTests/MenuItem+Fixture.swift +++ b/05-fixtures/1-end/AlbertosTests/MenuItem+Fixture.swift @@ -1,12 +1,11 @@ @testable import Albertos extension MenuItem { - - static func fixture( - category: String = "category", - name: String = "name", - spicy: Bool = false - ) -> MenuItem { - MenuItem(category: category, name: name, spicy: spicy) - } + static func fixture( + category: String = "category", + name: String = "name", + spicy: Bool = false + ) -> MenuItem { + MenuItem(category: category, name: name, spicy: spicy) + } } diff --git a/05-fixtures/1-end/AlbertosTests/MenuSection+Fixture.swift b/05-fixtures/1-end/AlbertosTests/MenuSection+Fixture.swift index c08d0cb..1314dc8 100644 --- a/05-fixtures/1-end/AlbertosTests/MenuSection+Fixture.swift +++ b/05-fixtures/1-end/AlbertosTests/MenuSection+Fixture.swift @@ -1,11 +1,10 @@ @testable import Albertos extension MenuSection { - static func fixture( category: String = "a category", items: [MenuItem] = [.fixture()] ) -> MenuSection { - return MenuSection(category: category, items: items) + MenuSection(category: category, items: items) } } diff --git a/06-testing-static-swiftui-views/0-start/Albertos/MenuItem.swift b/06-testing-static-swiftui-views/0-start/Albertos/MenuItem.swift index 33bd6d6..5b977db 100644 --- a/06-testing-static-swiftui-views/0-start/Albertos/MenuItem.swift +++ b/06-testing-static-swiftui-views/0-start/Albertos/MenuItem.swift @@ -1,5 +1,4 @@ struct MenuItem { - let category: String let name: String let spicy: Bool @@ -7,6 +6,5 @@ struct MenuItem { } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/06-testing-static-swiftui-views/0-start/AlbertosTests/MenuItem+Fixture.swift b/06-testing-static-swiftui-views/0-start/AlbertosTests/MenuItem+Fixture.swift index 036d8ef..8238532 100644 --- a/06-testing-static-swiftui-views/0-start/AlbertosTests/MenuItem+Fixture.swift +++ b/06-testing-static-swiftui-views/0-start/AlbertosTests/MenuItem+Fixture.swift @@ -1,13 +1,12 @@ @testable import Albertos extension MenuItem { - - static func fixture( - category: String = "category", - name: String = "name", - spicy: Bool = false, - price: Double = 1.0 - ) -> MenuItem { - MenuItem(category: category, name: name, spicy: spicy, price: price) - } + static func fixture( + category: String = "category", + name: String = "name", + spicy: Bool = false, + price: Double = 1.0 + ) -> MenuItem { + MenuItem(category: category, name: name, spicy: spicy, price: price) + } } diff --git a/06-testing-static-swiftui-views/1-end/Albertos/AlbertosApp.swift b/06-testing-static-swiftui-views/1-end/Albertos/AlbertosApp.swift index df0def4..2a6e97e 100644 --- a/06-testing-static-swiftui-views/1-end/Albertos/AlbertosApp.swift +++ b/06-testing-static-swiftui-views/1-end/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - var body: some Scene { WindowGroup { NavigationView { diff --git a/06-testing-static-swiftui-views/1-end/Albertos/MenuItem.swift b/06-testing-static-swiftui-views/1-end/Albertos/MenuItem.swift index deec8a4..c38d1bd 100644 --- a/06-testing-static-swiftui-views/1-end/Albertos/MenuItem.swift +++ b/06-testing-static-swiftui-views/1-end/Albertos/MenuItem.swift @@ -1,5 +1,4 @@ struct MenuItem { - let category: String let name: String let spicy: Bool @@ -7,7 +6,6 @@ struct MenuItem { } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/06-testing-static-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift b/06-testing-static-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift index d652663..e15dcfb 100644 --- a/06-testing-static-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift +++ b/06-testing-static-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift @@ -1,14 +1,12 @@ extension MenuList { - struct ViewModel { - let sections: [MenuSection] init( menu: [MenuItem], menuGrouping: @escaping ([MenuItem]) -> [MenuSection] = groupMenuByCategory ) { - self.sections = menuGrouping(menu) + sections = menuGrouping(menu) } } } diff --git a/06-testing-static-swiftui-views/1-end/Albertos/MenuList.swift b/06-testing-static-swiftui-views/1-end/Albertos/MenuList.swift index 8b65cf6..d216c66 100644 --- a/06-testing-static-swiftui-views/1-end/Albertos/MenuList.swift +++ b/06-testing-static-swiftui-views/1-end/Albertos/MenuList.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuList: View { - let viewModel: ViewModel var body: some View { diff --git a/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.ViewModel.swift b/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.ViewModel.swift index 83165a7..a6980a4 100644 --- a/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.ViewModel.swift +++ b/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.ViewModel.swift @@ -1,7 +1,5 @@ extension MenuRow { - struct ViewModel { - let text: String init(item: MenuItem) { diff --git a/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.swift b/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.swift index 8dcc6fe..461a936 100644 --- a/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.swift +++ b/06-testing-static-swiftui-views/1-end/Albertos/MenuRow.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuRow: View { - let viewModel: ViewModel var body: some View { diff --git a/06-testing-static-swiftui-views/1-end/Albertos/MenuSection.swift b/06-testing-static-swiftui-views/1-end/Albertos/MenuSection.swift index d267654..747d38d 100644 --- a/06-testing-static-swiftui-views/1-end/Albertos/MenuSection.swift +++ b/06-testing-static-swiftui-views/1-end/Albertos/MenuSection.swift @@ -1,11 +1,9 @@ struct MenuSection { - let category: String let items: [MenuItem] } extension MenuSection: Identifiable { - var id: String { category } } diff --git a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuGroupingTests.swift b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuGroupingTests.swift index 2d05e90..1499aab 100644 --- a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuGroupingTests.swift +++ b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuGroupingTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuGroupingTests: XCTestCase { - func testMenuWithManyCategoriesReturnsAsManySectionsInReverseAlphabeticalOrder() { let menu: [MenuItem] = [ .fixture(category: "pastas"), @@ -22,7 +21,7 @@ class MenuGroupingTests: XCTestCase { func testMenuWithOneCategoryReturnsOneSection() throws { let menu: [MenuItem] = [ .fixture(category: "pastas", name: "name"), - .fixture(category: "pastas", name: "other name") + .fixture(category: "pastas", name: "other name"), ] let sections = groupMenuByCategory(menu) diff --git a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuItem+Fixture.swift b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuItem+Fixture.swift index 036d8ef..8238532 100644 --- a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuItem+Fixture.swift +++ b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuItem+Fixture.swift @@ -1,13 +1,12 @@ @testable import Albertos extension MenuItem { - - static func fixture( - category: String = "category", - name: String = "name", - spicy: Bool = false, - price: Double = 1.0 - ) -> MenuItem { - MenuItem(category: category, name: name, spicy: spicy, price: price) - } + static func fixture( + category: String = "category", + name: String = "name", + spicy: Bool = false, + price: Double = 1.0 + ) -> MenuItem { + MenuItem(category: category, name: name, spicy: spicy, price: price) + } } diff --git a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift index ffcbeaf..060bf76 100644 --- a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift +++ b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuListViewModelTests: XCTestCase { - func testCallsGivenGroupingFunction() { var called = false let inputSections = [MenuSection.fixture()] diff --git a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuRow.ViewModelTests.swift b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuRow.ViewModelTests.swift index 1a0ed46..4857738 100644 --- a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuRow.ViewModelTests.swift +++ b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuRow.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuRowViewModelTests: XCTestCase { - func testWhenItemIsNotSpicyTextIsItemNameOnly() { let item = MenuItem.fixture(name: "name", spicy: false) let viewModel = MenuRow.ViewModel(item: item) diff --git a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuSection+Fixture.swift b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuSection+Fixture.swift index c08d0cb..1314dc8 100644 --- a/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuSection+Fixture.swift +++ b/06-testing-static-swiftui-views/1-end/AlbertosTests/MenuSection+Fixture.swift @@ -1,11 +1,10 @@ @testable import Albertos extension MenuSection { - static func fixture( category: String = "a category", items: [MenuItem] = [.fixture()] ) -> MenuSection { - return MenuSection(category: category, items: items) + MenuSection(category: category, items: items) } } diff --git a/07-testing-dynamic-swiftui-views/1-end/Albertos/AlbertosApp.swift b/07-testing-dynamic-swiftui-views/1-end/Albertos/AlbertosApp.swift index dc3fb04..52a4adf 100644 --- a/07-testing-dynamic-swiftui-views/1-end/Albertos/AlbertosApp.swift +++ b/07-testing-dynamic-swiftui-views/1-end/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - var body: some Scene { WindowGroup { NavigationView { diff --git a/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetching.swift b/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetching.swift index 43d2f1e..33c166c 100644 --- a/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetching.swift +++ b/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetching.swift @@ -1,6 +1,5 @@ import Combine protocol MenuFetching { - func fetchMenu() -> AnyPublisher<[MenuItem], Error> } diff --git a/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetchingPlaceholder.swift b/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetchingPlaceholder.swift index 193ab5f..c3bcddd 100644 --- a/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetchingPlaceholder.swift +++ b/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuFetchingPlaceholder.swift @@ -3,7 +3,7 @@ import Foundation class MenuFetchingPlaceholder: MenuFetching { func fetchMenu() -> AnyPublisher<[MenuItem], Error> { - return Future { $0(.success(menu)) } + Future { $0(.success(menu)) } // Use a delay to simulate async fetch .delay(for: 0.5, scheduler: RunLoop.main) .eraseToAnyPublisher() diff --git a/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift b/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift index 2b7dc97..17e601e 100644 --- a/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift +++ b/07-testing-dynamic-swiftui-views/1-end/Albertos/MenuList.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension MenuList { - class ViewModel: ObservableObject { - @Published private(set) var sections: [MenuSection] = [] private var cancellables = Set() diff --git a/07-testing-dynamic-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift b/07-testing-dynamic-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift index 06d97f3..6f2d5e9 100644 --- a/07-testing-dynamic-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift +++ b/07-testing-dynamic-swiftui-views/1-end/AlbertosTests/MenuList.ViewModelTests.swift @@ -3,7 +3,6 @@ import Combine import XCTest class MenuListViewModelTests: XCTestCase { - var cancellables = Set() func testWhenFetchingStartsPublishesEmptyMenu() { diff --git a/08-stub/1-end/Albertos/MenuList.ViewModel.swift b/08-stub/1-end/Albertos/MenuList.ViewModel.swift index 9bbe9e2..deccc7f 100644 --- a/08-stub/1-end/Albertos/MenuList.ViewModel.swift +++ b/08-stub/1-end/Albertos/MenuList.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension MenuList { - class ViewModel: ObservableObject { - @Published private(set) var sections: Result<[MenuSection], Error> = .success([]) private var cancellables = Set() @@ -17,7 +15,7 @@ extension MenuList { .map(menuGrouping) .sink( receiveCompletion: { [weak self] completion in - guard case .failure(let error) = completion else { return } + guard case let .failure(error) = completion else { return } self?.sections = .failure(error) }, receiveValue: { [weak self] value in diff --git a/08-stub/1-end/Albertos/MenuList.swift b/08-stub/1-end/Albertos/MenuList.swift index 0446d9e..f18b1b7 100644 --- a/08-stub/1-end/Albertos/MenuList.swift +++ b/08-stub/1-end/Albertos/MenuList.swift @@ -1,12 +1,11 @@ import SwiftUI struct MenuList: View { - @ObservedObject var viewModel: ViewModel var body: some View { switch viewModel.sections { - case .success(let sections): + case let .success(sections): List { ForEach(sections) { section in Section(header: Text(section.category)) { @@ -16,7 +15,7 @@ struct MenuList: View { } } } - case .failure(let error): + case let .failure(error): Text("An error occurred:") Text(error.localizedDescription).italic() } diff --git a/08-stub/1-end/AlbertosTests/MenuFetchingStub.swift b/08-stub/1-end/AlbertosTests/MenuFetchingStub.swift index 26138d0..65f6c44 100644 --- a/08-stub/1-end/AlbertosTests/MenuFetchingStub.swift +++ b/08-stub/1-end/AlbertosTests/MenuFetchingStub.swift @@ -3,7 +3,6 @@ import Combine import Foundation class MenuFetchingStub: MenuFetching { - let result: Result<[MenuItem], Error> init(returning result: Result<[MenuItem], Error>) { @@ -11,7 +10,7 @@ class MenuFetchingStub: MenuFetching { } func fetchMenu() -> AnyPublisher<[MenuItem], Error> { - return result.publisher + result.publisher // Use a delay to simulate the real world async behavior .delay(for: 0.1, scheduler: RunLoop.main) .eraseToAnyPublisher() diff --git a/08-stub/1-end/AlbertosTests/MenuList.ViewModelTests.swift b/08-stub/1-end/AlbertosTests/MenuList.ViewModelTests.swift index 95621e9..33c9df0 100644 --- a/08-stub/1-end/AlbertosTests/MenuList.ViewModelTests.swift +++ b/08-stub/1-end/AlbertosTests/MenuList.ViewModelTests.swift @@ -3,7 +3,6 @@ import Combine import XCTest class MenuListViewModelTests: XCTestCase { - var cancellables = Set() func testWhenFetchingStartsPublishesEmptyMenu() throws { @@ -31,7 +30,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .success(let sections) = value else { + guard case let .success(sections) = value else { return XCTFail("Expected a successful Result, got: \(value)") } @@ -60,7 +59,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .failure(let error) = value else { + guard case let .failure(error) = value else { return XCTFail("Expected a failing Result, got: \(value)") } diff --git a/09-json-decoding/1-end/Albertos/MenuItem.swift b/09-json-decoding/1-end/Albertos/MenuItem.swift index a515af5..27017b9 100644 --- a/09-json-decoding/1-end/Albertos/MenuItem.swift +++ b/09-json-decoding/1-end/Albertos/MenuItem.swift @@ -1,5 +1,4 @@ struct MenuItem { - let category: String let name: String let spicy: Bool @@ -7,7 +6,6 @@ struct MenuItem { } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/09-json-decoding/1-end/AlbertosTests/MenuItem+JSONFixture.swift b/09-json-decoding/1-end/AlbertosTests/MenuItem+JSONFixture.swift index adadb70..3b408bf 100644 --- a/09-json-decoding/1-end/AlbertosTests/MenuItem+JSONFixture.swift +++ b/09-json-decoding/1-end/AlbertosTests/MenuItem+JSONFixture.swift @@ -1,20 +1,19 @@ @testable import Albertos extension MenuItem { - static func jsonFixture( name: String = "a name", category: String = "a category", spicy: Bool = false, price: Double = 1.0 ) -> String { - return """ -{ - "name": "\(name)", - "category": "\(category)", - "spicy": \(spicy), - "price": \(price) -} -""" + """ + { + "name": "\(name)", + "category": "\(category)", + "spicy": \(spicy), + "price": \(price) + } + """ } } diff --git a/09-json-decoding/1-end/AlbertosTests/MenuItemAlternateJSONTests.swift b/09-json-decoding/1-end/AlbertosTests/MenuItemAlternateJSONTests.swift index 4ddbd04..965a6f0 100644 --- a/09-json-decoding/1-end/AlbertosTests/MenuItemAlternateJSONTests.swift +++ b/09-json-decoding/1-end/AlbertosTests/MenuItemAlternateJSONTests.swift @@ -4,7 +4,7 @@ // // If you want to verify the failure, uncomment the import of the production module and comment the // definition of MenuItem in this file -//@testable import Albertos +// @testable import Albertos import XCTest private struct MenuItem: Decodable { @@ -26,24 +26,23 @@ private struct MenuItem: Decodable { } class MenuItemAlternateJSONTests: XCTestCase { - func testWhenDecodedFromJSONDataHasAllTheInputProperties() throws { let json = """ -{ - "name": "a name", - "category": { - "name": "a category", - "id": 123 - }, - "spicy": false, - "price": 1.0 -} -""" + { + "name": "a name", + "category": { + "name": "a category", + "id": 123 + }, + "spicy": false, + "price": 1.0 + } + """ let data = try XCTUnwrap(json.data(using: .utf8)) let item: MenuItem do { - item = try JSONDecoder().decode(MenuItem.self, from: data) + item = try JSONDecoder().decode(MenuItem.self, from: data) } catch { XCTFail("\(error)") return diff --git a/09-json-decoding/1-end/AlbertosTests/MenuItemTests.swift b/09-json-decoding/1-end/AlbertosTests/MenuItemTests.swift index 3ecd15b..0ff79b2 100644 --- a/09-json-decoding/1-end/AlbertosTests/MenuItemTests.swift +++ b/09-json-decoding/1-end/AlbertosTests/MenuItemTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemTests: XCTestCase { - // MARK: Inline example with Triangulation func testWhenDecodedFromJSONDataHasAllTheInputPropertiesExample1() throws { @@ -57,6 +56,7 @@ class MenuItemTests: XCTestCase { } // MARK: Simpler check example + // Use this option if your models match the shape of the input JSON. func testWhenDecodingFromJSONDataDoesNotThrow() throws { diff --git a/09-json-decoding/1-end/AlbertosTests/XCTestCase+JSON.swift b/09-json-decoding/1-end/AlbertosTests/XCTestCase+JSON.swift index 9bbfa4d..744a363 100644 --- a/09-json-decoding/1-end/AlbertosTests/XCTestCase+JSON.swift +++ b/09-json-decoding/1-end/AlbertosTests/XCTestCase+JSON.swift @@ -1,7 +1,6 @@ import XCTest extension XCTestCase { - func dataFromJSONFileNamed(_ name: String) throws -> Data { let url = try XCTUnwrap( Bundle(for: type(of: self)).url(forResource: name, withExtension: "json") diff --git a/10-networking/1-end/Albertos/AlbertosApp.swift b/10-networking/1-end/Albertos/AlbertosApp.swift index 9bc89e6..c666718 100644 --- a/10-networking/1-end/Albertos/AlbertosApp.swift +++ b/10-networking/1-end/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - var body: some Scene { WindowGroup { NavigationView { diff --git a/10-networking/1-end/Albertos/MenuFetcher.swift b/10-networking/1-end/Albertos/MenuFetcher.swift index 4f9cc89..819ceea 100644 --- a/10-networking/1-end/Albertos/MenuFetcher.swift +++ b/10-networking/1-end/Albertos/MenuFetcher.swift @@ -2,7 +2,6 @@ import Combine import Foundation class MenuFetcher: MenuFetching { - let networkFetching: NetworkFetching init(networkFetching: NetworkFetching = URLSession.shared) { @@ -10,7 +9,7 @@ class MenuFetcher: MenuFetching { } func fetchMenu() -> AnyPublisher<[MenuItem], Error> { - return networkFetching.load(URLRequest(url: URL(string: "https://s3.amazonaws.com/mokacoding/menu_response.json")!)) + networkFetching.load(URLRequest(url: URL(string: "https://s3.amazonaws.com/mokacoding/menu_response.json")!)) .decode(type: [MenuItem].self, decoder: JSONDecoder()) .eraseToAnyPublisher() } diff --git a/10-networking/1-end/Albertos/NetworkFetching.swift b/10-networking/1-end/Albertos/NetworkFetching.swift index 2d4f186..af8c9c2 100644 --- a/10-networking/1-end/Albertos/NetworkFetching.swift +++ b/10-networking/1-end/Albertos/NetworkFetching.swift @@ -2,6 +2,5 @@ import Combine import Foundation protocol NetworkFetching { - func load(_ request: URLRequest) -> AnyPublisher } diff --git a/10-networking/1-end/Albertos/URLSession+NetworkFetching.swift b/10-networking/1-end/Albertos/URLSession+NetworkFetching.swift index 6f3b0b9..1d28729 100644 --- a/10-networking/1-end/Albertos/URLSession+NetworkFetching.swift +++ b/10-networking/1-end/Albertos/URLSession+NetworkFetching.swift @@ -2,10 +2,9 @@ import Combine import Foundation extension URLSession: NetworkFetching { - func load(_ request: URLRequest) -> AnyPublisher { - return dataTaskPublisher(for: request) - .map { $0.data } + dataTaskPublisher(for: request) + .map(\.data) .eraseToAnyPublisher() } } diff --git a/10-networking/1-end/AlbertosTests/MenuFetcherTests.swift b/10-networking/1-end/AlbertosTests/MenuFetcherTests.swift index f5bdc7f..e8c4c0a 100644 --- a/10-networking/1-end/AlbertosTests/MenuFetcherTests.swift +++ b/10-networking/1-end/AlbertosTests/MenuFetcherTests.swift @@ -3,16 +3,15 @@ import Combine import XCTest class MenuFetcherTests: XCTestCase { - var cancellables = Set() func testWhenRequestSucceedsPublishesDecodedMenuItems() throws { let json = """ -[ - { "name": "a name", "category": "a category", "spicy": true, "price": 1.0 }, - { "name": "another name", "category": "a category", "spicy": true, "price": 2.0 } -] -""" + [ + { "name": "a name", "category": "a category", "spicy": true, "price": 1.0 }, + { "name": "another name", "category": "a category", "spicy": true, "price": 2.0 } + ] + """ let data = try XCTUnwrap(json.data(using: .utf8)) let menuFetcher = MenuFetcher(networkFetching: NetworkFetchingStub(returning: .success(data))) @@ -42,7 +41,7 @@ class MenuFetcherTests: XCTestCase { menuFetcher.fetchMenu() .sink( receiveCompletion: { completion in - guard case .failure(let error) = completion else { return } + guard case let .failure(error) = completion else { return } XCTAssertEqual(error as? URLError, expectedError) expectation.fulfill() }, diff --git a/10-networking/1-end/AlbertosTests/MenuList.ViewModelTests.swift b/10-networking/1-end/AlbertosTests/MenuList.ViewModelTests.swift index c147e56..496ccc3 100644 --- a/10-networking/1-end/AlbertosTests/MenuList.ViewModelTests.swift +++ b/10-networking/1-end/AlbertosTests/MenuList.ViewModelTests.swift @@ -3,7 +3,6 @@ import Combine import XCTest class MenuListViewModelTests: XCTestCase { - var cancellables = Set() func testWhenFetchingStartsPublishesEmptyMenu() throws { @@ -31,7 +30,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .success(let sections) = value else { + guard case let .success(sections) = value else { return XCTFail("Expected a successful Result, got: \(value)") } @@ -60,7 +59,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .failure(let error) = value else { + guard case let .failure(error) = value else { return XCTFail("Expected a failing Result, got: \(value)") } diff --git a/10-networking/1-end/AlbertosTests/NetworkFetchingStub.swift b/10-networking/1-end/AlbertosTests/NetworkFetchingStub.swift index de00dd8..02f414c 100644 --- a/10-networking/1-end/AlbertosTests/NetworkFetchingStub.swift +++ b/10-networking/1-end/AlbertosTests/NetworkFetchingStub.swift @@ -3,15 +3,14 @@ import Combine import Foundation class NetworkFetchingStub: NetworkFetching { - private let result: Result init(returning result: Result) { self.result = result } - func load(_ request: URLRequest) -> AnyPublisher { - return result.publisher + func load(_: URLRequest) -> AnyPublisher { + result.publisher // Use a delay to simulate the real world async behavior .delay(for: 0.01, scheduler: RunLoop.main) .eraseToAnyPublisher() diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/AlbertosApp.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/AlbertosApp.swift index ee52d4c..c377b33 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/AlbertosApp.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - var body: some Scene { WindowGroup { ZStack(alignment: .bottom) { diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/Color+Custom.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/Color+Custom.swift index 0af8739..d646a7c 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/Color+Custom.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/Color+Custom.swift @@ -4,7 +4,6 @@ import SwiftUI // // See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value extension Color { - static var crimson: Color { Color(red: 220 / 255.0, green: 20 / 255.0, blue: 20 / 255.0) } static var tomato: Color { Color(red: 255 / 255.0, green: 99 / 255.0, blue: 71 / 255.0) } diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.ViewModel.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.ViewModel.swift index 8b76a5a..92be4ce 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.ViewModel.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.ViewModel.swift @@ -1,7 +1,5 @@ extension MenuItemDetail { - struct ViewModel { - let name: String let spicy: String? let price: String diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.swift index a38beb4..f7506d2 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/MenuItemDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuItemDetail: View { - let viewModel: ViewModel var body: some View { diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/MenuList.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/MenuList.swift index 14bf542..b8b1ddd 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/MenuList.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/MenuList.swift @@ -1,12 +1,11 @@ import SwiftUI struct MenuList: View { - @ObservedObject var viewModel: ViewModel var body: some View { switch viewModel.sections { - case .success(let sections): + case let .success(sections): List { ForEach(sections) { section in Section(header: Text(section.category)) { @@ -18,7 +17,7 @@ struct MenuList: View { } } } - case .failure(let error): + case let .failure(error): Text("An error occurred:") Text(error.localizedDescription).italic() } diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/Order.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/Order.swift index 0f6b158..0855ec8 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/Order.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/Order.swift @@ -1,5 +1,4 @@ struct Order { - let items: [MenuItem] var total: Double { items.reduce(0) { $0 + $1.price } } diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.ViewModel.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.ViewModel.swift index ef4751d..a7f7933 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.ViewModel.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.ViewModel.swift @@ -1,8 +1,6 @@ // This is just a placeholder to make working on the screen as we progress with the chapters easier. extension OrderButton { - struct ViewModel { - let text = "Your Order" } } diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.swift index e90bd58..4c32574 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderButton.swift @@ -1,14 +1,13 @@ import SwiftUI struct OrderButton: View { - let viewModel: ViewModel @State private(set) var showingDetail: Bool = false var body: some View { Button { - self.showingDetail.toggle() + showingDetail.toggle() } label: { Text(viewModel.text) .font(Font.callout.bold()) diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderController.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderController.swift index f7ec0bd..24d7df5 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderController.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderController.swift @@ -1,7 +1,6 @@ import Combine class OrderController: ObservableObject { - @Published private(set) var order: Order init(order: Order = Order(items: [])) { @@ -9,7 +8,7 @@ class OrderController: ObservableObject { } func isItemInOrder(_ item: MenuItem) -> Bool { - return order.items.contains { $0 == item } + order.items.contains { $0 == item } } func addToOrder(item: MenuItem) { @@ -20,7 +19,7 @@ class OrderController: ObservableObject { let items = order.items guard let indexToRemove = items.firstIndex(where: { $0.name == item.name }) else { return } - let newItems = items.enumerated().compactMap { (index, element) -> MenuItem? in + let newItems = items.enumerated().compactMap { index, element -> MenuItem? in guard index == indexToRemove else { return element } return .none } diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.ViewModel.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.ViewModel.swift index 0a2ccdd..6e43f10 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.ViewModel.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.ViewModel.swift @@ -1,8 +1,6 @@ // This is just a placeholder to make working on the screen as we progress with the chapters easier. extension OrderDetail { - struct ViewModel { let text = "Order Detail" } } - diff --git a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.swift b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.swift index 8a19c31..cdb345d 100644 --- a/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.swift +++ b/11-dependency-injection-with-environment-object/0-start/Albertos/OrderDetail.swift @@ -1,11 +1,9 @@ import SwiftUI struct OrderDetail: View { - let viewModel: ViewModel var body: some View { Text(viewModel.text) } } - diff --git a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/MenuItemDetail.ViewModelTests.swift b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/MenuItemDetail.ViewModelTests.swift index f6702bc..a42f303 100644 --- a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/MenuItemDetail.ViewModelTests.swift +++ b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/MenuItemDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemDetailViewModelTests: XCTestCase { - func testNameIsItemName() { XCTAssertEqual( MenuItemDetail.ViewModel(item: .fixture(name: "a name")).name, diff --git a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderButtonViewModelTests.swift b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderButtonViewModelTests.swift index 54d2560..2f59c66 100644 --- a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderButtonViewModelTests.swift +++ b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderButtonViewModelTests.swift @@ -2,7 +2,5 @@ import XCTest class OrderButtonViewModelTests: XCTestCase { - // This is just a placeholder to make adding tests as we progress with the chapters easier. } - diff --git a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderControllerTests.swift b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderControllerTests.swift index 7e78c8e..e4ee62a 100644 --- a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderControllerTests.swift +++ b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderControllerTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderControllerTests: XCTestCase { - func testInitsWithEmptyOrder() { let controller = OrderController() diff --git a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift index 034986b..3401a74 100644 --- a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -2,6 +2,5 @@ import XCTest class OrderDetailViewModelTests: XCTestCase { - // This is just a placeholder to make adding tests as we progress with the chapters easier. } diff --git a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderTests.swift b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderTests.swift index 153e13a..cc00e8c 100644 --- a/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderTests.swift +++ b/11-dependency-injection-with-environment-object/0-start/AlbertosTests/OrderTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderTests: XCTestCase { - func testTotalSumsPricesOfEachItem() { let order = Order( items: [.fixture(price: 1.0), .fixture(price: 2.0), .fixture(price: 3.5)] diff --git a/11-dependency-injection-with-environment-object/1-end/Albertos/AlbertosApp.swift b/11-dependency-injection-with-environment-object/1-end/Albertos/AlbertosApp.swift index 3854549..aea70f5 100644 --- a/11-dependency-injection-with-environment-object/1-end/Albertos/AlbertosApp.swift +++ b/11-dependency-injection-with-environment-object/1-end/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - let orderController = OrderController() var body: some Scene { diff --git a/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.ViewModel.swift b/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.ViewModel.swift index cda7b3d..a608464 100644 --- a/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.ViewModel.swift +++ b/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension MenuItemDetail { - class ViewModel: ObservableObject { - let name: String let spicy: String? let price: String @@ -25,12 +23,12 @@ extension MenuItemDetail { self.orderController.$order .sink { [weak self] order in - guard let self = self else { return } + guard let self else { return } if (order.items.contains { $0 == self.item }) { - self.addOrRemoveFromOrderButtonText = "Remove from order" + addOrRemoveFromOrderButtonText = "Remove from order" } else { - self.addOrRemoveFromOrderButtonText = "Add to order" + addOrRemoveFromOrderButtonText = "Add to order" } } .store(in: &cancellables) diff --git a/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.swift b/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.swift index b64a6e9..386f5b0 100644 --- a/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.swift +++ b/11-dependency-injection-with-environment-object/1-end/Albertos/MenuItemDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuItemDetail: View { - @ObservedObject private(set) var viewModel: ViewModel var body: some View { diff --git a/11-dependency-injection-with-environment-object/1-end/Albertos/MenuList.swift b/11-dependency-injection-with-environment-object/1-end/Albertos/MenuList.swift index 9b00577..f22f07b 100644 --- a/11-dependency-injection-with-environment-object/1-end/Albertos/MenuList.swift +++ b/11-dependency-injection-with-environment-object/1-end/Albertos/MenuList.swift @@ -1,14 +1,13 @@ import SwiftUI struct MenuList: View { - @ObservedObject var viewModel: ViewModel @EnvironmentObject private var orderController: OrderController var body: some View { switch viewModel.sections { - case .success(let sections): + case let .success(sections): List { ForEach(sections) { section in Section(header: Text(section.category)) { @@ -20,7 +19,7 @@ struct MenuList: View { } } } - case .failure(let error): + case let .failure(error): Text("An error occurred:") Text(error.localizedDescription).italic() } diff --git a/11-dependency-injection-with-environment-object/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift b/11-dependency-injection-with-environment-object/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift index d51f55a..698e627 100644 --- a/11-dependency-injection-with-environment-object/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift +++ b/11-dependency-injection-with-environment-object/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemDetailViewModelTests: XCTestCase { - func testWhenItemIsInOrderButtonSaysRemove() { let item = MenuItem.fixture() let orderController = OrderController() diff --git a/12-spy/0-start/Albertos/AlbertosApp.swift b/12-spy/0-start/Albertos/AlbertosApp.swift index 197cf3e..81b0447 100644 --- a/12-spy/0-start/Albertos/AlbertosApp.swift +++ b/12-spy/0-start/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - let orderController = OrderController() var body: some Scene { diff --git a/12-spy/0-start/Albertos/OrderButton.ViewModel.swift b/12-spy/0-start/Albertos/OrderButton.ViewModel.swift index d48b80c..a9232e1 100644 --- a/12-spy/0-start/Albertos/OrderButton.ViewModel.swift +++ b/12-spy/0-start/Albertos/OrderButton.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension OrderButton { - class ViewModel: ObservableObject { - @Published private(set) var text = "Your Order" private(set) var cancellables = Set() diff --git a/12-spy/0-start/Albertos/OrderButton.swift b/12-spy/0-start/Albertos/OrderButton.swift index ecf1a63..0a5a560 100644 --- a/12-spy/0-start/Albertos/OrderButton.swift +++ b/12-spy/0-start/Albertos/OrderButton.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderButton: View { - @ObservedObject private(set) var viewModel: ViewModel @State private(set) var showingDetail: Bool = false @@ -9,7 +8,7 @@ struct OrderButton: View { var body: some View { Button { - self.showingDetail.toggle() + showingDetail.toggle() } label: { Text(viewModel.text) .font(Font.callout.bold()) diff --git a/12-spy/0-start/Albertos/OrderDetail.ViewModel.swift b/12-spy/0-start/Albertos/OrderDetail.ViewModel.swift index 387e8a6..7a2a7f6 100644 --- a/12-spy/0-start/Albertos/OrderDetail.ViewModel.swift +++ b/12-spy/0-start/Albertos/OrderDetail.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension OrderDetail { - struct ViewModel { - let headerText = "Your Order" let menuListItems: [MenuItem] let emptyMenuFallbackText = "Add dishes to the order to see them here" diff --git a/12-spy/0-start/Albertos/OrderDetail.swift b/12-spy/0-start/Albertos/OrderDetail.swift index 44b5e4d..fe9054a 100644 --- a/12-spy/0-start/Albertos/OrderDetail.swift +++ b/12-spy/0-start/Albertos/OrderDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderDetail: View { - let viewModel: ViewModel var body: some View { diff --git a/12-spy/0-start/AlbertosTests/OrderButtonViewModelTests.swift b/12-spy/0-start/AlbertosTests/OrderButtonViewModelTests.swift index ffd896a..84dad6a 100644 --- a/12-spy/0-start/AlbertosTests/OrderButtonViewModelTests.swift +++ b/12-spy/0-start/AlbertosTests/OrderButtonViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderButtonViewModelTests: XCTestCase { - func testWhenOrderIsEmptyDoesNotShowTotal() { let orderController = OrderController() let viewModel = OrderButton.ViewModel(orderController: orderController) @@ -19,4 +18,3 @@ class OrderButtonViewModelTests: XCTestCase { XCTAssertEqual(viewModel.text, "Your Order $3.30") } } - diff --git a/12-spy/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift b/12-spy/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift index c34b3ed..b98db0f 100644 --- a/12-spy/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/12-spy/0-start/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderDetailViewModelTests: XCTestCase { - func testWhenOrderIsEmptyShouldNotShowTotalAmount() { let viewModel = OrderDetail.ViewModel(orderController: OrderController()) diff --git a/12-spy/1-end/Albertos/AlbertosApp.swift b/12-spy/1-end/Albertos/AlbertosApp.swift index f3a5dc6..6679f1a 100644 --- a/12-spy/1-end/Albertos/AlbertosApp.swift +++ b/12-spy/1-end/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - let orderController = OrderController() let paymentProcessor = PaymentProcessingProxy() diff --git a/12-spy/1-end/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift b/12-spy/1-end/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift index f8c6eb6..cd48cca 100644 --- a/12-spy/1-end/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift +++ b/12-spy/1-end/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift @@ -2,9 +2,8 @@ import Combine import HippoPayments extension HippoPaymentsProcessor: PaymentProcessing { - func process(order: Order) -> AnyPublisher { - return Future { promise in + Future { promise in self.processPayment( payload: order.hippoPaymentsPayload, onSuccess: { promise(.success(())) }, diff --git a/12-spy/1-end/Albertos/Order+HippoPayments.swift b/12-spy/1-end/Albertos/Order+HippoPayments.swift index 78fd5cf..77b3c2a 100644 --- a/12-spy/1-end/Albertos/Order+HippoPayments.swift +++ b/12-spy/1-end/Albertos/Order+HippoPayments.swift @@ -1,4 +1,3 @@ extension Order { - - var hippoPaymentsPayload: [String: Any] { ["items": items.map { $0.name }] } + var hippoPaymentsPayload: [String: Any] { ["items": items.map(\.name)] } } diff --git a/12-spy/1-end/Albertos/Order.swift b/12-spy/1-end/Albertos/Order.swift index 43e1ade..8a1d98a 100644 --- a/12-spy/1-end/Albertos/Order.swift +++ b/12-spy/1-end/Albertos/Order.swift @@ -1,5 +1,4 @@ struct Order { - let items: [MenuItem] var total: Double { items.reduce(0) { $0 + $1.price } } diff --git a/12-spy/1-end/Albertos/OrderButton.swift b/12-spy/1-end/Albertos/OrderButton.swift index 10b0a6d..ccc4d49 100644 --- a/12-spy/1-end/Albertos/OrderButton.swift +++ b/12-spy/1-end/Albertos/OrderButton.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderButton: View { - @ObservedObject private(set) var viewModel: ViewModel @State private(set) var showingDetail: Bool = false @@ -11,7 +10,7 @@ struct OrderButton: View { var body: some View { Button { - self.showingDetail.toggle() + showingDetail.toggle() } label: { Text(viewModel.text) .font(Font.callout.bold()) diff --git a/12-spy/1-end/Albertos/OrderDetail.ViewModel.swift b/12-spy/1-end/Albertos/OrderDetail.ViewModel.swift index fca6a7d..9da1ac7 100644 --- a/12-spy/1-end/Albertos/OrderDetail.ViewModel.swift +++ b/12-spy/1-end/Albertos/OrderDetail.ViewModel.swift @@ -2,9 +2,7 @@ import Combine import HippoPayments extension OrderDetail { - struct ViewModel { - let headerText = "Your Order" let menuListItems: [MenuItem] let emptyMenuFallbackText = "Add dishes to the order to see them here" diff --git a/12-spy/1-end/Albertos/OrderDetail.swift b/12-spy/1-end/Albertos/OrderDetail.swift index e5f0472..399a509 100644 --- a/12-spy/1-end/Albertos/OrderDetail.swift +++ b/12-spy/1-end/Albertos/OrderDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderDetail: View { - let viewModel: ViewModel var body: some View { diff --git a/12-spy/1-end/Albertos/PaymentProcessing.swift b/12-spy/1-end/Albertos/PaymentProcessing.swift index 23b8b25..9561f9e 100644 --- a/12-spy/1-end/Albertos/PaymentProcessing.swift +++ b/12-spy/1-end/Albertos/PaymentProcessing.swift @@ -1,6 +1,5 @@ import Combine protocol PaymentProcessing { - func process(order: Order) -> AnyPublisher } diff --git a/12-spy/1-end/Albertos/PaymentProcessingProxy.swift b/12-spy/1-end/Albertos/PaymentProcessingProxy.swift index 54e4094..c9a0410 100644 --- a/12-spy/1-end/Albertos/PaymentProcessingProxy.swift +++ b/12-spy/1-end/Albertos/PaymentProcessingProxy.swift @@ -7,7 +7,6 @@ import HippoPayments // value defined as `PaymentProcessing` because "only struct/enum/class types can conform to // protocols". class PaymentProcessingProxy: PaymentProcessing, ObservableObject { - private let proxiedProcessor: PaymentProcessing = HippoPaymentsProcessor(apiKey: "abcd") func process(order: Order) -> AnyPublisher { diff --git a/12-spy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift b/12-spy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift index 3968b50..d3bc0be 100644 --- a/12-spy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/12-spy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderDetailViewModelTests: XCTestCase { - func testWhenCheckoutButtonPressedStartsPaymentProcessingFlow() { // Create an OrderController and add some items to it let orderController = OrderController() diff --git a/12-spy/1-end/AlbertosTests/OrderTests.swift b/12-spy/1-end/AlbertosTests/OrderTests.swift index d9bde21..e64802d 100644 --- a/12-spy/1-end/AlbertosTests/OrderTests.swift +++ b/12-spy/1-end/AlbertosTests/OrderTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderTests: XCTestCase { - func testTotalSumsPricesOfEachItem() { let order = Order( items: [.fixture(price: 1.0), .fixture(price: 2.0), .fixture(price: 3.5)] diff --git a/12-spy/1-end/AlbertosTests/PaymentProcessingSpy.swift b/12-spy/1-end/AlbertosTests/PaymentProcessingSpy.swift index e87dfa6..bcba03e 100644 --- a/12-spy/1-end/AlbertosTests/PaymentProcessingSpy.swift +++ b/12-spy/1-end/AlbertosTests/PaymentProcessingSpy.swift @@ -2,7 +2,6 @@ import Combine class PaymentProcessingSpy: PaymentProcessing { - private(set) var receivedOrder: Order? func process(order: Order) -> AnyPublisher { diff --git a/13-testing-view-presentation/1-end/Albertos/Alert.ViewModel.swift b/13-testing-view-presentation/1-end/Albertos/Alert.ViewModel.swift index e58bead..74ca4f9 100644 --- a/13-testing-view-presentation/1-end/Albertos/Alert.ViewModel.swift +++ b/13-testing-view-presentation/1-end/Albertos/Alert.ViewModel.swift @@ -1,9 +1,7 @@ import SwiftUI extension Alert { - struct ViewModel: Identifiable { - let title: String let message: String let buttonText: String diff --git a/13-testing-view-presentation/1-end/Albertos/OrderButton.swift b/13-testing-view-presentation/1-end/Albertos/OrderButton.swift index fa66b72..882e268 100644 --- a/13-testing-view-presentation/1-end/Albertos/OrderButton.swift +++ b/13-testing-view-presentation/1-end/Albertos/OrderButton.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderButton: View { - @ObservedObject private(set) var viewModel: ViewModel @State private(set) var showingDetail: Bool = false @@ -11,7 +10,7 @@ struct OrderButton: View { var body: some View { Button { - self.showingDetail.toggle() + showingDetail.toggle() } label: { Text(viewModel.text) .font(Font.callout.bold()) @@ -25,7 +24,7 @@ struct OrderButton: View { viewModel: .init( orderController: orderController, paymentProcessor: paymentProcessor, - onAlertDismiss: { self.showingDetail = false } + onAlertDismiss: { showingDetail = false } ) ) } diff --git a/13-testing-view-presentation/1-end/Albertos/OrderDetail.ViewModel.swift b/13-testing-view-presentation/1-end/Albertos/OrderDetail.ViewModel.swift index 1a3f2f7..af07963 100644 --- a/13-testing-view-presentation/1-end/Albertos/OrderDetail.ViewModel.swift +++ b/13-testing-view-presentation/1-end/Albertos/OrderDetail.ViewModel.swift @@ -3,9 +3,7 @@ import HippoPayments import SwiftUI extension OrderDetail { - class ViewModel: ObservableObject { - let headerText = "Your Order" let menuListItems: [MenuItem] let emptyMenuFallbackText = "Add dishes to the order to see them here" diff --git a/13-testing-view-presentation/1-end/Albertos/OrderDetail.swift b/13-testing-view-presentation/1-end/Albertos/OrderDetail.swift index bfb4841..e7248f6 100644 --- a/13-testing-view-presentation/1-end/Albertos/OrderDetail.swift +++ b/13-testing-view-presentation/1-end/Albertos/OrderDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderDetail: View { - @ObservedObject private(set) var viewModel: ViewModel var body: some View { diff --git a/13-testing-view-presentation/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift b/13-testing-view-presentation/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift index 95c4312..0fc9264 100644 --- a/13-testing-view-presentation/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/13-testing-view-presentation/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderDetailViewModelTests: XCTestCase { - func testWhenCheckoutButtonPressedStartsPaymentProcessingFlow() { // Create an OrderController and add some items to it let orderController = OrderController() diff --git a/13-testing-view-presentation/1-end/AlbertosTests/PaymentProcessingStub.swift b/13-testing-view-presentation/1-end/AlbertosTests/PaymentProcessingStub.swift index 5abfde2..cbd1e04 100644 --- a/13-testing-view-presentation/1-end/AlbertosTests/PaymentProcessingStub.swift +++ b/13-testing-view-presentation/1-end/AlbertosTests/PaymentProcessingStub.swift @@ -3,15 +3,14 @@ import Combine import Foundation class PaymentProcessingStub: PaymentProcessing { - let result: Result init(returning result: Result) { self.result = result } - func process(order: Order) -> AnyPublisher { - return result.publisher + func process(order _: Order) -> AnyPublisher { + result.publisher // Use a delay to simulate the real world async behavior .delay(for: 0.01, scheduler: RunLoop.main) .eraseToAnyPublisher() diff --git a/13-testing-view-presentation/1-end/AlbertosTests/XCTestCase+Timeouts.swift b/13-testing-view-presentation/1-end/AlbertosTests/XCTestCase+Timeouts.swift index d48c4d7..3ab1c63 100644 --- a/13-testing-view-presentation/1-end/AlbertosTests/XCTestCase+Timeouts.swift +++ b/13-testing-view-presentation/1-end/AlbertosTests/XCTestCase+Timeouts.swift @@ -1,7 +1,6 @@ import XCTest extension XCTestCase { - /// Using a wait time of around 1 second seems to result in occasional /// test timeout failures when using `XCTNSPredicateExpectation`s. var timeoutForPredicateExpectations: Double { 2.0 } diff --git a/14-fixing-bugs-and-changing-code/1-end/Albertos/MenuRow.ViewModel.swift b/14-fixing-bugs-and-changing-code/1-end/Albertos/MenuRow.ViewModel.swift index 26f5b04..b3acaa5 100644 --- a/14-fixing-bugs-and-changing-code/1-end/Albertos/MenuRow.ViewModel.swift +++ b/14-fixing-bugs-and-changing-code/1-end/Albertos/MenuRow.ViewModel.swift @@ -1,7 +1,5 @@ extension MenuRow { - struct ViewModel { - let text: String init(item: MenuItem) { diff --git a/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderController.swift b/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderController.swift index 92fe190..9b2057e 100644 --- a/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderController.swift +++ b/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderController.swift @@ -1,7 +1,6 @@ import Combine class OrderController: ObservableObject { - @Published private(set) var order: Order init(order: Order = Order(items: [])) { @@ -9,7 +8,7 @@ class OrderController: ObservableObject { } func isItemInOrder(_ item: MenuItem) -> Bool { - return order.items.contains { $0 == item } + order.items.contains { $0 == item } } func addToOrder(item: MenuItem) { @@ -20,7 +19,7 @@ class OrderController: ObservableObject { let items = order.items guard let indexToRemove = items.firstIndex(where: { $0.name == item.name }) else { return } - let newItems = items.enumerated().compactMap { (index, element) -> MenuItem? in + let newItems = items.enumerated().compactMap { index, element -> MenuItem? in guard index == indexToRemove else { return element } return .none } diff --git a/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderDetail.ViewModel.swift b/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderDetail.ViewModel.swift index 0caaadb..4ac2b47 100644 --- a/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderDetail.ViewModel.swift +++ b/14-fixing-bugs-and-changing-code/1-end/Albertos/OrderDetail.ViewModel.swift @@ -3,9 +3,7 @@ import HippoPayments import SwiftUI extension OrderDetail { - class ViewModel: ObservableObject { - let headerText = "Your Order" let menuListItems: [MenuItem] let emptyMenuFallbackText = "Add dishes to the order to see them here" @@ -62,10 +60,10 @@ extension OrderDetail { message: "The payment was successful. Your food will be with you shortly.", buttonText: "Ok", buttonAction: { [weak self] in - guard let self = self else { return } + guard let self else { return } - self.orderController.resetOrder() - self.onAlertDismiss() + orderController.resetOrder() + onAlertDismiss() } ) } diff --git a/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/MenuRow.ViewModelTests.swift b/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/MenuRow.ViewModelTests.swift index bebc64d..bc10c85 100644 --- a/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/MenuRow.ViewModelTests.swift +++ b/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/MenuRow.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuRowViewModelTests: XCTestCase { - func testWhenItemIsNotSpicyTextIsItemNameOnly() { let item = MenuItem.fixture(name: "name", spicy: false) let viewModel = MenuRow.ViewModel(item: item) diff --git a/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift b/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift index 1363a5b..5b18132 100644 --- a/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/14-fixing-bugs-and-changing-code/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderDetailViewModelTests: XCTestCase { - func testWhenCheckoutButtonPressedStartsPaymentProcessingFlow() { // Create an OrderController and add some items to it let orderController = OrderController() diff --git a/15-fake-and-dummy/1-end/Albertos/MenuItem.swift b/15-fake-and-dummy/1-end/Albertos/MenuItem.swift index 63af8dc..7873820 100644 --- a/15-fake-and-dummy/1-end/Albertos/MenuItem.swift +++ b/15-fake-and-dummy/1-end/Albertos/MenuItem.swift @@ -1,5 +1,4 @@ struct MenuItem { - let category: String let name: String let spicy: Bool @@ -7,7 +6,6 @@ struct MenuItem { } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/15-fake-and-dummy/1-end/Albertos/MenuList.swift b/15-fake-and-dummy/1-end/Albertos/MenuList.swift index 93bf9a0..4304aad 100644 --- a/15-fake-and-dummy/1-end/Albertos/MenuList.swift +++ b/15-fake-and-dummy/1-end/Albertos/MenuList.swift @@ -1,14 +1,13 @@ import SwiftUI struct MenuList: View { - @ObservedObject var viewModel: ViewModel @EnvironmentObject private var orderController: OrderController var body: some View { switch viewModel.sections { - case .success(let sections): + case let .success(sections): List { ForEach(sections) { section in Section(header: Text(section.category)) { @@ -20,7 +19,7 @@ struct MenuList: View { } } } - case .failure(let error): + case let .failure(error): Text("An error occurred:") Text(error.localizedDescription).italic() } diff --git a/15-fake-and-dummy/1-end/Albertos/Order.swift b/15-fake-and-dummy/1-end/Albertos/Order.swift index 8f14348..a0db802 100644 --- a/15-fake-and-dummy/1-end/Albertos/Order.swift +++ b/15-fake-and-dummy/1-end/Albertos/Order.swift @@ -1,5 +1,4 @@ struct Order { - let items: [MenuItem] var total: Double { items.reduce(0) { $0 + $1.price } } diff --git a/15-fake-and-dummy/1-end/Albertos/OrderController.swift b/15-fake-and-dummy/1-end/Albertos/OrderController.swift index 630d109..5d29a49 100644 --- a/15-fake-and-dummy/1-end/Albertos/OrderController.swift +++ b/15-fake-and-dummy/1-end/Albertos/OrderController.swift @@ -2,7 +2,6 @@ import Combine import Foundation class OrderController: ObservableObject { - @Published private(set) var order: Order private let orderStoring: OrderStoring @@ -13,7 +12,7 @@ class OrderController: ObservableObject { } func isItemInOrder(_ item: MenuItem) -> Bool { - return order.items.contains { $0 == item } + order.items.contains { $0 == item } } func addToOrder(item: MenuItem) { @@ -24,7 +23,7 @@ class OrderController: ObservableObject { let items = order.items guard let indexToRemove = items.firstIndex(where: { $0.name == item.name }) else { return } - let newItems = items.enumerated().compactMap { (index, element) -> MenuItem? in + let newItems = items.enumerated().compactMap { index, element -> MenuItem? in guard index == indexToRemove else { return element } return .none } diff --git a/15-fake-and-dummy/1-end/Albertos/OrderStoring.swift b/15-fake-and-dummy/1-end/Albertos/OrderStoring.swift index b798268..1bb5882 100644 --- a/15-fake-and-dummy/1-end/Albertos/OrderStoring.swift +++ b/15-fake-and-dummy/1-end/Albertos/OrderStoring.swift @@ -1,5 +1,4 @@ protocol OrderStoring { - func getOrder() -> Order func updateOrder(_ order: Order) diff --git a/15-fake-and-dummy/1-end/Albertos/UserDefaults+OrderStoring.swift b/15-fake-and-dummy/1-end/Albertos/UserDefaults+OrderStoring.swift index 533ab64..8d9d152 100644 --- a/15-fake-and-dummy/1-end/Albertos/UserDefaults+OrderStoring.swift +++ b/15-fake-and-dummy/1-end/Albertos/UserDefaults+OrderStoring.swift @@ -1,7 +1,6 @@ import Foundation extension UserDefaults: OrderStoring { - func getOrder() -> Order { guard let data = data(forKey: orderKey), let order = try? JSONDecoder().decode(Order.self, from: data) else { let order = Order(items: []) @@ -19,4 +18,4 @@ extension UserDefaults: OrderStoring { } } -fileprivate var orderKey = "order" +private var orderKey = "order" diff --git a/15-fake-and-dummy/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift b/15-fake-and-dummy/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift index 881720f..18a61c8 100644 --- a/15-fake-and-dummy/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift +++ b/15-fake-and-dummy/1-end/AlbertosTests/MenuItemDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemDetailViewModelTests: XCTestCase { - func testWhenItemIsInOrderButtonSaysRemove() { let item = MenuItem.fixture() let orderController = OrderController(orderStoring: OrderStoringFake()) diff --git a/15-fake-and-dummy/1-end/AlbertosTests/OrderButtonViewModelTests.swift b/15-fake-and-dummy/1-end/AlbertosTests/OrderButtonViewModelTests.swift index ae7f29b..3da804a 100644 --- a/15-fake-and-dummy/1-end/AlbertosTests/OrderButtonViewModelTests.swift +++ b/15-fake-and-dummy/1-end/AlbertosTests/OrderButtonViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderButtonViewModelTests: XCTestCase { - func testWhenOrderIsEmptyDoesNotShowTotal() { let orderController = OrderController(orderStoring: OrderStoringFake()) let viewModel = OrderButton.ViewModel(orderController: orderController) @@ -19,4 +18,3 @@ class OrderButtonViewModelTests: XCTestCase { XCTAssertEqual(viewModel.text, "Your Order $3.30") } } - diff --git a/15-fake-and-dummy/1-end/AlbertosTests/OrderControllerTests.swift b/15-fake-and-dummy/1-end/AlbertosTests/OrderControllerTests.swift index 5bbc600..c2527dc 100644 --- a/15-fake-and-dummy/1-end/AlbertosTests/OrderControllerTests.swift +++ b/15-fake-and-dummy/1-end/AlbertosTests/OrderControllerTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderControllerTests: XCTestCase { - func testInitsWithEmptyOrder() { let controller = OrderController(orderStoring: OrderStoringFake()) diff --git a/15-fake-and-dummy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift b/15-fake-and-dummy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift index be7085c..2dae3cf 100644 --- a/15-fake-and-dummy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/15-fake-and-dummy/1-end/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderDetailViewModelTests: XCTestCase { - let alertDismissDummy: () -> Void = {} func testWhenCheckoutButtonPressedStartsPaymentProcessingFlow() { diff --git a/15-fake-and-dummy/1-end/AlbertosTests/OrderStoringFake.swift b/15-fake-and-dummy/1-end/AlbertosTests/OrderStoringFake.swift index a36caf8..6d41570 100644 --- a/15-fake-and-dummy/1-end/AlbertosTests/OrderStoringFake.swift +++ b/15-fake-and-dummy/1-end/AlbertosTests/OrderStoringFake.swift @@ -1,11 +1,10 @@ @testable import Albertos class OrderStoringFake: OrderStoring { - - private var order: Order = Order(items: []) + private var order: Order = .init(items: []) func getOrder() -> Order { - return order + order } func updateOrder(_ order: Order) { diff --git a/15-fake-and-dummy/1-end/AlbertosTests/PaymentProcessingDummy.swift b/15-fake-and-dummy/1-end/AlbertosTests/PaymentProcessingDummy.swift index cb7c0ab..3f36cbb 100644 --- a/15-fake-and-dummy/1-end/AlbertosTests/PaymentProcessingDummy.swift +++ b/15-fake-and-dummy/1-end/AlbertosTests/PaymentProcessingDummy.swift @@ -2,11 +2,10 @@ import Combine class PaymentProcessingDummy: PaymentProcessing { - // When implementing a dummy that has to return a result, like in this case, choose the simplest // code you can to make the it compile. Because dummies are meant to be used as placeholder // only, it doesn't matter what output they provide. - func process(order: Order) -> AnyPublisher { - return Result.success(()).publisher.eraseToAnyPublisher() + func process(order _: Order) -> AnyPublisher { + Result.success(()).publisher.eraseToAnyPublisher() } } diff --git a/17-appendix-b-nimble-only/Albertos/AlbertosApp.swift b/17-appendix-b-nimble-only/Albertos/AlbertosApp.swift index f3a5dc6..6679f1a 100644 --- a/17-appendix-b-nimble-only/Albertos/AlbertosApp.swift +++ b/17-appendix-b-nimble-only/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - let orderController = OrderController() let paymentProcessor = PaymentProcessingProxy() diff --git a/17-appendix-b-nimble-only/Albertos/Alert.ViewModel.swift b/17-appendix-b-nimble-only/Albertos/Alert.ViewModel.swift index e58bead..74ca4f9 100644 --- a/17-appendix-b-nimble-only/Albertos/Alert.ViewModel.swift +++ b/17-appendix-b-nimble-only/Albertos/Alert.ViewModel.swift @@ -1,9 +1,7 @@ import SwiftUI extension Alert { - struct ViewModel: Identifiable { - let title: String let message: String let buttonText: String diff --git a/17-appendix-b-nimble-only/Albertos/Color+Custom.swift b/17-appendix-b-nimble-only/Albertos/Color+Custom.swift index 0af8739..d646a7c 100644 --- a/17-appendix-b-nimble-only/Albertos/Color+Custom.swift +++ b/17-appendix-b-nimble-only/Albertos/Color+Custom.swift @@ -4,7 +4,6 @@ import SwiftUI // // See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value extension Color { - static var crimson: Color { Color(red: 220 / 255.0, green: 20 / 255.0, blue: 20 / 255.0) } static var tomato: Color { Color(red: 255 / 255.0, green: 99 / 255.0, blue: 71 / 255.0) } diff --git a/17-appendix-b-nimble-only/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift b/17-appendix-b-nimble-only/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift index f8c6eb6..cd48cca 100644 --- a/17-appendix-b-nimble-only/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift +++ b/17-appendix-b-nimble-only/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift @@ -2,9 +2,8 @@ import Combine import HippoPayments extension HippoPaymentsProcessor: PaymentProcessing { - func process(order: Order) -> AnyPublisher { - return Future { promise in + Future { promise in self.processPayment( payload: order.hippoPaymentsPayload, onSuccess: { promise(.success(())) }, diff --git a/17-appendix-b-nimble-only/Albertos/MenuFetcher.swift b/17-appendix-b-nimble-only/Albertos/MenuFetcher.swift index 4f9cc89..819ceea 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuFetcher.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuFetcher.swift @@ -2,7 +2,6 @@ import Combine import Foundation class MenuFetcher: MenuFetching { - let networkFetching: NetworkFetching init(networkFetching: NetworkFetching = URLSession.shared) { @@ -10,7 +9,7 @@ class MenuFetcher: MenuFetching { } func fetchMenu() -> AnyPublisher<[MenuItem], Error> { - return networkFetching.load(URLRequest(url: URL(string: "https://s3.amazonaws.com/mokacoding/menu_response.json")!)) + networkFetching.load(URLRequest(url: URL(string: "https://s3.amazonaws.com/mokacoding/menu_response.json")!)) .decode(type: [MenuItem].self, decoder: JSONDecoder()) .eraseToAnyPublisher() } diff --git a/17-appendix-b-nimble-only/Albertos/MenuFetching.swift b/17-appendix-b-nimble-only/Albertos/MenuFetching.swift index 43d2f1e..33c166c 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuFetching.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuFetching.swift @@ -1,6 +1,5 @@ import Combine protocol MenuFetching { - func fetchMenu() -> AnyPublisher<[MenuItem], Error> } diff --git a/17-appendix-b-nimble-only/Albertos/MenuItem.swift b/17-appendix-b-nimble-only/Albertos/MenuItem.swift index 63af8dc..7873820 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuItem.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuItem.swift @@ -1,5 +1,4 @@ struct MenuItem { - let category: String let name: String let spicy: Bool @@ -7,7 +6,6 @@ struct MenuItem { } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/17-appendix-b-nimble-only/Albertos/MenuItemDetail.ViewModel.swift b/17-appendix-b-nimble-only/Albertos/MenuItemDetail.ViewModel.swift index cda7b3d..a608464 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuItemDetail.ViewModel.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuItemDetail.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension MenuItemDetail { - class ViewModel: ObservableObject { - let name: String let spicy: String? let price: String @@ -25,12 +23,12 @@ extension MenuItemDetail { self.orderController.$order .sink { [weak self] order in - guard let self = self else { return } + guard let self else { return } if (order.items.contains { $0 == self.item }) { - self.addOrRemoveFromOrderButtonText = "Remove from order" + addOrRemoveFromOrderButtonText = "Remove from order" } else { - self.addOrRemoveFromOrderButtonText = "Add to order" + addOrRemoveFromOrderButtonText = "Add to order" } } .store(in: &cancellables) diff --git a/17-appendix-b-nimble-only/Albertos/MenuItemDetail.swift b/17-appendix-b-nimble-only/Albertos/MenuItemDetail.swift index b64a6e9..386f5b0 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuItemDetail.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuItemDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuItemDetail: View { - @ObservedObject private(set) var viewModel: ViewModel var body: some View { diff --git a/17-appendix-b-nimble-only/Albertos/MenuList.ViewModel.swift b/17-appendix-b-nimble-only/Albertos/MenuList.ViewModel.swift index 9bbe9e2..deccc7f 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuList.ViewModel.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuList.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension MenuList { - class ViewModel: ObservableObject { - @Published private(set) var sections: Result<[MenuSection], Error> = .success([]) private var cancellables = Set() @@ -17,7 +15,7 @@ extension MenuList { .map(menuGrouping) .sink( receiveCompletion: { [weak self] completion in - guard case .failure(let error) = completion else { return } + guard case let .failure(error) = completion else { return } self?.sections = .failure(error) }, receiveValue: { [weak self] value in diff --git a/17-appendix-b-nimble-only/Albertos/MenuList.swift b/17-appendix-b-nimble-only/Albertos/MenuList.swift index 93bf9a0..4304aad 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuList.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuList.swift @@ -1,14 +1,13 @@ import SwiftUI struct MenuList: View { - @ObservedObject var viewModel: ViewModel @EnvironmentObject private var orderController: OrderController var body: some View { switch viewModel.sections { - case .success(let sections): + case let .success(sections): List { ForEach(sections) { section in Section(header: Text(section.category)) { @@ -20,7 +19,7 @@ struct MenuList: View { } } } - case .failure(let error): + case let .failure(error): Text("An error occurred:") Text(error.localizedDescription).italic() } diff --git a/17-appendix-b-nimble-only/Albertos/MenuRow.ViewModel.swift b/17-appendix-b-nimble-only/Albertos/MenuRow.ViewModel.swift index 26f5b04..b3acaa5 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuRow.ViewModel.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuRow.ViewModel.swift @@ -1,7 +1,5 @@ extension MenuRow { - struct ViewModel { - let text: String init(item: MenuItem) { diff --git a/17-appendix-b-nimble-only/Albertos/MenuRow.swift b/17-appendix-b-nimble-only/Albertos/MenuRow.swift index 8dcc6fe..461a936 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuRow.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuRow.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuRow: View { - let viewModel: ViewModel var body: some View { diff --git a/17-appendix-b-nimble-only/Albertos/MenuSection.swift b/17-appendix-b-nimble-only/Albertos/MenuSection.swift index d267654..747d38d 100644 --- a/17-appendix-b-nimble-only/Albertos/MenuSection.swift +++ b/17-appendix-b-nimble-only/Albertos/MenuSection.swift @@ -1,11 +1,9 @@ struct MenuSection { - let category: String let items: [MenuItem] } extension MenuSection: Identifiable { - var id: String { category } } diff --git a/17-appendix-b-nimble-only/Albertos/NetworkFetching.swift b/17-appendix-b-nimble-only/Albertos/NetworkFetching.swift index 2d4f186..af8c9c2 100644 --- a/17-appendix-b-nimble-only/Albertos/NetworkFetching.swift +++ b/17-appendix-b-nimble-only/Albertos/NetworkFetching.swift @@ -2,6 +2,5 @@ import Combine import Foundation protocol NetworkFetching { - func load(_ request: URLRequest) -> AnyPublisher } diff --git a/17-appendix-b-nimble-only/Albertos/Order+HippoPayments.swift b/17-appendix-b-nimble-only/Albertos/Order+HippoPayments.swift index 78fd5cf..77b3c2a 100644 --- a/17-appendix-b-nimble-only/Albertos/Order+HippoPayments.swift +++ b/17-appendix-b-nimble-only/Albertos/Order+HippoPayments.swift @@ -1,4 +1,3 @@ extension Order { - - var hippoPaymentsPayload: [String: Any] { ["items": items.map { $0.name }] } + var hippoPaymentsPayload: [String: Any] { ["items": items.map(\.name)] } } diff --git a/17-appendix-b-nimble-only/Albertos/Order.swift b/17-appendix-b-nimble-only/Albertos/Order.swift index 8f14348..a0db802 100644 --- a/17-appendix-b-nimble-only/Albertos/Order.swift +++ b/17-appendix-b-nimble-only/Albertos/Order.swift @@ -1,5 +1,4 @@ struct Order { - let items: [MenuItem] var total: Double { items.reduce(0) { $0 + $1.price } } diff --git a/17-appendix-b-nimble-only/Albertos/OrderButton.ViewModel.swift b/17-appendix-b-nimble-only/Albertos/OrderButton.ViewModel.swift index d48b80c..a9232e1 100644 --- a/17-appendix-b-nimble-only/Albertos/OrderButton.ViewModel.swift +++ b/17-appendix-b-nimble-only/Albertos/OrderButton.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension OrderButton { - class ViewModel: ObservableObject { - @Published private(set) var text = "Your Order" private(set) var cancellables = Set() diff --git a/17-appendix-b-nimble-only/Albertos/OrderButton.swift b/17-appendix-b-nimble-only/Albertos/OrderButton.swift index fa66b72..882e268 100644 --- a/17-appendix-b-nimble-only/Albertos/OrderButton.swift +++ b/17-appendix-b-nimble-only/Albertos/OrderButton.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderButton: View { - @ObservedObject private(set) var viewModel: ViewModel @State private(set) var showingDetail: Bool = false @@ -11,7 +10,7 @@ struct OrderButton: View { var body: some View { Button { - self.showingDetail.toggle() + showingDetail.toggle() } label: { Text(viewModel.text) .font(Font.callout.bold()) @@ -25,7 +24,7 @@ struct OrderButton: View { viewModel: .init( orderController: orderController, paymentProcessor: paymentProcessor, - onAlertDismiss: { self.showingDetail = false } + onAlertDismiss: { showingDetail = false } ) ) } diff --git a/17-appendix-b-nimble-only/Albertos/OrderController.swift b/17-appendix-b-nimble-only/Albertos/OrderController.swift index 630d109..5d29a49 100644 --- a/17-appendix-b-nimble-only/Albertos/OrderController.swift +++ b/17-appendix-b-nimble-only/Albertos/OrderController.swift @@ -2,7 +2,6 @@ import Combine import Foundation class OrderController: ObservableObject { - @Published private(set) var order: Order private let orderStoring: OrderStoring @@ -13,7 +12,7 @@ class OrderController: ObservableObject { } func isItemInOrder(_ item: MenuItem) -> Bool { - return order.items.contains { $0 == item } + order.items.contains { $0 == item } } func addToOrder(item: MenuItem) { @@ -24,7 +23,7 @@ class OrderController: ObservableObject { let items = order.items guard let indexToRemove = items.firstIndex(where: { $0.name == item.name }) else { return } - let newItems = items.enumerated().compactMap { (index, element) -> MenuItem? in + let newItems = items.enumerated().compactMap { index, element -> MenuItem? in guard index == indexToRemove else { return element } return .none } diff --git a/17-appendix-b-nimble-only/Albertos/OrderDetail.ViewModel.swift b/17-appendix-b-nimble-only/Albertos/OrderDetail.ViewModel.swift index 0caaadb..4ac2b47 100644 --- a/17-appendix-b-nimble-only/Albertos/OrderDetail.ViewModel.swift +++ b/17-appendix-b-nimble-only/Albertos/OrderDetail.ViewModel.swift @@ -3,9 +3,7 @@ import HippoPayments import SwiftUI extension OrderDetail { - class ViewModel: ObservableObject { - let headerText = "Your Order" let menuListItems: [MenuItem] let emptyMenuFallbackText = "Add dishes to the order to see them here" @@ -62,10 +60,10 @@ extension OrderDetail { message: "The payment was successful. Your food will be with you shortly.", buttonText: "Ok", buttonAction: { [weak self] in - guard let self = self else { return } + guard let self else { return } - self.orderController.resetOrder() - self.onAlertDismiss() + orderController.resetOrder() + onAlertDismiss() } ) } diff --git a/17-appendix-b-nimble-only/Albertos/OrderDetail.swift b/17-appendix-b-nimble-only/Albertos/OrderDetail.swift index bfb4841..e7248f6 100644 --- a/17-appendix-b-nimble-only/Albertos/OrderDetail.swift +++ b/17-appendix-b-nimble-only/Albertos/OrderDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderDetail: View { - @ObservedObject private(set) var viewModel: ViewModel var body: some View { diff --git a/17-appendix-b-nimble-only/Albertos/OrderStoring.swift b/17-appendix-b-nimble-only/Albertos/OrderStoring.swift index b798268..1bb5882 100644 --- a/17-appendix-b-nimble-only/Albertos/OrderStoring.swift +++ b/17-appendix-b-nimble-only/Albertos/OrderStoring.swift @@ -1,5 +1,4 @@ protocol OrderStoring { - func getOrder() -> Order func updateOrder(_ order: Order) diff --git a/17-appendix-b-nimble-only/Albertos/PaymentProcessing.swift b/17-appendix-b-nimble-only/Albertos/PaymentProcessing.swift index 23b8b25..9561f9e 100644 --- a/17-appendix-b-nimble-only/Albertos/PaymentProcessing.swift +++ b/17-appendix-b-nimble-only/Albertos/PaymentProcessing.swift @@ -1,6 +1,5 @@ import Combine protocol PaymentProcessing { - func process(order: Order) -> AnyPublisher } diff --git a/17-appendix-b-nimble-only/Albertos/PaymentProcessingProxy.swift b/17-appendix-b-nimble-only/Albertos/PaymentProcessingProxy.swift index 54e4094..c9a0410 100644 --- a/17-appendix-b-nimble-only/Albertos/PaymentProcessingProxy.swift +++ b/17-appendix-b-nimble-only/Albertos/PaymentProcessingProxy.swift @@ -7,7 +7,6 @@ import HippoPayments // value defined as `PaymentProcessing` because "only struct/enum/class types can conform to // protocols". class PaymentProcessingProxy: PaymentProcessing, ObservableObject { - private let proxiedProcessor: PaymentProcessing = HippoPaymentsProcessor(apiKey: "abcd") func process(order: Order) -> AnyPublisher { diff --git a/17-appendix-b-nimble-only/Albertos/URLSession+NetworkFetching.swift b/17-appendix-b-nimble-only/Albertos/URLSession+NetworkFetching.swift index 6f3b0b9..1d28729 100644 --- a/17-appendix-b-nimble-only/Albertos/URLSession+NetworkFetching.swift +++ b/17-appendix-b-nimble-only/Albertos/URLSession+NetworkFetching.swift @@ -2,10 +2,9 @@ import Combine import Foundation extension URLSession: NetworkFetching { - func load(_ request: URLRequest) -> AnyPublisher { - return dataTaskPublisher(for: request) - .map { $0.data } + dataTaskPublisher(for: request) + .map(\.data) .eraseToAnyPublisher() } } diff --git a/17-appendix-b-nimble-only/Albertos/UserDefaults+OrderStoring.swift b/17-appendix-b-nimble-only/Albertos/UserDefaults+OrderStoring.swift index 533ab64..8d9d152 100644 --- a/17-appendix-b-nimble-only/Albertos/UserDefaults+OrderStoring.swift +++ b/17-appendix-b-nimble-only/Albertos/UserDefaults+OrderStoring.swift @@ -1,7 +1,6 @@ import Foundation extension UserDefaults: OrderStoring { - func getOrder() -> Order { guard let data = data(forKey: orderKey), let order = try? JSONDecoder().decode(Order.self, from: data) else { let order = Order(items: []) @@ -19,4 +18,4 @@ extension UserDefaults: OrderStoring { } } -fileprivate var orderKey = "order" +private var orderKey = "order" diff --git a/17-appendix-b-nimble-only/AlbertosTests/MenuFetcherTests.swift b/17-appendix-b-nimble-only/AlbertosTests/MenuFetcherTests.swift index 4afd89a..280c758 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/MenuFetcherTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/MenuFetcherTests.swift @@ -4,16 +4,15 @@ import Nimble import XCTest class MenuFetcherTests: XCTestCase { - var cancellables = Set() func testWhenRequestSucceedsPublishesDecodedMenuItems() throws { let json = """ -[ - { "name": "a name", "category": "a category", "spicy": true, "price": 1.0 }, - { "name": "another name", "category": "a category", "spicy": true, "price": 2.0 } -] -""" + [ + { "name": "a name", "category": "a category", "spicy": true, "price": 1.0 }, + { "name": "another name", "category": "a category", "spicy": true, "price": 2.0 } + ] + """ let data = try XCTUnwrap(json.data(using: .utf8)) let menuFetcher = MenuFetcher(networkFetching: NetworkFetchingStub(returning: .success(data))) @@ -40,7 +39,7 @@ class MenuFetcherTests: XCTestCase { menuFetcher.fetchMenu() .sink( receiveCompletion: { completion in - guard case .failure(let error) = completion else { return } + guard case let .failure(error) = completion else { return } expect(error as? URLError) == expectedError done() }, diff --git a/17-appendix-b-nimble-only/AlbertosTests/MenuGroupingTests.swift b/17-appendix-b-nimble-only/AlbertosTests/MenuGroupingTests.swift index 56adfc3..ccdd950 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/MenuGroupingTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/MenuGroupingTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class MenuGroupingTests: XCTestCase { - func testMenuWithManyCategoriesReturnsAsManySectionsInReverseAlphabeticalOrder() { let menu: [MenuItem] = [ .fixture(category: "pastas"), @@ -50,7 +49,7 @@ class MenuGroupingTests: XCTestCase { func testMenuWithOneCategoryReturnsOneSection() throws { let menu: [MenuItem] = [ .fixture(category: "pastas", name: "name"), - .fixture(category: "pastas", name: "other name") + .fixture(category: "pastas", name: "other name"), ] let sections = groupMenuByCategory(menu) diff --git a/17-appendix-b-nimble-only/AlbertosTests/MenuItemAlternateJSONTests.swift b/17-appendix-b-nimble-only/AlbertosTests/MenuItemAlternateJSONTests.swift index 8e88ba3..1ead28a 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/MenuItemAlternateJSONTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/MenuItemAlternateJSONTests.swift @@ -4,7 +4,7 @@ // // If you want to verify the failure, uncomment the import of the production module and comment the // definition of MenuItem in this file -//@testable import Albertos +// @testable import Albertos import Nimble import XCTest @@ -27,24 +27,23 @@ private struct MenuItem: Decodable { } class MenuItemAlternateJSONTests: XCTestCase { - func testWhenDecodedFromJSONDataHasAllTheInputProperties() throws { let json = """ -{ - "name": "a name", - "category": { - "name": "a category", - "id": 123 - }, - "spicy": false, - "price": 1.0 -} -""" + { + "name": "a name", + "category": { + "name": "a category", + "id": 123 + }, + "spicy": false, + "price": 1.0 + } + """ let data = try XCTUnwrap(json.data(using: .utf8)) let item: MenuItem do { - item = try JSONDecoder().decode(MenuItem.self, from: data) + item = try JSONDecoder().decode(MenuItem.self, from: data) } catch { fail("\(error)") return diff --git a/17-appendix-b-nimble-only/AlbertosTests/MenuItemDetail.ViewModelTests.swift b/17-appendix-b-nimble-only/AlbertosTests/MenuItemDetail.ViewModelTests.swift index 7f76cd6..2d34673 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/MenuItemDetail.ViewModelTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/MenuItemDetail.ViewModelTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class MenuItemDetailViewModelTests: XCTestCase { - func testWhenItemIsInOrderButtonSaysRemove() { let item = MenuItem.fixture() let orderController = OrderController(orderStoring: OrderStoringFake()) @@ -33,7 +32,7 @@ class MenuItemDetailViewModelTests: XCTestCase { viewModel.addOrRemoveFromOrder() - expect(orderController.order.items).toNot(containElementSatisfying({ $0 == item })) + expect(orderController.order.items).toNot(containElementSatisfying { $0 == item }) } func testWhenItemIsNotInOrderButtonActionAddsIt() { @@ -43,7 +42,7 @@ class MenuItemDetailViewModelTests: XCTestCase { viewModel.addOrRemoveFromOrder() - expect(orderController.order.items).to(containElementSatisfying({ $0 == item })) + expect(orderController.order.items).to(containElementSatisfying { $0 == item }) } func testNameIsItemName() { diff --git a/17-appendix-b-nimble-only/AlbertosTests/MenuItemTests.swift b/17-appendix-b-nimble-only/AlbertosTests/MenuItemTests.swift index 9781731..a704d1e 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/MenuItemTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/MenuItemTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class MenuItemTests: XCTestCase { - // MARK: Inline example with Triangulation func testWhenDecodedFromJSONDataHasAllTheInputPropertiesExample1() throws { @@ -58,6 +57,7 @@ class MenuItemTests: XCTestCase { } // MARK: Simpler check example + // Use this option if your models match the shape of the input JSON. func testWhenDecodingFromJSONDataDoesNotThrow() throws { diff --git a/17-appendix-b-nimble-only/AlbertosTests/MenuList.ViewModelTests.swift b/17-appendix-b-nimble-only/AlbertosTests/MenuList.ViewModelTests.swift index 26d3ce8..f18ec57 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/MenuList.ViewModelTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/MenuList.ViewModelTests.swift @@ -4,7 +4,6 @@ import Nimble import XCTest class MenuListViewModelTests: XCTestCase { - var cancellables = Set() func testWhenFetchingStartsPublishesEmptyMenu() throws { @@ -42,7 +41,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .success(let sections) = value else { + guard case let .success(sections) = value else { return XCTFail("Expected a successful Result, got: \(value)") } @@ -71,7 +70,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .failure(let error) = value else { + guard case let .failure(error) = value else { return XCTFail("Expected a failing Result, got: \(value)") } diff --git a/17-appendix-b-nimble-only/AlbertosTests/MenuRow.ViewModelTests.swift b/17-appendix-b-nimble-only/AlbertosTests/MenuRow.ViewModelTests.swift index 9c9642a..3bc2ea3 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/MenuRow.ViewModelTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/MenuRow.ViewModelTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class MenuRowViewModelTests: XCTestCase { - func testWhenItemIsNotSpicyTextIsItemNameOnly() { let item = MenuItem.fixture(name: "name", spicy: false) let viewModel = MenuRow.ViewModel(item: item) diff --git a/17-appendix-b-nimble-only/AlbertosTests/OrderButtonViewModelTests.swift b/17-appendix-b-nimble-only/AlbertosTests/OrderButtonViewModelTests.swift index 31c31fc..bff4ea5 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/OrderButtonViewModelTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/OrderButtonViewModelTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class OrderButtonViewModelTests: XCTestCase { - func testWhenOrderIsEmptyDoesNotShowTotal() { let orderController = OrderController(orderStoring: OrderStoringFake()) let viewModel = OrderButton.ViewModel(orderController: orderController) @@ -20,4 +19,3 @@ class OrderButtonViewModelTests: XCTestCase { expect(viewModel.text) == "Your Order $3.30" } } - diff --git a/17-appendix-b-nimble-only/AlbertosTests/OrderControllerTests.swift b/17-appendix-b-nimble-only/AlbertosTests/OrderControllerTests.swift index 7c7f7bd..56bdc5b 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/OrderControllerTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/OrderControllerTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class OrderControllerTests: XCTestCase { - func testInitsWithEmptyOrder() { let controller = OrderController(orderStoring: OrderStoringFake()) diff --git a/17-appendix-b-nimble-only/AlbertosTests/OrderDetail.ViewModelTests.swift b/17-appendix-b-nimble-only/AlbertosTests/OrderDetail.ViewModelTests.swift index fd54310..060173f 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class OrderDetailViewModelTests: XCTestCase { - let alertDismissDummy: () -> Void = {} func testWhenCheckoutButtonPressedStartsPaymentProcessingFlow() { diff --git a/17-appendix-b-nimble-only/AlbertosTests/OrderTests.swift b/17-appendix-b-nimble-only/AlbertosTests/OrderTests.swift index 3284a12..04150a8 100644 --- a/17-appendix-b-nimble-only/AlbertosTests/OrderTests.swift +++ b/17-appendix-b-nimble-only/AlbertosTests/OrderTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class OrderTests: XCTestCase { - func testTotalSumsPricesOfEachItem() { let order = Order( items: [.fixture(price: 1.0), .fixture(price: 2.0), .fixture(price: 3.5)] diff --git a/18-appendix-b-quick-and-nimble/Albertos/AlbertosApp.swift b/18-appendix-b-quick-and-nimble/Albertos/AlbertosApp.swift index f3a5dc6..6679f1a 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/AlbertosApp.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/AlbertosApp.swift @@ -2,7 +2,6 @@ import SwiftUI @main struct AlbertosApp: App { - let orderController = OrderController() let paymentProcessor = PaymentProcessingProxy() diff --git a/18-appendix-b-quick-and-nimble/Albertos/Alert.ViewModel.swift b/18-appendix-b-quick-and-nimble/Albertos/Alert.ViewModel.swift index e58bead..74ca4f9 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/Alert.ViewModel.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/Alert.ViewModel.swift @@ -1,9 +1,7 @@ import SwiftUI extension Alert { - struct ViewModel: Identifiable { - let title: String let message: String let buttonText: String diff --git a/18-appendix-b-quick-and-nimble/Albertos/Color+Custom.swift b/18-appendix-b-quick-and-nimble/Albertos/Color+Custom.swift index 0af8739..d646a7c 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/Color+Custom.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/Color+Custom.swift @@ -4,7 +4,6 @@ import SwiftUI // // See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value extension Color { - static var crimson: Color { Color(red: 220 / 255.0, green: 20 / 255.0, blue: 20 / 255.0) } static var tomato: Color { Color(red: 255 / 255.0, green: 99 / 255.0, blue: 71 / 255.0) } diff --git a/18-appendix-b-quick-and-nimble/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift b/18-appendix-b-quick-and-nimble/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift index f8c6eb6..cd48cca 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/HippoPaymentsProcessor+PaymentProcessing.swift @@ -2,9 +2,8 @@ import Combine import HippoPayments extension HippoPaymentsProcessor: PaymentProcessing { - func process(order: Order) -> AnyPublisher { - return Future { promise in + Future { promise in self.processPayment( payload: order.hippoPaymentsPayload, onSuccess: { promise(.success(())) }, diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuFetcher.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuFetcher.swift index 4f9cc89..819ceea 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuFetcher.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuFetcher.swift @@ -2,7 +2,6 @@ import Combine import Foundation class MenuFetcher: MenuFetching { - let networkFetching: NetworkFetching init(networkFetching: NetworkFetching = URLSession.shared) { @@ -10,7 +9,7 @@ class MenuFetcher: MenuFetching { } func fetchMenu() -> AnyPublisher<[MenuItem], Error> { - return networkFetching.load(URLRequest(url: URL(string: "https://s3.amazonaws.com/mokacoding/menu_response.json")!)) + networkFetching.load(URLRequest(url: URL(string: "https://s3.amazonaws.com/mokacoding/menu_response.json")!)) .decode(type: [MenuItem].self, decoder: JSONDecoder()) .eraseToAnyPublisher() } diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuFetching.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuFetching.swift index 43d2f1e..33c166c 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuFetching.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuFetching.swift @@ -1,6 +1,5 @@ import Combine protocol MenuFetching { - func fetchMenu() -> AnyPublisher<[MenuItem], Error> } diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuItem.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuItem.swift index 63af8dc..7873820 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuItem.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuItem.swift @@ -1,5 +1,4 @@ struct MenuItem { - let category: String let name: String let spicy: Bool @@ -7,7 +6,6 @@ struct MenuItem { } extension MenuItem: Identifiable { - var id: String { name } } diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.ViewModel.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.ViewModel.swift index cda7b3d..a608464 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.ViewModel.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension MenuItemDetail { - class ViewModel: ObservableObject { - let name: String let spicy: String? let price: String @@ -25,12 +23,12 @@ extension MenuItemDetail { self.orderController.$order .sink { [weak self] order in - guard let self = self else { return } + guard let self else { return } if (order.items.contains { $0 == self.item }) { - self.addOrRemoveFromOrderButtonText = "Remove from order" + addOrRemoveFromOrderButtonText = "Remove from order" } else { - self.addOrRemoveFromOrderButtonText = "Add to order" + addOrRemoveFromOrderButtonText = "Add to order" } } .store(in: &cancellables) diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.swift index b64a6e9..386f5b0 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuItemDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuItemDetail: View { - @ObservedObject private(set) var viewModel: ViewModel var body: some View { diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuList.ViewModel.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuList.ViewModel.swift index 9bbe9e2..deccc7f 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuList.ViewModel.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuList.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension MenuList { - class ViewModel: ObservableObject { - @Published private(set) var sections: Result<[MenuSection], Error> = .success([]) private var cancellables = Set() @@ -17,7 +15,7 @@ extension MenuList { .map(menuGrouping) .sink( receiveCompletion: { [weak self] completion in - guard case .failure(let error) = completion else { return } + guard case let .failure(error) = completion else { return } self?.sections = .failure(error) }, receiveValue: { [weak self] value in diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuList.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuList.swift index 93bf9a0..4304aad 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuList.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuList.swift @@ -1,14 +1,13 @@ import SwiftUI struct MenuList: View { - @ObservedObject var viewModel: ViewModel @EnvironmentObject private var orderController: OrderController var body: some View { switch viewModel.sections { - case .success(let sections): + case let .success(sections): List { ForEach(sections) { section in Section(header: Text(section.category)) { @@ -20,7 +19,7 @@ struct MenuList: View { } } } - case .failure(let error): + case let .failure(error): Text("An error occurred:") Text(error.localizedDescription).italic() } diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuRow.ViewModel.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuRow.ViewModel.swift index 26f5b04..b3acaa5 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuRow.ViewModel.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuRow.ViewModel.swift @@ -1,7 +1,5 @@ extension MenuRow { - struct ViewModel { - let text: String init(item: MenuItem) { diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuRow.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuRow.swift index 8dcc6fe..461a936 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuRow.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuRow.swift @@ -1,7 +1,6 @@ import SwiftUI struct MenuRow: View { - let viewModel: ViewModel var body: some View { diff --git a/18-appendix-b-quick-and-nimble/Albertos/MenuSection.swift b/18-appendix-b-quick-and-nimble/Albertos/MenuSection.swift index d267654..747d38d 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/MenuSection.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/MenuSection.swift @@ -1,11 +1,9 @@ struct MenuSection { - let category: String let items: [MenuItem] } extension MenuSection: Identifiable { - var id: String { category } } diff --git a/18-appendix-b-quick-and-nimble/Albertos/NetworkFetching.swift b/18-appendix-b-quick-and-nimble/Albertos/NetworkFetching.swift index 2d4f186..af8c9c2 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/NetworkFetching.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/NetworkFetching.swift @@ -2,6 +2,5 @@ import Combine import Foundation protocol NetworkFetching { - func load(_ request: URLRequest) -> AnyPublisher } diff --git a/18-appendix-b-quick-and-nimble/Albertos/Order+HippoPayments.swift b/18-appendix-b-quick-and-nimble/Albertos/Order+HippoPayments.swift index 78fd5cf..77b3c2a 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/Order+HippoPayments.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/Order+HippoPayments.swift @@ -1,4 +1,3 @@ extension Order { - - var hippoPaymentsPayload: [String: Any] { ["items": items.map { $0.name }] } + var hippoPaymentsPayload: [String: Any] { ["items": items.map(\.name)] } } diff --git a/18-appendix-b-quick-and-nimble/Albertos/Order.swift b/18-appendix-b-quick-and-nimble/Albertos/Order.swift index 8f14348..a0db802 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/Order.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/Order.swift @@ -1,5 +1,4 @@ struct Order { - let items: [MenuItem] var total: Double { items.reduce(0) { $0 + $1.price } } diff --git a/18-appendix-b-quick-and-nimble/Albertos/OrderButton.ViewModel.swift b/18-appendix-b-quick-and-nimble/Albertos/OrderButton.ViewModel.swift index d48b80c..a9232e1 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/OrderButton.ViewModel.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/OrderButton.ViewModel.swift @@ -1,9 +1,7 @@ import Combine extension OrderButton { - class ViewModel: ObservableObject { - @Published private(set) var text = "Your Order" private(set) var cancellables = Set() diff --git a/18-appendix-b-quick-and-nimble/Albertos/OrderButton.swift b/18-appendix-b-quick-and-nimble/Albertos/OrderButton.swift index fa66b72..882e268 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/OrderButton.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/OrderButton.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderButton: View { - @ObservedObject private(set) var viewModel: ViewModel @State private(set) var showingDetail: Bool = false @@ -11,7 +10,7 @@ struct OrderButton: View { var body: some View { Button { - self.showingDetail.toggle() + showingDetail.toggle() } label: { Text(viewModel.text) .font(Font.callout.bold()) @@ -25,7 +24,7 @@ struct OrderButton: View { viewModel: .init( orderController: orderController, paymentProcessor: paymentProcessor, - onAlertDismiss: { self.showingDetail = false } + onAlertDismiss: { showingDetail = false } ) ) } diff --git a/18-appendix-b-quick-and-nimble/Albertos/OrderController.swift b/18-appendix-b-quick-and-nimble/Albertos/OrderController.swift index 630d109..5d29a49 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/OrderController.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/OrderController.swift @@ -2,7 +2,6 @@ import Combine import Foundation class OrderController: ObservableObject { - @Published private(set) var order: Order private let orderStoring: OrderStoring @@ -13,7 +12,7 @@ class OrderController: ObservableObject { } func isItemInOrder(_ item: MenuItem) -> Bool { - return order.items.contains { $0 == item } + order.items.contains { $0 == item } } func addToOrder(item: MenuItem) { @@ -24,7 +23,7 @@ class OrderController: ObservableObject { let items = order.items guard let indexToRemove = items.firstIndex(where: { $0.name == item.name }) else { return } - let newItems = items.enumerated().compactMap { (index, element) -> MenuItem? in + let newItems = items.enumerated().compactMap { index, element -> MenuItem? in guard index == indexToRemove else { return element } return .none } diff --git a/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.ViewModel.swift b/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.ViewModel.swift index 0caaadb..4ac2b47 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.ViewModel.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.ViewModel.swift @@ -3,9 +3,7 @@ import HippoPayments import SwiftUI extension OrderDetail { - class ViewModel: ObservableObject { - let headerText = "Your Order" let menuListItems: [MenuItem] let emptyMenuFallbackText = "Add dishes to the order to see them here" @@ -62,10 +60,10 @@ extension OrderDetail { message: "The payment was successful. Your food will be with you shortly.", buttonText: "Ok", buttonAction: { [weak self] in - guard let self = self else { return } + guard let self else { return } - self.orderController.resetOrder() - self.onAlertDismiss() + orderController.resetOrder() + onAlertDismiss() } ) } diff --git a/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.swift b/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.swift index bfb4841..e7248f6 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/OrderDetail.swift @@ -1,7 +1,6 @@ import SwiftUI struct OrderDetail: View { - @ObservedObject private(set) var viewModel: ViewModel var body: some View { diff --git a/18-appendix-b-quick-and-nimble/Albertos/OrderStoring.swift b/18-appendix-b-quick-and-nimble/Albertos/OrderStoring.swift index b798268..1bb5882 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/OrderStoring.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/OrderStoring.swift @@ -1,5 +1,4 @@ protocol OrderStoring { - func getOrder() -> Order func updateOrder(_ order: Order) diff --git a/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessing.swift b/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessing.swift index 23b8b25..9561f9e 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessing.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessing.swift @@ -1,6 +1,5 @@ import Combine protocol PaymentProcessing { - func process(order: Order) -> AnyPublisher } diff --git a/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessingProxy.swift b/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessingProxy.swift index 54e4094..c9a0410 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessingProxy.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/PaymentProcessingProxy.swift @@ -7,7 +7,6 @@ import HippoPayments // value defined as `PaymentProcessing` because "only struct/enum/class types can conform to // protocols". class PaymentProcessingProxy: PaymentProcessing, ObservableObject { - private let proxiedProcessor: PaymentProcessing = HippoPaymentsProcessor(apiKey: "abcd") func process(order: Order) -> AnyPublisher { diff --git a/18-appendix-b-quick-and-nimble/Albertos/URLSession+NetworkFetching.swift b/18-appendix-b-quick-and-nimble/Albertos/URLSession+NetworkFetching.swift index 6f3b0b9..1d28729 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/URLSession+NetworkFetching.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/URLSession+NetworkFetching.swift @@ -2,10 +2,9 @@ import Combine import Foundation extension URLSession: NetworkFetching { - func load(_ request: URLRequest) -> AnyPublisher { - return dataTaskPublisher(for: request) - .map { $0.data } + dataTaskPublisher(for: request) + .map(\.data) .eraseToAnyPublisher() } } diff --git a/18-appendix-b-quick-and-nimble/Albertos/UserDefaults+OrderStoring.swift b/18-appendix-b-quick-and-nimble/Albertos/UserDefaults+OrderStoring.swift index 533ab64..8d9d152 100644 --- a/18-appendix-b-quick-and-nimble/Albertos/UserDefaults+OrderStoring.swift +++ b/18-appendix-b-quick-and-nimble/Albertos/UserDefaults+OrderStoring.swift @@ -1,7 +1,6 @@ import Foundation extension UserDefaults: OrderStoring { - func getOrder() -> Order { guard let data = data(forKey: orderKey), let order = try? JSONDecoder().decode(Order.self, from: data) else { let order = Order(items: []) @@ -19,4 +18,4 @@ extension UserDefaults: OrderStoring { } } -fileprivate var orderKey = "order" +private var orderKey = "order" diff --git a/18-appendix-b-quick-and-nimble/AlbertosTests/MenuItemDetail.ViewModelSpec.swift b/18-appendix-b-quick-and-nimble/AlbertosTests/MenuItemDetail.ViewModelSpec.swift index df8f008..3ef8715 100644 --- a/18-appendix-b-quick-and-nimble/AlbertosTests/MenuItemDetail.ViewModelSpec.swift +++ b/18-appendix-b-quick-and-nimble/AlbertosTests/MenuItemDetail.ViewModelSpec.swift @@ -3,13 +3,10 @@ import Nimble import Quick class MenuItemDetailViewModelSpec: QuickSpec { - override func spec() { - // Quick lets you organize your test using plain language: // "MenuItemDetail.ViewModel, order button, when the item is in the order, says remove from order". describe("MenuItemDetail.ViewModel") { - describe("order button") { // It also allow for an efficient grouping of common setup code while still having isolated // tests. @@ -31,7 +28,7 @@ class MenuItemDetailViewModelSpec: QuickSpec { it("removes the item from the order") { viewModel.addOrRemoveFromOrder() - expect(orderController.order.items).toNot(containElementSatisfying({ $0 == item })) + expect(orderController.order.items).toNot(containElementSatisfying { $0 == item }) } } @@ -46,7 +43,7 @@ class MenuItemDetailViewModelSpec: QuickSpec { it("adds the item to the order") { viewModel.addOrRemoveFromOrder() - expect(orderController.order.items).to(containElementSatisfying({ $0 == item })) + expect(orderController.order.items).to(containElementSatisfying { $0 == item }) } } } @@ -55,7 +52,6 @@ class MenuItemDetailViewModelSpec: QuickSpec { // Alternatively, you can replicate the setup code in each example, to avoid // spreading the code affecting each test and keep them compact. context("when the item is in the order") { - it("says remove from order") { let item = MenuItem.fixture() let orderController = OrderController(orderStoring: OrderStoringFake()) @@ -75,12 +71,11 @@ class MenuItemDetailViewModelSpec: QuickSpec { viewModel.addOrRemoveFromOrder() - expect(orderController.order.items).toNot(containElementSatisfying({ $0 == item })) + expect(orderController.order.items).toNot(containElementSatisfying { $0 == item }) } } context("when the item is not in the order") { - it("says add to order") { let item = MenuItem.fixture() let orderController = OrderController(orderStoring: OrderStoringFake()) @@ -98,7 +93,7 @@ class MenuItemDetailViewModelSpec: QuickSpec { viewModel.addOrRemoveFromOrder() - expect(orderController.order.items).to(containElementSatisfying({ $0 == item })) + expect(orderController.order.items).to(containElementSatisfying { $0 == item }) } } } diff --git a/19-appendix-c-uikit/Albertos/AlertViewModel.swift b/19-appendix-c-uikit/Albertos/AlertViewModel.swift index 2b1dcdc..cd857bb 100644 --- a/19-appendix-c-uikit/Albertos/AlertViewModel.swift +++ b/19-appendix-c-uikit/Albertos/AlertViewModel.swift @@ -1,5 +1,4 @@ struct AlertViewModel { - let title: String let message: String let buttonText: String diff --git a/19-appendix-c-uikit/Albertos/AppCoordinator.swift b/19-appendix-c-uikit/Albertos/AppCoordinator.swift index 4187946..b75e88b 100644 --- a/19-appendix-c-uikit/Albertos/AppCoordinator.swift +++ b/19-appendix-c-uikit/Albertos/AppCoordinator.swift @@ -2,7 +2,6 @@ import Combine import UIKit class AppCoordinator: MenuListViewControllerNavigationDelegate, OrderDetailViewControllerDelegate { - let navigationController: UINavigationController private let orderController: OrderController private let paymentProcessing: PaymentProcessing @@ -38,7 +37,7 @@ class AppCoordinator: MenuListViewControllerNavigationDelegate, OrderDetailViewC .store(in: &cancellables) orderButton.addAction( - UIAction(handler: { [weak self] _ in self?.presentOrderDetail()}), + UIAction(handler: { [weak self] _ in self?.presentOrderDetail() }), for: .primaryActionTriggered ) } @@ -52,12 +51,12 @@ class AppCoordinator: MenuListViewControllerNavigationDelegate, OrderDetailViewC orderButton.alignSafeAreaBottomAnchor(to: navigationController.view) } - func orderDetailViewControllerCompletedPaymentFlow(_ viewController: OrderDetailViewController) { + func orderDetailViewControllerCompletedPaymentFlow(_: OrderDetailViewController) { navigationController.dismiss(animated: true, completion: .none) } func menuListViewController( - _ viewController: MenuListViewController, + _: MenuListViewController, didSelectItem item: MenuItem ) { navigationController.pushViewController( @@ -69,7 +68,7 @@ class AppCoordinator: MenuListViewControllerNavigationDelegate, OrderDetailViewC } func presentOrderDetail() { - let orderDetailViewController = OrderDetailViewController( + let orderDetailViewController = OrderDetailViewController( orderController: orderController, paymentProcessor: paymentProcessing ) diff --git a/19-appendix-c-uikit/Albertos/AppDelegate.swift b/19-appendix-c-uikit/Albertos/AppDelegate.swift index a14f12a..6fc0acf 100644 --- a/19-appendix-c-uikit/Albertos/AppDelegate.swift +++ b/19-appendix-c-uikit/Albertos/AppDelegate.swift @@ -2,14 +2,13 @@ import UIKit @main class AppDelegate: UIResponder, UIApplicationDelegate { - - func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - return true + func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + true } // MARK: - UISceneSession Lifecycle - func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { - return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + func application(_: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options _: UIScene.ConnectionOptions) -> UISceneConfiguration { + UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) } } diff --git a/19-appendix-c-uikit/Albertos/MenuItemDetailView.swift b/19-appendix-c-uikit/Albertos/MenuItemDetailView.swift index b2e41cd..784ece5 100644 --- a/19-appendix-c-uikit/Albertos/MenuItemDetailView.swift +++ b/19-appendix-c-uikit/Albertos/MenuItemDetailView.swift @@ -1,11 +1,10 @@ import UIKit class MenuItemDetailView: UIStackView { - let nameLabel = UILabel() let priceLabel = UILabel() - lazy private(set) var spicyLabel = UILabel() - let addOrRemoveFromOrderButton: UIButton = UIButton(type: .system) + private(set) lazy var spicyLabel = UILabel() + let addOrRemoveFromOrderButton: UIButton = .init(type: .system) override init(frame: CGRect) { super.init(frame: frame) @@ -16,8 +15,8 @@ class MenuItemDetailView: UIStackView { spacing = 8 } - @available (*, unavailable, message: "This view has no `.xib` backing it. Use `init(frame:)` instead.") - required init(coder: NSCoder) { + @available(*, unavailable, message: "This view has no `.xib` backing it. Use `init(frame:)` instead.") + required init(coder _: NSCoder) { fatalError("This view has no `.xib` backing it. Use `init(frame:)` instead.") } diff --git a/19-appendix-c-uikit/Albertos/MenuItemDetailViewController.swift b/19-appendix-c-uikit/Albertos/MenuItemDetailViewController.swift index 5b02f5d..00be0f2 100644 --- a/19-appendix-c-uikit/Albertos/MenuItemDetailViewController.swift +++ b/19-appendix-c-uikit/Albertos/MenuItemDetailViewController.swift @@ -1,7 +1,6 @@ import UIKit class MenuItemDetailViewController: UIViewController { - let containerView = MenuItemDetailView() private let viewModel: MenuItemDetailViewModel @@ -19,12 +18,12 @@ class MenuItemDetailViewController: UIViewController { } @available(*, unavailable, message: "Use `init` instead") - override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + override init(nibName _: String?, bundle _: Bundle?) { fatalError("This view controller has no `.xib` backing it. Use `init` instead.") } @available(*, unavailable, message: "Use `init` instead") - required init?(coder: NSCoder) { + required init?(coder _: NSCoder) { fatalError("This view controller has no `.xib` backing it. Use `init` instead.") } @@ -40,9 +39,9 @@ class MenuItemDetailViewController: UIViewController { containerView.addOrRemoveFromOrderButton.addAction( UIAction( handler: { [weak self] _ in - guard let self = self else { return } - self.viewModel.addOrRemoveFromOrder() - self.containerView.configureContent(with: self.viewModel) + guard let self else { return } + viewModel.addOrRemoveFromOrder() + containerView.configureContent(with: viewModel) } ), for: .primaryActionTriggered diff --git a/19-appendix-c-uikit/Albertos/MenuItemDetailViewModel.swift b/19-appendix-c-uikit/Albertos/MenuItemDetailViewModel.swift index 6002bc3..57b511f 100644 --- a/19-appendix-c-uikit/Albertos/MenuItemDetailViewModel.swift +++ b/19-appendix-c-uikit/Albertos/MenuItemDetailViewModel.swift @@ -1,5 +1,4 @@ class MenuItemDetailViewModel { - let name: String let spicy: String? let price: String @@ -21,9 +20,9 @@ class MenuItemDetailViewModel { ) if (orderController.order.items.contains { $0 == item }) { - self.addOrRemoveFromOrderButtonText = "Remove from order" + addOrRemoveFromOrderButtonText = "Remove from order" } else { - self.addOrRemoveFromOrderButtonText = "Add to order" + addOrRemoveFromOrderButtonText = "Add to order" } } @@ -42,8 +41,8 @@ class MenuItemDetailViewModel { private func getAddOrRemoveFromOrderButtonText(item: MenuItem, order: Order) -> String { if (order.items.contains { $0 == item }) { - return "Remove from order" + "Remove from order" } else { - return "Add to order" + "Add to order" } } diff --git a/19-appendix-c-uikit/Albertos/MenuListTableViewDataSource.swift b/19-appendix-c-uikit/Albertos/MenuListTableViewDataSource.swift index acd2d4c..6d48be8 100644 --- a/19-appendix-c-uikit/Albertos/MenuListTableViewDataSource.swift +++ b/19-appendix-c-uikit/Albertos/MenuListTableViewDataSource.swift @@ -1,7 +1,6 @@ import UIKit class MenuListTableViewDataSource: NSObject, UITableViewDataSource { - private var sections: Result<[MenuSection], Error> private let cellIdentifier = "cell" @@ -20,18 +19,18 @@ class MenuListTableViewDataSource: NSObject, UITableViewDataSource { tableView.reloadData() } - func numberOfSections(in tableView: UITableView) -> Int { - guard case .success(let sections) = sections else { return 1 } + func numberOfSections(in _: UITableView) -> Int { + guard case let .success(sections) = sections else { return 1 } return sections.count } - func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { - guard case .success(let sections) = sections else { return .none } + func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? { + guard case let .success(sections) = sections else { return .none } return sections[safe: section]?.category.uppercased() } - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - guard case .success(let sections) = sections else { return 1 } + func tableView(_: UITableView, numberOfRowsInSection section: Int) -> Int { + guard case let .success(sections) = sections else { return 1 } return sections[safe: section]?.items.count ?? 1 } @@ -39,10 +38,10 @@ class MenuListTableViewDataSource: NSObject, UITableViewDataSource { let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) switch sections { - case .failure(let error): + case let .failure(error): cell.textLabel?.text = "An error occurred" cell.detailTextLabel?.text = "\(error.localizedDescription)" - case .success(let sections): + case let .success(sections): guard let item = sections[safe: indexPath.section]?.items[safe: indexPath.row] else { return cell } diff --git a/19-appendix-c-uikit/Albertos/MenuListTableViewDelegate.swift b/19-appendix-c-uikit/Albertos/MenuListTableViewDelegate.swift index 5ad02d6..e69ec09 100644 --- a/19-appendix-c-uikit/Albertos/MenuListTableViewDelegate.swift +++ b/19-appendix-c-uikit/Albertos/MenuListTableViewDelegate.swift @@ -1,19 +1,18 @@ import UIKit class MenuListTableViewDelegate: NSObject, UITableViewDelegate { - var sections: Result<[MenuSection], Error> = .success([]) - let onRowSelected: (MenuItem) -> () + let onRowSelected: (MenuItem) -> Void - init(onRowSelected: @escaping (MenuItem) -> ()) { + init(onRowSelected: @escaping (MenuItem) -> Void) { self.onRowSelected = onRowSelected } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) - guard case .success(let sections) = sections else { return } + guard case let .success(sections) = sections else { return } let item = sections[indexPath.section].items[indexPath.row] diff --git a/19-appendix-c-uikit/Albertos/MenuListViewController.swift b/19-appendix-c-uikit/Albertos/MenuListViewController.swift index 4bd9c30..567981e 100644 --- a/19-appendix-c-uikit/Albertos/MenuListViewController.swift +++ b/19-appendix-c-uikit/Albertos/MenuListViewController.swift @@ -2,7 +2,6 @@ import Combine import UIKit protocol MenuListViewControllerNavigationDelegate: AnyObject { - func menuListViewController( _ viewController: MenuListViewController, didSelectItem item: MenuItem @@ -10,35 +9,34 @@ protocol MenuListViewControllerNavigationDelegate: AnyObject { } class MenuListViewController: UIViewController { - let tableView = UITableView() weak var navigationDelegate: MenuListViewControllerNavigationDelegate? let viewModel: MenuListViewModel - lazy private var tableViewDataSource = MenuListTableViewDataSource() - lazy private var tableViewDelegate = MenuListTableViewDelegate( + private lazy var tableViewDataSource = MenuListTableViewDataSource() + private lazy var tableViewDelegate = MenuListTableViewDelegate( onRowSelected: { [weak self] in - guard let self = self else { return } - self.navigationDelegate?.menuListViewController(self, didSelectItem: $0) + guard let self else { return } + navigationDelegate?.menuListViewController(self, didSelectItem: $0) } ) private var cancellables = Set() init(menuFetching: MenuFetching) { - self.viewModel = MenuListViewModel(menuFetching: menuFetching) + viewModel = MenuListViewModel(menuFetching: menuFetching) super.init(nibName: .none, bundle: .none) } @available(*, unavailable, message: "Use `init` instead") - override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + override init(nibName _: String?, bundle _: Bundle?) { fatalError("This view controller has no `.xib` backing it. Use `init` instead.") } @available(*, unavailable, message: "Use `init` instead") - required init?(coder: NSCoder) { + required init?(coder _: NSCoder) { fatalError("This view controller has no `.xib` backing it. Use `init` instead.") } @@ -53,10 +51,10 @@ class MenuListViewController: UIViewController { viewModel.$sections .receive(on: RunLoop.main) .sink { [weak self] sections in - guard let self = self else { return } + guard let self else { return } - self.tableViewDataSource.reload(self.tableView, with: sections) - self.tableViewDelegate.sections = sections + tableViewDataSource.reload(tableView, with: sections) + tableViewDelegate.sections = sections } .store(in: &cancellables) } diff --git a/19-appendix-c-uikit/Albertos/MenuListViewModel.swift b/19-appendix-c-uikit/Albertos/MenuListViewModel.swift index bdf5dfc..caf2de8 100644 --- a/19-appendix-c-uikit/Albertos/MenuListViewModel.swift +++ b/19-appendix-c-uikit/Albertos/MenuListViewModel.swift @@ -1,7 +1,6 @@ import Combine class MenuListViewModel: ObservableObject { - @Published private(set) var sections: Result<[MenuSection], Error> = .success([]) private let menuFetching: MenuFetching @@ -18,7 +17,7 @@ class MenuListViewModel: ObservableObject { .map(menuGrouping) .sink( receiveCompletion: { [weak self] completion in - guard case .failure(let error) = completion else { return } + guard case let .failure(error) = completion else { return } self?.sections = .failure(error) }, receiveValue: { [weak self] value in diff --git a/19-appendix-c-uikit/Albertos/MenuRowViewModel.swift b/19-appendix-c-uikit/Albertos/MenuRowViewModel.swift index b6eb033..5d6ae7e 100644 --- a/19-appendix-c-uikit/Albertos/MenuRowViewModel.swift +++ b/19-appendix-c-uikit/Albertos/MenuRowViewModel.swift @@ -1,5 +1,4 @@ struct MenuRowViewModel { - let text: String init(item: MenuItem) { diff --git a/19-appendix-c-uikit/Albertos/Order+HippoPayments.swift b/19-appendix-c-uikit/Albertos/Order+HippoPayments.swift index 78fd5cf..77b3c2a 100644 --- a/19-appendix-c-uikit/Albertos/Order+HippoPayments.swift +++ b/19-appendix-c-uikit/Albertos/Order+HippoPayments.swift @@ -1,4 +1,3 @@ extension Order { - - var hippoPaymentsPayload: [String: Any] { ["items": items.map { $0.name }] } + var hippoPaymentsPayload: [String: Any] { ["items": items.map(\.name)] } } diff --git a/19-appendix-c-uikit/Albertos/OrderButton.ViewModel.swift b/19-appendix-c-uikit/Albertos/OrderButton.ViewModel.swift index 82ff5d4..40d0422 100644 --- a/19-appendix-c-uikit/Albertos/OrderButton.ViewModel.swift +++ b/19-appendix-c-uikit/Albertos/OrderButton.ViewModel.swift @@ -1,7 +1,6 @@ import Combine class OrderButtonViewModel: ObservableObject { - @Published private(set) var text = "Your Order" private(set) var cancellables = Set() diff --git a/19-appendix-c-uikit/Albertos/OrderDetailViewController.swift b/19-appendix-c-uikit/Albertos/OrderDetailViewController.swift index 622f036..612c465 100644 --- a/19-appendix-c-uikit/Albertos/OrderDetailViewController.swift +++ b/19-appendix-c-uikit/Albertos/OrderDetailViewController.swift @@ -2,16 +2,14 @@ import Combine import UIKit protocol OrderDetailViewControllerDelegate: AnyObject { - func orderDetailViewControllerCompletedPaymentFlow(_ viewController: OrderDetailViewController) } class OrderDetailViewController: UIViewController { - - lazy private var tableView = UITableView() - lazy private var emptyMenuLabel = UILabel() - lazy private var checkoutButton = BigButton() - lazy private var totalPriceLabel = UITableViewFooterLabel() + private lazy var tableView = UITableView() + private lazy var emptyMenuLabel = UILabel() + private lazy var checkoutButton = BigButton() + private lazy var totalPriceLabel = UITableViewFooterLabel() private let viewModel: OrderDetailViewModel @@ -20,7 +18,7 @@ class OrderDetailViewController: UIViewController { private var cancellables = Set() init(orderController: OrderController, paymentProcessor: PaymentProcessing) { - self.viewModel = OrderDetailViewModel( + viewModel = OrderDetailViewModel( orderController: orderController, paymentProcessor: paymentProcessor, // Leaving this empty and relying on a navigation delegate, which is more UIKit-style @@ -29,12 +27,12 @@ class OrderDetailViewController: UIViewController { super.init(nibName: .none, bundle: .none) } - override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + override init(nibName _: String?, bundle _: Bundle?) { fatalError("This view controller has no `.xib` backing it. Use `init` instead.") } @available(*, unavailable, message: "Use `init` instead") - required init?(coder: NSCoder) { + required init?(coder _: NSCoder) { fatalError("This view controller has no `.xib` backing it. Use `init` instead.") } @@ -51,7 +49,7 @@ class OrderDetailViewController: UIViewController { viewModel.$alertToShow .compactMap { $0 } .map { - return AlertViewModel( + AlertViewModel( title: $0.title, message: $0.message, buttonText: $0.buttonText, @@ -114,8 +112,8 @@ class OrderDetailViewController: UIViewController { style: .default, handler: { [weak self] _ in viewModel.buttonAction?() - guard let self = self else { return } - self.delegate?.orderDetailViewControllerCompletedPaymentFlow(self) + guard let self else { return } + delegate?.orderDetailViewControllerCompletedPaymentFlow(self) } ) ) @@ -125,16 +123,15 @@ class OrderDetailViewController: UIViewController { } extension OrderDetailViewController: UITableViewDataSource { - - func numberOfSections(in tableView: UITableView) -> Int { - return 1 + func numberOfSections(in _: UITableView) -> Int { + 1 } - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return viewModel.menuListItems.count + func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int { + viewModel.menuListItems.count } - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + func tableView(_: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .value1, reuseIdentifier: .none) let item = viewModel.menuListItems[indexPath.row] @@ -146,8 +143,7 @@ extension OrderDetailViewController: UITableViewDataSource { } extension OrderDetailViewController: UITableViewDelegate { - - func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { - return .none + func tableView(_: UITableView, willSelectRowAt _: IndexPath) -> IndexPath? { + .none } } diff --git a/19-appendix-c-uikit/Albertos/OrderDetailViewModel.swift b/19-appendix-c-uikit/Albertos/OrderDetailViewModel.swift index 084d1ed..9cbd210 100644 --- a/19-appendix-c-uikit/Albertos/OrderDetailViewModel.swift +++ b/19-appendix-c-uikit/Albertos/OrderDetailViewModel.swift @@ -2,7 +2,6 @@ import Combine import HippoPayments class OrderDetailViewModel: ObservableObject { - let headerText = "Your Order" let menuListItems: [MenuItem] let emptyMenuFallbackText = "Add dishes to the order to see them here" @@ -59,10 +58,10 @@ class OrderDetailViewModel: ObservableObject { message: "The payment was successful. Your food will be with you shortly.", buttonText: "Ok", buttonAction: { [weak self] in - guard let self = self else { return } + guard let self else { return } - self.orderController.resetOrder() - self.onAlertDismiss() + orderController.resetOrder() + onAlertDismiss() } ) } diff --git a/19-appendix-c-uikit/Albertos/SceneDelegate.swift b/19-appendix-c-uikit/Albertos/SceneDelegate.swift index ef8b7ab..c107383 100644 --- a/19-appendix-c-uikit/Albertos/SceneDelegate.swift +++ b/19-appendix-c-uikit/Albertos/SceneDelegate.swift @@ -3,7 +3,6 @@ import HippoPayments import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { - var window: UIWindow? let orderController = OrderController() @@ -18,7 +17,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { paymentProcessing: paymentProcessing ) - func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + func scene(_ scene: UIScene, willConnectTo _: UISceneSession, options _: UIScene.ConnectionOptions) { guard NSClassFromString("XCTestCase") == nil else { return } guard let windowScene = scene as? UIWindowScene else { return } diff --git a/19-appendix-c-uikit/Albertos/UIButton+BigButtonStyle.swift b/19-appendix-c-uikit/Albertos/UIButton+BigButtonStyle.swift index 7329ffc..57f5e02 100644 --- a/19-appendix-c-uikit/Albertos/UIButton+BigButtonStyle.swift +++ b/19-appendix-c-uikit/Albertos/UIButton+BigButtonStyle.swift @@ -1,7 +1,6 @@ import UIKit extension UIButton { - func applyBigButtonStyle() { backgroundColor = .crimson @@ -17,7 +16,6 @@ extension UIButton { } class BigButton: UIButton { - private let padding: CGFloat override init(frame: CGRect) { @@ -37,7 +35,8 @@ class BigButton: UIButton { layer.cornerRadius = 10 } - required init?(coder: NSCoder) { + @available(*, unavailable) + required init?(coder _: NSCoder) { fatalError("This view has no `.xib` backing it. Use `init` instead.") } diff --git a/19-appendix-c-uikit/Albertos/UIColor+Custom.swift b/19-appendix-c-uikit/Albertos/UIColor+Custom.swift index 081acea..48f1d56 100644 --- a/19-appendix-c-uikit/Albertos/UIColor+Custom.swift +++ b/19-appendix-c-uikit/Albertos/UIColor+Custom.swift @@ -4,7 +4,6 @@ import UIKit // // See https://developer.mozilla.org/en-US/docs/Web/CSS/color_value extension UIColor { - static var crimson: UIColor { UIColor(red: 220 / 255.0, green: 20 / 255.0, blue: 20 / 255.0, alpha: 1.0) } diff --git a/19-appendix-c-uikit/Albertos/UIFont+Utils.swift b/19-appendix-c-uikit/Albertos/UIFont+Utils.swift index 76473cc..6b9ac5c 100644 --- a/19-appendix-c-uikit/Albertos/UIFont+Utils.swift +++ b/19-appendix-c-uikit/Albertos/UIFont+Utils.swift @@ -1,7 +1,6 @@ import UIKit extension UIFont { - func adding(_ trait: UIFontDescriptor.SymbolicTraits) -> UIFont { guard let fontDescriptor = fontDescriptor.withSymbolicTraits(trait) else { return self diff --git a/19-appendix-c-uikit/Albertos/UITableViewFooterLabel.swift b/19-appendix-c-uikit/Albertos/UITableViewFooterLabel.swift index 7789abe..6cc6d00 100644 --- a/19-appendix-c-uikit/Albertos/UITableViewFooterLabel.swift +++ b/19-appendix-c-uikit/Albertos/UITableViewFooterLabel.swift @@ -1,7 +1,6 @@ import UIKit class UITableViewFooterLabel: UIView { - var text: String? { get { label.text } set { label.text = newValue } @@ -28,7 +27,8 @@ class UITableViewFooterLabel: UIView { label.fill(self) } - required init?(coder aDecoder: NSCoder) { + @available(*, unavailable) + required init?(coder _: NSCoder) { fatalError("This view has no `.xib` backing it. Use `init` instead.") } } diff --git a/19-appendix-c-uikit/Albertos/UIView+AutoLayout.swift b/19-appendix-c-uikit/Albertos/UIView+AutoLayout.swift index ba71a77..fb0acd2 100644 --- a/19-appendix-c-uikit/Albertos/UIView+AutoLayout.swift +++ b/19-appendix-c-uikit/Albertos/UIView+AutoLayout.swift @@ -1,7 +1,6 @@ import UIKit extension UIView { - func set( _ attribute: NSLayoutConstraint.Attribute, relatedBy relation: NSLayoutConstraint.Relation = .equal, @@ -15,7 +14,7 @@ extension UIView { relatedBy relation: NSLayoutConstraint.Relation = .equal, to constant: CGFloat ) { - self.translatesAutoresizingMaskIntoConstraints = false + translatesAutoresizingMaskIntoConstraints = false let matchesConstraint: (NSLayoutConstraint) -> Bool = { $0.relation == relation @@ -48,13 +47,13 @@ extension UIView { ) { pin([attribute], to: view, padding: padding) } - + func pin( _ attributes: [NSLayoutConstraint.Attribute], to view: UIView, padding: Double = 0 ) { - self.translatesAutoresizingMaskIntoConstraints = false + translatesAutoresizingMaskIntoConstraints = false view.addConstraints( attributes.map { @@ -85,7 +84,7 @@ extension UIView { anchorToAlightWith.constraint( equalToSystemSpacingBelow: anchor, multiplier: 0 - ) + ), ] ) } diff --git a/19-appendix-c-uikit/Albertos/UIViewControllerPresenting.swift b/19-appendix-c-uikit/Albertos/UIViewControllerPresenting.swift index 4be88f0..2ae277c 100644 --- a/19-appendix-c-uikit/Albertos/UIViewControllerPresenting.swift +++ b/19-appendix-c-uikit/Albertos/UIViewControllerPresenting.swift @@ -5,7 +5,6 @@ import UIKit /// /// Tests can implement a double for this and bypass stateful window management. protocol UIViewControllerModalPresenting { - func present(_ viewController: UIViewController, animated: Bool, completion: (() -> Void)?) func dismiss(animated: Bool, completion: (() -> Void)?) diff --git a/19-appendix-c-uikit/AlbertosTests/AppCoordinatorTests.swift b/19-appendix-c-uikit/AlbertosTests/AppCoordinatorTests.swift index 1845148..be775d5 100644 --- a/19-appendix-c-uikit/AlbertosTests/AppCoordinatorTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/AppCoordinatorTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class AppCoordinatorTests: XCTestCase { - func testInitialViewControllerIsNavigationWithMenuList() throws { let navigationController = UINavigationController() let coordinator = makeAppCoordinator(with: navigationController) @@ -89,7 +88,7 @@ class AppCoordinatorTests: XCTestCase { } private func makeAppCoordinator(with navigationController: UINavigationController) -> AppCoordinator { - return AppCoordinator( + AppCoordinator( orderController: OrderController(orderStoring: OrderStoringFake()), paymentProcessing: PaymentProcessingDummy(), navigationController: navigationController diff --git a/19-appendix-c-uikit/AlbertosTests/MenuFetcherTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuFetcherTests.swift index f5bdc7f..e8c4c0a 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuFetcherTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuFetcherTests.swift @@ -3,16 +3,15 @@ import Combine import XCTest class MenuFetcherTests: XCTestCase { - var cancellables = Set() func testWhenRequestSucceedsPublishesDecodedMenuItems() throws { let json = """ -[ - { "name": "a name", "category": "a category", "spicy": true, "price": 1.0 }, - { "name": "another name", "category": "a category", "spicy": true, "price": 2.0 } -] -""" + [ + { "name": "a name", "category": "a category", "spicy": true, "price": 1.0 }, + { "name": "another name", "category": "a category", "spicy": true, "price": 2.0 } + ] + """ let data = try XCTUnwrap(json.data(using: .utf8)) let menuFetcher = MenuFetcher(networkFetching: NetworkFetchingStub(returning: .success(data))) @@ -42,7 +41,7 @@ class MenuFetcherTests: XCTestCase { menuFetcher.fetchMenu() .sink( receiveCompletion: { completion in - guard case .failure(let error) = completion else { return } + guard case let .failure(error) = completion else { return } XCTAssertEqual(error as? URLError, expectedError) expectation.fulfill() }, diff --git a/19-appendix-c-uikit/AlbertosTests/MenuGroupingTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuGroupingTests.swift index 2d05e90..1499aab 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuGroupingTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuGroupingTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuGroupingTests: XCTestCase { - func testMenuWithManyCategoriesReturnsAsManySectionsInReverseAlphabeticalOrder() { let menu: [MenuItem] = [ .fixture(category: "pastas"), @@ -22,7 +21,7 @@ class MenuGroupingTests: XCTestCase { func testMenuWithOneCategoryReturnsOneSection() throws { let menu: [MenuItem] = [ .fixture(category: "pastas", name: "name"), - .fixture(category: "pastas", name: "other name") + .fixture(category: "pastas", name: "other name"), ] let sections = groupMenuByCategory(menu) diff --git a/19-appendix-c-uikit/AlbertosTests/MenuItemAlternateJSONTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuItemAlternateJSONTests.swift index 4ddbd04..965a6f0 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuItemAlternateJSONTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuItemAlternateJSONTests.swift @@ -4,7 +4,7 @@ // // If you want to verify the failure, uncomment the import of the production module and comment the // definition of MenuItem in this file -//@testable import Albertos +// @testable import Albertos import XCTest private struct MenuItem: Decodable { @@ -26,24 +26,23 @@ private struct MenuItem: Decodable { } class MenuItemAlternateJSONTests: XCTestCase { - func testWhenDecodedFromJSONDataHasAllTheInputProperties() throws { let json = """ -{ - "name": "a name", - "category": { - "name": "a category", - "id": 123 - }, - "spicy": false, - "price": 1.0 -} -""" + { + "name": "a name", + "category": { + "name": "a category", + "id": 123 + }, + "spicy": false, + "price": 1.0 + } + """ let data = try XCTUnwrap(json.data(using: .utf8)) let item: MenuItem do { - item = try JSONDecoder().decode(MenuItem.self, from: data) + item = try JSONDecoder().decode(MenuItem.self, from: data) } catch { XCTFail("\(error)") return diff --git a/19-appendix-c-uikit/AlbertosTests/MenuItemDetail.ViewModelTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuItemDetail.ViewModelTests.swift index 91d436e..4bbe5d5 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuItemDetail.ViewModelTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuItemDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemDetailViewModelTests: XCTestCase { - func testWhenItemIsInOrderButtonSaysRemove() { let item = MenuItem.fixture() let orderController = OrderController(orderStoring: OrderStoringFake()) diff --git a/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewControllerTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewControllerTests.swift index c301ab1..fe557fa 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewControllerTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewControllerTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemDetailViewControllerTests: XCTestCase { - func testConfiguresViewWithViewModel() { let viewModel = MenuItemDetailViewModel( item: MenuItem.fixture(), diff --git a/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewTests.swift index 4a4f6c8..c906dd3 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuItemDetailViewTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemDetailViewTests: XCTestCase { - func testWhenViewModelHasSpicyNilDoesNotAddSpicyLabel() { let viewModel = MenuItemDetailViewModel( item: .fixture(spicy: false), diff --git a/19-appendix-c-uikit/AlbertosTests/MenuItemTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuItemTests.swift index 3ecd15b..0ff79b2 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuItemTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuItemTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuItemTests: XCTestCase { - // MARK: Inline example with Triangulation func testWhenDecodedFromJSONDataHasAllTheInputPropertiesExample1() throws { @@ -57,6 +56,7 @@ class MenuItemTests: XCTestCase { } // MARK: Simpler check example + // Use this option if your models match the shape of the input JSON. func testWhenDecodingFromJSONDataDoesNotThrow() throws { diff --git a/19-appendix-c-uikit/AlbertosTests/MenuList.ViewModelTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuList.ViewModelTests.swift index 5cb671b..25fae45 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuList.ViewModelTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuList.ViewModelTests.swift @@ -3,7 +3,6 @@ import Combine import XCTest class MenuListViewModelTests: XCTestCase { - var cancellables = Set() func testWhenFetchingStartsPublishesEmptyMenu() throws { @@ -31,7 +30,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .success(let sections) = value else { + guard case let .success(sections) = value else { return XCTFail("Expected a successful Result, got: \(value)") } @@ -60,7 +59,7 @@ class MenuListViewModelTests: XCTestCase { .$sections .dropFirst() .sink { value in - guard case .failure(let error) = value else { + guard case let .failure(error) = value else { return XCTFail("Expected a failing Result, got: \(value)") } diff --git a/19-appendix-c-uikit/AlbertosTests/MenuListTableViewDataSourceTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuListTableViewDataSourceTests.swift index ad3258b..11033ce 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuListTableViewDataSourceTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuListTableViewDataSourceTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuListTableViewDataSourceTests: XCTestCase { - func testWhenViewModelSectionsIsErrorSectionNumberIsOne() { let dataSource = MenuListTableViewDataSource() let tableView = UITableView(frame: UIScreen.main.bounds) @@ -23,7 +22,7 @@ class MenuListTableViewDataSourceTests: XCTestCase { with: .success( [ .fixture(category: "a category"), - .fixture(category: "another category") + .fixture(category: "another category"), ] ) ) diff --git a/19-appendix-c-uikit/AlbertosTests/MenuListViewControllerTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuListViewControllerTests.swift index 523e396..c10c644 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuListViewControllerTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuListViewControllerTests.swift @@ -3,7 +3,6 @@ import Nimble import XCTest class MenuListViewControllerTests: XCTestCase { - func testWhenNewDataArrivesUpdatesTableView() { let vc = MenuListViewController( menuFetching: MenuFetchingStub(returning: .success([.fixture(name: "a name")])) diff --git a/19-appendix-c-uikit/AlbertosTests/MenuRow.ViewModelTests.swift b/19-appendix-c-uikit/AlbertosTests/MenuRow.ViewModelTests.swift index dc6a750..35b2b21 100644 --- a/19-appendix-c-uikit/AlbertosTests/MenuRow.ViewModelTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MenuRow.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuRowViewModelTests: XCTestCase { - func testWhenItemIsNotSpicyTextIsItemNameOnly() { let item = MenuItem.fixture(name: "name", spicy: false) let viewModel = MenuRowViewModel(item: item) diff --git a/19-appendix-c-uikit/AlbertosTests/MeunListTableViewDelegateTests.swift b/19-appendix-c-uikit/AlbertosTests/MeunListTableViewDelegateTests.swift index 035cb99..5d007dd 100644 --- a/19-appendix-c-uikit/AlbertosTests/MeunListTableViewDelegateTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/MeunListTableViewDelegateTests.swift @@ -2,7 +2,6 @@ import XCTest class MenuListTableViewDelegateTests: XCTestCase { - func testWhenSectionsIsFailureDoesNotCallSelectionCallback() { var called = false let delegate = MenuListTableViewDelegate(onRowSelected: { _ in called = true }) diff --git a/19-appendix-c-uikit/AlbertosTests/OrderButtonViewModelTests.swift b/19-appendix-c-uikit/AlbertosTests/OrderButtonViewModelTests.swift index 74ff071..65d3eeb 100644 --- a/19-appendix-c-uikit/AlbertosTests/OrderButtonViewModelTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/OrderButtonViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderButtonViewModelTests: XCTestCase { - func testWhenOrderIsEmptyDoesNotShowTotal() { let orderController = OrderController(orderStoring: OrderStoringFake()) let viewModel = OrderButtonViewModel(orderController: orderController) @@ -19,4 +18,3 @@ class OrderButtonViewModelTests: XCTestCase { XCTAssertEqual(viewModel.text, "Your Order $3.30") } } - diff --git a/19-appendix-c-uikit/AlbertosTests/OrderControllerTests.swift b/19-appendix-c-uikit/AlbertosTests/OrderControllerTests.swift index 5bbc600..c2527dc 100644 --- a/19-appendix-c-uikit/AlbertosTests/OrderControllerTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/OrderControllerTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderControllerTests: XCTestCase { - func testInitsWithEmptyOrder() { let controller = OrderController(orderStoring: OrderStoringFake()) diff --git a/19-appendix-c-uikit/AlbertosTests/OrderDetail.ViewModelTests.swift b/19-appendix-c-uikit/AlbertosTests/OrderDetail.ViewModelTests.swift index 39e0332..9d0e889 100644 --- a/19-appendix-c-uikit/AlbertosTests/OrderDetail.ViewModelTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/OrderDetail.ViewModelTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderDetailViewModelTests: XCTestCase { - let alertDismissDummy: () -> Void = {} func testWhenCheckoutButtonPressedStartsPaymentProcessingFlow() { diff --git a/19-appendix-c-uikit/AlbertosTests/OrderTests.swift b/19-appendix-c-uikit/AlbertosTests/OrderTests.swift index d9bde21..e64802d 100644 --- a/19-appendix-c-uikit/AlbertosTests/OrderTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/OrderTests.swift @@ -2,7 +2,6 @@ import XCTest class OrderTests: XCTestCase { - func testTotalSumsPricesOfEachItem() { let order = Order( items: [.fixture(price: 1.0), .fixture(price: 2.0), .fixture(price: 3.5)] diff --git a/19-appendix-c-uikit/AlbertosTests/SceneDelegateTests.swift b/19-appendix-c-uikit/AlbertosTests/SceneDelegateTests.swift index 7af51d7..d2df0b0 100644 --- a/19-appendix-c-uikit/AlbertosTests/SceneDelegateTests.swift +++ b/19-appendix-c-uikit/AlbertosTests/SceneDelegateTests.swift @@ -1,8 +1,8 @@ -//@testable import Albertos -//import Nimble -//import XCTest +// @testable import Albertos +// import Nimble +// import XCTest // -//class SceneDelegateTests: XCTestCase { +// class SceneDelegateTests: XCTestCase { // // // TODO: Need better name // func testShowsMenuDetailViewControllerOnNavigationStack() { @@ -87,4 +87,4 @@ // // expect(sceneDelegate.navigationController.presentedViewController).toEventually(beNil()) // } -//} +// } diff --git a/Packages/CollectionSafe/Package.swift b/Packages/CollectionSafe/Package.swift index e208cf2..49a202f 100644 --- a/Packages/CollectionSafe/Package.swift +++ b/Packages/CollectionSafe/Package.swift @@ -8,7 +8,8 @@ let package = Package( products: [ .library( name: "CollectionSafe", - targets: ["CollectionSafe"]), + targets: ["CollectionSafe"] + ), ], targets: [ .target( diff --git a/Packages/CollectionSafe/Sources/Collection+Safe.swift b/Packages/CollectionSafe/Sources/Collection+Safe.swift index 0d7daad..5660e2e 100644 --- a/Packages/CollectionSafe/Sources/Collection+Safe.swift +++ b/Packages/CollectionSafe/Sources/Collection+Safe.swift @@ -1,7 +1,6 @@ extension Collection { - /// Returns the element at the specified index if it is within range, otherwise nil. subscript(safe index: Index) -> Element? { - return indices.contains(index) ? self[index] : nil + indices.contains(index) ? self[index] : nil } } diff --git a/Packages/HippoAnalytics/Package.swift b/Packages/HippoAnalytics/Package.swift index a8dcf6f..7073ca2 100644 --- a/Packages/HippoAnalytics/Package.swift +++ b/Packages/HippoAnalytics/Package.swift @@ -8,13 +8,15 @@ let package = Package( products: [ .library( name: "HippoAnalytics", - targets: ["HippoAnalytics"]), + targets: ["HippoAnalytics"] + ), ], targets: [ .target( name: "HippoAnalytics"), .testTarget( name: "HippoAnalyticsTests", - dependencies: ["HippoAnalytics"]), + dependencies: ["HippoAnalytics"] + ), ] ) diff --git a/Packages/HippoAnalytics/Sources/HippoAnalytics/HippoAnalyticsClient.swift b/Packages/HippoAnalytics/Sources/HippoAnalytics/HippoAnalyticsClient.swift index 7fa0672..caf7a6c 100644 --- a/Packages/HippoAnalytics/Sources/HippoAnalytics/HippoAnalyticsClient.swift +++ b/Packages/HippoAnalytics/Sources/HippoAnalytics/HippoAnalyticsClient.swift @@ -1,9 +1,8 @@ public class HippoAnalyticsClient { - - public init(apiKey: String) {} + public init(apiKey _: String) {} public func logEvent(named name: String, properties: [String: Any]? = .none) { - if let properties = properties { + if let properties { print("🦛 HippoAnalytics: Logged event named '\(name)' with properties '\(properties)'") } else { print("🦛 HippoAnalytics: Logged event named '\(name)'") diff --git a/Packages/HippoAnalytics/Tests/HippoAnalyticsTests/HippoAnalyticsTests.swift b/Packages/HippoAnalytics/Tests/HippoAnalyticsTests/HippoAnalyticsTests.swift index 52399c3..0d4ccc6 100644 --- a/Packages/HippoAnalytics/Tests/HippoAnalyticsTests/HippoAnalyticsTests.swift +++ b/Packages/HippoAnalytics/Tests/HippoAnalyticsTests/HippoAnalyticsTests.swift @@ -1,5 +1,5 @@ -import XCTest @testable import HippoAnalytics +import XCTest final class HippoAnalyticsTests: XCTestCase { func testExample() throws { diff --git a/Packages/HippoPayments/Package.swift b/Packages/HippoPayments/Package.swift index 7899d29..d61c6c8 100644 --- a/Packages/HippoPayments/Package.swift +++ b/Packages/HippoPayments/Package.swift @@ -8,13 +8,15 @@ let package = Package( products: [ .library( name: "HippoPayments", - targets: ["HippoPayments"]), + targets: ["HippoPayments"] + ), ], targets: [ .target( name: "HippoPayments"), .testTarget( name: "HippoPaymentsTests", - dependencies: ["HippoPayments"]), + dependencies: ["HippoPayments"] + ), ] ) diff --git a/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsConfirmationViewController.swift b/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsConfirmationViewController.swift index 7d557ad..20847b8 100644 --- a/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsConfirmationViewController.swift +++ b/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsConfirmationViewController.swift @@ -1,9 +1,8 @@ #if canImport(UIKit) -import UIKit + import UIKit #endif class HippoPaymentsConfirmationViewController: UIViewController { - let dismissButton = UIButton() let textLabel = UILabel() let container = UIStackView() diff --git a/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsProcessor.swift b/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsProcessor.swift index 20f6b15..a708635 100644 --- a/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsProcessor.swift +++ b/Packages/HippoPayments/Sources/HippoPayments/HippoPaymentsProcessor.swift @@ -1,9 +1,8 @@ #if canImport(UIKit) -import UIKit + import UIKit #endif public class HippoPaymentsProcessor { - private let apiKey: String public init(apiKey: String) { @@ -11,9 +10,9 @@ public class HippoPaymentsProcessor { } public func processPayment( - payload: [String: Any], + payload _: [String: Any], onSuccess: @escaping () -> Void, - onFailure: @escaping (HippoPaymentsError) -> Void + onFailure _: @escaping (HippoPaymentsError) -> Void ) { let vc = HippoPaymentsConfirmationViewController() vc.onDismiss = onSuccess diff --git a/Packages/HippoPayments/Sources/HippoPayments/UIViewController+Presentation.swift b/Packages/HippoPayments/Sources/HippoPayments/UIViewController+Presentation.swift index e05b868..ac44452 100644 --- a/Packages/HippoPayments/Sources/HippoPayments/UIViewController+Presentation.swift +++ b/Packages/HippoPayments/Sources/HippoPayments/UIViewController+Presentation.swift @@ -1,12 +1,11 @@ #if canImport(UIKit) -import UIKit + import UIKit #endif extension UIViewController { - /// Travels the `presentedViewController` hierarchy backwards till it finds the topmost one. var viewControllerPresentationSource: UIViewController { - guard let presentedViewController = self.presentedViewController else { return self } + guard let presentedViewController else { return self } return presentedViewController.viewControllerPresentationSource } diff --git a/Packages/HippoPayments/Tests/HippoPaymentsTests/HippoPaymentsTests.swift b/Packages/HippoPayments/Tests/HippoPaymentsTests/HippoPaymentsTests.swift index 3e83e91..972ce1e 100644 --- a/Packages/HippoPayments/Tests/HippoPaymentsTests/HippoPaymentsTests.swift +++ b/Packages/HippoPayments/Tests/HippoPaymentsTests/HippoPaymentsTests.swift @@ -1,5 +1,5 @@ -import XCTest @testable import HippoPayments +import XCTest final class HippoPaymentsTests: XCTestCase { func testExample() throws { From 0662764e5aee5e975c525f048665cb9fb8046489 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sat, 28 Sep 2024 09:22:16 +1000 Subject: [PATCH 4/7] Update `.git-blame-ignore-revs` --- .git-blame-ignore-revs | 1 + 1 file changed, 1 insertion(+) diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 1a49603..9ddaf4a 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -6,3 +6,4 @@ # # GitHub supports this out of the box. # See https://github.com/orgs/community/discussions/5033 +7a7c96e1cd9889ff3221c09528a6e857feea4a61 From 5da9a358b9c67516659544dad1917d3c1c57b8f1 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sat, 28 Sep 2024 09:27:12 +1000 Subject: [PATCH 5/7] Track `.swiftformat` with note to use default ruleset --- .swiftformat | 1 + 1 file changed, 1 insertion(+) create mode 100644 .swiftformat diff --git a/.swiftformat b/.swiftformat new file mode 100644 index 0000000..3582539 --- /dev/null +++ b/.swiftformat @@ -0,0 +1 @@ +# Use the default SwiftFormat ruleset so we don't have to think about it ;) From 4773af87f45ac4ea85e6b4bf234d50168c8e031f Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sat, 28 Sep 2024 09:48:16 +1000 Subject: [PATCH 6/7] Add `.editorconfig` with indentation settings --- .editorconfig | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..800fc4c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +# Make indentation settings explicit, to override possible system-wide settings + +[*.swift] +indent_style = space +indent_size = 4 From f25d82aacf8dc90ef6d29e02ae0fed29fdf0ba82 Mon Sep 17 00:00:00 2001 From: Gio Lodi Date: Sun, 29 Sep 2024 21:07:44 +1000 Subject: [PATCH 7/7] =?UTF-8?q?WIP=20-=20Set=20up=20SwiftFormat=20via=20lo?= =?UTF-8?q?cal=20package=20and=20build=20phase=20=E2=80=94=20Fails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 04-tdd-in-the-real-world/1-end/project.yml | 6 ++++++ BuildTools/Empty.swift | 2 ++ BuildTools/Package.resolved | 15 +++++++++++++++ BuildTools/Package.swift | 11 +++++++++++ 4 files changed, 34 insertions(+) create mode 100644 BuildTools/Empty.swift create mode 100644 BuildTools/Package.resolved create mode 100644 BuildTools/Package.swift diff --git a/04-tdd-in-the-real-world/1-end/project.yml b/04-tdd-in-the-real-world/1-end/project.yml index aebccbe..9fb732e 100644 --- a/04-tdd-in-the-real-world/1-end/project.yml +++ b/04-tdd-in-the-real-world/1-end/project.yml @@ -12,6 +12,12 @@ targets: UIRequiredDeviceCapabilities: [armv7] scheme: testTargets: [AlbertosTests] + settings: + ENABLE_USER_SCRIPT_SANDBOXING: NO + preBuildScripts: + - name: Format + script: swift run -c release --package-path ../../BuildTools swiftformat "$SRCROOT" + basedOnDependencyAnalysis: false AlbertosTests: target: Albertos type: bundle.unit-test diff --git a/BuildTools/Empty.swift b/BuildTools/Empty.swift new file mode 100644 index 0000000..b2aca6b --- /dev/null +++ b/BuildTools/Empty.swift @@ -0,0 +1,2 @@ +// Required to satisfy SwiftPM requirements as of Xcode 11.4 +// See https://github.com/nicklockwood/SwiftFormat#using-swift-package-manage diff --git a/BuildTools/Package.resolved b/BuildTools/Package.resolved new file mode 100644 index 0000000..7b7b675 --- /dev/null +++ b/BuildTools/Package.resolved @@ -0,0 +1,15 @@ +{ + "originHash" : "d07c3e2d919fdf70233890c1d8484e8bd766f9b04984fbecf723a5ca744d4dd5", + "pins" : [ + { + "identity" : "swiftformat", + "kind" : "remoteSourceControl", + "location" : "https://github.com/nicklockwood/SwiftFormat", + "state" : { + "revision" : "ab6844edb79a7b88dc6320e6cee0a0db7674dac3", + "version" : "0.54.5" + } + } + ], + "version" : 3 +} diff --git a/BuildTools/Package.swift b/BuildTools/Package.swift new file mode 100644 index 0000000..96e63a3 --- /dev/null +++ b/BuildTools/Package.swift @@ -0,0 +1,11 @@ +// swift-tools-version:6.0 +import PackageDescription + +let package = Package( + name: "BuildTools", + platforms: [.macOS(.v10_13)], + dependencies: [ + .package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.54.5"), + ], + targets: [.target(name: "BuildTools", path: "")] +)