From 98860aff53fd080a90bea3ef4952908195f1cd51 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Tue, 2 Apr 2024 10:42:05 +0200 Subject: [PATCH 01/16] update flow layout section controller --- SectionKit.xcodeproj/project.pbxproj | 16 ++---- .../BaseFlowLayoutSectionController.swift | 48 ++++++++++++++++++ ...undationDiffingListSectionController.swift | 0 .../ListSectionController.swift | 2 +- .../SingleItemSectionController.swift | 2 +- .../SingleModelSectionController.swift | 2 +- .../Generic/BaseSectionController.swift | 50 ++----------------- .../SectionController/SectionController.swift | 11 ++-- 8 files changed, 63 insertions(+), 68 deletions(-) create mode 100644 SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift rename SectionKit/Sources/SectionController/{Generic => FlowLayout}/FoundationDiffingListSectionController.swift (100%) rename SectionKit/Sources/SectionController/{Generic => FlowLayout}/ListSectionController.swift (97%) rename SectionKit/Sources/SectionController/{Generic => FlowLayout}/SingleItemSectionController.swift (98%) rename SectionKit/Sources/SectionController/{Generic => FlowLayout}/SingleModelSectionController.swift (96%) diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index c4e95594..94ecdde1 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -468,6 +468,7 @@ 5AA9D95126AAA5E000679D88 /* MockCollectionViewCell.swift */, 5A8D3E5327E8D0E200073712 /* MockCollectionViewContext.swift */, 5AA9D95526AAA61700679D88 /* MockErrorHandler.swift */, + D91425802BBBF8670005E8CD /* MockFlowLayoutSectionController.swift */, 5A0B776F26B19EB300B054D4 /* MockListCollectionViewAdapterDataSource.swift */, 5A0B775326AFF4D500B054D4 /* MockScrollViewDelegate.swift */, 5AB6644A26A86F7A004DC230 /* MockSectionController.swift */, @@ -544,8 +545,9 @@ 5AE175A92667DA3E00D4DCE1 /* SectionController */ = { isa = PBXGroup; children = ( + D9CCE9B62BADF2FD00EED204 /* Generic */, + D9CCE9B22BADED3D00EED204 /* FlowLayout */, 5AE175AD2667DA3E00D4DCE1 /* Update */, - 5AE175B42667DA3E00D4DCE1 /* Generic */, 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */, 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */, 5AE175AB2667DA3E00D4DCE1 /* SectionDataSource.swift */, @@ -568,18 +570,6 @@ path = Update; sourceTree = ""; }; - 5AE175B42667DA3E00D4DCE1 /* Generic */ = { - isa = PBXGroup; - children = ( - 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */, - 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */, - 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */, - 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */, - 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */, - ); - path = Generic; - sourceTree = ""; - }; 5AE175BC2667DA3F00D4DCE1 /* CollectionViewAdapter */ = { isa = PBXGroup; children = ( diff --git a/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift new file mode 100644 index 00000000..c9b6ebe4 --- /dev/null +++ b/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift @@ -0,0 +1,48 @@ +import UIKit + +/// This is a foundational implementation of `FlowLayoutSectionController`, implementing the flow layout delegate while inheriting from the `BaseSectionController`. +@MainActor +open class BaseFlowLayoutSectionController: BaseSectionController, + SectionFlowDelegate, + FlowLayoutSectionController { + open var flowDelegate: SectionFlowDelegate? { self } + + // MARK: - SectionFlowDelegate + + open func sizeForItem( + at indexPath: SectionIndexPath, + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGSize { + (layout as? UICollectionViewFlowLayout)?.itemSize ?? CGSize(width: 50, height: 50) + } + + open func inset(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> UIEdgeInsets { + (layout as? UICollectionViewFlowLayout)?.sectionInset ?? .zero + } + + open func minimumLineSpacing(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGFloat { + (layout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 10 + } + + open func minimumInteritemSpacing( + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGFloat { + (layout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 10 + } + + open func referenceSizeForHeader( + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGSize { + (layout as? UICollectionViewFlowLayout)?.headerReferenceSize ?? .zero + } + + open func referenceSizeForFooter( + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGSize { + (layout as? UICollectionViewFlowLayout)?.footerReferenceSize ?? .zero + } +} diff --git a/SectionKit/Sources/SectionController/Generic/FoundationDiffingListSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListSectionController.swift similarity index 100% rename from SectionKit/Sources/SectionController/Generic/FoundationDiffingListSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListSectionController.swift diff --git a/SectionKit/Sources/SectionController/Generic/ListSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/ListSectionController.swift similarity index 97% rename from SectionKit/Sources/SectionController/Generic/ListSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/ListSectionController.swift index cc216a4b..d8d5124c 100644 --- a/SectionKit/Sources/SectionController/Generic/ListSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/ListSectionController.swift @@ -8,7 +8,7 @@ import UIKit of a model to be displayed and the list of items (almost) never changes or should not perform animated updates. */ @MainActor -open class ListSectionController: BaseSectionController { +open class ListSectionController: BaseFlowLayoutSectionController { /** Initialise an instance of `ListSectionController`. diff --git a/SectionKit/Sources/SectionController/Generic/SingleItemSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/SingleItemSectionController.swift similarity index 98% rename from SectionKit/Sources/SectionController/Generic/SingleItemSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/SingleItemSectionController.swift index e003fff9..9f88725d 100644 --- a/SectionKit/Sources/SectionController/Generic/SingleItemSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/SingleItemSectionController.swift @@ -9,7 +9,7 @@ import UIKit - Warning: If `numberOfItems` is overridden, `calculateUpdate(from:to:)` needs to be overridden as well. */ @MainActor -open class SingleItemSectionController: BaseSectionController { +open class SingleItemSectionController: BaseFlowLayoutSectionController { private let areItemsEqual: @MainActor (Item, Item) -> Bool /** diff --git a/SectionKit/Sources/SectionController/Generic/SingleModelSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/SingleModelSectionController.swift similarity index 96% rename from SectionKit/Sources/SectionController/Generic/SingleModelSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/SingleModelSectionController.swift index 143408d1..f2144b49 100644 --- a/SectionKit/Sources/SectionController/Generic/SingleModelSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/SingleModelSectionController.swift @@ -9,7 +9,7 @@ import UIKit it is recommended to use `ListSectionController` instead. */ @MainActor -open class SingleModelSectionController: BaseSectionController { +open class SingleModelSectionController: BaseFlowLayoutSectionController { /** Initialise an instance of `SingleModelSectionController`. diff --git a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift index 7c97544f..bb1b7151 100644 --- a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift @@ -1,16 +1,13 @@ import UIKit -/** - A base implementation of all `SectionController` datasource and delegate protocols. - - Every declaration is marked `open` and can be overridden. - */ +/// This serves as a fundamental `SectionController` implementation, +/// encompassing data source and delegate protocols, with the exception of the flow layout delegate. +/// Each access control is designated as` open`, allowing for easy customization through overrides. @MainActor open class BaseSectionController: SectionController, SectionDataSource, SectionDataSourcePrefetchingDelegate, SectionDelegate, - SectionFlowDelegate, SectionDragDelegate, SectionDropDelegate { // MARK: - Init @@ -28,8 +25,6 @@ open class BaseSectionController: SectionController, open var delegate: SectionDelegate? { self } - open var flowDelegate: SectionFlowDelegate? { self } - @available(iOS 11.0, *) open var dragDelegate: SectionDragDelegate? { self } @@ -263,43 +258,4 @@ open class BaseSectionController: SectionController, ) -> UIDragPreviewParameters? { nil } - - // MARK: - SectionFlowDelegate - - open func sizeForItem( - at indexPath: SectionIndexPath, - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.itemSize ?? CGSize(width: 50, height: 50) - } - - open func inset(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> UIEdgeInsets { - (layout as? UICollectionViewFlowLayout)?.sectionInset ?? .zero - } - - open func minimumLineSpacing(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 10 - } - - open func minimumInteritemSpacing( - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 10 - } - - open func referenceSizeForHeader( - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.headerReferenceSize ?? .zero - } - - open func referenceSizeForFooter( - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.footerReferenceSize ?? .zero - } } diff --git a/SectionKit/Sources/SectionController/SectionController.swift b/SectionKit/Sources/SectionController/SectionController.swift index 6e155d3b..744c0ade 100644 --- a/SectionKit/Sources/SectionController/SectionController.swift +++ b/SectionKit/Sources/SectionController/SectionController.swift @@ -16,9 +16,6 @@ public protocol SectionController: AnyObject { /// The delegate of this section. var delegate: SectionDelegate? { get } - /// The delegate for the `UICollectionViewFlowLayout` of this section. - var flowDelegate: SectionFlowDelegate? { get } - /// The drag delegate of this section. @available(iOS 11.0, *) var dragDelegate: SectionDragDelegate? { get } @@ -37,11 +34,15 @@ extension SectionController { public var delegate: SectionDelegate? { nil } - public var flowDelegate: SectionFlowDelegate? { nil } - @available(iOS 11.0, *) public var dragDelegate: SectionDragDelegate? { nil } @available(iOS 11.0, *) public var dropDelegate: SectionDropDelegate? { nil } } + +@MainActor +public protocol FlowLayoutSectionController: SectionController { + /// The delegate for the `UICollectionViewFlowLayout` of this section. + var flowDelegate: SectionFlowDelegate? { get } +} From 63338a70d0800682ac5a9241456b5f05cd014270 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Tue, 2 Apr 2024 10:43:05 +0200 Subject: [PATCH 02/16] add compositional support for the section controller --- ...CompositionalLayoutSectionController.swift | 14 +++ ...CompositionalLayoutSectionController.swift | 115 ++++++++++++++++++ .../SectionController/SectionController.swift | 12 ++ 3 files changed, 141 insertions(+) create mode 100644 SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift create mode 100644 SectionKit/Sources/SectionController/CompositionalLayout/ListCompositionalLayoutSectionController.swift diff --git a/SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift b/SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift new file mode 100644 index 00000000..7c2b5162 --- /dev/null +++ b/SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift @@ -0,0 +1,14 @@ +import UIKit + +/// This is a foundational implementation of `CompositionalLayoutSectionController`, adding the compositional layout section delegate function while inheriting from the `BaseSectionController`. +@MainActor +@available(iOS 13.0, *) +open class BaseCompositionalLayoutSectionController: BaseSectionController, + CompositionalLayoutSectionController { + open func layoutSection( + layoutEnvironment: any NSCollectionLayoutEnvironment + ) -> NSCollectionLayoutSection { + context?.errorHandler.nonCritical(error: .notImplemented()) + return .empty + } +} diff --git a/SectionKit/Sources/SectionController/CompositionalLayout/ListCompositionalLayoutSectionController.swift b/SectionKit/Sources/SectionController/CompositionalLayout/ListCompositionalLayoutSectionController.swift new file mode 100644 index 00000000..fcaf743a --- /dev/null +++ b/SectionKit/Sources/SectionController/CompositionalLayout/ListCompositionalLayoutSectionController.swift @@ -0,0 +1,115 @@ +import UIKit + +/** + A `SectionController` that contains a list of items. Changes to that list will result in a call to + `reloadSections(_:)` on the underlying `UICollectionView`. + + This `SectionController` is typically used when there are multiple semantically similar items + of a model to be displayed and the list of items (almost) never changes or should not perform animated updates. + */ +@MainActor +@available(iOS 13.0, *) +open class ListCompositionalLayoutSectionController: BaseCompositionalLayoutSectionController { + /** + Initialise an instance of `ListSectionController`. + + - Parameter model: The model of this `SectionController`. + */ + public init(model: Model) { + self.model = model + super.init() + if shouldUpdateItems(afterModelChangedTo: model) { + items = items(for: model) + } + } + + override open func didUpdate(model: Any) { + guard let model = model as? Model else { + context?.errorHandler.nonCritical( + error: .sectionControllerModelTypeMismatch( + expected: Model.self, + actual: type(of: model) + ) + ) + return + } + self.model = model + } + + /// The model of this `SectionController`. + open var model: Model { + didSet { + if shouldUpdateItems(afterModelChangedTo: model) { + items = items(for: model) + } + } + } + + /** + Determines if the list of items should be updated after the model was updated to a new value. + + The default value is `true`. + + - Parameter model: The new value of the model. + + - Returns: If the list of items should be updated after the model was updated to a new value. + */ + open func shouldUpdateItems(afterModelChangedTo model: Model) -> Bool { true } + + /** + Derives a list of items from the given `Model`. + + Will be called automatically if `shouldUpdateItems(afterModelChangedTo:)` returned `true`. + + - Parameter model: The new value of the model. + + - Returns: The new items to be displayed in this section. + */ + open func items(for model: Model) -> [Item] { + context?.errorHandler.nonCritical(error: .notImplemented()) + return [] + } + + /** + The list of items currently displayed in the `UICollectionView`. + + Only set this property if `UICollectionView` insertions and deletions are handled, otherwise use `items` instead. + */ + open var collectionViewItems: [Item] = [] + + /// The items of this section. + open var items: [Item] { + get { collectionViewItems } + set { + guard let context = context else { + collectionViewItems = newValue + return + } + if let sectionUpdate = calculateUpdate(from: collectionViewItems, to: newValue) { + context.apply(update: sectionUpdate) + } + } + } + + /** + Calculate the `UICollectionView` events using the difference from the old to the new data. + + - Parameter oldData: The old data currently displayed in the section. + + - Parameter newData: The new data that should be displayed in the section. + + - Returns: The update that should be performed on the section. + */ + open func calculateUpdate( + from oldData: [Item], + to newData: [Item] + ) -> CollectionViewSectionUpdate<[Item]>? { + CollectionViewSectionUpdate( + controller: self, + data: newData, + setData: { self.collectionViewItems = $0 } + ) + } + + override open func numberOfItems(in context: CollectionViewContext) -> Int { items.count } +} diff --git a/SectionKit/Sources/SectionController/SectionController.swift b/SectionKit/Sources/SectionController/SectionController.swift index 744c0ade..78e14e54 100644 --- a/SectionKit/Sources/SectionController/SectionController.swift +++ b/SectionKit/Sources/SectionController/SectionController.swift @@ -46,3 +46,15 @@ public protocol FlowLayoutSectionController: SectionController { /// The delegate for the `UICollectionViewFlowLayout` of this section. var flowDelegate: SectionFlowDelegate? { get } } + +@MainActor +public protocol CompositionalLayoutSectionController: SectionController { + /// Provide the layout section for the Compositional Layout + /// - Parameters: + /// - layoutEnvironment: the environment value for the layout + /// - Returns: The layout for the section + @available(iOS 13.0, *) + func layoutSection( + layoutEnvironment: NSCollectionLayoutEnvironment + ) -> NSCollectionLayoutSection +} From 05222c195304ac389c1da11a3127b733355801b1 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Tue, 2 Apr 2024 10:43:43 +0200 Subject: [PATCH 03/16] add bridge between layout provider and adapter --- ...istCollectionViewAdapter+Convenience.swift | 4 +- .../ListCollectionViewAdapter.swift | 12 +++++ ...ionCollectionViewAdapter+Convenience.swift | 4 +- .../NSCollectionLayoutSection+Empty.swift | 18 +++++++ .../SectionKitCompositionalLayout.swift | 53 +++++++++++++++++++ 5 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 SectionKit/Sources/Utility/CompositionalLayout/NSCollectionLayoutSection+Empty.swift create mode 100644 SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift diff --git a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift index d98d0429..9b1f82ab 100644 --- a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift @@ -58,12 +58,12 @@ extension ListCollectionViewAdapter { extension ListCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { - controller(at: indexPath)?.flowDelegate + (controller(at: indexPath) as? FlowLayoutSectionController)?.flowDelegate } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { - controller(at: index)?.flowDelegate + (controller(at: index) as? FlowLayoutSectionController)?.flowDelegate } } diff --git a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift index ee54431c..d86535c2 100644 --- a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift +++ b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter.swift @@ -49,6 +49,12 @@ open class ListCollectionViewAdapter: NSObject, CollectionViewAdapter { collectionView.dragDelegate = self collectionView.dropDelegate = self } + if #available(iOS 13.0, *), + let layout = collectionView.collectionViewLayout as? SectionKitCompositionalLayout { + layout.sections = { [weak self] in + self?.collectionViewSections ?? [] + } + } } /** @@ -90,6 +96,12 @@ open class ListCollectionViewAdapter: NSObject, CollectionViewAdapter { collectionView.dragDelegate = self collectionView.dropDelegate = self } + if #available(iOS 13.0, *), + let layout = collectionView.collectionViewLayout as? SectionKitCompositionalLayout { + layout.sections = { [weak self] in + self?.collectionViewSections ?? [] + } + } } public let context: CollectionViewContext diff --git a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift index e27e473f..4fb424e7 100644 --- a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift @@ -58,12 +58,12 @@ extension SingleSectionCollectionViewAdapter { extension SingleSectionCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { - controller(at: indexPath)?.flowDelegate + (controller(at: indexPath) as? FlowLayoutSectionController)?.flowDelegate } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { - controller(at: index)?.flowDelegate + (controller(at: index) as? FlowLayoutSectionController)?.flowDelegate } } diff --git a/SectionKit/Sources/Utility/CompositionalLayout/NSCollectionLayoutSection+Empty.swift b/SectionKit/Sources/Utility/CompositionalLayout/NSCollectionLayoutSection+Empty.swift new file mode 100644 index 00000000..39e68e45 --- /dev/null +++ b/SectionKit/Sources/Utility/CompositionalLayout/NSCollectionLayoutSection+Empty.swift @@ -0,0 +1,18 @@ +import UIKit + +@available(iOS 13.0, *) +extension NSCollectionLayoutSection { + static let empty: NSCollectionLayoutSection = { + let layoutSize = NSCollectionLayoutSize( + widthDimension: .absolute(0), + heightDimension: .absolute(0) + ) + return NSCollectionLayoutSection( + group: .vertical( + layoutSize: layoutSize, + subitem: .init(layoutSize: layoutSize), + count: 1 + ) + ) + }() +} diff --git a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift new file mode 100644 index 00000000..b033cccf --- /dev/null +++ b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift @@ -0,0 +1,53 @@ +import UIKit + +/// This compositional layout is designed for the section kit. +/// It ensures that the layout provider utilizes the layout section provided by the compositional layout section controller. +@MainActor +@available(iOS 13.0, *) +final public class SectionKitCompositionalLayout: UICollectionViewCompositionalLayout { + // Use internally to bridge the sections from the adapter to the section provider. + var sections: (() -> [Section])? + + public init() { + var sections: (() -> [Section])? + super.init { index, environment in + guard let sections = sections?() else { + assertionFailure("The section provider doesn't set up correctly, please use the `CollectionViewCompositionalLayoutAdapter`") + return .empty + } + guard sections.count > index else { + assertionFailure("Section index out of bound") + return .empty + } + guard let compositionalLayoutSectionController = sections[index].controller + as? BaseCompositionalLayoutSectionController else { + assertionFailure("Please use the `CompositionalLayoutSectionControler`") + return .empty + } + return compositionalLayoutSectionController.layoutSection( + layoutEnvironment: environment + ) + } + sections = { [weak self] in + self?.sections?() ?? [] + } + } + + @available(*, unavailable) + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @available(*, unavailable) + override init( + sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider, + configuration: UICollectionViewCompositionalLayoutConfiguration + ) { + fatalError("init(sectionProvider:configuration:) has not been implemented") + } + + @available(*, unavailable) + override init(sectionProvider: @escaping UICollectionViewCompositionalLayoutSectionProvider) { + fatalError("init(sectionProvider:) has not been implemented") + } +} From c5a73379e8992fad6bb70ee3a8a1476ec42bf984 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Tue, 2 Apr 2024 10:44:10 +0200 Subject: [PATCH 04/16] update tests --- SectionKit.xcodeproj/project.pbxproj | 100 +++++++++++++++--- ...ollectionViewDelegateFlowLayoutTests.swift | 57 ++++++---- ...ollectionViewDelegateFlowLayoutTests.swift | 6 +- ...BaseFlowLayoutSectionControllerTests.swift | 10 ++ .../BaseSectionControllerTests.swift | 5 - ...lDefaultValuesSectionControllerTests.swift | 43 ++++---- ...sitionalLayoutSectionControllerTests.swift | 24 +++++ ...onControllerSectionFlowDelegateTests.swift | 9 ++ ...eFlowLayoutSectionFlowDelegateTests.swift} | 18 +++- ...onControllerSectionFlowDelegateTests.swift | 9 -- ...efaultValuesSectionFlowDelegateTests.swift | 2 +- .../MockFlowLayoutSectionController.swift | 10 ++ .../TestUtilities/MockSectionController.swift | 5 - 13 files changed, 216 insertions(+), 82 deletions(-) create mode 100644 SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift create mode 100644 SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift create mode 100644 SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift rename SectionKit/Tests/SectionController/SectionFlowDelegate/{BaseSectionFlowDelegateTests.swift => BaseFlowLayoutSectionFlowDelegateTests.swift} (96%) delete mode 100644 SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionControllerSectionFlowDelegateTests.swift create mode 100644 SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index 94ecdde1..fdbbd9d8 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -53,8 +53,6 @@ 5A31B8CF26BAE93900036A3F /* BaseSectionDropDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8CE26BAE93900036A3F /* BaseSectionDropDelegateTests.swift */; }; 5A31B8D126BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D026BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift */; }; 5A31B8D326BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D226BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift */; }; - 5A31B8D526BAE95700036A3F /* BaseSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D426BAE95700036A3F /* BaseSectionFlowDelegateTests.swift */; }; - 5A31B8D726BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D626BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift */; }; 5A31B8D926BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8D826BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift */; }; 5A31B8E026BBF32D00036A3F /* UICollectionViewApplyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8DF26BBF32D00036A3F /* UICollectionViewApplyTests.swift */; }; 5A31B8E226BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */; }; @@ -114,13 +112,9 @@ 5AE175FB2667DA3F00D4DCE1 /* CollectionViewUpdate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C52667DA3F00D4DCE1 /* CollectionViewUpdate.swift */; }; 5AE175FC2667DA3F00D4DCE1 /* ListCollectionViewAdapter+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C72667DA3F00D4DCE1 /* ListCollectionViewAdapter+Convenience.swift */; }; 5AE175FD2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C82667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDropDelegate.swift */; }; - 5AE175FE2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C92667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift */; }; - 5AE175FF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CA2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift */; }; 5AE176002667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegateFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CB2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegateFlowLayout.swift */; }; 5AE176012667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CC2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegate.swift */; }; 5AE176022667DA3F00D4DCE1 /* ListCollectionViewAdapter+UIScrollViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CD2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UIScrollViewDelegate.swift */; }; - 5AE176032667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CE2667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift */; }; - 5AE176042667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift */; }; 5AE176052667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175D02667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift */; }; 5AE176062667DA3F00D4DCE1 /* ListCollectionViewAdapterDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175D12667DA3F00D4DCE1 /* ListCollectionViewAdapterDataSource.swift */; }; 5AE176072667DA3F00D4DCE1 /* Section.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175D22667DA3F00D4DCE1 /* Section.swift */; }; @@ -136,6 +130,18 @@ 5AE176112667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */; }; 5AE1761B2667DA7000D4DCE1 /* SectionIndexPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */; }; 5AE1761E2667DA7000D4DCE1 /* SequenceUniqueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */; }; + D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */; }; + D91425692BBBF79E0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */; }; + D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */; }; + D91425822BBBF8780005E8CD /* MockFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425802BBBF8670005E8CD /* MockFlowLayoutSectionController.swift */; }; + D91425852BBBFB840005E8CD /* ListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CE2667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift */; }; + D91425862BBBFB930005E8CD /* BaseFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9B72BADF31D00EED204 /* BaseFlowLayoutSectionController.swift */; }; + D91425872BBBFBA40005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */; }; + D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CA2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift */; }; + D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C92667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift */; }; + D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift */; }; + D9CCE9B52BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9B42BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift */; }; + D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -195,8 +201,6 @@ 5A31B8CE26BAE93900036A3F /* BaseSectionDropDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionDropDelegateTests.swift; sourceTree = ""; }; 5A31B8D026BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerSectionDropDelegateTests.swift; sourceTree = ""; }; 5A31B8D226BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolDefaultValuesSectionDropDelegateTests.swift; sourceTree = ""; }; - 5A31B8D426BAE95700036A3F /* BaseSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionFlowDelegateTests.swift; sourceTree = ""; }; - 5A31B8D626BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerSectionFlowDelegateTests.swift; sourceTree = ""; }; 5A31B8D826BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolDefaultValuesSectionFlowDelegateTests.swift; sourceTree = ""; }; 5A31B8DF26BBF32D00036A3F /* UICollectionViewApplyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewApplyTests.swift; sourceTree = ""; }; 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProtocolDefaultValuesSectionControllerTests.swift; sourceTree = ""; }; @@ -281,6 +285,15 @@ 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleSectionCollectionViewAdapter.swift; sourceTree = ""; }; 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionIndexPathTests.swift; sourceTree = ""; }; 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceUniqueTests.swift; sourceTree = ""; }; + D91425622BBBF7320005E8CD /* ListCompositionalLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListCompositionalLayoutSectionController.swift; sourceTree = ""; }; + D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionKitCompositionalLayout.swift; sourceTree = ""; }; + D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseCompositionalLayoutSectionControllerTests.swift; sourceTree = ""; }; + D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionFlowDelegateTests.swift; sourceTree = ""; }; + D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift; sourceTree = ""; }; + D91425802BBBF8670005E8CD /* MockFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockFlowLayoutSectionController.swift; sourceTree = ""; }; + D9CCE9B42BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCompositionalLayoutSectionController.swift; sourceTree = ""; }; + D9CCE9B72BADF31D00EED204 /* BaseFlowLayoutSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionController.swift; sourceTree = ""; }; + D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSCollectionLayoutSection+Empty.swift"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -403,8 +416,8 @@ 5A31B8B426BAE86700036A3F /* SectionFlowDelegate */ = { isa = PBXGroup; children = ( - 5A31B8D426BAE95700036A3F /* BaseSectionFlowDelegateTests.swift */, - 5A31B8D626BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift */, + D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */, + D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */, 5A31B8D826BAE96800036A3F /* ProtocolDefaultValuesSectionFlowDelegateTests.swift */, ); path = SectionFlowDelegate; @@ -531,6 +544,7 @@ 5AE175A12667DA3E00D4DCE1 /* Utility */ = { isa = PBXGroup; children = ( + D9CCE9B92BADF6F600EED204 /* CompositionalLayout */, 5AE175A22667DA3E00D4DCE1 /* Sequence+Unique.swift */, 5AE175A52667DA3E00D4DCE1 /* IndexPath+IsValid.swift */, 5AE175A42667DA3E00D4DCE1 /* Move.swift */, @@ -546,6 +560,7 @@ isa = PBXGroup; children = ( D9CCE9B62BADF2FD00EED204 /* Generic */, + D9CCE9B32BADED5B00EED204 /* CompositionalLayout */, D9CCE9B22BADED3D00EED204 /* FlowLayout */, 5AE175AD2667DA3E00D4DCE1 /* Update */, 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */, @@ -641,6 +656,7 @@ 5AE176122667DA7000D4DCE1 /* SectionController */ = { isa = PBXGroup; children = ( + D91425672BBBF77C0005E8CD /* SectionCompositionalLayout */, 5A31B8AF26BAE81000036A3F /* SectionDataSource */, 5A31B8B026BAE82200036A3F /* SectionDataSourcePrefetchingDelegate */, 5A31B8B126BAE82D00036A3F /* SectionDelegate */, @@ -688,6 +704,52 @@ path = CollectionViewAdapter; sourceTree = ""; }; + D91425672BBBF77C0005E8CD /* SectionCompositionalLayout */ = { + isa = PBXGroup; + children = ( + D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */, + ); + path = SectionCompositionalLayout; + sourceTree = ""; + }; + D9CCE9B22BADED3D00EED204 /* FlowLayout */ = { + isa = PBXGroup; + children = ( + D9CCE9B72BADF31D00EED204 /* BaseFlowLayoutSectionController.swift */, + 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */, + 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */, + 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */, + 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */, + ); + path = FlowLayout; + sourceTree = ""; + }; + D9CCE9B32BADED5B00EED204 /* CompositionalLayout */ = { + isa = PBXGroup; + children = ( + D9CCE9B42BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift */, + D91425622BBBF7320005E8CD /* ListCompositionalLayoutSectionController.swift */, + ); + path = CompositionalLayout; + sourceTree = ""; + }; + D9CCE9B62BADF2FD00EED204 /* Generic */ = { + isa = PBXGroup; + children = ( + 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */, + ); + path = Generic; + sourceTree = ""; + }; + D9CCE9B92BADF6F600EED204 /* CompositionalLayout */ = { + isa = PBXGroup; + children = ( + D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */, + D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */, + ); + path = CompositionalLayout; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -797,6 +859,7 @@ files = ( 5AE176022667DA3F00D4DCE1 /* ListCollectionViewAdapter+UIScrollViewDelegate.swift in Sources */, 5AE175ED2667DA3F00D4DCE1 /* SectionDelegate.swift in Sources */, + D91425852BBBFB840005E8CD /* ListCollectionViewAdapter.swift in Sources */, 5AE175EE2667DA3F00D4DCE1 /* BaseSectionController.swift in Sources */, 5AE1760B2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */, 5AE176072667DA3F00D4DCE1 /* Section.swift in Sources */, @@ -808,10 +871,12 @@ 5AE175F42667DA3F00D4DCE1 /* SectionDragDelegate.swift in Sources */, 5AE176062667DA3F00D4DCE1 /* ListCollectionViewAdapterDataSource.swift in Sources */, 5AE175F62667DA3F00D4DCE1 /* CollectionViewContext+Size.swift in Sources */, + D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, + D9CCE9B52BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift in Sources */, 5AE175F52667DA3F00D4DCE1 /* CollectionViewAdapter.swift in Sources */, 5AE175F32667DA3F00D4DCE1 /* SectionController.swift in Sources */, 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift in Sources */, - 5AE176042667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */, + D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */, 5AB6644626A854A9004DC230 /* ErrorHandling.swift in Sources */, 5AE176052667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift in Sources */, 5AE175E92667DA3F00D4DCE1 /* CollectionViewSectionBatchOperation.swift in Sources */, @@ -820,14 +885,13 @@ 5AE175EC2667DA3F00D4DCE1 /* SectionIndexPath.swift in Sources */, 5AE1760F2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, 5AE1760A2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, - 5AE175FE2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, 5AE175F12667DA3F00D4DCE1 /* SingleModelSectionController.swift in Sources */, 5AE175FB2667DA3F00D4DCE1 /* CollectionViewUpdate.swift in Sources */, 5AE175E42667DA3F00D4DCE1 /* Collection+Extensions.swift in Sources */, - 5AE176032667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift in Sources */, 5AE175E12667DA3F00D4DCE1 /* IndexPath+IsValid.swift in Sources */, 5AE175F82667DA3F00D4DCE1 /* MainCollectionViewContext.swift in Sources */, - 5AE175FF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, + D91425862BBBFB930005E8CD /* BaseFlowLayoutSectionController.swift in Sources */, + D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */, 5AE176102667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+Convenience.swift in Sources */, 5AE175DE2667DA3F00D4DCE1 /* Sequence+Unique.swift in Sources */, 5AB6644426A85463004DC230 /* Error.swift in Sources */, @@ -840,6 +904,7 @@ 5AE175F02667DA3F00D4DCE1 /* SingleItemSectionController.swift in Sources */, 5AE175FD2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */, 5AE176092667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */, + D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, 5AE1760C2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UIScrollViewDelegate.swift in Sources */, 5A98000B2678D6BD00378EB5 /* Array+SectionIndexPath.swift in Sources */, 5AE175FA2667DA3F00D4DCE1 /* CollectionViewContext+CollectionViewUpdate.swift in Sources */, @@ -848,6 +913,7 @@ 5AE176012667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */, 5AE1760E2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapterDataSource.swift in Sources */, 5AE176112667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift in Sources */, + D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */, 5AE175FC2667DA3F00D4DCE1 /* ListCollectionViewAdapter+Convenience.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -861,12 +927,13 @@ 5A0B775626B0050800B054D4 /* MockSectionDropDelegate.swift in Sources */, 5A0B774B26AEEB3100B054D4 /* SingleSectionCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift in Sources */, 5AB6643026A59626004DC230 /* BaseCollectionViewAdapterUICollectionViewDataSourceTests.swift in Sources */, - 5A31B8D526BAE95700036A3F /* BaseSectionFlowDelegateTests.swift in Sources */, + D91425872BBBFBA40005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift in Sources */, 5A31B8D326BAE94E00036A3F /* ProtocolDefaultValuesSectionDropDelegateTests.swift in Sources */, 5A0B776626B146EC00B054D4 /* ListCollectionViewAdapterUICollectionViewDragDelegateTests.swift in Sources */, 5AA9D96A26AACACF00679D88 /* MockSectionDelegate.swift in Sources */, 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */, 5A0B777026B19EB300B054D4 /* MockListCollectionViewAdapterDataSource.swift in Sources */, + D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */, 5A31B8E426BC36C400036A3F /* CollectionViewContextExtensionsTests.swift in Sources */, 5AA9D96E26AAD06100679D88 /* SingleSectionCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, 5AE1761E2667DA7000D4DCE1 /* SequenceUniqueTests.swift in Sources */, @@ -900,6 +967,7 @@ 5A0B778926B3EA4D00B054D4 /* ErrorTests.swift in Sources */, 5A31B8E226BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift in Sources */, 5AA9D95426AAA5EA00679D88 /* MockCollectionReusableView.swift in Sources */, + D91425822BBBF8780005E8CD /* MockFlowLayoutSectionController.swift in Sources */, 5A0B777C26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift in Sources */, 5A0B774526AED0F600B054D4 /* BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift in Sources */, 5A31B8C326BAE90300036A3F /* BaseSectionDelegateTests.swift in Sources */, @@ -909,7 +977,6 @@ 5AA9D96326AAC65200679D88 /* ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift in Sources */, 5AE1761B2667DA7000D4DCE1 /* SectionIndexPathTests.swift in Sources */, 5AA9D96C26AAD05400679D88 /* ListCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, - 5A31B8D726BAE96000036A3F /* BaseSectionControllerSectionFlowDelegateTests.swift in Sources */, 5A31B8C726BAE91300036A3F /* ProtocolDefaultValuesSectionDelegateTests.swift in Sources */, 5A0B776A26B1826100B054D4 /* ListCollectionViewAdapterTests.swift in Sources */, 5A31B8B926BAE8C600036A3F /* BaseSectionControllerSectionDataSourceTests.swift in Sources */, @@ -923,6 +990,7 @@ 5A31B8CD26BAE92D00036A3F /* ProtocolDefaultValuesSectionDragDelegateTests.swift in Sources */, 5A0B774726AEE24700B054D4 /* MockSectionFlowDelegate.swift in Sources */, 5AA9D95826AAA65900679D88 /* ListCollectionViewAdapterUICollectionViewDataSourceTests.swift in Sources */, + D91425692BBBF79E0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift in Sources */, 5AB6644926A86F4D004DC230 /* MockSectionDataSource.swift in Sources */, 5A31B8D126BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift in Sources */, 5A31B8C526BAE90B00036A3F /* BaseSectionControllerSectionDelegateTests.swift in Sources */, diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift index 887b5b98..121bd8c5 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift @@ -2,7 +2,6 @@ import UIKit import XCTest -@MainActor internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() @@ -22,6 +21,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: UICollectionView(frame: frame, collectionViewLayout: layout ?? UICollectionViewFlowLayout()) } + @MainActor internal func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], @@ -33,7 +33,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: } // MARK: - sizeForItem - + @MainActor internal func testSizeForItemWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() @@ -44,7 +44,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._sizeForItem = { indexPath, layout, _ in @@ -66,6 +66,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } + @MainActor internal func testSizeForItemWithoutDelegateButWithFlowLayout() throws { let itemSize = CGSize(width: 1, height: 2) let layout = UICollectionViewFlowLayout() @@ -76,7 +77,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -88,6 +89,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } + @MainActor internal func testSizeForItemWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) @@ -96,7 +98,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -110,6 +112,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - inset + @MainActor internal func testInsetWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() @@ -119,7 +122,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._inset = { layout, _ in @@ -140,6 +143,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } + @MainActor internal func testInsetWithoutDelegateButWithFlowLayout() throws { let sectionInset = UIEdgeInsets(top: 1, left: 2, bottom: 4, right: 8) let layout = UICollectionViewFlowLayout() @@ -149,7 +153,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -161,6 +165,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } + @MainActor internal func testInsetWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) @@ -168,7 +173,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -182,6 +187,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - minimumLineSpacing + @MainActor internal func testMinimumLineSpacingWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() @@ -191,7 +197,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._minimumLineSpacing = { layout, _ in @@ -212,6 +218,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } + @MainActor internal func testMinimumLineSpacingWithoutDelegateButWithFlowLayout() throws { let lineSpacing: CGFloat = 1 let layout = UICollectionViewFlowLayout() @@ -221,7 +228,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -233,6 +240,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } + @MainActor internal func testMinimumLineSpacingWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) @@ -240,7 +248,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -254,6 +262,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - minimumInteritemSpacing + @MainActor internal func testMinimumInteritemSpacingWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() @@ -263,7 +272,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._minimumInteritemSpacing = { layout, _ in @@ -284,6 +293,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } + @MainActor internal func testMinimumInteritemSpacingWithoutDelegateButWithFlowLayout() throws { let interitemSpacing: CGFloat = 1 let layout = UICollectionViewFlowLayout() @@ -293,7 +303,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -305,6 +315,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } + @MainActor internal func testMinimumInteritemSpacingWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) @@ -312,7 +323,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -326,6 +337,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - referenceSizeForHeader + @MainActor internal func testReferenceSizeForHeaderWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() @@ -335,7 +347,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._referenceSizeForHeader = { layout, _ in @@ -356,6 +368,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } + @MainActor internal func testReferenceSizeForHeaderWithoutDelegateButWithFlowLayout() throws { let headerSize = CGSize(width: 1, height: 2) let layout = UICollectionViewFlowLayout() @@ -365,7 +378,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -377,6 +390,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } + @MainActor internal func testReferenceSizeForHeaderWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) @@ -384,7 +398,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -398,6 +412,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: // MARK: - referenceSizeForFooter + @MainActor internal func testReferenceSizeForFooterWithDelegate() throws { let testExpectation = expectation(description: "Should invoke flow layout delegate") let mockLayout = UICollectionViewFlowLayout() @@ -407,7 +422,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._referenceSizeForFooter = { layout, _ in @@ -428,6 +443,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: waitForExpectations(timeout: 1) } + @MainActor internal func testReferenceSizeForFooterWithoutDelegateButWithFlowLayout() throws { let footerSize = CGSize(width: 1, height: 2) let layout = UICollectionViewFlowLayout() @@ -437,7 +453,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) @@ -449,6 +465,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: ) } + @MainActor internal func testReferenceSizeForFooterWithoutDelegateAndFlowLayout() throws { let layout = UICollectionViewLayout() let collectionView = createCollectionView(collectionViewLayout: layout) @@ -456,7 +473,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockSectionController() + let sectionController = MockFlowLayoutSectionController() sectionController.flowDelegate = nil return sectionController }) diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift index 7227d369..afc5972c 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift @@ -2,9 +2,9 @@ import UIKit import XCTest -@MainActor -internal final class ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests { - override internal func createCollectionViewAdapter( +final class ListCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests { + @MainActor + override func createCollectionViewAdapter( collectionView: UICollectionView, sections: [Section] = [], viewController: UIViewController? = nil, diff --git a/SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift new file mode 100644 index 00000000..e87dfe9d --- /dev/null +++ b/SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift @@ -0,0 +1,10 @@ +import SectionKit +import XCTest + +internal final class BaseFlowLayoutSectionControllerTests: XCTestCase { + @MainActor + internal func testFlowDelegateIsSelf() { + let sectionController = BaseFlowLayoutSectionController() + XCTAssert(sectionController.flowDelegate === sectionController) + } +} diff --git a/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift b/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift index 26a3edb7..7598ce13 100644 --- a/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift @@ -24,11 +24,6 @@ internal final class BaseSectionControllerTests: XCTestCase { XCTAssert(sectionController.delegate === sectionController) } - internal func testFlowDelegateIsSelf() { - let sectionController = BaseSectionController() - XCTAssert(sectionController.flowDelegate === sectionController) - } - @available(iOS 11.0, *) internal func testDragDelegateIsSelf() { let sectionController = BaseSectionController() diff --git a/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift b/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift index a63371e8..d01408be 100644 --- a/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/ProtocolDefaultValuesSectionControllerTests.swift @@ -1,42 +1,45 @@ import SectionKit import XCTest -@MainActor -internal final class ProtocolDefaultValuesSectionControllerTests: XCTestCase { - private func createSectionController() -> SectionController { +final class ProtocolDefaultValuesSectionControllerTests: XCTestCase { + private var sut: SectionController! + + @MainActor + override func setUp() { + super.setUp() class DefaultSectionController: SectionController { var context: CollectionViewContext? var dataSource: SectionDataSource = MockSectionDataSource() func didUpdate(model: Any) { } } - return DefaultSectionController() + sut = DefaultSectionController() } - @available(iOS 10.0, *) - internal func testDataSourcePrefetchingDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.dataSourcePrefetchingDelegate) + override func tearDown() { + sut = nil + super.tearDown() } - internal func testDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.delegate) + @MainActor + @available(iOS 10.0, *) + func testDataSourcePrefetchingDelegateIsNil() { + XCTAssertNil(sut.dataSourcePrefetchingDelegate) } - internal func testFlowDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.flowDelegate) + @MainActor + func testDelegateIsNil() { + XCTAssertNil(sut.delegate) } + @MainActor @available(iOS 11.0, *) - internal func testDragDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.dragDelegate) + func testDragDelegateIsNil() { + XCTAssertNil(sut.dragDelegate) } + @MainActor @available(iOS 11.0, *) - internal func testDropDelegateIsNil() { - let sectionController = createSectionController() - XCTAssertNil(sectionController.dropDelegate) + func testDropDelegateIsNil() { + XCTAssertNil(sut.dropDelegate) } } diff --git a/SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift new file mode 100644 index 00000000..528568ba --- /dev/null +++ b/SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift @@ -0,0 +1,24 @@ +@testable import SectionKit +import XCTest + +final class BaseCompositionalLayoutSectionControllerTests: XCTestCase { + final class TestLayoutEnvironment: NSObject, NSCollectionLayoutEnvironment { + final class TestLayoutContainer: NSObject, NSCollectionLayoutContainer { + let contentSize: CGSize = .zero + let effectiveContentSize: CGSize = .zero + let contentInsets: NSDirectionalEdgeInsets = .zero + let effectiveContentInsets: NSDirectionalEdgeInsets = .zero + } + let container: NSCollectionLayoutContainer = TestLayoutContainer() + let traitCollection: UITraitCollection = .current + } + + @MainActor + func test_layout_isEmpty() { + let sut = BaseCompositionalLayoutSectionController() + let layoutSection = sut.layoutSection( + layoutEnvironment: TestLayoutEnvironment() + ) + XCTAssertEqual(layoutSection, .empty) + } +} diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift new file mode 100644 index 00000000..4710fa1d --- /dev/null +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift @@ -0,0 +1,9 @@ +import SectionKit +import XCTest + +internal final class BaseFlowLayoutSectionControllerSectionFlowDelegateTests: BaseFlowLayoutSectionFlowDelegateTests { + @MainActor + override func createSectionFlowDelegate() throws -> SectionFlowDelegate { + BaseFlowLayoutSectionController() + } +} diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift similarity index 96% rename from SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionFlowDelegateTests.swift rename to SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift index d6700d55..526003c5 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift @@ -1,8 +1,7 @@ import SectionKit import XCTest -@MainActor -internal class BaseSectionFlowDelegateTests: XCTestCase { +internal class BaseFlowLayoutSectionFlowDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false @@ -10,14 +9,16 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { } internal func skipIfNeeded() throws { - guard Self.self === BaseSectionFlowDelegateTests.self else { return } + guard Self.self === BaseFlowLayoutSectionFlowDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } + @MainActor internal func createSectionFlowDelegate() throws -> SectionFlowDelegate { throw XCTSkip("Tests from base class are skipped") } + @MainActor internal func testSizeForItemWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -39,6 +40,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testSizeForItemWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -58,6 +60,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testInsetWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -77,6 +80,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testInsetWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -94,6 +98,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testMinimumLineSpacingWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -112,6 +117,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testMinimumLineSpacingWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -129,6 +135,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testMinimumInteritemSpacingWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -147,6 +154,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testMinimumInteritemSpacingWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -164,6 +172,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testReferenceSizeForHeaderWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -183,6 +192,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testReferenceSizeForHeaderWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -200,6 +210,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testReferenceSizeForFooterWithFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( @@ -219,6 +230,7 @@ internal class BaseSectionFlowDelegateTests: XCTestCase { ) } + @MainActor internal func testReferenceSizeForFooterWithoutFlowLayout() throws { let sectionFlowDelegate = try createSectionFlowDelegate() let context = MainCollectionViewContext( diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionControllerSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionControllerSectionFlowDelegateTests.swift deleted file mode 100644 index 6624c139..00000000 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseSectionControllerSectionFlowDelegateTests.swift +++ /dev/null @@ -1,9 +0,0 @@ -import SectionKit -import XCTest - -@MainActor -internal final class BaseSectionControllerSectionFlowDelegateTests: BaseSectionFlowDelegateTests { - override func createSectionFlowDelegate() throws -> SectionFlowDelegate { - BaseSectionController() - } -} diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift index 11d7246e..8dd8e583 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift @@ -2,7 +2,7 @@ import SectionKit import XCTest @MainActor -internal final class ProtocolDefaultValuesSectionFlowDelegateTests: BaseSectionFlowDelegateTests { +internal final class ProtocolDefaultValuesSectionFlowDelegateTests: BaseFlowLayoutSectionFlowDelegateTests { override func createSectionFlowDelegate() throws -> SectionFlowDelegate { class DefaultSectionFlowDelegate: SectionFlowDelegate { } return DefaultSectionFlowDelegate() diff --git a/SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift b/SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift new file mode 100644 index 00000000..7cf6be8f --- /dev/null +++ b/SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift @@ -0,0 +1,10 @@ +import SectionKit +import XCTest + +final class MockFlowLayoutSectionController: MockSectionController, + FlowLayoutSectionController { + lazy var flowDelegate: SectionFlowDelegate? = { + XCTFail("flow delegate is not set") + return nil + }() +} diff --git a/SectionKit/Tests/TestUtilities/MockSectionController.swift b/SectionKit/Tests/TestUtilities/MockSectionController.swift index f787dbf6..b6a8d80f 100644 --- a/SectionKit/Tests/TestUtilities/MockSectionController.swift +++ b/SectionKit/Tests/TestUtilities/MockSectionController.swift @@ -20,11 +20,6 @@ internal class MockSectionController: SectionController { return nil }() - internal lazy var flowDelegate: SectionFlowDelegate? = { - XCTFail("flow delegate is not set") - return nil - }() - @available(iOS 11.0, *) internal lazy var dragDelegate: SectionDragDelegate? = { XCTFail("dragDelegate is not set") From 855685d6de4aed7251566fb721ff96ad46e0253f Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Tue, 2 Apr 2024 12:17:10 +0200 Subject: [PATCH 05/16] add references --- SectionKit.xcodeproj/project.pbxproj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index fdbbd9d8..ff259593 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -140,6 +140,7 @@ D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CA2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift */; }; D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C92667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift */; }; D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift */; }; + D941851A2BBC123C001B5086 /* ListCompositionalLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425622BBBF7320005E8CD /* ListCompositionalLayoutSectionController.swift */; }; D9CCE9B52BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9B42BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift */; }; D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */; }; /* End PBXBuildFile section */ @@ -887,6 +888,7 @@ 5AE1760A2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, 5AE175F12667DA3F00D4DCE1 /* SingleModelSectionController.swift in Sources */, 5AE175FB2667DA3F00D4DCE1 /* CollectionViewUpdate.swift in Sources */, + D941851A2BBC123C001B5086 /* ListCompositionalLayoutSectionController.swift in Sources */, 5AE175E42667DA3F00D4DCE1 /* Collection+Extensions.swift in Sources */, 5AE175E12667DA3F00D4DCE1 /* IndexPath+IsValid.swift in Sources */, 5AE175F82667DA3F00D4DCE1 /* MainCollectionViewContext.swift in Sources */, From 81ae84ada256918c1697f0c1a03b4e5ee21c069a Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 3 Apr 2024 15:27:41 +0200 Subject: [PATCH 06/16] Add the constants for the better reading --- .../BaseFlowLayoutSectionController.swift | 12 ++++----- .../SectionFlowDelegate.swift | 27 ++++++++++++++----- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift index c9b6ebe4..07ee64a4 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift @@ -14,35 +14,35 @@ open class BaseFlowLayoutSectionController: BaseSectionController, using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.itemSize ?? CGSize(width: 50, height: 50) + layout.flowLayout?.itemSize ?? FlowLayoutConstants.defaultItemSize } open func inset(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> UIEdgeInsets { - (layout as? UICollectionViewFlowLayout)?.sectionInset ?? .zero + layout.flowLayout?.sectionInset ?? FlowLayoutConstants.defaultInset } open func minimumLineSpacing(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 10 + layout.flowLayout?.minimumLineSpacing ?? FlowLayoutConstants.defaultMinimumLineSpacing } open func minimumInteritemSpacing( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 10 + layout.flowLayout?.minimumInteritemSpacing ?? FlowLayoutConstants.defaultMinimumInteritemSpacing } open func referenceSizeForHeader( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.headerReferenceSize ?? .zero + layout.flowLayout?.headerReferenceSize ?? FlowLayoutConstants.defaultHeaderSize } open func referenceSizeForFooter( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.footerReferenceSize ?? .zero + layout.flowLayout?.footerReferenceSize ?? FlowLayoutConstants.defaultFooterSize } } diff --git a/SectionKit/Sources/SectionController/SectionFlowDelegate.swift b/SectionKit/Sources/SectionController/SectionFlowDelegate.swift index 49cd338a..b3ae71a5 100644 --- a/SectionKit/Sources/SectionController/SectionFlowDelegate.swift +++ b/SectionKit/Sources/SectionController/SectionFlowDelegate.swift @@ -76,47 +76,62 @@ public protocol SectionFlowDelegate: AnyObject { func referenceSizeForFooter(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGSize } +enum FlowLayoutConstants { + static let defaultItemSize = CGSize(width: 50, height: 50) + static let defaultInset: UIEdgeInsets = .zero + static let defaultMinimumLineSpacing: CGFloat = 10 + static let defaultMinimumInteritemSpacing: CGFloat = 10 + static let defaultHeaderSize: CGSize = .zero + static let defaultFooterSize: CGSize = .zero +} + extension SectionFlowDelegate { public func sizeForItem( at indexPath: SectionIndexPath, using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.itemSize ?? CGSize(width: 50, height: 50) + layout.flowLayout?.itemSize ?? FlowLayoutConstants.defaultItemSize } public func inset( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> UIEdgeInsets { - (layout as? UICollectionViewFlowLayout)?.sectionInset ?? .zero + layout.flowLayout?.sectionInset ?? FlowLayoutConstants.defaultInset } public func minimumLineSpacing( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumLineSpacing ?? 10 + layout.flowLayout?.minimumLineSpacing ?? FlowLayoutConstants.defaultMinimumLineSpacing } public func minimumInteritemSpacing( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGFloat { - (layout as? UICollectionViewFlowLayout)?.minimumInteritemSpacing ?? 10 + layout.flowLayout?.minimumInteritemSpacing ?? FlowLayoutConstants.defaultMinimumInteritemSpacing } public func referenceSizeForHeader( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.headerReferenceSize ?? .zero + layout.flowLayout?.headerReferenceSize ?? FlowLayoutConstants.defaultHeaderSize } public func referenceSizeForFooter( using layout: UICollectionViewLayout, in context: CollectionViewContext ) -> CGSize { - (layout as? UICollectionViewFlowLayout)?.footerReferenceSize ?? .zero + layout.flowLayout?.footerReferenceSize ?? FlowLayoutConstants.defaultFooterSize + } +} + +extension UICollectionViewLayout { + var flowLayout: UICollectionViewFlowLayout? { + self as? UICollectionViewFlowLayout } } From 2ecea0cfcf7638c64f757658e38a3afefdde49b3 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 10:31:08 +0200 Subject: [PATCH 07/16] add typealias --- ...fingListFlowLayoutSectionController.swift} | 11 ++++++++++- ...fingListFlowLayoutSectionController.swift} | 19 ++++++++++++++----- ...t => ListFlowLaoutSectionController.swift} | 10 +++++++++- ...ngleItemFlowLayoutSectionController.swift} | 12 ++++++++++-- ...gleModelFlowLayoutSectionController.swift} | 10 +++++++++- 5 files changed, 52 insertions(+), 10 deletions(-) rename DiffingSectionKit/Sources/{DiffingListSectionController.swift => DiffingListFlowLayoutSectionController.swift} (68%) rename DiffingSectionKit/Sources/{ManualDiffingListSectionController.swift => ManualDiffingListFlowLayoutSectionController.swift} (86%) rename SectionKit/Sources/SectionController/FlowLayout/{ListSectionController.swift => ListFlowLaoutSectionController.swift} (91%) rename SectionKit/Sources/SectionController/FlowLayout/{SingleItemSectionController.swift => SingleItemFlowLayoutSectionController.swift} (91%) rename SectionKit/Sources/SectionController/FlowLayout/{SingleModelSectionController.swift => SingleModelFlowLayoutSectionController.swift} (87%) diff --git a/DiffingSectionKit/Sources/DiffingListSectionController.swift b/DiffingSectionKit/Sources/DiffingListFlowLayoutSectionController.swift similarity index 68% rename from DiffingSectionKit/Sources/DiffingListSectionController.swift rename to DiffingSectionKit/Sources/DiffingListFlowLayoutSectionController.swift index 4d5cd989..714b2a2b 100644 --- a/DiffingSectionKit/Sources/DiffingListSectionController.swift +++ b/DiffingSectionKit/Sources/DiffingListFlowLayoutSectionController.swift @@ -9,7 +9,7 @@ import SectionKit of a model to be displayed and the list of items may dynamically change. */ @MainActor -open class DiffingListSectionController: ListSectionController { +open class DiffingListFlowLayoutSectionController: ListFlowLaoutSectionController { override open func calculateUpdate( from oldData: [Item], to newData: [Item] @@ -23,3 +23,12 @@ open class DiffingListSectionController: ListSectio ) } } + +@available( + *, + deprecated, + renamed: "DiffingListFlowLayoutSectionController", + message: "It has been renamed to DiffingListFlowLayoutSectionController" +) + +public typealias DiffingListSectionController = DiffingListFlowLayoutSectionController diff --git a/DiffingSectionKit/Sources/ManualDiffingListSectionController.swift b/DiffingSectionKit/Sources/ManualDiffingListFlowLayoutSectionController.swift similarity index 86% rename from DiffingSectionKit/Sources/ManualDiffingListSectionController.swift rename to DiffingSectionKit/Sources/ManualDiffingListFlowLayoutSectionController.swift index 53d42dba..93542e6f 100644 --- a/DiffingSectionKit/Sources/ManualDiffingListSectionController.swift +++ b/DiffingSectionKit/Sources/ManualDiffingListFlowLayoutSectionController.swift @@ -12,10 +12,10 @@ import SectionKit `Item` type, instead it requires closures to get diffing information for an item. */ @MainActor -open class ManualDiffingListSectionController< +open class ManualDiffingListFlowLayoutSectionController< Model, Item ->: ListSectionController { +>: ListFlowLaoutSectionController { private let itemId: @MainActor (Item) -> AnyHashable private let itemContentIsEqual: @MainActor (Item, Item) -> Bool @@ -55,7 +55,7 @@ open class ManualDiffingListSectionController< } } -extension ManualDiffingListSectionController where Item: Equatable { +extension ManualDiffingListFlowLayoutSectionController where Item: Equatable { /** Initialise an instance of `ManualDiffingListSectionController`. @@ -69,7 +69,7 @@ extension ManualDiffingListSectionController where Item: Equatable { } @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension ManualDiffingListSectionController where Item: Identifiable { +extension ManualDiffingListFlowLayoutSectionController where Item: Identifiable { /** Initialise an instance of `ManualDiffingListSectionController`. @@ -89,7 +89,7 @@ extension ManualDiffingListSectionController where Item: Identifiable { the base init (apart from the default values), we have to specify `@_disfavoredOverload` so it doesn't call itself. */ @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension ManualDiffingListSectionController where Item: Identifiable & Equatable { +extension ManualDiffingListFlowLayoutSectionController where Item: Identifiable & Equatable { /** Initialise an instance of `ManualDiffingListSectionController`. @@ -108,3 +108,12 @@ extension ManualDiffingListSectionController where Item: Identifiable & Equatabl self.init(model: model, itemId: itemId, itemContentIsEqual: itemContentIsEqual) } } + +@available( + *, + deprecated, + renamed: "ManualDiffingListFlowLayoutSectionController", + message: "It has been renamed to ManualDiffingListFlowLayoutSectionController" +) + +public typealias ManualDiffingListSectionController = ManualDiffingListFlowLayoutSectionController diff --git a/SectionKit/Sources/SectionController/FlowLayout/ListSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/ListFlowLaoutSectionController.swift similarity index 91% rename from SectionKit/Sources/SectionController/FlowLayout/ListSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/ListFlowLaoutSectionController.swift index d8d5124c..a3f016d4 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/ListSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/ListFlowLaoutSectionController.swift @@ -8,7 +8,7 @@ import UIKit of a model to be displayed and the list of items (almost) never changes or should not perform animated updates. */ @MainActor -open class ListSectionController: BaseFlowLayoutSectionController { +open class ListFlowLaoutSectionController: BaseFlowLayoutSectionController { /** Initialise an instance of `ListSectionController`. @@ -112,3 +112,11 @@ open class ListSectionController: BaseFlowLayoutSectionController { override open func numberOfItems(in context: CollectionViewContext) -> Int { items.count } } + +@available( + *, + deprecated, + renamed: "ListFlowLaoutSectionController", + message: "It has been renamed to ListFlowLaoutSectionController" +) +public typealias ListSectionController = ListFlowLaoutSectionController diff --git a/SectionKit/Sources/SectionController/FlowLayout/SingleItemSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/SingleItemFlowLayoutSectionController.swift similarity index 91% rename from SectionKit/Sources/SectionController/FlowLayout/SingleItemSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/SingleItemFlowLayoutSectionController.swift index 9f88725d..7ecb9e77 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/SingleItemSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/SingleItemFlowLayoutSectionController.swift @@ -9,7 +9,7 @@ import UIKit - Warning: If `numberOfItems` is overridden, `calculateUpdate(from:to:)` needs to be overridden as well. */ @MainActor -open class SingleItemSectionController: BaseFlowLayoutSectionController { +open class SingleItemFlowLayoutSectionController: BaseFlowLayoutSectionController { private let areItemsEqual: @MainActor (Item, Item) -> Bool /** @@ -133,7 +133,7 @@ open class SingleItemSectionController: BaseFlowLayoutSectionContro override open func numberOfItems(in context: CollectionViewContext) -> Int { item != nil ? 1 : 0 } } -extension SingleItemSectionController where Item: Equatable { +extension SingleItemFlowLayoutSectionController where Item: Equatable { /** Initialise an instance of `SingleItemSectionController` which will only reload when the new item is different from the old one. @@ -144,3 +144,11 @@ extension SingleItemSectionController where Item: Equatable { self.init(model: model, areItemsEqual: ==) } } + +@available( + *, + deprecated, + renamed: "SingleItemFlowLayoutSectionController", + message: "It has been renamed to SingleItemFlowLayoutSectionController" +) +public typealias SingleItemSectionController = SingleItemFlowLayoutSectionController diff --git a/SectionKit/Sources/SectionController/FlowLayout/SingleModelSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/SingleModelFlowLayoutSectionController.swift similarity index 87% rename from SectionKit/Sources/SectionController/FlowLayout/SingleModelSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/SingleModelFlowLayoutSectionController.swift index f2144b49..4a563ab6 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/SingleModelSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/SingleModelFlowLayoutSectionController.swift @@ -9,7 +9,7 @@ import UIKit it is recommended to use `ListSectionController` instead. */ @MainActor -open class SingleModelSectionController: BaseFlowLayoutSectionController { +open class SingleModelFlowLayoutSectionController: BaseFlowLayoutSectionController { /** Initialise an instance of `SingleModelSectionController`. @@ -76,3 +76,11 @@ open class SingleModelSectionController: BaseFlowLayoutSectionController override open func numberOfItems(in context: CollectionViewContext) -> Int { 1 } } + +@available( + *, + deprecated, + renamed: "SingleModelFlowLayoutSectionController", + message: "It has been renamed to SingleModelFlowLayoutSectionController" +) +public typealias SingleModelSectionController = SingleModelFlowLayoutSectionController From db28d6e18b0cf2a03c755b6cd7f574b3d0266cfd Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 11:38:29 +0200 Subject: [PATCH 08/16] fix tests --- SectionKit.xcodeproj/project.pbxproj | 56 +++++++++---------- ...fingListFlowLayoutSectionController.swift} | 13 ++++- ...istFlowLayoutSectionControllerTests.swift} | 16 +++--- ...temFlowLayoutSectionControllerTests.swift} | 28 +++++----- ...delFlowLayoutSectionControllerTests.swift} | 10 ++-- 5 files changed, 66 insertions(+), 57 deletions(-) rename SectionKit/Sources/SectionController/FlowLayout/{FoundationDiffingListSectionController.swift => FoundationDiffingListFlowLayoutSectionController.swift} (69%) rename SectionKit/Tests/SectionController/{ListSectionControllerTests.swift => ListFlowLayoutSectionControllerTests.swift} (87%) rename SectionKit/Tests/SectionController/{SingleItemSectionControllerTests.swift => SingleItemFlowLayoutSectionControllerTests.swift} (86%) rename SectionKit/Tests/SectionController/{SingleModelSectionControllerTests.swift => SingleModelFlowLayoutSectionControllerTests.swift} (84%) diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index ff259593..ed6b3fa6 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -33,9 +33,9 @@ 5A0B777A26B1A81300B054D4 /* MainCollectionViewContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777926B1A81300B054D4 /* MainCollectionViewContextTests.swift */; }; 5A0B777C26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */; }; 5A0B777E26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */; }; - 5A0B778026B299FF00B054D4 /* ListSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777F26B299FF00B054D4 /* ListSectionControllerTests.swift */; }; - 5A0B778226B2A92C00B054D4 /* SingleItemSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */; }; - 5A0B778426B2AA2000B054D4 /* SingleModelSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778326B2AA2000B054D4 /* SingleModelSectionControllerTests.swift */; }; + 5A0B778026B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */; }; + 5A0B778226B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778126B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift */; }; + 5A0B778426B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */; }; 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */; }; 5A0B778926B3EA4D00B054D4 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */; }; 5A31B8B726BAE8A900036A3F /* BaseSectionDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8B526BAE8A300036A3F /* BaseSectionDataSourceTests.swift */; }; @@ -97,10 +97,7 @@ 5AE175EC2667DA3F00D4DCE1 /* SectionIndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */; }; 5AE175ED2667DA3F00D4DCE1 /* SectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B32667DA3E00D4DCE1 /* SectionDelegate.swift */; }; 5AE175EE2667DA3F00D4DCE1 /* BaseSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */; }; - 5AE175EF2667DA3F00D4DCE1 /* ListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */; }; - 5AE175F02667DA3F00D4DCE1 /* SingleItemSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */; }; - 5AE175F12667DA3F00D4DCE1 /* SingleModelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */; }; - 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */; }; + 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift */; }; 5AE175F32667DA3F00D4DCE1 /* SectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */; }; 5AE175F42667DA3F00D4DCE1 /* SectionDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BB2667DA3F00D4DCE1 /* SectionDragDelegate.swift */; }; 5AE175F52667DA3F00D4DCE1 /* CollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BD2667DA3F00D4DCE1 /* CollectionViewAdapter.swift */; }; @@ -130,6 +127,9 @@ 5AE176112667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */; }; 5AE1761B2667DA7000D4DCE1 /* SectionIndexPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */; }; 5AE1761E2667DA7000D4DCE1 /* SequenceUniqueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */; }; + D90764C32BC692BB0083306E /* ListFlowLaoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C02BC692BB0083306E /* ListFlowLaoutSectionController.swift */; }; + D90764C42BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C12BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift */; }; + D90764C52BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C22BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift */; }; D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */; }; D91425692BBBF79E0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */; }; D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */; }; @@ -182,9 +182,9 @@ 5A0B777926B1A81300B054D4 /* MainCollectionViewContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainCollectionViewContextTests.swift; sourceTree = ""; }; 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewSectionBatchOperationTests.swift; sourceTree = ""; }; 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewBatchOperationTests.swift; sourceTree = ""; }; - 5A0B777F26B299FF00B054D4 /* ListSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListSectionControllerTests.swift; sourceTree = ""; }; - 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleItemSectionControllerTests.swift; sourceTree = ""; }; - 5A0B778326B2AA2000B054D4 /* SingleModelSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleModelSectionControllerTests.swift; sourceTree = ""; }; + 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; + 5A0B778126B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleItemFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; + 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleModelFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerTests.swift; sourceTree = ""; }; 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = ""; }; 5A31B8B526BAE8A300036A3F /* BaseSectionDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionDataSourceTests.swift; sourceTree = ""; }; @@ -249,10 +249,7 @@ 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionIndexPath.swift; sourceTree = ""; }; 5AE175B32667DA3E00D4DCE1 /* SectionDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDelegate.swift; sourceTree = ""; }; 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseSectionController.swift; sourceTree = ""; }; - 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListSectionController.swift; sourceTree = ""; }; - 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleItemSectionController.swift; sourceTree = ""; }; - 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelSectionController.swift; sourceTree = ""; }; - 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDiffingListSectionController.swift; sourceTree = ""; }; + 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDiffingListFlowLayoutSectionController.swift; sourceTree = ""; }; 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionController.swift; sourceTree = ""; }; 5AE175BB2667DA3F00D4DCE1 /* SectionDragDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDragDelegate.swift; sourceTree = ""; }; 5AE175BD2667DA3F00D4DCE1 /* CollectionViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewAdapter.swift; sourceTree = ""; }; @@ -286,6 +283,9 @@ 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleSectionCollectionViewAdapter.swift; sourceTree = ""; }; 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionIndexPathTests.swift; sourceTree = ""; }; 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceUniqueTests.swift; sourceTree = ""; }; + D90764C02BC692BB0083306E /* ListFlowLaoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListFlowLaoutSectionController.swift; sourceTree = ""; }; + D90764C12BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelFlowLayoutSectionController.swift; sourceTree = ""; }; + D90764C22BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleItemFlowLayoutSectionController.swift; sourceTree = ""; }; D91425622BBBF7320005E8CD /* ListCompositionalLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListCompositionalLayoutSectionController.swift; sourceTree = ""; }; D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionKitCompositionalLayout.swift; sourceTree = ""; }; D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseCompositionalLayoutSectionControllerTests.swift; sourceTree = ""; }; @@ -668,9 +668,9 @@ 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */, 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */, 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */, - 5A0B777F26B299FF00B054D4 /* ListSectionControllerTests.swift */, - 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */, - 5A0B778326B2AA2000B054D4 /* SingleModelSectionControllerTests.swift */, + 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */, + 5A0B778126B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift */, + 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */, ); path = SectionController; sourceTree = ""; @@ -717,10 +717,10 @@ isa = PBXGroup; children = ( D9CCE9B72BADF31D00EED204 /* BaseFlowLayoutSectionController.swift */, - 5AE175B62667DA3E00D4DCE1 /* ListSectionController.swift */, - 5AE175B72667DA3F00D4DCE1 /* SingleItemSectionController.swift */, - 5AE175B82667DA3F00D4DCE1 /* SingleModelSectionController.swift */, - 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift */, + D90764C02BC692BB0083306E /* ListFlowLaoutSectionController.swift */, + D90764C22BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift */, + D90764C12BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift */, + 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift */, ); path = FlowLayout; sourceTree = ""; @@ -876,22 +876,24 @@ D9CCE9B52BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift in Sources */, 5AE175F52667DA3F00D4DCE1 /* CollectionViewAdapter.swift in Sources */, 5AE175F32667DA3F00D4DCE1 /* SectionController.swift in Sources */, - 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListSectionController.swift in Sources */, + 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift in Sources */, D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */, 5AB6644626A854A9004DC230 /* ErrorHandling.swift in Sources */, 5AE176052667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift in Sources */, 5AE175E92667DA3F00D4DCE1 /* CollectionViewSectionBatchOperation.swift in Sources */, + D90764C42BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift in Sources */, 5AE175E02667DA3F00D4DCE1 /* Move.swift in Sources */, 5AE175EB2667DA3F00D4DCE1 /* SectionDataSourcePrefetchingDelegate.swift in Sources */, 5AE175EC2667DA3F00D4DCE1 /* SectionIndexPath.swift in Sources */, 5AE1760F2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, 5AE1760A2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, - 5AE175F12667DA3F00D4DCE1 /* SingleModelSectionController.swift in Sources */, 5AE175FB2667DA3F00D4DCE1 /* CollectionViewUpdate.swift in Sources */, + D90764C32BC692BB0083306E /* ListFlowLaoutSectionController.swift in Sources */, D941851A2BBC123C001B5086 /* ListCompositionalLayoutSectionController.swift in Sources */, 5AE175E42667DA3F00D4DCE1 /* Collection+Extensions.swift in Sources */, 5AE175E12667DA3F00D4DCE1 /* IndexPath+IsValid.swift in Sources */, 5AE175F82667DA3F00D4DCE1 /* MainCollectionViewContext.swift in Sources */, + D90764C52BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift in Sources */, D91425862BBBFB930005E8CD /* BaseFlowLayoutSectionController.swift in Sources */, D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */, 5AE176102667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+Convenience.swift in Sources */, @@ -902,8 +904,6 @@ 5AE175E82667DA3F00D4DCE1 /* CollectionViewContext+CollectionViewSectionUpdate.swift in Sources */, 5AE175EA2667DA3F00D4DCE1 /* CollectionViewSectionUpdate.swift in Sources */, 5AE175F92667DA3F00D4DCE1 /* CollectionViewBatchOperation.swift in Sources */, - 5AE175EF2667DA3F00D4DCE1 /* ListSectionController.swift in Sources */, - 5AE175F02667DA3F00D4DCE1 /* SingleItemSectionController.swift in Sources */, 5AE175FD2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */, 5AE176092667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */, D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, @@ -946,7 +946,7 @@ 5AB6642926A587AE004DC230 /* CollectionViewContextSizeTests.swift in Sources */, 5A31B8CF26BAE93900036A3F /* BaseSectionDropDelegateTests.swift in Sources */, 5A31B8BF26BAE8EE00036A3F /* BaseSectionControllerSectionDataSourcePrefetchingDelegateTests.swift in Sources */, - 5A0B778426B2AA2000B054D4 /* SingleModelSectionControllerTests.swift in Sources */, + 5A0B778426B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift in Sources */, 5A0B775926B0069700B054D4 /* BaseCollectionViewAdapterUICollectionViewDropDelegateTests.swift in Sources */, 5A0B776E26B19E8C00B054D4 /* MockSingleSectionCollectionViewAdapterDataSource.swift in Sources */, 5A8D3E5927E8D16200073712 /* MockCollectionViewAdapter.swift in Sources */, @@ -955,7 +955,7 @@ 5A31B8BB26BAE8D400036A3F /* ProtocolDefaultValuesSectionDataSourceTests.swift in Sources */, 5A0B774E26AF0C2100B054D4 /* BaseCollectionViewAdapterUIScrollViewDelegateTests.swift in Sources */, 5AA9D96826AAC9AF00679D88 /* BaseCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, - 5A0B778026B299FF00B054D4 /* ListSectionControllerTests.swift in Sources */, + 5A0B778026B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift in Sources */, 5A0B775B26B006AA00B054D4 /* ListCollectionViewAdapterUICollectionViewDropDelegateTests.swift in Sources */, 5A31B8BD26BAE8E300036A3F /* BaseSectionDataSourcePrefetchingDelegateTests.swift in Sources */, 5A31B8C126BAE8F800036A3F /* ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests.swift in Sources */, @@ -996,7 +996,7 @@ 5AB6644926A86F4D004DC230 /* MockSectionDataSource.swift in Sources */, 5A31B8D126BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift in Sources */, 5A31B8C526BAE90B00036A3F /* BaseSectionControllerSectionDelegateTests.swift in Sources */, - 5A0B778226B2A92C00B054D4 /* SingleItemSectionControllerTests.swift in Sources */, + 5A0B778226B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift in Sources */, 5A8D3E5527E8D11600073712 /* MockCollectionViewContext.swift in Sources */, 5A8D3E5727E8D14700073712 /* MockCollectionView.swift in Sources */, 5A0B777E26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift in Sources */, diff --git a/SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListFlowLayoutSectionController.swift similarity index 69% rename from SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListSectionController.swift rename to SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListFlowLayoutSectionController.swift index c6a06e07..37ff065c 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListSectionController.swift +++ b/SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListFlowLayoutSectionController.swift @@ -8,10 +8,10 @@ import Foundation */ @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) @MainActor -open class FoundationDiffingListSectionController< +open class FoundationDiffingListFlowLayoutSectionController< Model, Item: Hashable ->: ListSectionController { +>: ListFlowLaoutSectionController { override open func calculateUpdate( from oldData: [Item], to newData: [Item] @@ -32,3 +32,12 @@ open class FoundationDiffingListSectionController< ) } } + +@available( + *, + deprecated, + renamed: "FoundationDiffingListFlowLayoutSectionController", + message: "It has been renamed to FoundationDiffingListFlowLayoutSectionController" +) +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public typealias FoundationDiffingListSectionController = FoundationDiffingListFlowLayoutSectionController diff --git a/SectionKit/Tests/SectionController/ListSectionControllerTests.swift b/SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift similarity index 87% rename from SectionKit/Tests/SectionController/ListSectionControllerTests.swift rename to SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift index 4aa22352..194ca9d1 100644 --- a/SectionKit/Tests/SectionController/ListSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift @@ -2,16 +2,16 @@ import XCTest @MainActor -internal final class ListSectionControllerTests: XCTestCase { +internal final class ListFlowLayoutSectionControllerTests: XCTestCase { internal func testDidUpdateModelWithValidTypeSetsModel() { - let sectionController = ListSectionController(model: "1") + let sectionController = ListFlowLaoutSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } internal func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = ListSectionController(model: "1") + let sectionController = ListFlowLaoutSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -33,7 +33,7 @@ internal final class ListSectionControllerTests: XCTestCase { } internal func testInitDoesNotUpdateItemsIfShouldNotUpdateItems() { - class TestSectionController: ListSectionController { + class TestSectionController: ListFlowLaoutSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -57,7 +57,7 @@ internal final class ListSectionControllerTests: XCTestCase { } internal func testSettingModelDoesNotUpdateItemsIfShouldNotUpdateItems() { - class TestSectionController: ListSectionController { + class TestSectionController: ListFlowLaoutSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -84,13 +84,13 @@ internal final class ListSectionControllerTests: XCTestCase { } internal func testShouldUpdateItemsDefaultsToTrue() { - let sectionController = ListSectionController(model: "1") + let sectionController = ListFlowLaoutSectionController(model: "1") XCTAssert(sectionController.shouldUpdateItems(afterModelChangedTo: "2")) } internal func testItemsForModelInvokesNotImplementedError() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = ListSectionController(model: "1") + let sectionController = ListFlowLaoutSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -109,7 +109,7 @@ internal final class ListSectionControllerTests: XCTestCase { } internal func testNumberOfItems() { - let sectionController = ListSectionController(model: "1") + let sectionController = ListFlowLaoutSectionController(model: "1") sectionController.items = ["1", "2"] let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift b/SectionKit/Tests/SectionController/SingleItemFlowLayoutSectionControllerTests.swift similarity index 86% rename from SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift rename to SectionKit/Tests/SectionController/SingleItemFlowLayoutSectionControllerTests.swift index 4077f3ee..53d2ad0b 100644 --- a/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/SingleItemFlowLayoutSectionControllerTests.swift @@ -2,16 +2,16 @@ import XCTest @MainActor -internal final class SingleItemSectionControllerTests: XCTestCase { +internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { internal func testDidUpdateModelWithValidTypeSetsModel() { - let sectionController = SingleItemSectionController(model: "1") + let sectionController = SingleItemFlowLayoutSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } internal func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = SingleItemSectionController(model: "1") + let sectionController = SingleItemFlowLayoutSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -33,7 +33,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testInitDoesNotUpdateItemIfShouldNotUpdateItem() { - class TestSectionController: SingleItemSectionController { + class TestSectionController: SingleItemFlowLayoutSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -57,7 +57,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testSettingModelDoesNotUpdateItemIfShouldNotUpdateItem() { - class TestSectionController: SingleItemSectionController { + class TestSectionController: SingleItemFlowLayoutSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -84,13 +84,13 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testShouldUpdateItemDefaultsToTrue() { - let sectionController = SingleItemSectionController(model: "1") + let sectionController = SingleItemFlowLayoutSectionController(model: "1") XCTAssert(sectionController.shouldUpdateItem(afterModelChangedTo: "2")) } internal func testItemForModelInvokesNotImplementedError() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = SingleItemSectionController(model: "1") + let sectionController = SingleItemFlowLayoutSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -109,7 +109,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToSomeWithEqualItems() throws { - let sectionController = SingleItemSectionController(model: "") + let sectionController = SingleItemFlowLayoutSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -126,7 +126,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { - let sectionController = SingleItemSectionController(model: "") + let sectionController = SingleItemFlowLayoutSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -143,7 +143,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromNoneToSome() throws { - let sectionController = SingleItemSectionController(model: "") + let sectionController = SingleItemFlowLayoutSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: nil, @@ -160,7 +160,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToNone() throws { - let sectionController = SingleItemSectionController(model: "") + let sectionController = SingleItemFlowLayoutSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -177,7 +177,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromNoneToNone() throws { - let sectionController = SingleItemSectionController(model: "") + let sectionController = SingleItemFlowLayoutSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: nil, @@ -194,7 +194,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testNumberOfItemsWithItem() { - let sectionController = SingleItemSectionController(model: "1") + let sectionController = SingleItemFlowLayoutSectionController(model: "1") sectionController.item = "1" let context = MainCollectionViewContext( viewController: nil, @@ -205,7 +205,7 @@ internal final class SingleItemSectionControllerTests: XCTestCase { } internal func testNumberOfItemsWithoutItem() { - let sectionController = SingleItemSectionController(model: "1") + let sectionController = SingleItemFlowLayoutSectionController(model: "1") sectionController.item = nil let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift b/SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift similarity index 84% rename from SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift rename to SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift index 15c142e9..93f50af1 100644 --- a/SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift @@ -2,16 +2,16 @@ import XCTest @MainActor -internal final class SingleModelSectionControllerTests: XCTestCase { +internal final class SingleModelFlowLayoutSectionControllerTests: XCTestCase { internal func testDidUpdateModelWithValidTypeSetsModel() { - let sectionController = SingleModelSectionController(model: "1") + let sectionController = SingleModelFlowLayoutSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } internal func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = SingleModelSectionController(model: "1") + let sectionController = SingleModelFlowLayoutSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -33,7 +33,7 @@ internal final class SingleModelSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { - let sectionController = SingleModelSectionController(model: 1) + let sectionController = SingleModelFlowLayoutSectionController(model: 1) let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -50,7 +50,7 @@ internal final class SingleModelSectionControllerTests: XCTestCase { } internal func testNumberOfItems() { - let sectionController = SingleModelSectionController(model: "1") + let sectionController = SingleModelFlowLayoutSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), From a1baeedbd82ae80e1c59c1fef356069a0e9acf0b Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 14:30:50 +0200 Subject: [PATCH 09/16] merge the section controller with section layout provider and deprecated the old functions --- SectionKit.xcodeproj/project.pbxproj | 84 +++--------- ...istCollectionViewAdapter+Convenience.swift | 12 +- ...ionCollectionViewAdapter+Convenience.swift | 12 +- ...CompositionalLayoutSectionController.swift | 14 -- .../BaseFlowLayoutSectionController.swift | 48 ------- .../ListFlowLaoutSectionController.swift | 122 ------------------ .../Generic/BaseSectionController.swift | 79 ++++++++++++ ...ndationDiffingListSectionController.swift} | 13 +- .../ListSectionController.swift} | 11 +- .../SingleItemSectionController.swift} | 12 +- .../SingleModelSectionController.swift} | 10 +- .../SectionController/SectionController.swift | 52 ++++++-- .../SectionKitCompositionalLayout.swift | 9 +- ...ollectionViewDelegateFlowLayoutTests.swift | 84 ++++++------ ...ListFlowLayoutSectionControllerTests.swift | 16 +-- ...sitionalLayoutSectionControllerTests.swift | 24 ---- ...onControllerSectionFlowDelegateTests.swift | 4 +- ...seFlowLayoutSectionFlowDelegateTests.swift | 4 +- ...efaultValuesSectionFlowDelegateTests.swift | 2 +- ...=> SingleItemSectionControllerTests.swift} | 28 ++-- ...odelFlowLayoutSectionControllerTests.swift | 10 +- .../MockFlowLayoutSectionController.swift | 10 -- .../TestUtilities/MockSectionController.swift | 10 ++ 23 files changed, 259 insertions(+), 411 deletions(-) delete mode 100644 SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift delete mode 100644 SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift delete mode 100644 SectionKit/Sources/SectionController/FlowLayout/ListFlowLaoutSectionController.swift rename SectionKit/Sources/SectionController/{FlowLayout/FoundationDiffingListFlowLayoutSectionController.swift => Generic/FoundationDiffingListSectionController.swift} (69%) rename SectionKit/Sources/SectionController/{CompositionalLayout/ListCompositionalLayoutSectionController.swift => Generic/ListSectionController.swift} (96%) rename SectionKit/Sources/SectionController/{FlowLayout/SingleItemFlowLayoutSectionController.swift => Generic/SingleItemSectionController.swift} (91%) rename SectionKit/Sources/SectionController/{FlowLayout/SingleModelFlowLayoutSectionController.swift => Generic/SingleModelSectionController.swift} (87%) delete mode 100644 SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift rename SectionKit/Tests/SectionController/{SingleItemFlowLayoutSectionControllerTests.swift => SingleItemSectionControllerTests.swift} (86%) delete mode 100644 SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index ed6b3fa6..4f1fc83c 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -34,7 +34,7 @@ 5A0B777C26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */; }; 5A0B777E26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */; }; 5A0B778026B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */; }; - 5A0B778226B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778126B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift */; }; + 5A0B778226B2A92C00B054D4 /* SingleItemSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */; }; 5A0B778426B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */; }; 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */; }; 5A0B778926B3EA4D00B054D4 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */; }; @@ -97,7 +97,6 @@ 5AE175EC2667DA3F00D4DCE1 /* SectionIndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */; }; 5AE175ED2667DA3F00D4DCE1 /* SectionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B32667DA3E00D4DCE1 /* SectionDelegate.swift */; }; 5AE175EE2667DA3F00D4DCE1 /* BaseSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */; }; - 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift */; }; 5AE175F32667DA3F00D4DCE1 /* SectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */; }; 5AE175F42667DA3F00D4DCE1 /* SectionDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BB2667DA3F00D4DCE1 /* SectionDragDelegate.swift */; }; 5AE175F52667DA3F00D4DCE1 /* CollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175BD2667DA3F00D4DCE1 /* CollectionViewAdapter.swift */; }; @@ -127,21 +126,17 @@ 5AE176112667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */; }; 5AE1761B2667DA7000D4DCE1 /* SectionIndexPathTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */; }; 5AE1761E2667DA7000D4DCE1 /* SequenceUniqueTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */; }; - D90764C32BC692BB0083306E /* ListFlowLaoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C02BC692BB0083306E /* ListFlowLaoutSectionController.swift */; }; - D90764C42BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C12BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift */; }; - D90764C52BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C22BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift */; }; + D90764CA2BC6B9120083306E /* FoundationDiffingListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C62BC6B9120083306E /* FoundationDiffingListSectionController.swift */; }; + D90764CB2BC6B9120083306E /* ListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C72BC6B9120083306E /* ListSectionController.swift */; }; + D90764CC2BC6B9120083306E /* SingleModelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C82BC6B9120083306E /* SingleModelSectionController.swift */; }; + D90764CD2BC6B9120083306E /* SingleItemSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C92BC6B9120083306E /* SingleItemSectionController.swift */; }; D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */; }; - D91425692BBBF79E0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */; }; D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */; }; - D91425822BBBF8780005E8CD /* MockFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425802BBBF8670005E8CD /* MockFlowLayoutSectionController.swift */; }; D91425852BBBFB840005E8CD /* ListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CE2667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift */; }; - D91425862BBBFB930005E8CD /* BaseFlowLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9B72BADF31D00EED204 /* BaseFlowLayoutSectionController.swift */; }; D91425872BBBFBA40005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */; }; D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CA2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift */; }; D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C92667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift */; }; D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift */; }; - D941851A2BBC123C001B5086 /* ListCompositionalLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425622BBBF7320005E8CD /* ListCompositionalLayoutSectionController.swift */; }; - D9CCE9B52BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9B42BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift */; }; D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */; }; /* End PBXBuildFile section */ @@ -183,7 +178,7 @@ 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewSectionBatchOperationTests.swift; sourceTree = ""; }; 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewBatchOperationTests.swift; sourceTree = ""; }; 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; - 5A0B778126B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleItemFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; + 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleItemSectionControllerTests.swift; sourceTree = ""; }; 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleModelFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerTests.swift; sourceTree = ""; }; 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = ""; }; @@ -249,7 +244,6 @@ 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionIndexPath.swift; sourceTree = ""; }; 5AE175B32667DA3E00D4DCE1 /* SectionDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDelegate.swift; sourceTree = ""; }; 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseSectionController.swift; sourceTree = ""; }; - 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDiffingListFlowLayoutSectionController.swift; sourceTree = ""; }; 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionController.swift; sourceTree = ""; }; 5AE175BB2667DA3F00D4DCE1 /* SectionDragDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionDragDelegate.swift; sourceTree = ""; }; 5AE175BD2667DA3F00D4DCE1 /* CollectionViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewAdapter.swift; sourceTree = ""; }; @@ -283,17 +277,13 @@ 5AE175DD2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleSectionCollectionViewAdapter.swift; sourceTree = ""; }; 5AE176132667DA7000D4DCE1 /* SectionIndexPathTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionIndexPathTests.swift; sourceTree = ""; }; 5AE176182667DA7000D4DCE1 /* SequenceUniqueTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SequenceUniqueTests.swift; sourceTree = ""; }; - D90764C02BC692BB0083306E /* ListFlowLaoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListFlowLaoutSectionController.swift; sourceTree = ""; }; - D90764C12BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelFlowLayoutSectionController.swift; sourceTree = ""; }; - D90764C22BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleItemFlowLayoutSectionController.swift; sourceTree = ""; }; - D91425622BBBF7320005E8CD /* ListCompositionalLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListCompositionalLayoutSectionController.swift; sourceTree = ""; }; + D90764C62BC6B9120083306E /* FoundationDiffingListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationDiffingListSectionController.swift; sourceTree = ""; }; + D90764C72BC6B9120083306E /* ListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListSectionController.swift; sourceTree = ""; }; + D90764C82BC6B9120083306E /* SingleModelSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelSectionController.swift; sourceTree = ""; }; + D90764C92BC6B9120083306E /* SingleItemSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleItemSectionController.swift; sourceTree = ""; }; D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionKitCompositionalLayout.swift; sourceTree = ""; }; - D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseCompositionalLayoutSectionControllerTests.swift; sourceTree = ""; }; D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionFlowDelegateTests.swift; sourceTree = ""; }; D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift; sourceTree = ""; }; - D91425802BBBF8670005E8CD /* MockFlowLayoutSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MockFlowLayoutSectionController.swift; sourceTree = ""; }; - D9CCE9B42BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseCompositionalLayoutSectionController.swift; sourceTree = ""; }; - D9CCE9B72BADF31D00EED204 /* BaseFlowLayoutSectionController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionController.swift; sourceTree = ""; }; D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSCollectionLayoutSection+Empty.swift"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -482,7 +472,6 @@ 5AA9D95126AAA5E000679D88 /* MockCollectionViewCell.swift */, 5A8D3E5327E8D0E200073712 /* MockCollectionViewContext.swift */, 5AA9D95526AAA61700679D88 /* MockErrorHandler.swift */, - D91425802BBBF8670005E8CD /* MockFlowLayoutSectionController.swift */, 5A0B776F26B19EB300B054D4 /* MockListCollectionViewAdapterDataSource.swift */, 5A0B775326AFF4D500B054D4 /* MockScrollViewDelegate.swift */, 5AB6644A26A86F7A004DC230 /* MockSectionController.swift */, @@ -561,8 +550,6 @@ isa = PBXGroup; children = ( D9CCE9B62BADF2FD00EED204 /* Generic */, - D9CCE9B32BADED5B00EED204 /* CompositionalLayout */, - D9CCE9B22BADED3D00EED204 /* FlowLayout */, 5AE175AD2667DA3E00D4DCE1 /* Update */, 5AE175B22667DA3E00D4DCE1 /* SectionIndexPath.swift */, 5AE175BA2667DA3F00D4DCE1 /* SectionController.swift */, @@ -657,7 +644,6 @@ 5AE176122667DA7000D4DCE1 /* SectionController */ = { isa = PBXGroup; children = ( - D91425672BBBF77C0005E8CD /* SectionCompositionalLayout */, 5A31B8AF26BAE81000036A3F /* SectionDataSource */, 5A31B8B026BAE82200036A3F /* SectionDataSourcePrefetchingDelegate */, 5A31B8B126BAE82D00036A3F /* SectionDelegate */, @@ -669,7 +655,7 @@ 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */, 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */, 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */, - 5A0B778126B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift */, + 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */, 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */, ); path = SectionController; @@ -705,39 +691,14 @@ path = CollectionViewAdapter; sourceTree = ""; }; - D91425672BBBF77C0005E8CD /* SectionCompositionalLayout */ = { - isa = PBXGroup; - children = ( - D91425662BBBF77C0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift */, - ); - path = SectionCompositionalLayout; - sourceTree = ""; - }; - D9CCE9B22BADED3D00EED204 /* FlowLayout */ = { - isa = PBXGroup; - children = ( - D9CCE9B72BADF31D00EED204 /* BaseFlowLayoutSectionController.swift */, - D90764C02BC692BB0083306E /* ListFlowLaoutSectionController.swift */, - D90764C22BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift */, - D90764C12BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift */, - 5AE175B92667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift */, - ); - path = FlowLayout; - sourceTree = ""; - }; - D9CCE9B32BADED5B00EED204 /* CompositionalLayout */ = { - isa = PBXGroup; - children = ( - D9CCE9B42BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift */, - D91425622BBBF7320005E8CD /* ListCompositionalLayoutSectionController.swift */, - ); - path = CompositionalLayout; - sourceTree = ""; - }; D9CCE9B62BADF2FD00EED204 /* Generic */ = { isa = PBXGroup; children = ( 5AE175B52667DA3E00D4DCE1 /* BaseSectionController.swift */, + D90764C72BC6B9120083306E /* ListSectionController.swift */, + D90764C92BC6B9120083306E /* SingleItemSectionController.swift */, + D90764C82BC6B9120083306E /* SingleModelSectionController.swift */, + D90764C62BC6B9120083306E /* FoundationDiffingListSectionController.swift */, ); path = Generic; sourceTree = ""; @@ -865,6 +826,7 @@ 5AE1760B2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDropDelegate.swift in Sources */, 5AE176072667DA3F00D4DCE1 /* Section.swift in Sources */, 5AE175DF2667DA3F00D4DCE1 /* CollectionDifference+Changes.swift in Sources */, + D90764CB2BC6B9120083306E /* ListSectionController.swift in Sources */, 5AE175E62667DA3F00D4DCE1 /* SectionDataSource.swift in Sources */, 5AE176002667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegateFlowLayout.swift in Sources */, 5AE1760D2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */, @@ -872,29 +834,24 @@ 5AE175F42667DA3F00D4DCE1 /* SectionDragDelegate.swift in Sources */, 5AE176062667DA3F00D4DCE1 /* ListCollectionViewAdapterDataSource.swift in Sources */, 5AE175F62667DA3F00D4DCE1 /* CollectionViewContext+Size.swift in Sources */, + D90764CA2BC6B9120083306E /* FoundationDiffingListSectionController.swift in Sources */, D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, - D9CCE9B52BADED9400EED204 /* BaseCompositionalLayoutSectionController.swift in Sources */, 5AE175F52667DA3F00D4DCE1 /* CollectionViewAdapter.swift in Sources */, 5AE175F32667DA3F00D4DCE1 /* SectionController.swift in Sources */, - 5AE175F22667DA3F00D4DCE1 /* FoundationDiffingListFlowLayoutSectionController.swift in Sources */, D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */, 5AB6644626A854A9004DC230 /* ErrorHandling.swift in Sources */, 5AE176052667DA3F00D4DCE1 /* FoundationDiffingListCollectionViewAdapter.swift in Sources */, 5AE175E92667DA3F00D4DCE1 /* CollectionViewSectionBatchOperation.swift in Sources */, - D90764C42BC692BB0083306E /* SingleModelFlowLayoutSectionController.swift in Sources */, 5AE175E02667DA3F00D4DCE1 /* Move.swift in Sources */, + D90764CC2BC6B9120083306E /* SingleModelSectionController.swift in Sources */, 5AE175EB2667DA3F00D4DCE1 /* SectionDataSourcePrefetchingDelegate.swift in Sources */, 5AE175EC2667DA3F00D4DCE1 /* SectionIndexPath.swift in Sources */, 5AE1760F2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */, 5AE1760A2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */, 5AE175FB2667DA3F00D4DCE1 /* CollectionViewUpdate.swift in Sources */, - D90764C32BC692BB0083306E /* ListFlowLaoutSectionController.swift in Sources */, - D941851A2BBC123C001B5086 /* ListCompositionalLayoutSectionController.swift in Sources */, 5AE175E42667DA3F00D4DCE1 /* Collection+Extensions.swift in Sources */, 5AE175E12667DA3F00D4DCE1 /* IndexPath+IsValid.swift in Sources */, 5AE175F82667DA3F00D4DCE1 /* MainCollectionViewContext.swift in Sources */, - D90764C52BC692BB0083306E /* SingleItemFlowLayoutSectionController.swift in Sources */, - D91425862BBBFB930005E8CD /* BaseFlowLayoutSectionController.swift in Sources */, D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */, 5AE176102667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter+Convenience.swift in Sources */, 5AE175DE2667DA3F00D4DCE1 /* Sequence+Unique.swift in Sources */, @@ -913,6 +870,7 @@ 5AE175E72667DA3F00D4DCE1 /* SectionFlowDelegate.swift in Sources */, 5AE175E32667DA3F00D4DCE1 /* UICollectionView+Apply.swift in Sources */, 5AE176012667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDelegate.swift in Sources */, + D90764CD2BC6B9120083306E /* SingleItemSectionController.swift in Sources */, 5AE1760E2667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapterDataSource.swift in Sources */, 5AE176112667DA3F00D4DCE1 /* SingleSectionCollectionViewAdapter.swift in Sources */, D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */, @@ -969,7 +927,6 @@ 5A0B778926B3EA4D00B054D4 /* ErrorTests.swift in Sources */, 5A31B8E226BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift in Sources */, 5AA9D95426AAA5EA00679D88 /* MockCollectionReusableView.swift in Sources */, - D91425822BBBF8780005E8CD /* MockFlowLayoutSectionController.swift in Sources */, 5A0B777C26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift in Sources */, 5A0B774526AED0F600B054D4 /* BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift in Sources */, 5A31B8C326BAE90300036A3F /* BaseSectionDelegateTests.swift in Sources */, @@ -992,11 +949,10 @@ 5A31B8CD26BAE92D00036A3F /* ProtocolDefaultValuesSectionDragDelegateTests.swift in Sources */, 5A0B774726AEE24700B054D4 /* MockSectionFlowDelegate.swift in Sources */, 5AA9D95826AAA65900679D88 /* ListCollectionViewAdapterUICollectionViewDataSourceTests.swift in Sources */, - D91425692BBBF79E0005E8CD /* BaseCompositionalLayoutSectionControllerTests.swift in Sources */, 5AB6644926A86F4D004DC230 /* MockSectionDataSource.swift in Sources */, 5A31B8D126BAE94500036A3F /* BaseSectionControllerSectionDropDelegateTests.swift in Sources */, 5A31B8C526BAE90B00036A3F /* BaseSectionControllerSectionDelegateTests.swift in Sources */, - 5A0B778226B2A92C00B054D4 /* SingleItemFlowLayoutSectionControllerTests.swift in Sources */, + 5A0B778226B2A92C00B054D4 /* SingleItemSectionControllerTests.swift in Sources */, 5A8D3E5527E8D11600073712 /* MockCollectionViewContext.swift in Sources */, 5A8D3E5727E8D14700073712 /* MockCollectionView.swift in Sources */, 5A0B777E26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift in Sources */, diff --git a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift index 9b1f82ab..ca76b284 100644 --- a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift @@ -58,12 +58,20 @@ extension ListCollectionViewAdapter { extension ListCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { - (controller(at: indexPath) as? FlowLayoutSectionController)?.flowDelegate + if #available(iOS 13.0, *) { + controller(at: indexPath)?.layoutProvider?.flowLayoutProvider + } else { + controller(at: indexPath)?.flowDelegate + } } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { - (controller(at: index) as? FlowLayoutSectionController)?.flowDelegate + if #available(iOS 13.0, *) { + controller(at: index)?.layoutProvider?.flowLayoutProvider + } else { + controller(at: index)?.flowDelegate + } } } diff --git a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift index 4fb424e7..5dbeb43e 100644 --- a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift @@ -58,12 +58,20 @@ extension SingleSectionCollectionViewAdapter { extension SingleSectionCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { - (controller(at: indexPath) as? FlowLayoutSectionController)?.flowDelegate + if #available(iOS 13.0, *) { + controller(at: indexPath)?.layoutProvider?.flowLayoutProvider + } else { + controller(at: indexPath)?.flowDelegate + } } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { - (controller(at: index) as? FlowLayoutSectionController)?.flowDelegate + if #available(iOS 13.0, *) { + controller(at: index)?.layoutProvider?.flowLayoutProvider + } else { + controller(at: index)?.flowDelegate + } } } diff --git a/SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift b/SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift deleted file mode 100644 index 7c2b5162..00000000 --- a/SectionKit/Sources/SectionController/CompositionalLayout/BaseCompositionalLayoutSectionController.swift +++ /dev/null @@ -1,14 +0,0 @@ -import UIKit - -/// This is a foundational implementation of `CompositionalLayoutSectionController`, adding the compositional layout section delegate function while inheriting from the `BaseSectionController`. -@MainActor -@available(iOS 13.0, *) -open class BaseCompositionalLayoutSectionController: BaseSectionController, - CompositionalLayoutSectionController { - open func layoutSection( - layoutEnvironment: any NSCollectionLayoutEnvironment - ) -> NSCollectionLayoutSection { - context?.errorHandler.nonCritical(error: .notImplemented()) - return .empty - } -} diff --git a/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift deleted file mode 100644 index 07ee64a4..00000000 --- a/SectionKit/Sources/SectionController/FlowLayout/BaseFlowLayoutSectionController.swift +++ /dev/null @@ -1,48 +0,0 @@ -import UIKit - -/// This is a foundational implementation of `FlowLayoutSectionController`, implementing the flow layout delegate while inheriting from the `BaseSectionController`. -@MainActor -open class BaseFlowLayoutSectionController: BaseSectionController, - SectionFlowDelegate, - FlowLayoutSectionController { - open var flowDelegate: SectionFlowDelegate? { self } - - // MARK: - SectionFlowDelegate - - open func sizeForItem( - at indexPath: SectionIndexPath, - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGSize { - layout.flowLayout?.itemSize ?? FlowLayoutConstants.defaultItemSize - } - - open func inset(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> UIEdgeInsets { - layout.flowLayout?.sectionInset ?? FlowLayoutConstants.defaultInset - } - - open func minimumLineSpacing(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGFloat { - layout.flowLayout?.minimumLineSpacing ?? FlowLayoutConstants.defaultMinimumLineSpacing - } - - open func minimumInteritemSpacing( - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGFloat { - layout.flowLayout?.minimumInteritemSpacing ?? FlowLayoutConstants.defaultMinimumInteritemSpacing - } - - open func referenceSizeForHeader( - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGSize { - layout.flowLayout?.headerReferenceSize ?? FlowLayoutConstants.defaultHeaderSize - } - - open func referenceSizeForFooter( - using layout: UICollectionViewLayout, - in context: CollectionViewContext - ) -> CGSize { - layout.flowLayout?.footerReferenceSize ?? FlowLayoutConstants.defaultFooterSize - } -} diff --git a/SectionKit/Sources/SectionController/FlowLayout/ListFlowLaoutSectionController.swift b/SectionKit/Sources/SectionController/FlowLayout/ListFlowLaoutSectionController.swift deleted file mode 100644 index a3f016d4..00000000 --- a/SectionKit/Sources/SectionController/FlowLayout/ListFlowLaoutSectionController.swift +++ /dev/null @@ -1,122 +0,0 @@ -import UIKit - -/** - A `SectionController` that contains a list of items. Changes to that list will result in a call to - `reloadSections(_:)` on the underlying `UICollectionView`. - - This `SectionController` is typically used when there are multiple semantically similar items - of a model to be displayed and the list of items (almost) never changes or should not perform animated updates. - */ -@MainActor -open class ListFlowLaoutSectionController: BaseFlowLayoutSectionController { - /** - Initialise an instance of `ListSectionController`. - - - Parameter model: The model of this `SectionController`. - */ - public init(model: Model) { - self.model = model - super.init() - if shouldUpdateItems(afterModelChangedTo: model) { - items = items(for: model) - } - } - - override open func didUpdate(model: Any) { - guard let model = model as? Model else { - context?.errorHandler.nonCritical( - error: .sectionControllerModelTypeMismatch( - expected: Model.self, - actual: type(of: model) - ) - ) - return - } - self.model = model - } - - /// The model of this `SectionController`. - open var model: Model { - didSet { - if shouldUpdateItems(afterModelChangedTo: model) { - items = items(for: model) - } - } - } - - /** - Determines if the list of items should be updated after the model was updated to a new value. - - The default value is `true`. - - - Parameter model: The new value of the model. - - - Returns: If the list of items should be updated after the model was updated to a new value. - */ - open func shouldUpdateItems(afterModelChangedTo model: Model) -> Bool { true } - - /** - Derives a list of items from the given `Model`. - - Will be called automatically if `shouldUpdateItems(afterModelChangedTo:)` returned `true`. - - - Parameter model: The new value of the model. - - - Returns: The new items to be displayed in this section. - */ - open func items(for model: Model) -> [Item] { - context?.errorHandler.nonCritical(error: .notImplemented()) - return [] - } - - /** - The list of items currently displayed in the `UICollectionView`. - - Only set this property if `UICollectionView` insertions and deletions are handled, otherwise use `items` instead. - */ - open var collectionViewItems: [Item] = [] - - /// The items of this section. - open var items: [Item] { - get { collectionViewItems } - set { - guard let context = context else { - collectionViewItems = newValue - return - } - if let sectionUpdate = calculateUpdate(from: collectionViewItems, to: newValue) { - context.apply(update: sectionUpdate) - } - } - } - - /** - Calculate the `UICollectionView` events using the difference from the old to the new data. - - - Parameter oldData: The old data currently displayed in the section. - - - Parameter newData: The new data that should be displayed in the section. - - - Returns: The update that should be performed on the section. - */ - open func calculateUpdate( - from oldData: [Item], - to newData: [Item] - ) -> CollectionViewSectionUpdate<[Item]>? { - CollectionViewSectionUpdate( - controller: self, - data: newData, - setData: { self.collectionViewItems = $0 } - ) - } - - override open func numberOfItems(in context: CollectionViewContext) -> Int { items.count } -} - -@available( - *, - deprecated, - renamed: "ListFlowLaoutSectionController", - message: "It has been renamed to ListFlowLaoutSectionController" -) -public typealias ListSectionController = ListFlowLaoutSectionController diff --git a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift index bb1b7151..e39f9e5d 100644 --- a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift @@ -8,6 +8,7 @@ open class BaseSectionController: SectionController, SectionDataSource, SectionDataSourcePrefetchingDelegate, SectionDelegate, + SectionFlowDelegate, SectionDragDelegate, SectionDropDelegate { // MARK: - Init @@ -31,6 +32,9 @@ open class BaseSectionController: SectionController, @available(iOS 11.0, *) open var dropDelegate: SectionDropDelegate? { self } + @available(iOS 13.0, *) + open var layoutProvider: SectionLayoutProvider? { .flowLayout(self) } + open func didUpdate(model: Any) { } // MARK: - SectionDataSource @@ -221,6 +225,81 @@ open class BaseSectionController: SectionController, nil } + // MARK: - SectionFlowDelegate + + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) + open func sizeForItem( + at indexPath: SectionIndexPath, + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGSize { + layout.flowLayout?.itemSize ?? FlowLayoutConstants.defaultItemSize + } + + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) + open func inset(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> UIEdgeInsets { + layout.flowLayout?.sectionInset ?? FlowLayoutConstants.defaultInset + } + + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) + open func minimumLineSpacing(using layout: UICollectionViewLayout, in context: CollectionViewContext) -> CGFloat { + layout.flowLayout?.minimumLineSpacing ?? FlowLayoutConstants.defaultMinimumLineSpacing + } + + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) + open func minimumInteritemSpacing( + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGFloat { + layout.flowLayout?.minimumInteritemSpacing ?? FlowLayoutConstants.defaultMinimumInteritemSpacing + } + + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) + open func referenceSizeForHeader( + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGSize { + layout.flowLayout?.headerReferenceSize ?? FlowLayoutConstants.defaultHeaderSize + } + + @available( + iOS, + introduced: 6.0, + deprecated: 13.0, + message: "Please use the layoutProvider with the flowLayout type" + ) + open func referenceSizeForFooter( + using layout: UICollectionViewLayout, + in context: CollectionViewContext + ) -> CGSize { + layout.flowLayout?.footerReferenceSize ?? FlowLayoutConstants.defaultFooterSize + } + // MARK: - SectionDropDelegate @available(iOS 11.0, *) diff --git a/SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListFlowLayoutSectionController.swift b/SectionKit/Sources/SectionController/Generic/FoundationDiffingListSectionController.swift similarity index 69% rename from SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListFlowLayoutSectionController.swift rename to SectionKit/Sources/SectionController/Generic/FoundationDiffingListSectionController.swift index 37ff065c..c6a06e07 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/FoundationDiffingListFlowLayoutSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/FoundationDiffingListSectionController.swift @@ -8,10 +8,10 @@ import Foundation */ @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) @MainActor -open class FoundationDiffingListFlowLayoutSectionController< +open class FoundationDiffingListSectionController< Model, Item: Hashable ->: ListFlowLaoutSectionController { +>: ListSectionController { override open func calculateUpdate( from oldData: [Item], to newData: [Item] @@ -32,12 +32,3 @@ open class FoundationDiffingListFlowLayoutSectionController< ) } } - -@available( - *, - deprecated, - renamed: "FoundationDiffingListFlowLayoutSectionController", - message: "It has been renamed to FoundationDiffingListFlowLayoutSectionController" -) -@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -public typealias FoundationDiffingListSectionController = FoundationDiffingListFlowLayoutSectionController diff --git a/SectionKit/Sources/SectionController/CompositionalLayout/ListCompositionalLayoutSectionController.swift b/SectionKit/Sources/SectionController/Generic/ListSectionController.swift similarity index 96% rename from SectionKit/Sources/SectionController/CompositionalLayout/ListCompositionalLayoutSectionController.swift rename to SectionKit/Sources/SectionController/Generic/ListSectionController.swift index fcaf743a..cc216a4b 100644 --- a/SectionKit/Sources/SectionController/CompositionalLayout/ListCompositionalLayoutSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/ListSectionController.swift @@ -8,8 +8,7 @@ import UIKit of a model to be displayed and the list of items (almost) never changes or should not perform animated updates. */ @MainActor -@available(iOS 13.0, *) -open class ListCompositionalLayoutSectionController: BaseCompositionalLayoutSectionController { +open class ListSectionController: BaseSectionController { /** Initialise an instance of `ListSectionController`. @@ -72,7 +71,7 @@ open class ListCompositionalLayoutSectionController: BaseCompositio /** The list of items currently displayed in the `UICollectionView`. - + Only set this property if `UICollectionView` insertions and deletions are handled, otherwise use `items` instead. */ open var collectionViewItems: [Item] = [] @@ -93,11 +92,11 @@ open class ListCompositionalLayoutSectionController: BaseCompositio /** Calculate the `UICollectionView` events using the difference from the old to the new data. - + - Parameter oldData: The old data currently displayed in the section. - + - Parameter newData: The new data that should be displayed in the section. - + - Returns: The update that should be performed on the section. */ open func calculateUpdate( diff --git a/SectionKit/Sources/SectionController/FlowLayout/SingleItemFlowLayoutSectionController.swift b/SectionKit/Sources/SectionController/Generic/SingleItemSectionController.swift similarity index 91% rename from SectionKit/Sources/SectionController/FlowLayout/SingleItemFlowLayoutSectionController.swift rename to SectionKit/Sources/SectionController/Generic/SingleItemSectionController.swift index 7ecb9e77..e003fff9 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/SingleItemFlowLayoutSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/SingleItemSectionController.swift @@ -9,7 +9,7 @@ import UIKit - Warning: If `numberOfItems` is overridden, `calculateUpdate(from:to:)` needs to be overridden as well. */ @MainActor -open class SingleItemFlowLayoutSectionController: BaseFlowLayoutSectionController { +open class SingleItemSectionController: BaseSectionController { private let areItemsEqual: @MainActor (Item, Item) -> Bool /** @@ -133,7 +133,7 @@ open class SingleItemFlowLayoutSectionController: BaseFlowLayoutSec override open func numberOfItems(in context: CollectionViewContext) -> Int { item != nil ? 1 : 0 } } -extension SingleItemFlowLayoutSectionController where Item: Equatable { +extension SingleItemSectionController where Item: Equatable { /** Initialise an instance of `SingleItemSectionController` which will only reload when the new item is different from the old one. @@ -144,11 +144,3 @@ extension SingleItemFlowLayoutSectionController where Item: Equatable { self.init(model: model, areItemsEqual: ==) } } - -@available( - *, - deprecated, - renamed: "SingleItemFlowLayoutSectionController", - message: "It has been renamed to SingleItemFlowLayoutSectionController" -) -public typealias SingleItemSectionController = SingleItemFlowLayoutSectionController diff --git a/SectionKit/Sources/SectionController/FlowLayout/SingleModelFlowLayoutSectionController.swift b/SectionKit/Sources/SectionController/Generic/SingleModelSectionController.swift similarity index 87% rename from SectionKit/Sources/SectionController/FlowLayout/SingleModelFlowLayoutSectionController.swift rename to SectionKit/Sources/SectionController/Generic/SingleModelSectionController.swift index 4a563ab6..143408d1 100644 --- a/SectionKit/Sources/SectionController/FlowLayout/SingleModelFlowLayoutSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/SingleModelSectionController.swift @@ -9,7 +9,7 @@ import UIKit it is recommended to use `ListSectionController` instead. */ @MainActor -open class SingleModelFlowLayoutSectionController: BaseFlowLayoutSectionController { +open class SingleModelSectionController: BaseSectionController { /** Initialise an instance of `SingleModelSectionController`. @@ -76,11 +76,3 @@ open class SingleModelFlowLayoutSectionController: BaseFlowLayoutSectionC override open func numberOfItems(in context: CollectionViewContext) -> Int { 1 } } - -@available( - *, - deprecated, - renamed: "SingleModelFlowLayoutSectionController", - message: "It has been renamed to SingleModelFlowLayoutSectionController" -) -public typealias SingleModelSectionController = SingleModelFlowLayoutSectionController diff --git a/SectionKit/Sources/SectionController/SectionController.swift b/SectionKit/Sources/SectionController/SectionController.swift index 78e14e54..b49bb6fd 100644 --- a/SectionKit/Sources/SectionController/SectionController.swift +++ b/SectionKit/Sources/SectionController/SectionController.swift @@ -16,6 +16,9 @@ public protocol SectionController: AnyObject { /// The delegate of this section. var delegate: SectionDelegate? { get } + /// The delegate for the `UICollectionViewFlowLayout` of this section. + var flowDelegate: SectionFlowDelegate? { get } + /// The drag delegate of this section. @available(iOS 11.0, *) var dragDelegate: SectionDragDelegate? { get } @@ -24,6 +27,9 @@ public protocol SectionController: AnyObject { @available(iOS 11.0, *) var dropDelegate: SectionDropDelegate? { get } + @available(iOS 13.0, *) + var layoutProvider: SectionLayoutProvider? { get } + /// The model of this section controller changed. func didUpdate(model: Any) } @@ -34,27 +40,55 @@ extension SectionController { public var delegate: SectionDelegate? { nil } + public var flowDelegate: SectionFlowDelegate? { nil } + @available(iOS 11.0, *) public var dragDelegate: SectionDragDelegate? { nil } @available(iOS 11.0, *) public var dropDelegate: SectionDropDelegate? { nil } + + @available(iOS 13.0, *) + public var layoutProvider: SectionLayoutProvider? { nil } } -@MainActor -public protocol FlowLayoutSectionController: SectionController { - /// The delegate for the `UICollectionViewFlowLayout` of this section. - var flowDelegate: SectionFlowDelegate? { get } +@available(iOS 13.0, *) +public enum SectionLayoutProvider { + case flowLayout(FlowLayoutProvider) + case compositionalLayout(CompositionalLayoutProvider) } +public typealias FlowLayoutProvider = SectionFlowDelegate + @MainActor -public protocol CompositionalLayoutSectionController: SectionController { +@available(iOS 13.0, *) +public struct CompositionalLayoutProvider { /// Provide the layout section for the Compositional Layout /// - Parameters: /// - layoutEnvironment: the environment value for the layout /// - Returns: The layout for the section - @available(iOS 13.0, *) - func layoutSection( - layoutEnvironment: NSCollectionLayoutEnvironment - ) -> NSCollectionLayoutSection + var layoutSection: (_ layoutEnvironment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection + + public init( + layoutSection: @escaping (any NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection + ) { + self.layoutSection = layoutSection + } +} + +@available(iOS 13.0, *) +public extension SectionLayoutProvider { + var flowLayoutProvider: FlowLayoutProvider? { + guard case .flowLayout(let flowLayoutProvider) = self else { + return nil + } + return flowLayoutProvider + } + + var compositionalLayoutProvider: CompositionalLayoutProvider? { + guard case .compositionalLayout(let compositionalLayoutProvider) = self else { + return nil + } + return compositionalLayoutProvider + } } diff --git a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift index b033cccf..8c119562 100644 --- a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift +++ b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift @@ -19,14 +19,11 @@ final public class SectionKitCompositionalLayout: UICollectionViewCompositionalL assertionFailure("Section index out of bound") return .empty } - guard let compositionalLayoutSectionController = sections[index].controller - as? BaseCompositionalLayoutSectionController else { - assertionFailure("Please use the `CompositionalLayoutSectionControler`") + guard case .compositionalLayout(let provider) = sections[index].controller.layoutProvider else { + assertionFailure("Please set the layout provider with `CompositionalLayoutProvider`") return .empty } - return compositionalLayoutSectionController.layoutSection( - layoutEnvironment: environment - ) + return provider.layoutSection(environment) } sections = { [weak self] in self?.sections?() ?? [] diff --git a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift index 121bd8c5..ace37e1c 100644 --- a/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift +++ b/SectionKit/Tests/CollectionViewAdapter/UICollectionViewDelegateFlowLayout/BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests.swift @@ -44,8 +44,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = { + let sectionController = MockSectionController() + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._sizeForItem = { indexPath, layout, _ in XCTAssertEqual(indexPath.indexInCollectionView, itemIndexPath) @@ -53,7 +53,7 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: testExpectation.fulfill() return itemSize } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -77,8 +77,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -98,8 +98,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -122,15 +122,15 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = { + let sectionController = MockSectionController() + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._inset = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return sectionInset } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -153,8 +153,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -173,8 +173,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -197,15 +197,15 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = { + let sectionController = MockSectionController() + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._minimumLineSpacing = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return lineSpacing } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -228,8 +228,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -248,8 +248,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -272,15 +272,15 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = { + let sectionController = MockSectionController() + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._minimumInteritemSpacing = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return interitemSpacing } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -303,8 +303,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -323,8 +323,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -347,15 +347,15 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = { + let sectionController = MockSectionController() + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._referenceSizeForHeader = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return headerSize } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -378,8 +378,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -398,8 +398,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -422,15 +422,15 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = { + let sectionController = MockSectionController() + sectionController.layoutProvider = { let flowDelegate = MockSectionFlowDelegate() flowDelegate._referenceSizeForFooter = { layout, _ in XCTAssert(layout === mockLayout) testExpectation.fulfill() return footerSize } - return flowDelegate + return .flowLayout(flowDelegate) }() return sectionController }) @@ -453,8 +453,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] @@ -473,8 +473,8 @@ internal class BaseCollectionViewAdapterUICollectionViewDelegateFlowLayoutTests: collectionView: collectionView, sections: [ Section(id: "", model: "", controller: { - let sectionController = MockFlowLayoutSectionController() - sectionController.flowDelegate = nil + let sectionController = MockSectionController() + sectionController.layoutProvider = nil return sectionController }) ] diff --git a/SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift index 194ca9d1..4aa22352 100644 --- a/SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift @@ -2,16 +2,16 @@ import XCTest @MainActor -internal final class ListFlowLayoutSectionControllerTests: XCTestCase { +internal final class ListSectionControllerTests: XCTestCase { internal func testDidUpdateModelWithValidTypeSetsModel() { - let sectionController = ListFlowLaoutSectionController(model: "1") + let sectionController = ListSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } internal func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = ListFlowLaoutSectionController(model: "1") + let sectionController = ListSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -33,7 +33,7 @@ internal final class ListFlowLayoutSectionControllerTests: XCTestCase { } internal func testInitDoesNotUpdateItemsIfShouldNotUpdateItems() { - class TestSectionController: ListFlowLaoutSectionController { + class TestSectionController: ListSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -57,7 +57,7 @@ internal final class ListFlowLayoutSectionControllerTests: XCTestCase { } internal func testSettingModelDoesNotUpdateItemsIfShouldNotUpdateItems() { - class TestSectionController: ListFlowLaoutSectionController { + class TestSectionController: ListSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -84,13 +84,13 @@ internal final class ListFlowLayoutSectionControllerTests: XCTestCase { } internal func testShouldUpdateItemsDefaultsToTrue() { - let sectionController = ListFlowLaoutSectionController(model: "1") + let sectionController = ListSectionController(model: "1") XCTAssert(sectionController.shouldUpdateItems(afterModelChangedTo: "2")) } internal func testItemsForModelInvokesNotImplementedError() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = ListFlowLaoutSectionController(model: "1") + let sectionController = ListSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -109,7 +109,7 @@ internal final class ListFlowLayoutSectionControllerTests: XCTestCase { } internal func testNumberOfItems() { - let sectionController = ListFlowLaoutSectionController(model: "1") + let sectionController = ListSectionController(model: "1") sectionController.items = ["1", "2"] let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift deleted file mode 100644 index 528568ba..00000000 --- a/SectionKit/Tests/SectionController/SectionCompositionalLayout/BaseCompositionalLayoutSectionControllerTests.swift +++ /dev/null @@ -1,24 +0,0 @@ -@testable import SectionKit -import XCTest - -final class BaseCompositionalLayoutSectionControllerTests: XCTestCase { - final class TestLayoutEnvironment: NSObject, NSCollectionLayoutEnvironment { - final class TestLayoutContainer: NSObject, NSCollectionLayoutContainer { - let contentSize: CGSize = .zero - let effectiveContentSize: CGSize = .zero - let contentInsets: NSDirectionalEdgeInsets = .zero - let effectiveContentInsets: NSDirectionalEdgeInsets = .zero - } - let container: NSCollectionLayoutContainer = TestLayoutContainer() - let traitCollection: UITraitCollection = .current - } - - @MainActor - func test_layout_isEmpty() { - let sut = BaseCompositionalLayoutSectionController() - let layoutSection = sut.layoutSection( - layoutEnvironment: TestLayoutEnvironment() - ) - XCTAssertEqual(layoutSection, .empty) - } -} diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift index 4710fa1d..aab5c664 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift @@ -1,9 +1,9 @@ import SectionKit import XCTest -internal final class BaseFlowLayoutSectionControllerSectionFlowDelegateTests: BaseFlowLayoutSectionFlowDelegateTests { +internal final class BaseSectionControllerSectionFlowDelegateTests: BaseSectionFlowDelegateTests { @MainActor override func createSectionFlowDelegate() throws -> SectionFlowDelegate { - BaseFlowLayoutSectionController() + BaseSectionController() } } diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift index 526003c5..33c25f83 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/BaseFlowLayoutSectionFlowDelegateTests.swift @@ -1,7 +1,7 @@ import SectionKit import XCTest -internal class BaseFlowLayoutSectionFlowDelegateTests: XCTestCase { +internal class BaseSectionFlowDelegateTests: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() continueAfterFailure = false @@ -9,7 +9,7 @@ internal class BaseFlowLayoutSectionFlowDelegateTests: XCTestCase { } internal func skipIfNeeded() throws { - guard Self.self === BaseFlowLayoutSectionFlowDelegateTests.self else { return } + guard Self.self === BaseSectionFlowDelegateTests.self else { return } throw XCTSkip("Tests from base class are skipped") } diff --git a/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift b/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift index 8dd8e583..11d7246e 100644 --- a/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift +++ b/SectionKit/Tests/SectionController/SectionFlowDelegate/ProtocolDefaultValuesSectionFlowDelegateTests.swift @@ -2,7 +2,7 @@ import SectionKit import XCTest @MainActor -internal final class ProtocolDefaultValuesSectionFlowDelegateTests: BaseFlowLayoutSectionFlowDelegateTests { +internal final class ProtocolDefaultValuesSectionFlowDelegateTests: BaseSectionFlowDelegateTests { override func createSectionFlowDelegate() throws -> SectionFlowDelegate { class DefaultSectionFlowDelegate: SectionFlowDelegate { } return DefaultSectionFlowDelegate() diff --git a/SectionKit/Tests/SectionController/SingleItemFlowLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift similarity index 86% rename from SectionKit/Tests/SectionController/SingleItemFlowLayoutSectionControllerTests.swift rename to SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift index 53d2ad0b..4077f3ee 100644 --- a/SectionKit/Tests/SectionController/SingleItemFlowLayoutSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/SingleItemSectionControllerTests.swift @@ -2,16 +2,16 @@ import XCTest @MainActor -internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { +internal final class SingleItemSectionControllerTests: XCTestCase { internal func testDidUpdateModelWithValidTypeSetsModel() { - let sectionController = SingleItemFlowLayoutSectionController(model: "1") + let sectionController = SingleItemSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } internal func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = SingleItemFlowLayoutSectionController(model: "1") + let sectionController = SingleItemSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -33,7 +33,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testInitDoesNotUpdateItemIfShouldNotUpdateItem() { - class TestSectionController: SingleItemFlowLayoutSectionController { + class TestSectionController: SingleItemSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -57,7 +57,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testSettingModelDoesNotUpdateItemIfShouldNotUpdateItem() { - class TestSectionController: SingleItemFlowLayoutSectionController { + class TestSectionController: SingleItemSectionController { var itemsForModelExpectation: XCTestExpectation? init(model: String, itemsForModelExpectation: XCTestExpectation?) { @@ -84,13 +84,13 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testShouldUpdateItemDefaultsToTrue() { - let sectionController = SingleItemFlowLayoutSectionController(model: "1") + let sectionController = SingleItemSectionController(model: "1") XCTAssert(sectionController.shouldUpdateItem(afterModelChangedTo: "2")) } internal func testItemForModelInvokesNotImplementedError() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = SingleItemFlowLayoutSectionController(model: "1") + let sectionController = SingleItemSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -109,7 +109,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToSomeWithEqualItems() throws { - let sectionController = SingleItemFlowLayoutSectionController(model: "") + let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -126,7 +126,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { - let sectionController = SingleItemFlowLayoutSectionController(model: "") + let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -143,7 +143,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromNoneToSome() throws { - let sectionController = SingleItemFlowLayoutSectionController(model: "") + let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: nil, @@ -160,7 +160,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToNone() throws { - let sectionController = SingleItemFlowLayoutSectionController(model: "") + let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -177,7 +177,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromNoneToNone() throws { - let sectionController = SingleItemFlowLayoutSectionController(model: "") + let sectionController = SingleItemSectionController(model: "") let update = try XCTUnwrap( sectionController.calculateUpdate( from: nil, @@ -194,7 +194,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testNumberOfItemsWithItem() { - let sectionController = SingleItemFlowLayoutSectionController(model: "1") + let sectionController = SingleItemSectionController(model: "1") sectionController.item = "1" let context = MainCollectionViewContext( viewController: nil, @@ -205,7 +205,7 @@ internal final class SingleItemFlowLayoutSectionControllerTests: XCTestCase { } internal func testNumberOfItemsWithoutItem() { - let sectionController = SingleItemFlowLayoutSectionController(model: "1") + let sectionController = SingleItemSectionController(model: "1") sectionController.item = nil let context = MainCollectionViewContext( viewController: nil, diff --git a/SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift index 93f50af1..15c142e9 100644 --- a/SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift @@ -2,16 +2,16 @@ import XCTest @MainActor -internal final class SingleModelFlowLayoutSectionControllerTests: XCTestCase { +internal final class SingleModelSectionControllerTests: XCTestCase { internal func testDidUpdateModelWithValidTypeSetsModel() { - let sectionController = SingleModelFlowLayoutSectionController(model: "1") + let sectionController = SingleModelSectionController(model: "1") sectionController.didUpdate(model: "2") XCTAssertEqual(sectionController.model, "2") } internal func testDidUpdateModelWithInvalidType() { let errorExpectation = expectation(description: "The errorHandler should be called") - let sectionController = SingleModelFlowLayoutSectionController(model: "1") + let sectionController = SingleModelSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), @@ -33,7 +33,7 @@ internal final class SingleModelFlowLayoutSectionControllerTests: XCTestCase { } internal func testCalculateUpdateFromSomeToSomeWithDifferentItems() throws { - let sectionController = SingleModelFlowLayoutSectionController(model: 1) + let sectionController = SingleModelSectionController(model: 1) let update = try XCTUnwrap( sectionController.calculateUpdate( from: 1, @@ -50,7 +50,7 @@ internal final class SingleModelFlowLayoutSectionControllerTests: XCTestCase { } internal func testNumberOfItems() { - let sectionController = SingleModelFlowLayoutSectionController(model: "1") + let sectionController = SingleModelSectionController(model: "1") let context = MainCollectionViewContext( viewController: nil, collectionView: UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewFlowLayout()), diff --git a/SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift b/SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift deleted file mode 100644 index 7cf6be8f..00000000 --- a/SectionKit/Tests/TestUtilities/MockFlowLayoutSectionController.swift +++ /dev/null @@ -1,10 +0,0 @@ -import SectionKit -import XCTest - -final class MockFlowLayoutSectionController: MockSectionController, - FlowLayoutSectionController { - lazy var flowDelegate: SectionFlowDelegate? = { - XCTFail("flow delegate is not set") - return nil - }() -} diff --git a/SectionKit/Tests/TestUtilities/MockSectionController.swift b/SectionKit/Tests/TestUtilities/MockSectionController.swift index b6a8d80f..23ab185b 100644 --- a/SectionKit/Tests/TestUtilities/MockSectionController.swift +++ b/SectionKit/Tests/TestUtilities/MockSectionController.swift @@ -20,6 +20,11 @@ internal class MockSectionController: SectionController { return nil }() + internal lazy var flowDelegate: SectionFlowDelegate? = { + XCTFail("flow delegate is not set") + return nil + }() + @available(iOS 11.0, *) internal lazy var dragDelegate: SectionDragDelegate? = { XCTFail("dragDelegate is not set") @@ -37,6 +42,11 @@ internal class MockSectionController: SectionController { return MockErrorHandler() }() + internal lazy var layoutProvider: SectionLayoutProvider? = { + XCTFail("layoutProvider is not set") + return nil + }() + // MARK: - didUpdate internal typealias DidUpdateBlock = (Any) -> Void From 69b982a84a736736f891e80315470e69e6da172f Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 17:29:01 +0200 Subject: [PATCH 10/16] revert changes --- ...ift => DiffingListSectionController.swift} | 11 +-- ... ManualDiffingListSectionController.swift} | 19 ++--- .../Generic/BaseSectionController.swift | 85 ++++++++++--------- ...BaseFlowLayoutSectionControllerTests.swift | 10 --- .../BaseSectionControllerTests.swift | 5 ++ ...swift => ListSectionControllerTests.swift} | 0 6 files changed, 56 insertions(+), 74 deletions(-) rename DiffingSectionKit/Sources/{DiffingListFlowLayoutSectionController.swift => DiffingListSectionController.swift} (68%) rename DiffingSectionKit/Sources/{ManualDiffingListFlowLayoutSectionController.swift => ManualDiffingListSectionController.swift} (86%) delete mode 100644 SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift rename SectionKit/Tests/SectionController/{ListFlowLayoutSectionControllerTests.swift => ListSectionControllerTests.swift} (100%) diff --git a/DiffingSectionKit/Sources/DiffingListFlowLayoutSectionController.swift b/DiffingSectionKit/Sources/DiffingListSectionController.swift similarity index 68% rename from DiffingSectionKit/Sources/DiffingListFlowLayoutSectionController.swift rename to DiffingSectionKit/Sources/DiffingListSectionController.swift index 714b2a2b..4d5cd989 100644 --- a/DiffingSectionKit/Sources/DiffingListFlowLayoutSectionController.swift +++ b/DiffingSectionKit/Sources/DiffingListSectionController.swift @@ -9,7 +9,7 @@ import SectionKit of a model to be displayed and the list of items may dynamically change. */ @MainActor -open class DiffingListFlowLayoutSectionController: ListFlowLaoutSectionController { +open class DiffingListSectionController: ListSectionController { override open func calculateUpdate( from oldData: [Item], to newData: [Item] @@ -23,12 +23,3 @@ open class DiffingListFlowLayoutSectionController: ) } } - -@available( - *, - deprecated, - renamed: "DiffingListFlowLayoutSectionController", - message: "It has been renamed to DiffingListFlowLayoutSectionController" -) - -public typealias DiffingListSectionController = DiffingListFlowLayoutSectionController diff --git a/DiffingSectionKit/Sources/ManualDiffingListFlowLayoutSectionController.swift b/DiffingSectionKit/Sources/ManualDiffingListSectionController.swift similarity index 86% rename from DiffingSectionKit/Sources/ManualDiffingListFlowLayoutSectionController.swift rename to DiffingSectionKit/Sources/ManualDiffingListSectionController.swift index 93542e6f..53d42dba 100644 --- a/DiffingSectionKit/Sources/ManualDiffingListFlowLayoutSectionController.swift +++ b/DiffingSectionKit/Sources/ManualDiffingListSectionController.swift @@ -12,10 +12,10 @@ import SectionKit `Item` type, instead it requires closures to get diffing information for an item. */ @MainActor -open class ManualDiffingListFlowLayoutSectionController< +open class ManualDiffingListSectionController< Model, Item ->: ListFlowLaoutSectionController { +>: ListSectionController { private let itemId: @MainActor (Item) -> AnyHashable private let itemContentIsEqual: @MainActor (Item, Item) -> Bool @@ -55,7 +55,7 @@ open class ManualDiffingListFlowLayoutSectionController< } } -extension ManualDiffingListFlowLayoutSectionController where Item: Equatable { +extension ManualDiffingListSectionController where Item: Equatable { /** Initialise an instance of `ManualDiffingListSectionController`. @@ -69,7 +69,7 @@ extension ManualDiffingListFlowLayoutSectionController where Item: Equatable { } @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension ManualDiffingListFlowLayoutSectionController where Item: Identifiable { +extension ManualDiffingListSectionController where Item: Identifiable { /** Initialise an instance of `ManualDiffingListSectionController`. @@ -89,7 +89,7 @@ extension ManualDiffingListFlowLayoutSectionController where Item: Identifiable the base init (apart from the default values), we have to specify `@_disfavoredOverload` so it doesn't call itself. */ @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) -extension ManualDiffingListFlowLayoutSectionController where Item: Identifiable & Equatable { +extension ManualDiffingListSectionController where Item: Identifiable & Equatable { /** Initialise an instance of `ManualDiffingListSectionController`. @@ -108,12 +108,3 @@ extension ManualDiffingListFlowLayoutSectionController where Item: Identifiable self.init(model: model, itemId: itemId, itemContentIsEqual: itemContentIsEqual) } } - -@available( - *, - deprecated, - renamed: "ManualDiffingListFlowLayoutSectionController", - message: "It has been renamed to ManualDiffingListFlowLayoutSectionController" -) - -public typealias ManualDiffingListSectionController = ManualDiffingListFlowLayoutSectionController diff --git a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift index e39f9e5d..475d538f 100644 --- a/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift +++ b/SectionKit/Sources/SectionController/Generic/BaseSectionController.swift @@ -1,8 +1,10 @@ import UIKit -/// This serves as a fundamental `SectionController` implementation, -/// encompassing data source and delegate protocols, with the exception of the flow layout delegate. -/// Each access control is designated as` open`, allowing for easy customization through overrides. +/** + A base implementation of all `SectionController` datasource and delegate protocols. + + Every declaration is marked `open` and can be overridden. + */ @MainActor open class BaseSectionController: SectionController, SectionDataSource, @@ -26,6 +28,8 @@ open class BaseSectionController: SectionController, open var delegate: SectionDelegate? { self } + open var flowDelegate: SectionFlowDelegate? { self } + @available(iOS 11.0, *) open var dragDelegate: SectionDragDelegate? { self } @@ -225,6 +229,44 @@ open class BaseSectionController: SectionController, nil } + // MARK: - SectionDropDelegate + + @available(iOS 11.0, *) + open func canHandle(drop session: UIDropSession, in context: CollectionViewContext) -> Bool { true } + + @available(iOS 11.0, *) + open func dropSessionDidUpdate( + _ session: UIDropSession, + at indexPath: SectionIndexPath?, + in context: CollectionViewContext + ) -> UICollectionViewDropProposal { + UICollectionViewDropProposal(operation: .forbidden) + } + + @available(iOS 11.0, *) + open func performDrop( + at indexPath: SectionIndexPath?, + with coordinator: UICollectionViewDropCoordinator, + in context: CollectionViewContext + ) { } + + @available(iOS 11.0, *) + open func dropSessionDidEnter(_ session: UIDropSession, in context: CollectionViewContext) { } + + @available(iOS 11.0, *) + open func dropSessionDidExit(_ session: UIDropSession, in context: CollectionViewContext) { } + + @available(iOS 11.0, *) + open func dropSessionDidEnd(_ session: UIDropSession, in context: CollectionViewContext) { } + + @available(iOS 11.0, *) + open func dropPreviewParametersForItem( + at indexPath: SectionIndexPath, + in context: CollectionViewContext + ) -> UIDragPreviewParameters? { + nil + } + // MARK: - SectionFlowDelegate @available( @@ -300,41 +342,4 @@ open class BaseSectionController: SectionController, layout.flowLayout?.footerReferenceSize ?? FlowLayoutConstants.defaultFooterSize } - // MARK: - SectionDropDelegate - - @available(iOS 11.0, *) - open func canHandle(drop session: UIDropSession, in context: CollectionViewContext) -> Bool { true } - - @available(iOS 11.0, *) - open func dropSessionDidUpdate( - _ session: UIDropSession, - at indexPath: SectionIndexPath?, - in context: CollectionViewContext - ) -> UICollectionViewDropProposal { - UICollectionViewDropProposal(operation: .forbidden) - } - - @available(iOS 11.0, *) - open func performDrop( - at indexPath: SectionIndexPath?, - with coordinator: UICollectionViewDropCoordinator, - in context: CollectionViewContext - ) { } - - @available(iOS 11.0, *) - open func dropSessionDidEnter(_ session: UIDropSession, in context: CollectionViewContext) { } - - @available(iOS 11.0, *) - open func dropSessionDidExit(_ session: UIDropSession, in context: CollectionViewContext) { } - - @available(iOS 11.0, *) - open func dropSessionDidEnd(_ session: UIDropSession, in context: CollectionViewContext) { } - - @available(iOS 11.0, *) - open func dropPreviewParametersForItem( - at indexPath: SectionIndexPath, - in context: CollectionViewContext - ) -> UIDragPreviewParameters? { - nil - } } diff --git a/SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift deleted file mode 100644 index e87dfe9d..00000000 --- a/SectionKit/Tests/SectionController/BaseFlowLayoutSectionControllerTests.swift +++ /dev/null @@ -1,10 +0,0 @@ -import SectionKit -import XCTest - -internal final class BaseFlowLayoutSectionControllerTests: XCTestCase { - @MainActor - internal func testFlowDelegateIsSelf() { - let sectionController = BaseFlowLayoutSectionController() - XCTAssert(sectionController.flowDelegate === sectionController) - } -} diff --git a/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift b/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift index 7598ce13..26a3edb7 100644 --- a/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift +++ b/SectionKit/Tests/SectionController/BaseSectionControllerTests.swift @@ -24,6 +24,11 @@ internal final class BaseSectionControllerTests: XCTestCase { XCTAssert(sectionController.delegate === sectionController) } + internal func testFlowDelegateIsSelf() { + let sectionController = BaseSectionController() + XCTAssert(sectionController.flowDelegate === sectionController) + } + @available(iOS 11.0, *) internal func testDragDelegateIsSelf() { let sectionController = BaseSectionController() diff --git a/SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/ListSectionControllerTests.swift similarity index 100% rename from SectionKit/Tests/SectionController/ListFlowLayoutSectionControllerTests.swift rename to SectionKit/Tests/SectionController/ListSectionControllerTests.swift From 2e714a21f3ea9837ec6ca0415beb759ddea28fce Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 17:29:34 +0200 Subject: [PATCH 11/16] put return inside available to compatible with older versions --- .../ListCollectionViewAdapter+Convenience.swift | 8 ++++---- .../SingleSectionCollectionViewAdapter+Convenience.swift | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift index ca76b284..2ddbd2d7 100644 --- a/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/ListCollectionViewAdapter/ListCollectionViewAdapter+Convenience.swift @@ -59,18 +59,18 @@ extension ListCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { if #available(iOS 13.0, *) { - controller(at: indexPath)?.layoutProvider?.flowLayoutProvider + return controller(at: indexPath)?.layoutProvider?.flowLayoutProvider } else { - controller(at: indexPath)?.flowDelegate + return controller(at: indexPath)?.flowDelegate } } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { if #available(iOS 13.0, *) { - controller(at: index)?.layoutProvider?.flowLayoutProvider + return controller(at: index)?.layoutProvider?.flowLayoutProvider } else { - controller(at: index)?.flowDelegate + return controller(at: index)?.flowDelegate } } } diff --git a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift index 5dbeb43e..d6666281 100644 --- a/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift +++ b/SectionKit/Sources/CollectionViewAdapter/SingleSectionCollectionViewAdapter/SingleSectionCollectionViewAdapter+Convenience.swift @@ -59,18 +59,18 @@ extension SingleSectionCollectionViewAdapter { @inlinable public func flowDelegate(at indexPath: IndexPath) -> SectionFlowDelegate? { if #available(iOS 13.0, *) { - controller(at: indexPath)?.layoutProvider?.flowLayoutProvider + return controller(at: indexPath)?.layoutProvider?.flowLayoutProvider } else { - controller(at: indexPath)?.flowDelegate + return controller(at: indexPath)?.flowDelegate } } @inlinable public func flowDelegate(at index: Int) -> SectionFlowDelegate? { if #available(iOS 13.0, *) { - controller(at: index)?.layoutProvider?.flowLayoutProvider + return controller(at: index)?.layoutProvider?.flowLayoutProvider } else { - controller(at: index)?.flowDelegate + return controller(at: index)?.flowDelegate } } } From 50e1d8a7bfb34c42d7ab16c886b1b27c74a44544 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 17:31:04 +0200 Subject: [PATCH 12/16] fix project file --- SectionKit.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index 4f1fc83c..2024c5b8 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -33,7 +33,6 @@ 5A0B777A26B1A81300B054D4 /* MainCollectionViewContextTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777926B1A81300B054D4 /* MainCollectionViewContextTests.swift */; }; 5A0B777C26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */; }; 5A0B777E26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */; }; - 5A0B778026B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */; }; 5A0B778226B2A92C00B054D4 /* SingleItemSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */; }; 5A0B778426B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */; }; 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */; }; @@ -130,6 +129,7 @@ D90764CB2BC6B9120083306E /* ListSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C72BC6B9120083306E /* ListSectionController.swift */; }; D90764CC2BC6B9120083306E /* SingleModelSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C82BC6B9120083306E /* SingleModelSectionController.swift */; }; D90764CD2BC6B9120083306E /* SingleItemSectionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764C92BC6B9120083306E /* SingleItemSectionController.swift */; }; + D90764CF2BC6E8140083306E /* ListSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90764CE2BC6E8140083306E /* ListSectionControllerTests.swift */; }; D91425652BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */; }; D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */; }; D91425852BBBFB840005E8CD /* ListCollectionViewAdapter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CE2667DA3F00D4DCE1 /* ListCollectionViewAdapter.swift */; }; @@ -177,7 +177,6 @@ 5A0B777926B1A81300B054D4 /* MainCollectionViewContextTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainCollectionViewContextTests.swift; sourceTree = ""; }; 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewSectionBatchOperationTests.swift; sourceTree = ""; }; 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewBatchOperationTests.swift; sourceTree = ""; }; - 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleItemSectionControllerTests.swift; sourceTree = ""; }; 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleModelFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerTests.swift; sourceTree = ""; }; @@ -281,6 +280,7 @@ D90764C72BC6B9120083306E /* ListSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListSectionController.swift; sourceTree = ""; }; D90764C82BC6B9120083306E /* SingleModelSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelSectionController.swift; sourceTree = ""; }; D90764C92BC6B9120083306E /* SingleItemSectionController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleItemSectionController.swift; sourceTree = ""; }; + D90764CE2BC6E8140083306E /* ListSectionControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListSectionControllerTests.swift; sourceTree = ""; }; D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionKitCompositionalLayout.swift; sourceTree = ""; }; D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionFlowDelegateTests.swift; sourceTree = ""; }; D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift; sourceTree = ""; }; @@ -654,7 +654,7 @@ 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */, 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */, 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */, - 5A0B777F26B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift */, + D90764CE2BC6E8140083306E /* ListSectionControllerTests.swift */, 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */, 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */, ); @@ -894,6 +894,7 @@ 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */, 5A0B777026B19EB300B054D4 /* MockListCollectionViewAdapterDataSource.swift in Sources */, D914257F2BBBF8310005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift in Sources */, + D90764CF2BC6E8140083306E /* ListSectionControllerTests.swift in Sources */, 5A31B8E426BC36C400036A3F /* CollectionViewContextExtensionsTests.swift in Sources */, 5AA9D96E26AAD06100679D88 /* SingleSectionCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, 5AE1761E2667DA7000D4DCE1 /* SequenceUniqueTests.swift in Sources */, @@ -913,7 +914,6 @@ 5A31B8BB26BAE8D400036A3F /* ProtocolDefaultValuesSectionDataSourceTests.swift in Sources */, 5A0B774E26AF0C2100B054D4 /* BaseCollectionViewAdapterUIScrollViewDelegateTests.swift in Sources */, 5AA9D96826AAC9AF00679D88 /* BaseCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, - 5A0B778026B299FF00B054D4 /* ListFlowLayoutSectionControllerTests.swift in Sources */, 5A0B775B26B006AA00B054D4 /* ListCollectionViewAdapterUICollectionViewDropDelegateTests.swift in Sources */, 5A31B8BD26BAE8E300036A3F /* BaseSectionDataSourcePrefetchingDelegateTests.swift in Sources */, 5A31B8C126BAE8F800036A3F /* ProtocolDefaultValuesSectionDataSourcePrefetchingDelegateTests.swift in Sources */, From 72107ac534746106181e631e0badf7a0647e73dd Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 17:34:48 +0200 Subject: [PATCH 13/16] clean up --- ...trollerTests.swift => SingleModelSectionControllerTests.swift} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename SectionKit/Tests/SectionController/{SingleModelFlowLayoutSectionControllerTests.swift => SingleModelSectionControllerTests.swift} (100%) diff --git a/SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift b/SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift similarity index 100% rename from SectionKit/Tests/SectionController/SingleModelFlowLayoutSectionControllerTests.swift rename to SectionKit/Tests/SectionController/SingleModelSectionControllerTests.swift From fde70d52c2eeec91cfa10acf1210d51b8398a503 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 10 Apr 2024 17:55:56 +0200 Subject: [PATCH 14/16] fix proj file --- SectionKit.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SectionKit.xcodeproj/project.pbxproj b/SectionKit.xcodeproj/project.pbxproj index 2024c5b8..4052815b 100644 --- a/SectionKit.xcodeproj/project.pbxproj +++ b/SectionKit.xcodeproj/project.pbxproj @@ -34,7 +34,6 @@ 5A0B777C26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */; }; 5A0B777E26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */; }; 5A0B778226B2A92C00B054D4 /* SingleItemSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */; }; - 5A0B778426B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */; }; 5A0B778626B2AB7800B054D4 /* BaseSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */; }; 5A0B778926B3EA4D00B054D4 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */; }; 5A31B8B726BAE8A900036A3F /* BaseSectionDataSourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A31B8B526BAE8A300036A3F /* BaseSectionDataSourceTests.swift */; }; @@ -137,6 +136,7 @@ D93269A22BBBFC2400B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CA2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSourcePrefetching.swift */; }; D93269A32BBBFC2700B33C32 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175C92667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDataSource.swift */; }; D93269A42BBBFC2B00B33C32 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5AE175CF2667DA3F00D4DCE1 /* ListCollectionViewAdapter+UICollectionViewDragDelegate.swift */; }; + D952494D2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D952494C2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift */; }; D9CCE9BF2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */; }; /* End PBXBuildFile section */ @@ -178,7 +178,6 @@ 5A0B777B26B2931700B054D4 /* CollectionViewSectionBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewSectionBatchOperationTests.swift; sourceTree = ""; }; 5A0B777D26B2944F00B054D4 /* CollectionViewBatchOperationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionViewBatchOperationTests.swift; sourceTree = ""; }; 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleItemSectionControllerTests.swift; sourceTree = ""; }; - 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleModelFlowLayoutSectionControllerTests.swift; sourceTree = ""; }; 5A0B778526B2AB7800B054D4 /* BaseSectionControllerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionControllerTests.swift; sourceTree = ""; }; 5A0B778826B3EA4D00B054D4 /* ErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = ""; }; 5A31B8B526BAE8A300036A3F /* BaseSectionDataSourceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BaseSectionDataSourceTests.swift; sourceTree = ""; }; @@ -284,6 +283,7 @@ D91425642BBBF74A0005E8CD /* SectionKitCompositionalLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionKitCompositionalLayout.swift; sourceTree = ""; }; D914257A2BBBF8130005E8CD /* BaseFlowLayoutSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionFlowDelegateTests.swift; sourceTree = ""; }; D914257B2BBBF8130005E8CD /* BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseFlowLayoutSectionControllerSectionFlowDelegateTests.swift; sourceTree = ""; }; + D952494C2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleModelSectionControllerTests.swift; sourceTree = ""; }; D9CCE9BE2BADF7C700EED204 /* NSCollectionLayoutSection+Empty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSCollectionLayoutSection+Empty.swift"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -656,7 +656,7 @@ 5A31B8E126BC25A700036A3F /* ProtocolDefaultValuesSectionControllerTests.swift */, D90764CE2BC6E8140083306E /* ListSectionControllerTests.swift */, 5A0B778126B2A92C00B054D4 /* SingleItemSectionControllerTests.swift */, - 5A0B778326B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift */, + D952494C2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift */, ); path = SectionController; sourceTree = ""; @@ -905,7 +905,6 @@ 5AB6642926A587AE004DC230 /* CollectionViewContextSizeTests.swift in Sources */, 5A31B8CF26BAE93900036A3F /* BaseSectionDropDelegateTests.swift in Sources */, 5A31B8BF26BAE8EE00036A3F /* BaseSectionControllerSectionDataSourcePrefetchingDelegateTests.swift in Sources */, - 5A0B778426B2AA2000B054D4 /* SingleModelFlowLayoutSectionControllerTests.swift in Sources */, 5A0B775926B0069700B054D4 /* BaseCollectionViewAdapterUICollectionViewDropDelegateTests.swift in Sources */, 5A0B776E26B19E8C00B054D4 /* MockSingleSectionCollectionViewAdapterDataSource.swift in Sources */, 5A8D3E5927E8D16200073712 /* MockCollectionViewAdapter.swift in Sources */, @@ -936,6 +935,7 @@ 5AA9D96326AAC65200679D88 /* ListCollectionViewAdapterUICollectionViewDataSourcePrefetchingTests.swift in Sources */, 5AE1761B2667DA7000D4DCE1 /* SectionIndexPathTests.swift in Sources */, 5AA9D96C26AAD05400679D88 /* ListCollectionViewAdapterUICollectionViewDelegateTests.swift in Sources */, + D952494D2BC6EDFB00108510 /* SingleModelSectionControllerTests.swift in Sources */, 5A31B8C726BAE91300036A3F /* ProtocolDefaultValuesSectionDelegateTests.swift in Sources */, 5A0B776A26B1826100B054D4 /* ListCollectionViewAdapterTests.swift in Sources */, 5A31B8B926BAE8C600036A3F /* BaseSectionControllerSectionDataSourceTests.swift in Sources */, From 09520029232b531c3227a5360c7d6aa5b141d508 Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 17 Apr 2024 00:03:27 +0200 Subject: [PATCH 15/16] fix assert message --- .../CompositionalLayout/SectionKitCompositionalLayout.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift index 8c119562..d1713597 100644 --- a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift +++ b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift @@ -12,7 +12,7 @@ final public class SectionKitCompositionalLayout: UICollectionViewCompositionalL var sections: (() -> [Section])? super.init { index, environment in guard let sections = sections?() else { - assertionFailure("The section provider doesn't set up correctly, please use the `CollectionViewCompositionalLayoutAdapter`") + assertionFailure("The section update closure doesn't set up correctly, please check the `CollectionViewAdapter`") return .empty } guard sections.count > index else { From a2a364c04238ac136f3cfa5cf36807b5fc35388c Mon Sep 17 00:00:00 2001 From: Calvin Chang Date: Wed, 17 Apr 2024 00:05:56 +0200 Subject: [PATCH 16/16] improve assert message --- .../CompositionalLayout/SectionKitCompositionalLayout.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift index d1713597..71aa453d 100644 --- a/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift +++ b/SectionKit/Sources/Utility/CompositionalLayout/SectionKitCompositionalLayout.swift @@ -12,7 +12,7 @@ final public class SectionKitCompositionalLayout: UICollectionViewCompositionalL var sections: (() -> [Section])? super.init { index, environment in guard let sections = sections?() else { - assertionFailure("The section update closure doesn't set up correctly, please check the `CollectionViewAdapter`") + assertionFailure("The section update closure doesn't set up correctly, please use the `CollectionViewAdapter`") return .empty } guard sections.count > index else {