From 023496233fa189b2fe98f3b3ed25f51f632bba30 Mon Sep 17 00:00:00 2001 From: Christian Elies Date: Sat, 22 Feb 2020 17:54:50 +0100 Subject: [PATCH] refactor(advanced list): replaced switch and any views with group + if ; test(advanced list): refactored and improved tests using the view inspector swift package --- Package.resolved | 9 +++ Package.swift | 5 +- .../Models/AnyDynamicViewContent.swift | 16 ++-- .../public/Models/ListState.swift | 9 +++ .../public/Views/AdvancedList.swift | 21 ++--- .../AdvancedListTests/AdvancedListTests.swift | 80 +++++++++++++------ .../Extensions/AdvancedList+Inspectable.swift | 11 +++ .../AnyDynamicViewContent+Inspectable.swift | 11 +++ 8 files changed, 117 insertions(+), 45 deletions(-) create mode 100644 Tests/AdvancedListTests/Extensions/AdvancedList+Inspectable.swift create mode 100644 Tests/AdvancedListTests/Extensions/AnyDynamicViewContent+Inspectable.swift diff --git a/Package.resolved b/Package.resolved index 1ff9c54..bde54e8 100644 --- a/Package.resolved +++ b/Package.resolved @@ -9,6 +9,15 @@ "revision": "af667b368a10512da79605b61698d53c11d24cbf", "version": "0.1.1" } + }, + { + "package": "ViewInspector", + "repositoryURL": "https://github.com/nalexn/ViewInspector.git", + "state": { + "branch": null, + "revision": "ec943ed718cd293b95f17a2b81e8917d6ed70752", + "version": "0.3.8" + } } ] }, diff --git a/Package.swift b/Package.swift index 0b2a0fc..dfb9074 100644 --- a/Package.swift +++ b/Package.swift @@ -16,7 +16,8 @@ let package = Package( targets: ["AdvancedList"]), ], dependencies: [ - .package(url: "https://github.com/crelies/ListPagination", from: "0.1.0") + .package(url: "https://github.com/crelies/ListPagination", from: "0.1.0"), + .package(url: "https://github.com/nalexn/ViewInspector.git", from: "0.3.8") ], targets: [ .target( @@ -24,6 +25,6 @@ let package = Package( dependencies: ["ListPagination"]), .testTarget( name: "AdvancedListTests", - dependencies: ["AdvancedList"]), + dependencies: ["AdvancedList", "ViewInspector"]), ] ) diff --git a/Sources/AdvancedList/private/Models/AnyDynamicViewContent.swift b/Sources/AdvancedList/private/Models/AnyDynamicViewContent.swift index be61623..6f3285f 100644 --- a/Sources/AdvancedList/private/Models/AnyDynamicViewContent.swift +++ b/Sources/AdvancedList/private/Models/AnyDynamicViewContent.swift @@ -7,16 +7,14 @@ import SwiftUI -extension AdvancedList { - struct AnyDynamicViewContent: DynamicViewContent { - private let view: AnyView +struct AnyDynamicViewContent: DynamicViewContent { + private let view: AnyView - private(set) var data: AnyCollection - var body: some View { view } + private(set) var data: AnyCollection + var body: some View { view } - init(_ view: View) { - self.view = AnyView(view) - self.data = AnyCollection(view.data.map { $0 as Any }) - } + init(_ view: View) { + self.view = AnyView(view) + self.data = AnyCollection(view.data.map { $0 as Any }) } } diff --git a/Sources/AdvancedList/public/Models/ListState.swift b/Sources/AdvancedList/public/Models/ListState.swift index 41fe6b5..9f0a49f 100644 --- a/Sources/AdvancedList/public/Models/ListState.swift +++ b/Sources/AdvancedList/public/Models/ListState.swift @@ -14,6 +14,15 @@ public enum ListState { case loading } +extension ListState { + var error: Error? { + guard case let ListState.error(error) = self else { + return nil + } + return error + } +} + extension ListState: Equatable { public static func ==(lhs: ListState, rhs: ListState) -> Bool { switch (lhs, rhs) { diff --git a/Sources/AdvancedList/public/Views/AdvancedList.swift b/Sources/AdvancedList/public/Views/AdvancedList.swift index 96a124c..98e4130 100644 --- a/Sources/AdvancedList/public/Views/AdvancedList.swift +++ b/Sources/AdvancedList/public/Views/AdvancedList.swift @@ -40,12 +40,9 @@ public struct AdvancedList = .constant(.items) + let items: [String] = [] let view = AdvancedList(items, content: { item in Text(item) }, - listState: $listState, + listState: emptyListState, emptyStateView: { self.emptyStateView }, errorStateView: { _ in self.errorStateView }, loadingStateView: { self.loadingStateView }, pagination: .noPagination) - let body = view.body as? AnyView - XCTAssertNotNil(body) + do { + let inspectableView = try view.body.inspect() + let textString = try inspectableView.group().first?.text().string() + XCTAssertEqual(textString, emptyStateString) + } catch { + XCTFail("\(error)") + } } func testNotEmptyStateView() { - let items: [String] = ["MockItem1", "MockItem2"] + let itemsListState: Binding = .constant(.items) + + let mockItem1 = "MockItem1" + let mockItem2 = "MockItem2" + let items: [String] = [mockItem1, mockItem2] let view = AdvancedList(items, content: { item in Text(item) }, - listState: $listState, + listState: itemsListState, emptyStateView: { self.emptyStateView }, errorStateView: { _ in self.errorStateView }, loadingStateView: { self.loadingStateView }, pagination: .noPagination) - let body = view.body as? AnyView - XCTAssertNotNil(body) + do { + let inspectableView = try view.body.inspect() + let group = try inspectableView.group().first + let vStack = try group?.vStack() + let list = try vStack?.list(0) + let anyDynamicViewContent = try list?.first?.view(AnyDynamicViewContent.self) + let forEach = try anyDynamicViewContent?.anyView().forEach() + + let firstElement = forEach?.first + XCTAssertEqual(try firstElement?.text().string(), mockItem1) + + let secondElement = forEach?[1] + XCTAssertEqual(try secondElement?.text().string(), mockItem2) + } catch { + XCTFail("\(error)") + } } func testLoadingStateView() { - listState = .loading + let loadingListState: Binding = .constant(.loading) let items: [String] = [] let view = AdvancedList(items, content: { item in Text(item) }, - listState: $listState, + listState: loadingListState, emptyStateView: { self.emptyStateView }, errorStateView: { _ in self.errorStateView }, loadingStateView: { self.loadingStateView }, pagination: .noPagination) - let body = view.body as? AnyView - XCTAssertNotNil(body) + do { + let inspectableView = try view.body.inspect() + let textString = try inspectableView.group().first?.text().string() + XCTAssertEqual(textString, loadingStateString) + } catch { + XCTFail("\(error)") + } } func testErrorStateView() { let error = NSError(domain: "MockDomain", code: 1, userInfo: nil) - listState = .error(error) + let errorListState: Binding = .constant(.error(error)) let items: [String] = [] let view = AdvancedList(items, content: { item in Text(item) }, - listState: $listState, + listState: errorListState, emptyStateView: { self.emptyStateView }, errorStateView: { _ in self.errorStateView }, loadingStateView: { self.loadingStateView }, pagination: .noPagination) - let body = view.body as? AnyView - XCTAssertNotNil(body) + do { + let inspectableView = try view.body.inspect() + let textString = try inspectableView.group().first?.text().string() + XCTAssertEqual(textString, errorStateString) + } catch { + XCTFail("\(error)") + } } static var allTests = [ diff --git a/Tests/AdvancedListTests/Extensions/AdvancedList+Inspectable.swift b/Tests/AdvancedListTests/Extensions/AdvancedList+Inspectable.swift new file mode 100644 index 0000000..61eeddd --- /dev/null +++ b/Tests/AdvancedListTests/Extensions/AdvancedList+Inspectable.swift @@ -0,0 +1,11 @@ +// +// AdvancedList+Inspectable.swift +// AdvancedListTests +// +// Created by Christian Elies on 22.02.20. +// + +@testable import AdvancedList +import ViewInspector + +extension AdvancedList: Inspectable {} diff --git a/Tests/AdvancedListTests/Extensions/AnyDynamicViewContent+Inspectable.swift b/Tests/AdvancedListTests/Extensions/AnyDynamicViewContent+Inspectable.swift new file mode 100644 index 0000000..38e69ac --- /dev/null +++ b/Tests/AdvancedListTests/Extensions/AnyDynamicViewContent+Inspectable.swift @@ -0,0 +1,11 @@ +// +// AnyDynamicViewContent+Inspectable.swift +// AdvancedListTests +// +// Created by Christian Elies on 22.02.20. +// + +@testable import AdvancedList +import ViewInspector + +extension AnyDynamicViewContent: Inspectable {}