Skip to content
Snippets Groups Projects
Commit c7b8637e authored by Dariusz Rybicki's avatar Dariusz Rybicki
Browse files

Merge branch 'feature/collection-view-library' into 'development'

CollectionView library

See merge request elixxir/client-ios!51
parents 3499fcc8 4484d801
No related branches found
No related tags found
2 merge requests!54Releasing 1.1.4,!51CollectionView library
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1340"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CollectionView"
BuildableName = "CollectionView"
BlueprintName = "CollectionView"
ReferencedContainer = "container:">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CollectionViewTests"
BuildableName = "CollectionViewTests"
BlueprintName = "CollectionViewTests"
ReferencedContainer = "container:">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "CollectionView"
BuildableName = "CollectionView"
BlueprintName = "CollectionView"
ReferencedContainer = "container:">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
......@@ -35,6 +35,7 @@ let package = Package(
.library(name: "iCloudFeature", targets: ["iCloudFeature"]),
.library(name: "SearchFeature", targets: ["SearchFeature"]),
.library(name: "DrawerFeature", targets: ["DrawerFeature"]),
.library(name: "CollectionView", targets: ["CollectionView"]),
.library(name: "RestoreFeature", targets: ["RestoreFeature"]),
.library(name: "CrashReporting", targets: ["CrashReporting"]),
.library(name: "ProfileFeature", targets: ["ProfileFeature"]),
......@@ -70,7 +71,9 @@ let package = Package(
.package(url: "https://git.xx.network/elixxir/client-ios-db.git", .upToNextMajor(from: "1.0.5")),
.package(url: "https://github.com/firebase/firebase-ios-sdk.git", .upToNextMajor(from: "8.10.0")),
.package(url: "https://github.com/darrarski/Shout.git", revision: "df5a662293f0ac15eeb4f2fd3ffd0c07b73d0de0"),
.package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",.upToNextMajor(from: "0.32.0"))
.package(url: "https://github.com/pointfreeco/swift-composable-architecture.git",.upToNextMajor(from: "0.32.0")),
.package(url: "https://github.com/pointfreeco/swift-custom-dump.git", .upToNextMajor(from: "0.5.0")),
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay.git", .upToNextMajor(from: "0.3.3")),
],
targets: [
.target(
......@@ -857,6 +860,23 @@ let package = Package(
.product(name: "Quick", package: "Quick"),
.product(name: "Nimble", package: "Nimble")
]
)
),
// MARK: - CollectionView
.target(
name: "CollectionView",
dependencies: [
.product(name: "ChatLayout", package: "ChatLayout"),
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
]
),
.testTarget(
name: "CollectionViewTests",
dependencies: [
.target(name: "CollectionView"),
.product(name: "CustomDump", package: "swift-custom-dump"),
]
),
]
)
import UIKit
import XCTestDynamicOverlay
public struct CellFactory<Model> {
public struct Registrar {
public init(register: @escaping (UICollectionView) -> Void) {
self.register = register
}
public var register: (UICollectionView) -> Void
public func callAsFunction(in view: UICollectionView) {
register(view)
}
}
public struct Builder {
public init(build: @escaping (Model, UICollectionView, IndexPath) -> UICollectionViewCell?) {
self.build = build
}
public var build: (Model, UICollectionView, IndexPath) -> UICollectionViewCell?
public func callAsFunction(
for model: Model,
in view: UICollectionView,
at indexPath: IndexPath
) -> UICollectionViewCell? {
build(model, view, indexPath)
}
}
public init(
register: Registrar,
build: Builder
) {
self.register = register
self.build = build
}
public var register: Registrar
public var build: Builder
}
extension CellFactory {
public static func combined(_ factories: CellFactory...) -> CellFactory {
combined(factories)
}
public static func combined(_ factories: [CellFactory]) -> CellFactory {
CellFactory(
register: .init { collectionView in
factories.forEach { $0.register(in: collectionView) }
},
build: .init { model, collectionView, indexPath in
for factory in factories {
if let cell = factory.build(for: model, in: collectionView, at: indexPath) {
return cell
}
}
return nil
}
)
}
}
#if DEBUG
extension CellFactory {
public static func unimplemented() -> CellFactory {
CellFactory(
register: .init(register: XCTUnimplemented("\(Self.self).Registrar")),
build: .init(build: XCTUnimplemented("\(Self.self).Builder"))
)
}
}
#endif
import UIKit
import XCTestDynamicOverlay
public struct ViewConfigurator<View: UIView, Model> {
public init(configure: @escaping (View, Model) -> Void) {
self.configure = configure
}
public var configure: (View, Model) -> Void
public func callAsFunction(_ view: View, with model: Model) {
configure(view, model)
}
}
#if DEBUG
extension ViewConfigurator {
public static func unimplemented() -> ViewConfigurator {
ViewConfigurator(configure: XCTUnimplemented("\(Self.self)"))
}
}
#endif
import CustomDump
import XCTest
@testable import CollectionView
final class CellFactoryTests: XCTestCase {
func testCombined() {
struct Cell: Equatable {
var model: Int
var collectionView: UICollectionView
var indexPath: IndexPath
}
var didRegisterFirst = [UICollectionView]()
var didRegisterSecond = [UICollectionView]()
var didRegisterThird = [UICollectionView]()
var didBuildFirst = [Cell]()
var didBuildSecond = [Cell]()
var didBuildThird = [Cell]()
let factory = CellFactory<Int>.combined(
.init(
register: .init { didRegisterFirst.append($0) },
build: .init { model, collectionView, indexPath in
guard model == 1 else { return nil }
didBuildFirst.append(Cell(model: model, collectionView: collectionView, indexPath: indexPath))
return UICollectionViewCell()
}
),
.init(
register: .init { didRegisterSecond.append($0) },
build: .init { model, collectionView, indexPath in
guard model == 2 else { return nil }
didBuildSecond.append(Cell(model: model, collectionView: collectionView, indexPath: indexPath))
return UICollectionViewCell()
}
),
.init(
register: .init { didRegisterThird.append($0) },
build: .init { model, collectionView, indexPath in
guard model == 3 else { return nil }
didBuildThird.append(Cell(model: model, collectionView: collectionView, indexPath: indexPath))
return UICollectionViewCell()
}
)
)
let collectionView = UICollectionView(frame: .zero, collectionViewLayout: .init())
factory.register(in: collectionView)
XCTAssertEqual(didRegisterFirst, [collectionView])
XCTAssertEqual(didRegisterSecond, [collectionView])
XCTAssertEqual(didRegisterThird, [collectionView])
let firstCell = factory.build(for: 1, in: collectionView, at: IndexPath(item: 0, section: 1))
XCTAssertNotNil(firstCell)
XCTAssertNoDifference(didBuildFirst, [Cell(
model: 1,
collectionView: collectionView,
indexPath: IndexPath(row: 0, section: 1)
)])
XCTAssertNoDifference(didBuildSecond, [])
XCTAssertNoDifference(didBuildThird, [])
didBuildFirst = []
didBuildSecond = []
didBuildThird = []
let secondCell = factory.build(for: 2, in: collectionView, at: IndexPath(item: 2, section: 3))
XCTAssertNotNil(secondCell)
XCTAssertNoDifference(didBuildFirst, [])
XCTAssertNoDifference(didBuildSecond, [Cell(
model: 2,
collectionView: collectionView,
indexPath: IndexPath(row: 2, section: 3)
)])
XCTAssertNoDifference(didBuildThird, [])
didBuildFirst = []
didBuildSecond = []
didBuildThird = []
let thirdCell = factory.build(for: 3, in: collectionView, at: IndexPath(item: 4, section: 5))
XCTAssertNotNil(thirdCell)
XCTAssertNoDifference(didBuildFirst, [])
XCTAssertNoDifference(didBuildSecond, [])
XCTAssertNoDifference(didBuildThird, [Cell(
model: 3,
collectionView: collectionView,
indexPath: IndexPath(row: 4, section: 5)
)])
didBuildFirst = []
didBuildSecond = []
didBuildThird = []
let otherCell = factory.build(for: 4, in: collectionView, at: IndexPath(item: 0, section: 0))
XCTAssertNil(otherCell)
XCTAssertNoDifference(didBuildFirst, [])
XCTAssertNoDifference(didBuildSecond, [])
XCTAssertNoDifference(didBuildThird, [])
}
}
import CustomDump
import XCTest
@testable import CollectionView
// MARK: - Example view configurator:
private class ProfileView: UIView {
let username = UILabel()
}
private struct User {
var name: String
}
private extension ViewConfigurator where View == ProfileView, Model == User {
static let profileViewUserConfigurator = ViewConfigurator { view, model in
view.username.text = model.name
}
}
// MARK: - Tests:
final class ViewConfiguratorTests: XCTestCase {
func testExampleConfigurator() {
let profileView = ProfileView()
let user = User(name: "John")
let configure = ViewConfigurator.profileViewUserConfigurator
configure(profileView, with: user)
XCTAssertNoDifference(profileView.username.text, user.name)
}
}
......@@ -328,8 +328,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/swift-custom-dump",
"state" : {
"revision" : "51698ece74ecf31959d3fa81733f0a5363ef1b4e",
"version" : "0.3.0"
"revision" : "21ec1d717c07cea5a026979cb0471dd95c7087e7",
"version" : "0.5.0"
}
},
{
......@@ -373,8 +373,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/pointfreeco/xctest-dynamic-overlay",
"state" : {
"revision" : "50a70a9d3583fe228ce672e8923010c8df2deddd",
"version" : "0.2.1"
"revision" : "ef8e14e7ce1c0c304c644c6ba365d06c468ded6b",
"version" : "0.3.3"
}
}
],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment