diff --git a/.github/workflows/parchment.yml b/.github/workflows/parchment.yml index 32db64d3..cb4d3972 100644 --- a/.github/workflows/parchment.yml +++ b/.github/workflows/parchment.yml @@ -2,13 +2,13 @@ name: "Parchment" on: [push] jobs: build: - runs-on: macos-latest + runs-on: macos-14 steps: - uses: maxim-lobanov/setup-xcode@v1 with: - xcode-version: latest-stable + xcode-version: '16.0-beta' - uses: actions/checkout@v3 - name: Unit Tests - run: xcodebuild -project Parchment.xcodeproj -scheme "Parchment" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.5' test + run: xcodebuild -project Parchment.xcodeproj -scheme "Parchment" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=18.0' test - name: UI Tests - run: xcodebuild -project Parchment.xcodeproj -scheme "ParchmentUITests" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=17.5' test + run: xcodebuild -project Parchment.xcodeproj -scheme "ParchmentUITests" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 15 Pro,OS=18.0' test diff --git a/.swift-version b/.swift-version index f9ce5a96..e0ea36fe 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -5.10 +6.0 diff --git a/Example/AppDelegate.swift b/Example/AppDelegate.swift index 49cc4db9..43ae9d5e 100644 --- a/Example/AppDelegate.swift +++ b/Example/AppDelegate.swift @@ -1,6 +1,6 @@ import UIKit -@UIApplicationMain +@main class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? } diff --git a/Example/Examples/Calendar/DateFormatters.swift b/Example/Examples/Calendar/DateFormatters.swift index 7756632b..9a77761a 100644 --- a/Example/Examples/Calendar/DateFormatters.swift +++ b/Example/Examples/Calendar/DateFormatters.swift @@ -1,20 +1,20 @@ import Foundation struct DateFormatters { - static var shortDateFormatter: DateFormatter = { + static let shortDateFormatter: DateFormatter = { let dateFormatter = DateFormatter() dateFormatter.timeStyle = .none dateFormatter.dateStyle = .short return dateFormatter }() - static var dateFormatter: DateFormatter = { + static let dateFormatter: DateFormatter = { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "d" return dateFormatter }() - static var weekdayFormatter: DateFormatter = { + static let weekdayFormatter: DateFormatter = { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "EEE" return dateFormatter diff --git a/Example/Examples/Images/ImagesViewController.swift b/Example/Examples/Images/ImagesViewController.swift index 6d358b08..2dbb1803 100644 --- a/Example/Examples/Images/ImagesViewController.swift +++ b/Example/Examples/Images/ImagesViewController.swift @@ -1,6 +1,7 @@ import Parchment import UIKit +@MainActor protocol ImagesViewControllerDelegate: AnyObject { func imagesViewControllerDidScroll(_: ImagesViewController) } diff --git a/Package.swift b/Package.swift index 8e5d9893..931f3147 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.10 +// swift-tools-version: 6.0 import PackageDescription let package = Package( diff --git a/Parchment.xcodeproj/project.pbxproj b/Parchment.xcodeproj/project.pbxproj index 8b1bff8f..73d316d0 100644 --- a/Parchment.xcodeproj/project.pbxproj +++ b/Parchment.xcodeproj/project.pbxproj @@ -937,7 +937,7 @@ attributes = { BuildIndependentTargetsInParallel = YES; LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1540; + LastUpgradeCheck = 1600; ORGANIZATIONNAME = "Martin Rechsteiner"; TargetAttributes = { 3E504EC31C7465B000AE1CE3 = { @@ -1275,7 +1275,6 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.ParchmentTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; name = Debug; @@ -1292,7 +1291,6 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.ParchmentTests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Example.app/Example"; }; name = Release; @@ -1351,7 +1349,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0.1; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1406,7 +1404,7 @@ SDKROOT = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; - SWIFT_VERSION = 3.0.1; + SWIFT_VERSION = 6.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1441,7 +1439,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; }; name = Debug; }; @@ -1471,14 +1468,12 @@ PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.Parchment; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; - SWIFT_VERSION = 5.0; }; name = Release; }; 3EA04A6A1C53BFF40054E5E0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; DEVELOPMENT_TEAM = G4TGN24VA2; @@ -1490,14 +1485,12 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.Example; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; }; name = Debug; }; 3EA04A6B1C53BFF40054E5E0 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; DEVELOPMENT_TEAM = G4TGN24VA2; @@ -1509,7 +1502,6 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.Example; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; }; name = Release; }; @@ -1537,7 +1529,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.ParchmentUITests; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_TARGET_NAME = Example; }; @@ -1565,7 +1556,6 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.ParchmentUITests; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; TEST_TARGET_NAME = Example; }; @@ -1597,7 +1587,6 @@ PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.ExampleSwiftUI; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -1626,7 +1615,6 @@ MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.martinrechsteiner.ExampleSwiftUI; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Parchment.xcodeproj/xcshareddata/xcschemes/Example.xcscheme b/Parchment.xcodeproj/xcshareddata/xcschemes/Example.xcscheme index 9e221c8d..b7a024dc 100644 --- a/Parchment.xcodeproj/xcshareddata/xcschemes/Example.xcscheme +++ b/Parchment.xcodeproj/xcshareddata/xcschemes/Example.xcscheme @@ -1,6 +1,6 @@ Any { let copy = super.copy(with: zone) as! PagingBorderLayoutAttributes diff --git a/Parchment/Classes/PagingCellLayoutAttributes.swift b/Parchment/Classes/PagingCellLayoutAttributes.swift index 4db57035..05a4b010 100644 --- a/Parchment/Classes/PagingCellLayoutAttributes.swift +++ b/Parchment/Classes/PagingCellLayoutAttributes.swift @@ -3,7 +3,7 @@ import UIKit /// A custom `UICollectionViewLayoutAttributes` subclass that adds a /// `progress` property indicating how far the user has scrolled. open class PagingCellLayoutAttributes: UICollectionViewLayoutAttributes { - open var progress: CGFloat = 0.0 + nonisolated(unsafe) open var progress: CGFloat = 0.0 open override func copy(with zone: NSZone? = nil) -> Any { let copy = super.copy(with: zone) as! PagingCellLayoutAttributes diff --git a/Parchment/Classes/PagingIndicatorLayoutAttributes.swift b/Parchment/Classes/PagingIndicatorLayoutAttributes.swift index 253a09f3..df76c72b 100644 --- a/Parchment/Classes/PagingIndicatorLayoutAttributes.swift +++ b/Parchment/Classes/PagingIndicatorLayoutAttributes.swift @@ -1,7 +1,7 @@ import UIKit open class PagingIndicatorLayoutAttributes: UICollectionViewLayoutAttributes { - open var backgroundColor: UIColor? + nonisolated(unsafe) open var backgroundColor: UIColor? open override func copy(with zone: NSZone? = nil) -> Any { let copy = super.copy(with: zone) as! PagingIndicatorLayoutAttributes diff --git a/Parchment/Protocols/PagingViewControllerSizeDelegate.swift b/Parchment/Protocols/PagingViewControllerSizeDelegate.swift index 4d3d8725..4c265dce 100644 --- a/Parchment/Protocols/PagingViewControllerSizeDelegate.swift +++ b/Parchment/Protocols/PagingViewControllerSizeDelegate.swift @@ -1,5 +1,6 @@ import UIKit +@MainActor public protocol PagingViewControllerSizeDelegate: AnyObject { /// Manually control the width for a given `PagingItem`. Parchment /// does not support self-sizing cells, so you have to use this if diff --git a/ParchmentTests/Mocks/Mock.swift b/ParchmentTests/Mocks/Mock.swift index c7e4aaf9..4c018fdf 100644 --- a/ParchmentTests/Mocks/Mock.swift +++ b/ParchmentTests/Mocks/Mock.swift @@ -7,11 +7,13 @@ enum Action: Equatable { } struct MockCall: Equatable { + @MainActor static var callCount: Int = 0 let index: Int let action: Action + @MainActor init(action: Action) { Self.callCount += 1 self.index = Self.callCount @@ -25,6 +27,7 @@ extension MockCall: Comparable { } } +@MainActor protocol Mock { var calls: [MockCall] { get } } diff --git a/ParchmentTests/Mocks/MockCollectionView.swift b/ParchmentTests/Mocks/MockCollectionView.swift index 64724990..7d21c856 100644 --- a/ParchmentTests/Mocks/MockCollectionView.swift +++ b/ParchmentTests/Mocks/MockCollectionView.swift @@ -1,6 +1,7 @@ @testable import Parchment import UIKit +@MainActor final class MockCollectionView: CollectionView, Mock { enum Action: Equatable { case contentOffset(CGPoint) diff --git a/ParchmentTests/Mocks/MockPagingControllerDelegate.swift b/ParchmentTests/Mocks/MockPagingControllerDelegate.swift index f2e4f523..d807d533 100644 --- a/ParchmentTests/Mocks/MockPagingControllerDelegate.swift +++ b/ParchmentTests/Mocks/MockPagingControllerDelegate.swift @@ -1,6 +1,7 @@ import Foundation @testable import Parchment +@MainActor final class MockPagingControllerDelegate: PagingMenuDelegate, Mock { enum Action: Equatable { case selectContent(pagingItem: Item, direction: PagingDirection, animated: Bool) diff --git a/ParchmentTests/PageViewManagerTests.swift b/ParchmentTests/PageViewManagerTests.swift index 588871ca..4a8e78c0 100644 --- a/ParchmentTests/PageViewManagerTests.swift +++ b/ParchmentTests/PageViewManagerTests.swift @@ -1,14 +1,14 @@ import Foundation +import Testing @testable import Parchment -import XCTest @MainActor -final class PageViewManagerTests: XCTestCase { - var dataSource: MockPageViewManagerDataSource! - var delegate: MockPageViewManagerDelegate! - var manager: PageViewManager! +final class PageViewManagerTests { + private var dataSource: MockPageViewManagerDataSource + private var delegate: MockPageViewManagerDelegate + private var manager: PageViewManager - override func setUp() { + init() { dataSource = MockPageViewManagerDataSource() delegate = MockPageViewManagerDelegate() manager = PageViewManager() @@ -18,7 +18,7 @@ final class PageViewManagerTests: XCTestCase { // MARK: - Selection - func testSelectWhenEmpty() { + @Test func selectWhenEmpty() { let previousVc = UIViewController() let selectedVc = UIViewController() let nextVc = UIViewController() @@ -29,7 +29,7 @@ final class PageViewManagerTests: XCTestCase { manager.viewDidAppear(false) manager.select(viewController: selectedVc, animated: true) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(true, selectedVc, true), .addViewController(previousVc), .addViewController(selectedVc), @@ -39,7 +39,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectAllNewViewControllersForwardAnimated() { + @Test func selectAllNewViewControllersForwardAnimated() { let oldPreviousVc = UIViewController() let oldSelectedVc = UIViewController() let oldNextVc = UIViewController() @@ -61,7 +61,7 @@ final class PageViewManagerTests: XCTestCase { manager.didScroll(progress: 0.1) manager.didScroll(progress: 1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ // Add the new upcoming view controller .removeViewController(oldNextVc), .addViewController(newSelectedVc), @@ -91,7 +91,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testCancelSelectAllNewViewControllersForwardAnimated() { + @Test func cancelSelectAllNewViewControllersForwardAnimated() { let oldPreviousVc = UIViewController() let oldSelectedVc = UIViewController() let oldNextVc = UIViewController() @@ -115,7 +115,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerAfter = { _ in oldNextVc } manager.didScroll(progress: 0.0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: oldSelectedVc, to: newSelectedVc, progress: 0.0), .beginAppearanceTransition(true, oldSelectedVc, true), .beginAppearanceTransition(false, newSelectedVc, true), @@ -132,7 +132,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectAllNewViewControllersReverseAnimated() { + @Test func selectAllNewViewControllersReverseAnimated() { let oldPreviousVc = UIViewController() let oldSelectedVc = UIViewController() let oldNextVc = UIViewController() @@ -154,7 +154,7 @@ final class PageViewManagerTests: XCTestCase { manager.didScroll(progress: -0.1) manager.didScroll(progress: -1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ // Add the new upcoming view controller .removeViewController(oldPreviousVc), .addViewController(newSelectedVc), @@ -184,7 +184,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testCancelSelectAllNewViewControllersReverseAnimated() { + @Test func cancelSelectAllNewViewControllersReverseAnimated() { let oldPreviousVc = UIViewController() let oldSelectedVc = UIViewController() let oldNextVc = UIViewController() @@ -208,7 +208,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerBefore = { _ in oldPreviousVc } manager.didScroll(progress: 0.0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: oldSelectedVc, to: newSelectedVc, progress: 0.0), .beginAppearanceTransition(true, oldSelectedVc, true), .beginAppearanceTransition(false, newSelectedVc, true), @@ -225,7 +225,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectAllNewViewControllersWithoutAnimation() { + @Test func selectAllNewViewControllersWithoutAnimation() { let oldPreviousVc = UIViewController() let oldSelectedVc = UIViewController() let oldNextVc = UIViewController() @@ -245,7 +245,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerAfter = { _ in newNextVc } manager.select(viewController: newSelectedVc, animated: false) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ // Start the appearance transitions. .beginAppearanceTransition(false, oldSelectedVc, false), .beginAppearanceTransition(true, newSelectedVc, false), @@ -265,7 +265,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectShiftOneForwardWithoutAnimation() { + @Test func selectShiftOneForwardWithoutAnimation() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -282,7 +282,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerAfter = { _ in viewController3 } manager.select(viewController: viewController2, animated: false) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ // Start the appearance transitions. .beginAppearanceTransition(false, viewController1, false), .beginAppearanceTransition(true, viewController2, false), @@ -298,7 +298,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectShiftOneReverseWithoutAnimation() { + @Test func selectShiftOneReverseWithoutAnimation() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -315,7 +315,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerAfter = { _ in viewController2 } manager.select(viewController: viewController1, animated: false) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ // Start the appearance transitions. .beginAppearanceTransition(false, viewController2, false), .beginAppearanceTransition(true, viewController1, false), @@ -331,7 +331,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectNextAnimated() { + @Test func selectNextAnimated() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -345,7 +345,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerAfter = { _ in nil } dataSource.viewControllerBefore = { _ in - XCTFail() + Issue.record("Expected this to not be called") return nil } @@ -354,7 +354,7 @@ final class PageViewManagerTests: XCTestCase { // Assert that the willScroll event is triggered which means the // initialDirection state was reset. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .scrollForward, .isScrolling(from: viewController1, to: viewController2, progress: 0.1), .willScroll(from: viewController1, to: viewController2), @@ -363,7 +363,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectNextWithoutAnimation() { + @Test func selectNextWithoutAnimation() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -378,7 +378,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerAfter = { _ in viewController3 } dataSource.viewControllerBefore = { _ in - XCTFail() + Issue.record("Expected this to not be called") return nil } @@ -386,7 +386,7 @@ final class PageViewManagerTests: XCTestCase { // Expect that it moves the view controllers immediately instead // of triggered the .scrollForward event. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(false, viewController1, false), .beginAppearanceTransition(true, viewController2, false), .removeViewController(viewController0), @@ -397,7 +397,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectPreviousAnimated() { + @Test func selectPreviousAnimated() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -411,7 +411,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerBefore = { _ in nil } dataSource.viewControllerAfter = { _ in - XCTFail() + Issue.record("Expected this to not be called") return nil } @@ -420,7 +420,7 @@ final class PageViewManagerTests: XCTestCase { // Expect that the willScroll event is triggered which means the // initialDirection state was reset. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .scrollReverse, .isScrolling(from: viewController1, to: viewController0, progress: -0.1), .willScroll(from: viewController1, to: viewController0), @@ -429,7 +429,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectPreviousWithoutAnimation() { + @Test func selectPreviousWithoutAnimation() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -444,7 +444,7 @@ final class PageViewManagerTests: XCTestCase { dataSource.viewControllerBefore = { _ in viewController0 } dataSource.viewControllerAfter = { _ in - XCTFail() + Issue.record("Expected this to not be called") return nil } @@ -452,7 +452,7 @@ final class PageViewManagerTests: XCTestCase { // Expect that it moves the view controllers immediately instead // of triggered the .scrollForward event. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(false, viewController2, false), .beginAppearanceTransition(true, viewController1, false), .removeViewController(viewController3), @@ -465,7 +465,7 @@ final class PageViewManagerTests: XCTestCase { // MARK: - Scrolling - func testStartedScrollingForward() { + @Test func startedScrollingForward() { let selectedVc = UIViewController() let nextVc = UIViewController() @@ -477,7 +477,7 @@ final class PageViewManagerTests: XCTestCase { manager.willBeginDragging() manager.didScroll(progress: 0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: selectedVc, to: nextVc, progress: 0.1), .willScroll(from: selectedVc, to: nextVc), .beginAppearanceTransition(true, nextVc, true), @@ -485,7 +485,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testStartedScrollingForwardNextNil() { + @Test func startedScrollingForwardNextNil() { let selectedVc = UIViewController() manager.viewDidAppear(false) @@ -495,12 +495,12 @@ final class PageViewManagerTests: XCTestCase { manager.willBeginDragging() manager.didScroll(progress: 0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: selectedVc, to: nil, progress: 0.1), ]) } - func testStartedScrollingReverse() { + @Test func startedScrollingReverse() { let selectedVc = UIViewController() let previousVc = UIViewController() @@ -512,7 +512,7 @@ final class PageViewManagerTests: XCTestCase { manager.willBeginDragging() manager.didScroll(progress: -0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: selectedVc, to: previousVc, progress: -0.1), .willScroll(from: selectedVc, to: previousVc), .beginAppearanceTransition(true, previousVc, true), @@ -520,7 +520,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testStartedScrollingReversePreviousNil() { + @Test func startedScrollingReversePreviousNil() { let selectedVc = UIViewController() manager.viewDidAppear(false) @@ -530,12 +530,12 @@ final class PageViewManagerTests: XCTestCase { manager.willBeginDragging() manager.didScroll(progress: -0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: selectedVc, to: nil, progress: -0.1), ]) } - func testIsScrollingForward() { + @Test func isScrollingForward() { let selectedVc = UIViewController() let nextVc = UIViewController() @@ -549,13 +549,13 @@ final class PageViewManagerTests: XCTestCase { manager.didScroll(progress: 0.2) manager.didScroll(progress: 0.3) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: selectedVc, to: nextVc, progress: 0.2), .isScrolling(from: selectedVc, to: nextVc, progress: 0.3), ]) } - func testIsScrollingReverse() { + @Test func isScrollingReverse() { let previousVc = UIViewController() let selectedVc = UIViewController() @@ -569,13 +569,13 @@ final class PageViewManagerTests: XCTestCase { manager.didScroll(progress: -0.2) manager.didScroll(progress: -0.3) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: selectedVc, to: previousVc, progress: -0.2), .isScrolling(from: selectedVc, to: previousVc, progress: -0.3), ]) } - func testFinishedScrollingForward() { + @Test func finishedScrollingForward() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -592,7 +592,7 @@ final class PageViewManagerTests: XCTestCase { delegate.calls = [] manager.didScroll(progress: 1.0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController1, to: viewController2, progress: 1.0), .didFinishScrolling(from: viewController1, to: viewController2, success: true), .removeViewController(viewController0), @@ -603,7 +603,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testFinishedScrollingForwardNextNil() { + @Test func finishedScrollingForwardNextNil() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -620,7 +620,7 @@ final class PageViewManagerTests: XCTestCase { delegate.calls = [] manager.didScroll(progress: 1.0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController1, to: viewController2, progress: 1.0), .didFinishScrolling(from: viewController1, to: viewController2, success: true), .removeViewController(viewController0), @@ -630,7 +630,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testFinishedScrollingReverse() { + @Test func finishedScrollingReverse() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -648,7 +648,7 @@ final class PageViewManagerTests: XCTestCase { delegate.calls = [] manager.didScroll(progress: -1.0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController2, to: viewController1, progress: -1.0), .didFinishScrolling(from: viewController2, to: viewController1, success: true), .removeViewController(viewController3), @@ -659,7 +659,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testFinishedScrollingReversePreviousNil() { + @Test func finishedScrollingReversePreviousNil() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -676,7 +676,7 @@ final class PageViewManagerTests: XCTestCase { delegate.calls = [] manager.didScroll(progress: -1.0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController2, to: viewController1, progress: -1.0), .didFinishScrolling(from: viewController2, to: viewController1, success: true), .removeViewController(viewController3), @@ -686,7 +686,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testDidScrollAfterDraggingEnded() { + @Test func didScrollAfterDraggingEnded() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -710,13 +710,13 @@ final class PageViewManagerTests: XCTestCase { // Expect that it continues to trigger .isScrolling events for the // correct view controllers. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController1, to: viewController2, progress: 0.2), .isScrolling(from: viewController1, to: viewController2, progress: 0.3), ]) } - func testFinishedScrollingOvershooting() { + @Test func finishedScrollingOvershooting() { let viewController0 = UIViewController() let viewController1 = UIViewController() let viewController2 = UIViewController() @@ -740,14 +740,14 @@ final class PageViewManagerTests: XCTestCase { // Expect that it triggers .isScrolling events for scroll events // when overshooting, but does not trigger appearance transitions // for the next upcoming view (viewController3). - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController2, to: viewController3, progress: 0.0), .isScrolling(from: viewController2, to: viewController3, progress: 0.01), .isScrolling(from: viewController2, to: viewController3, progress: -0.01), ]) } - func testCancelScrollForward() { + @Test func cancelScrollForward() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -762,7 +762,7 @@ final class PageViewManagerTests: XCTestCase { delegate.calls = [] manager.didScroll(progress: 0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController2, to: viewController3, progress: 0.0), .beginAppearanceTransition(true, viewController2, true), .beginAppearanceTransition(false, viewController3, true), @@ -772,7 +772,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testCancelScrollReverse() { + @Test func cancelScrollReverse() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -787,7 +787,7 @@ final class PageViewManagerTests: XCTestCase { delegate.calls = [] manager.didScroll(progress: 0) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController2, to: viewController1, progress: 0.0), .beginAppearanceTransition(true, viewController2, true), .beginAppearanceTransition(false, viewController1, true), @@ -797,7 +797,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testCancelScrollForwardThenSwipeForwardAgain() { + @Test func cancelScrollForwardThenSwipeForwardAgain() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -816,7 +816,7 @@ final class PageViewManagerTests: XCTestCase { manager.willEndDragging() manager.didScroll(progress: 0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController2, to: viewController3, progress: 0.1), .willScroll(from: viewController2, to: viewController3), .beginAppearanceTransition(true, viewController3, true), @@ -824,7 +824,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testCancelScrollReverseThenSwipeReverseAgain() { + @Test func cancelScrollReverseThenSwipeReverseAgain() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -843,7 +843,7 @@ final class PageViewManagerTests: XCTestCase { manager.willEndDragging() manager.didScroll(progress: -0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController2, to: viewController1, progress: -0.1), .willScroll(from: viewController2, to: viewController1), .beginAppearanceTransition(true, viewController1, true), @@ -851,7 +851,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testCancelScrollForwardThenSwipeReverse() { + @Test func cancelScrollForwardThenSwipeReverse() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -869,7 +869,7 @@ final class PageViewManagerTests: XCTestCase { manager.willEndDragging() manager.didScroll(progress: -0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(true, viewController2, true), .beginAppearanceTransition(false, viewController3, true), .endAppearanceTransition(viewController2), @@ -882,7 +882,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testCancelScrollReverseThenSwipeForward() { + @Test func cancelScrollReverseThenSwipeForward() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -900,7 +900,7 @@ final class PageViewManagerTests: XCTestCase { manager.willEndDragging() manager.didScroll(progress: 0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(true, viewController2, true), .beginAppearanceTransition(false, viewController1, true), .endAppearanceTransition(viewController2), @@ -913,7 +913,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testStartedScrollingBeforeCurrentSwipeReloaded() { + @Test func startedScrollingBeforeCurrentSwipeReloaded() { let viewController1 = UIViewController() let viewController2 = UIViewController() let viewController3 = UIViewController() @@ -934,7 +934,7 @@ final class PageViewManagerTests: XCTestCase { manager.willEndDragging() manager.didScroll(progress: 0.1) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .isScrolling(from: viewController3, to: viewController4, progress: 0.1), .willScroll(from: viewController3, to: viewController4), .beginAppearanceTransition(true, viewController4, true), @@ -944,7 +944,7 @@ final class PageViewManagerTests: XCTestCase { // MARK: - Removing - func testRemoveAll() { + @Test func removeAll() { let previousVc = UIViewController() let selectedVc = UIViewController() let nextVc = UIViewController() @@ -960,7 +960,7 @@ final class PageViewManagerTests: XCTestCase { // Expects that it removes all view controller and starts // appearance transitions without animations. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(false, selectedVc, false), .removeViewController(selectedVc), .removeViewController(previousVc), @@ -972,73 +972,73 @@ final class PageViewManagerTests: XCTestCase { // MARK: - View Appearance - func testViewAppeared() { + @Test func viewAppeared() { let viewController = UIViewController() manager.select(viewController: viewController) delegate.calls = [] manager.viewWillAppear(false) manager.viewDidAppear(false) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(true, viewController, false), .layoutViews([viewController]), .endAppearanceTransition(viewController), ]) } - func testViewAppearedAnimated() { + @Test func viewAppearedAnimated() { let viewController = UIViewController() manager.select(viewController: viewController) delegate.calls = [] manager.viewWillAppear(true) manager.viewDidAppear(true) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(true, viewController, true), .layoutViews([viewController]), .endAppearanceTransition(viewController), ]) } - func testViewDisappeared() { + @Test func viewDisappeared() { let viewController = UIViewController() manager.select(viewController: viewController) delegate.calls = [] manager.viewWillDisappear(false) manager.viewDidDisappear(false) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(false, viewController, false), .endAppearanceTransition(viewController), ]) } - func testViewDidDisappearAnimated() { + @Test func viewDidDisappearAnimated() { let viewController = UIViewController() manager.select(viewController: viewController) delegate.calls = [] manager.viewWillDisappear(true) manager.viewDidDisappear(true) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(false, viewController, true), .endAppearanceTransition(viewController), ]) } - func testSelectBeforeViewAppeared() { + @Test func selectBeforeViewAppeared() { let viewController = UIViewController() manager.select(viewController: viewController) // Expect that the appearance transitions methods are not called // for the selected view controller. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .addViewController(viewController), .layoutViews([viewController]), ]) } - func testSelectWhenAppearing() { + @Test func selectWhenAppearing() { let viewController = UIViewController() manager.viewWillAppear(true) manager.select(viewController: viewController, animated: false) @@ -1046,7 +1046,7 @@ final class PageViewManagerTests: XCTestCase { // Expect that it begins appearance transitions with the same // animated flag as viewWillAppear. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(true, viewController, true), .addViewController(viewController), .layoutViews([viewController]), @@ -1054,7 +1054,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectWhenDisappearing() { + @Test func selectWhenDisappearing() { let viewController = UIViewController() manager.viewWillAppear(true) manager.viewDidAppear(true) @@ -1064,7 +1064,7 @@ final class PageViewManagerTests: XCTestCase { // Expect that it begins appearance transitions with the same // animated flag as viewWillDisappear. - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .beginAppearanceTransition(false, viewController, true), .addViewController(viewController), .layoutViews([viewController]), @@ -1072,7 +1072,7 @@ final class PageViewManagerTests: XCTestCase { ]) } - func testSelectWhenDisappeared() { + @Test func selectWhenDisappeared() { let viewController = UIViewController() manager.viewWillAppear(true) manager.viewDidAppear(true) @@ -1080,7 +1080,7 @@ final class PageViewManagerTests: XCTestCase { manager.viewDidDisappear(true) manager.select(viewController: viewController, animated: false) - XCTAssertEqual(delegate.calls, [ + #expect(delegate.calls == [ .addViewController(viewController), .layoutViews([viewController]), ]) diff --git a/ParchmentTests/PagingCollectionViewLayoutTests.swift b/ParchmentTests/PagingCollectionViewLayoutTests.swift index 4f136191..504b1501 100644 --- a/ParchmentTests/PagingCollectionViewLayoutTests.swift +++ b/ParchmentTests/PagingCollectionViewLayoutTests.swift @@ -1,96 +1,118 @@ -@testable import Parchment import UIKit -import XCTest +import Testing +@testable import Parchment @MainActor -final class PagingCollectionViewLayoutTests: XCTestCase { - private var window: UIWindow! - private var options: PagingOptions! - private var dataSource: DataSource! - private var sizeCache: PagingSizeCache! - private var layout: PagingCollectionViewLayout! - private var collectionView: UICollectionView! - - override func setUp() { +final class PagingCollectionViewLayoutTests { + private let options: PagingOptions + private let dataSource: DataSource + private let sizeCache: PagingSizeCache + private let layout: PagingCollectionViewLayout + private let collectionView: UICollectionView + + init() { options = PagingOptions() sizeCache = PagingSizeCache(options: options) + + layout = PagingCollectionViewLayout() + layout.options = options + layout.sizeCache = sizeCache + layout.state = .selected(pagingItem: Item(index: 0)) + layout.visibleItems = PagingItems(items: [ + Item(index: 0), + Item(index: 1), + Item(index: 2), + ]) + + dataSource = DataSource() + collectionView = UICollectionView( + frame: UIScreen.main.bounds, + collectionViewLayout: layout + ) + collectionView.dataSource = dataSource + collectionView.register( + Cell.self, + forCellWithReuseIdentifier: DataSource.CellIdentifier + ) + + // Trigger a layout invalidation by calling layoutIfNeeded + collectionView.layoutIfNeeded() } // MARK: - Cell Frames - func testCellFramesForItemSizeFixed() { - options.menuItemSize = .fixed(width: 100, height: 50) - setupLayout() - let frames = sortedCellFrames() + @Test func cellFramesForItemSizeFixed() { + layout.options.menuItemSize = .fixed(width: 100, height: 50) - XCTAssertEqual(frames, [ + let frames = createSortedCellFrames() + + #expect(frames == [ CGRect(x: 0, y: 0, width: 100, height: 50), CGRect(x: 100, y: 0, width: 100, height: 50), CGRect(x: 200, y: 0, width: 100, height: 50), ]) } - func testCellFramesForItemSizeToFit() { - options.menuItemSize = .sizeToFit(minWidth: 10, height: 50) - options.menuHorizontalAlignment = .center - setupLayout() - let frames = sortedCellFrames() + @Test func cellFramesForItemSizeToFit() { + layout.options.menuItemSize = .sizeToFit(minWidth: 10, height: 50) + layout.options.menuHorizontalAlignment = .center + + let frames = createSortedCellFrames() let expectedWidth = UIScreen.main.bounds.width / 3 - XCTAssertEqual(frames, [ + #expect(frames == [ CGRect(x: 0, y: 0, width: expectedWidth, height: 50), CGRect(x: expectedWidth, y: 0, width: expectedWidth, height: 50), CGRect(x: expectedWidth * 2, y: 0, width: expectedWidth, height: 50), ]) } - func testCellFramesForItemSizeToFitWhenMinWidthExtendsOutside() { + @Test func cellFramesForItemSizeToFitWhenMinWidthExtendsOutside() { let minWidth = UIScreen.main.bounds.width - options.menuItemSize = .sizeToFit(minWidth: minWidth, height: 50) - options.menuHorizontalAlignment = .center - setupLayout() - let frames = sortedCellFrames() + layout.options.menuItemSize = .sizeToFit(minWidth: minWidth, height: 50) + layout.options.menuHorizontalAlignment = .center - XCTAssertEqual(frames, [ + let frames = createSortedCellFrames() + + #expect(frames == [ CGRect(x: 0, y: 0, width: minWidth, height: 50), CGRect(x: minWidth, y: 0, width: minWidth, height: 50), CGRect(x: minWidth * 2, y: 0, width: minWidth, height: 50), ]) } - func testCellFramesForItemSizeToFitWhenUsingSizeDelegate() { + @Test func cellFramesForItemSizeToFitWhenUsingSizeDelegate() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, _ in 50 } - setupLayout() - options.menuItemSize = .sizeToFit(minWidth: 10, height: 50) - setupLayout() - let frames = sortedCellFrames() + layout.options.menuItemSize = .sizeToFit(minWidth: 10, height: 50) + + let frames = createSortedCellFrames() // Expects it to use the size delegate width and not size the // cells to match the bounds. - XCTAssertEqual(frames, [ + #expect(frames == [ CGRect(x: 0, y: 0, width: 50, height: 50), CGRect(x: 50, y: 0, width: 50, height: 50), CGRect(x: 100, y: 0, width: 50, height: 50), ]) } - func testCellFramesForItemSizeSelfSizing() { - options.menuItemSize = .selfSizing(estimatedWidth: 0, height: 50) - setupLayout() - let frames = sortedCellFrames() + @Test func cellFramesForItemSizeSelfSizing() { + layout.options.menuItemSize = .selfSizing(estimatedWidth: 0, height: 50) - XCTAssertEqual(frames, [ + let frames = createSortedCellFrames() + + #expect(frames == [ CGRect(x: 0, y: 0, width: 50, height: 50), CGRect(x: 50, y: 0, width: 100, height: 50), CGRect(x: 150, y: 0, width: 150, height: 50), ]) } - func testCellFramesForSizeDelegate() { - options.menuItemSize = .fixed(width: 0, height: 50) + @Test func cellFramesForSizeDelegate() { + layout.options.menuItemSize = .fixed(width: 0, height: 50) sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -99,19 +121,18 @@ final class PagingCollectionViewLayoutTests: XCTestCase { return 50 } } - setupLayout() - let frames = sortedCellFrames() + let frames = createSortedCellFrames() - XCTAssertEqual(frames, [ + #expect(frames == [ CGRect(x: 0, y: 0, width: 100, height: 50), CGRect(x: 100, y: 0, width: 50, height: 50), CGRect(x: 150, y: 0, width: 50, height: 50), ]) } - func testCellFramesForSizeDelegateWhenScrollingToItem() { - options.menuItemSize = .fixed(width: 0, height: 50) + @Test func cellFramesForSizeDelegateWhenScrollingToItem() { + layout.options.menuItemSize = .fixed(width: 0, height: 50) sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -120,7 +141,7 @@ final class PagingCollectionViewLayoutTests: XCTestCase { return 50 } } - setupLayout() + layout.state = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: Item(index: 1), @@ -131,40 +152,38 @@ final class PagingCollectionViewLayoutTests: XCTestCase { layout.invalidateLayout() collectionView.layoutIfNeeded() - let frames = sortedCellFrames() + let frames = createSortedCellFrames() - XCTAssertEqual(frames, [ + #expect(frames == [ CGRect(x: 0, y: 0, width: 75, height: 50), CGRect(x: 75, y: 0, width: 75, height: 50), CGRect(x: 150, y: 0, width: 50, height: 50), ]) } - func testCellFramesForHorizontalMenuAlignment() { - options.menuItemSize = .fixed(width: 10, height: 50) - options.menuHorizontalAlignment = .center - setupLayout() + @Test func cellFramesForHorizontalMenuAlignment() { + layout.options.menuItemSize = .fixed(width: 10, height: 50) + layout.options.menuHorizontalAlignment = .center - let frames = sortedCellFrames() + let frames = createSortedCellFrames() let expectedInsets = (UIScreen.main.bounds.width - 30) / 2 - XCTAssertEqual(frames, [ + #expect(frames == [ CGRect(x: expectedInsets, y: 0, width: 10, height: 50), CGRect(x: 10 + expectedInsets, y: 0, width: 10, height: 50), CGRect(x: 20 + expectedInsets, y: 0, width: 10, height: 50), ]) } - func testCellFramesForSelectedScrollPositionCentered() { + @Test func cellFramesForSelectedScrollPositionCentered() { let expectedWidth = UIScreen.main.bounds.width / 2 - options.menuItemSize = .fixed(width: expectedWidth, height: 50) - options.selectedScrollPosition = .center - setupLayout() + layout.options.menuItemSize = .fixed(width: expectedWidth, height: 50) + layout.options.selectedScrollPosition = .center - let frames = sortedCellFrames() + let frames = createSortedCellFrames() let expectedInsets = (UIScreen.main.bounds.width / 2) - (expectedWidth / 2) - XCTAssertEqual(frames, [ + #expect(frames == [ CGRect(x: expectedInsets, y: 0, width: expectedWidth, height: 50), CGRect(x: expectedInsets + expectedWidth, y: 0, width: expectedWidth, height: 50), CGRect(x: expectedInsets + expectedWidth * 2, y: 0, width: expectedWidth, height: 50), @@ -173,54 +192,50 @@ final class PagingCollectionViewLayoutTests: XCTestCase { // MARK: - Indicator Frame - func testIndicatorFrame() { - options.menuItemSize = .fixed(width: 100, height: 50) - options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: .zero) - setupLayout() + @Test func indicatorFrame() { + layout.options.menuItemSize = .fixed(width: 100, height: 50) + layout.options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: .zero) layout.state = .selected(pagingItem: Item(index: 1)) layout.invalidateLayout() collectionView.layoutIfNeeded() - let frame = indicatorFrame() + let frame = createIndicatorFrame() - XCTAssertEqual(frame, CGRect(x: 100, y: 40, width: 100, height: 10)) + #expect(frame == CGRect(x: 100, y: 40, width: 100, height: 10)) } - func testIndicatorFrameWithInsets() { + @Test func indicatorFrameWithInsets() { let insets = UIEdgeInsets(top: 0, left: 20, bottom: 20, right: 20) - options.menuItemSize = .fixed(width: 100, height: 50) - options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: insets) - setupLayout() + layout.options.menuItemSize = .fixed(width: 100, height: 50) + layout.options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: insets) layout.state = .selected(pagingItem: Item(index: 0)) layout.invalidateLayout() collectionView.layoutIfNeeded() - let frame = indicatorFrame() + let frame = createIndicatorFrame() - XCTAssertEqual(frame, CGRect(x: 20, y: 20, width: 80, height: 10)) + #expect(frame == CGRect(x: 20, y: 20, width: 80, height: 10)) } - func testIndicatorFrameWithSpacing() { + @Test func indicatorFrameWithSpacing() { let spacing = UIEdgeInsets(top: 0, left: 20, bottom: 20, right: 20) - options.menuItemSize = .fixed(width: 100, height: 50) - options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: spacing, insets: .zero) - setupLayout() + layout.options.menuItemSize = .fixed(width: 100, height: 50) + layout.options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: spacing, insets: .zero) layout.state = .selected(pagingItem: Item(index: 0)) layout.invalidateLayout() collectionView.layoutIfNeeded() - let frame = indicatorFrame() + let frame = createIndicatorFrame() - XCTAssertEqual(frame, CGRect(x: 20, y: 40, width: 60, height: 10)) + #expect(frame == CGRect(x: 20, y: 40, width: 60, height: 10)) } - func testIndicatorFrameOutsideFirstItem() { - options.menuItemSize = .fixed(width: 100, height: 50) - options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: .zero) - setupLayout() + @Test func indicatorFrameOutsideFirstItem() { + layout.options.menuItemSize = .fixed(width: 100, height: 50) + layout.options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: .zero) layout.state = .scrolling( pagingItem: Item(index: 0), @@ -232,15 +247,14 @@ final class PagingCollectionViewLayoutTests: XCTestCase { layout.invalidateLayout() collectionView.layoutIfNeeded() - let frame = indicatorFrame() + let frame = createIndicatorFrame() - XCTAssertEqual(frame, CGRect(x: -100, y: 40, width: 100, height: 10)) + #expect(frame == CGRect(x: -100, y: 40, width: 100, height: 10)) } - func testIndicatorFrameOutsideLastItem() { - options.menuItemSize = .fixed(width: 100, height: 50) - options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: .zero) - setupLayout() + @Test func indicatorFrameOutsideLastItem() { + layout.options.menuItemSize = .fixed(width: 100, height: 50) + layout.options.indicatorOptions = .visible(height: 10, zIndex: Int.max, spacing: .zero, insets: .zero) layout.state = .scrolling( pagingItem: Item(index: 3), @@ -252,39 +266,40 @@ final class PagingCollectionViewLayoutTests: XCTestCase { layout.invalidateLayout() collectionView.layoutIfNeeded() - let frame = indicatorFrame() + let frame = createIndicatorFrame() - XCTAssertEqual(frame, CGRect(x: 300, y: 40, width: 100, height: 10)) + #expect(frame == CGRect(x: 300, y: 40, width: 100, height: 10)) } // MARK: - Border Frame - func testBorderFrame() { - options.menuItemSize = .fixed(width: 100, height: 50) - options.borderOptions = .visible(height: 10, zIndex: Int.max, insets: .zero) - setupLayout() + @Test func borderFrame() { + layout.options.menuItemSize = .fixed(width: 100, height: 50) + layout.options.borderOptions = .visible(height: 10, zIndex: Int.max, insets: .zero) - let frame = borderFrame() + let frame = createBorderFrame() let expectedWidth = UIScreen.main.bounds.width - XCTAssertEqual(frame, CGRect(x: 0, y: 40, width: expectedWidth, height: 10)) + #expect(frame == CGRect(x: 0, y: 40, width: expectedWidth, height: 10)) } - func testBorderFrameWithInsets() { + @Test func borderFrameWithInsets() { let insets = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20) - options.menuItemSize = .fixed(width: 100, height: 50) - options.borderOptions = .visible(height: 10, zIndex: Int.max, insets: insets) - setupLayout() + layout.options.menuItemSize = .fixed(width: 100, height: 50) + layout.options.borderOptions = .visible(height: 10, zIndex: Int.max, insets: insets) - let frame = borderFrame() + let frame = createBorderFrame() let expectedWidth = UIScreen.main.bounds.width - insets.left - insets.right - XCTAssertEqual(frame, CGRect(x: insets.left, y: 40, width: expectedWidth, height: 10)) + #expect(frame == CGRect(x: insets.left, y: 40, width: expectedWidth, height: 10)) } // MARK: - Private - private func borderFrame() -> CGRect? { + private func createBorderFrame() -> CGRect? { + layout.invalidateLayout() + collectionView.layoutIfNeeded() + let layoutAttributes = layout.layoutAttributesForElements(in: collectionView.bounds) ?? [] return layoutAttributes .filter { $0 is PagingBorderLayoutAttributes } @@ -292,7 +307,10 @@ final class PagingCollectionViewLayoutTests: XCTestCase { .first } - private func indicatorFrame() -> CGRect? { + private func createIndicatorFrame() -> CGRect? { + layout.invalidateLayout() + collectionView.layoutIfNeeded() + let layoutAttributes = layout.layoutAttributesForElements(in: collectionView.bounds) ?? [] return layoutAttributes .filter { $0 is PagingIndicatorLayoutAttributes } @@ -300,43 +318,16 @@ final class PagingCollectionViewLayoutTests: XCTestCase { .first } - private func sortedCellFrames() -> [CGRect] { + private func createSortedCellFrames() -> [CGRect] { + layout.invalidateLayout() + collectionView.layoutIfNeeded() + let layoutAttributes = layout.layoutAttributesForElements(in: collectionView.bounds) ?? [] return layoutAttributes .filter { $0 is PagingCellLayoutAttributes } .sorted { $0.indexPath < $1.indexPath } .map { $0.frame } } - - private func setupLayout() { - layout = PagingCollectionViewLayout() - layout.options = options - layout.sizeCache = sizeCache - layout.state = .selected(pagingItem: Item(index: 0)) - layout.visibleItems = PagingItems(items: [ - Item(index: 0), - Item(index: 1), - Item(index: 2), - ]) - - dataSource = DataSource() - collectionView = UICollectionView( - frame: UIScreen.main.bounds, - collectionViewLayout: layout - ) - collectionView.dataSource = dataSource - collectionView.register( - Cell.self, - forCellWithReuseIdentifier: DataSource.CellIdentifier - ) - - window = UIWindow(frame: UIScreen.main.bounds) - window.addSubview(collectionView) - window.makeKeyAndVisible() - - // Trigger a layout invalidation by calling layoutIfNeeded - collectionView.layoutIfNeeded() - } } private final class DataSource: NSObject, UICollectionViewDataSource { diff --git a/ParchmentTests/PagingControllerTests.swift b/ParchmentTests/PagingControllerTests.swift index c4317b92..31b5f535 100644 --- a/ParchmentTests/PagingControllerTests.swift +++ b/ParchmentTests/PagingControllerTests.swift @@ -1,32 +1,35 @@ import Foundation -import XCTest +import Testing @testable import Parchment -final class PagingControllerTests: XCTestCase { +@MainActor +final class PagingControllerTests { static let ItemSize: CGFloat = 50 - var options: PagingOptions! - var collectionView: MockCollectionView! - var collectionViewLayout: MockCollectionViewLayout! - var dataSource: MockPagingControllerDataSource! - var delegate: MockPagingControllerDelegate! - var sizeDelegate: MockPagingControllerSizeDelegate? - var pagingController: PagingController! - - @MainActor - override func setUp() { - options = PagingOptions() + private let options: PagingOptions + private let collectionView: MockCollectionView + private let collectionViewLayout: MockCollectionViewLayout + private let dataSource: MockPagingControllerDataSource + private let delegate: MockPagingControllerDelegate + private var sizeDelegate: MockPagingControllerSizeDelegate? + private let pagingController: PagingController + private let window: UIWindow + + init() { + var options = PagingOptions() options.selectedScrollPosition = .left options.menuItemSize = .fixed( width: PagingControllerTests.ItemSize, height: PagingControllerTests.ItemSize ) + self.options = options + window = UIWindow(frame: .zero) collectionViewLayout = MockCollectionViewLayout() collectionView = MockCollectionView() collectionView.superview = UIView(frame: .zero) collectionView.collectionViewLayout = collectionViewLayout - collectionView.window = UIWindow(frame: .zero) + collectionView.window = window collectionView.bounds = CGRect( origin: .zero, size: CGSize( @@ -34,24 +37,25 @@ final class PagingControllerTests: XCTestCase { height: PagingControllerTests.ItemSize ) ) - collectionView.visibleItems = { - self.pagingController.visibleItems.items.count - } dataSource = MockPagingControllerDataSource() delegate = MockPagingControllerDelegate() - pagingController = PagingController(options: options) + let pagingController = PagingController(options: options) pagingController.collectionView = collectionView pagingController.collectionViewLayout = collectionViewLayout pagingController.dataSource = dataSource pagingController.delegate = delegate + self.pagingController = pagingController + + collectionView.visibleItems = { + pagingController.visibleItems.items.count + } } // MARK: - Content scrolled - @MainActor - func testContentScrolledFromSelectedProgressPositive() { + @Test func contentScrolledFromSelectedProgressPositive() { // Select the first item. pagingController.select(pagingItem: Item(index: 3), animated: false) @@ -63,7 +67,7 @@ final class PagingControllerTests: XCTestCase { pagingController.contentScrolled(progress: 0.5) // Expect to enter the .scrolling state and update the content offset - XCTAssertEqual(pagingController.state, PagingState.scrolling( + #expect(pagingController.state == PagingState.scrolling( pagingItem: Item(index: 3), upcomingPagingItem: Item(index: 4), progress: 0.5, @@ -75,7 +79,7 @@ final class PagingControllerTests: XCTestCase { // collection view layout to ensure that they were called in // the correct order. let actions = combinedActions(collectionView.calls, collectionViewLayout.calls) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.setContentOffset( contentOffset: CGPoint(x: 125, y: 0), animated: false @@ -86,8 +90,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testContentScrolledFromSelectedProgressNegative() { + @Test func contentScrolledFromSelectedProgressNegative() { // Select the first item. pagingController.select(pagingItem: Item(index: 3), animated: false) @@ -99,7 +102,7 @@ final class PagingControllerTests: XCTestCase { pagingController.contentScrolled(progress: -0.1) // Expect to enter the .scrolling state and update the content offset - XCTAssertEqual(pagingController.state, PagingState.scrolling( + #expect(pagingController.state == PagingState.scrolling( pagingItem: Item(index: 3), upcomingPagingItem: Item(index: 2), progress: -0.1, @@ -111,7 +114,7 @@ final class PagingControllerTests: XCTestCase { // collection view layout to ensure that they were called in // the correct order. let actions = combinedActions(collectionView.calls, collectionViewLayout.calls) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.setContentOffset( contentOffset: CGPoint(x: 95, y: 0), animated: false @@ -122,8 +125,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testContentOffsetFromSelectedProgressZero() { + @Test func contentOffsetFromSelectedProgressZero() { // Select the first item. pagingController.select(pagingItem: Item(index: 3), animated: false) @@ -135,15 +137,14 @@ final class PagingControllerTests: XCTestCase { pagingController.contentScrolled(progress: 0) // Expect to not update the state or call any methods. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(pagingController.state, PagingState.selected( + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(pagingController.state == PagingState.selected( pagingItem: Item(index: 3) )) } - @MainActor - func testContentScrolledNoUpcomingPagingItem() { + @Test func contentScrolledNoUpcomingPagingItem() { // Prevent the data source from returning an upcoming item. dataSource.maxIndexAfter = 3 @@ -159,15 +160,14 @@ final class PagingControllerTests: XCTestCase { // Expect that the content offset is not updated. let actions = combinedActions(collectionView.calls, collectionViewLayout.calls) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionViewLayout(.invalidateLayoutWithContext( invalidateSizes: false )), ]) } - @MainActor - func testContentScrolledSizeDelegate() { + @Test func contentScrolledSizeDelegate() { // Setup the size delegate. sizeDelegate = MockPagingControllerSizeDelegate() sizeDelegate?.pagingItemWidth = { 100 } @@ -181,13 +181,12 @@ final class PagingControllerTests: XCTestCase { // Expect it to invalidate the collection view layout sizes. let action = collectionViewLayout.calls.last?.action - XCTAssertEqual(action, .collectionViewLayout(.invalidateLayoutWithContext( + #expect(action == .collectionViewLayout(.invalidateLayoutWithContext( invalidateSizes: true ))) } - @MainActor - func testContentScrolledNoUpcomingPagingItemAndSizeDelegate() { + @Test func contentScrolledNoUpcomingPagingItemAndSizeDelegate() { // Prevent the data source from returning an upcoming item. dataSource.maxIndexAfter = 3 @@ -208,15 +207,14 @@ final class PagingControllerTests: XCTestCase { // Expect it does not update the content offset or invalidate the sizes. let actions = combinedActions(collectionView.calls, collectionViewLayout.calls) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionViewLayout(.invalidateLayoutWithContext( invalidateSizes: false )), ]) } - @MainActor - func testContentScrolledUpcomingItemOutsideVisibleItems() { + @Test func contentScrolledUpcomingItemOutsideVisibleItems() { // Select the first item, and scroll to the edge of the // collection view a few times to make sure the selected // item is no longer in view. @@ -239,7 +237,7 @@ final class PagingControllerTests: XCTestCase { // The visible items should now contain the items that were // visible before scrolling (6..10), plus the items around // the selected item (0...4). - XCTAssertEqual(pagingController.visibleItems.items as? [Item], [ + #expect(pagingController.visibleItems.items as? [Item] == [ Item(index: 0), Item(index: 1), Item(index: 2), @@ -256,7 +254,7 @@ final class PagingControllerTests: XCTestCase { // collection view layout to ensure that they were called in // the correct order. let actions = combinedActions(collectionView.calls, collectionViewLayout.calls) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.reloadData), .collectionViewLayout(.prepare), .collectionView(.contentOffset(CGPoint(x: 400, y: 0))), @@ -271,8 +269,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testContentScrolledProgressChangedFromPositiveToNegative() { + @Test func contentScrolledProgressChangedFromPositiveToNegative() { // Select an item and enter the scrolling state. pagingController.select(pagingItem: Item(index: 1), animated: false) pagingController.contentScrolled(progress: 0.1) @@ -285,15 +282,14 @@ final class PagingControllerTests: XCTestCase { pagingController.contentScrolled(progress: -0.1) // Expect that it enters the selected state. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(pagingController.state, PagingState.selected( + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(pagingController.state == PagingState.selected( pagingItem: Item(index: 1) )) } - @MainActor - func testContentScrolledProgressChangedFromNegativeToPositive() { + @Test func contentScrolledProgressChangedFromNegativeToPositive() { // Select an item and enter the scrolling state. pagingController.select(pagingItem: Item(index: 1), animated: false) pagingController.contentScrolled(progress: -0.1) @@ -306,15 +302,14 @@ final class PagingControllerTests: XCTestCase { pagingController.contentScrolled(progress: 0.1) // Expect that it enters the selected state. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(pagingController.state, PagingState.selected( + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(pagingController.state == PagingState.selected( pagingItem: Item(index: 1) )) } - @MainActor - func testContentScrolledProgressChangedToZero() { + @Test func contentScrolledProgressChangedToZero() { // Select an item and enter the scrolling state. pagingController.select(pagingItem: Item(index: 1), animated: false) pagingController.contentScrolled(progress: -0.1) @@ -327,15 +322,14 @@ final class PagingControllerTests: XCTestCase { pagingController.contentScrolled(progress: 0) // Expect that it enters the selected state. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(pagingController.state, PagingState.selected( + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(pagingController.state == PagingState.selected( pagingItem: Item(index: 1) )) } - @MainActor - func testContentScrolledProgressChangedSameSign() { + @Test func contentScrolledProgressChangedSameSign() { // Select an item and enter the scrolling state. pagingController.select(pagingItem: Item(index: 1), animated: false) pagingController.contentScrolled(progress: 0.1) @@ -348,7 +342,7 @@ final class PagingControllerTests: XCTestCase { pagingController.contentScrolled(progress: 0.2) // Expect it to update the scrolling state and update the content offset. - XCTAssertEqual(pagingController.state, PagingState.scrolling( + #expect(pagingController.state == PagingState.scrolling( pagingItem: Item(index: 1), upcomingPagingItem: Item(index: 2), progress: 0.2, @@ -360,7 +354,7 @@ final class PagingControllerTests: XCTestCase { // collection view layout to ensure that they were called in // the correct order. let actions = combinedActions(collectionView.calls, collectionViewLayout.calls) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.setContentOffset( contentOffset: CGPoint(x: 110, y: 0), animated: false @@ -373,20 +367,18 @@ final class PagingControllerTests: XCTestCase { // MARK: - Select item - @MainActor - func testSelectWhileEmpty() { + @Test func selectWhileEmpty() { // Make sure there is no item before index 0. dataSource.minIndexBefore = 0 - // Make sure we have a superview and window + // Make sure we have a superview collectionView.superview = UIView(frame: .zero) - collectionView.window = UIWindow(frame: .zero) // Select the first item. pagingController.select(pagingItem: Item(index: 0), animated: false) // Expect it to enter selected state. - XCTAssertEqual(pagingController.state, PagingState.selected( + #expect(pagingController.state == PagingState.selected( pagingItem: Item(index: 0) )) @@ -399,7 +391,7 @@ final class PagingControllerTests: XCTestCase { delegate.calls ) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.reloadData), .collectionViewLayout(.prepare), .collectionView(.contentOffset(.zero)), @@ -418,8 +410,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testSelectWhileEmptyAndNoSuperview() { + @Test func selectWhileEmptyAndNoSuperview() { // Remove the superview. collectionView.superview = nil @@ -427,16 +418,15 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 0), animated: false) // Expect it to enter the selected state with no actions. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(delegate.calls, []) - XCTAssertEqual(pagingController.state, PagingState.selected( + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(delegate.calls == []) + #expect(pagingController.state == PagingState.selected( pagingItem: Item(index: 0) )) } - @MainActor - func testSelectWhileEmptyAndNoWindow() { + @Test func selectWhileEmptyAndNoWindow() { // Remove the window and make sure we have a superview. collectionView.superview = UIView(frame: .zero) collectionView.window = nil @@ -444,16 +434,15 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 0), animated: false) // Expect it to enter the selected state with no actions. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(delegate.calls, []) - XCTAssertEqual(pagingController.state, PagingState.selected( + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(delegate.calls == []) + #expect(pagingController.state == PagingState.selected( pagingItem: Item(index: 0) )) } - @MainActor - func testSelectItemWhileScrolling() { + @Test func selectItemWhileScrolling() { // Select an item and enter the scrolling state. pagingController.select(pagingItem: Item(index: 1), animated: false) pagingController.contentScrolled(progress: -0.1) @@ -468,14 +457,13 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 2), animated: false) // Expect it do not change the state. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(delegate.calls, []) - XCTAssertEqual(pagingController.state, oldState) + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(delegate.calls == []) + #expect(pagingController.state == oldState) } - @MainActor - func testSelectSameItem() { + @Test func selectSameItem() { // Select an item and enter the scrolling state. pagingController.select(pagingItem: Item(index: 0), animated: false) @@ -489,14 +477,13 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 0), animated: false) // Expect it do not change the state. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(delegate.calls, []) - XCTAssertEqual(pagingController.state, oldState) + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(delegate.calls == []) + #expect(pagingController.state == oldState) } - @MainActor - func testSelectDifferentItem() { + @Test func selectDifferentItem() { // Make sure there is no item before index 0. dataSource.minIndexBefore = 0 @@ -512,7 +499,7 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 0), animated: true) // Expect it to enter the scrolling state. - XCTAssertEqual(pagingController.state, PagingState.scrolling( + #expect(pagingController.state == PagingState.scrolling( pagingItem: Item(index: 1), upcomingPagingItem: Item(index: 0), progress: 0, @@ -521,8 +508,7 @@ final class PagingControllerTests: XCTestCase { )) } - @MainActor - func testSelectPreviousSibling() { + @Test func selectPreviousSibling() { // Make sure there is no item before index 0. dataSource.minIndexBefore = 0 @@ -538,9 +524,9 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 0), animated: true) // Expect it to select the previous content view. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(actions(delegate.calls), [ + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(actions(delegate.calls) == [ .delegate(.selectContent( pagingItem: Item(index: 0), direction: .reverse(sibling: true), @@ -549,8 +535,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testSelectNextSibling() { + @Test func selectNextSibling() { // Make sure there is no item before index 0. dataSource.minIndexBefore = 0 @@ -566,9 +551,9 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 2), animated: true) // Expect it to select the previous content view. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(actions(delegate.calls), [ + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(actions(delegate.calls) == [ .delegate(.selectContent( pagingItem: Item(index: 2), direction: .forward(sibling: true), @@ -577,8 +562,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testSelectNotSibling() { + @Test func selectNotSibling() { // Make sure there is no item before index 0. dataSource.minIndexBefore = 0 @@ -594,9 +578,9 @@ final class PagingControllerTests: XCTestCase { pagingController.select(pagingItem: Item(index: 4), animated: true) // Expect it to select the content view. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(actions(delegate.calls), [ + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(actions(delegate.calls) == [ .delegate(.selectContent( pagingItem: Item(index: 4), direction: .forward(sibling: false), @@ -605,8 +589,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testSelectItemOutsideVisibleItems() { + @Test func selectItemOutsideVisibleItems() { // Select the first item, and scroll to the edge of the // collection view a few times to make sure the selected // item is no longer in view. @@ -631,7 +614,7 @@ final class PagingControllerTests: XCTestCase { // The visible items should now contain the items that were // visible before scrolling (6..10), plus the items around // the selected item (0...4). - XCTAssertEqual(pagingController.visibleItems.items as? [Item], [ + #expect(pagingController.visibleItems.items as? [Item] == [ Item(index: 0), Item(index: 1), Item(index: 2), @@ -653,7 +636,7 @@ final class PagingControllerTests: XCTestCase { delegate.calls ) - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.reloadData), .collectionViewLayout(.prepare), .collectionView(.contentOffset(CGPoint(x: 400, y: 0))), @@ -668,8 +651,7 @@ final class PagingControllerTests: XCTestCase { // MARK: - Content finished scrolling - @MainActor - func testContentFinishedScrollingWithUpcomingItem() { + @Test func contentFinishedScrollingWithUpcomingItem() { // Select an item and enter the scrolling state. dataSource.minIndexBefore = 0 pagingController.select(pagingItem: Item(index: 0), animated: false) @@ -684,7 +666,7 @@ final class PagingControllerTests: XCTestCase { pagingController.contentFinishedScrolling() // Expect it to enter the selected state with the upcoming item. - XCTAssertEqual(pagingController.state, .selected(pagingItem: Item(index: 1))) + #expect(pagingController.state == .selected(pagingItem: Item(index: 1))) // Combine the method calls for the collection view, // collection view layout and delegate to ensure that @@ -697,7 +679,7 @@ final class PagingControllerTests: XCTestCase { // Expect it to reload data, update the layout and select the item // in the collectio view. - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.reloadData), .collectionViewLayout(.prepare), .collectionView(.contentOffset(CGPoint(x: 0, y: 0))), @@ -711,8 +693,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testContentFinishedScrollingCollectionViewBeingDragged() { + @Test func contentFinishedScrollingCollectionViewBeingDragged() { // Select an item and enter the scrolling state. dataSource.minIndexBefore = 0 pagingController.select(pagingItem: Item(index: 0), animated: false) @@ -728,13 +709,12 @@ final class PagingControllerTests: XCTestCase { pagingController.contentFinishedScrolling() // Expect it to not update the collection view. - XCTAssertEqual(collectionView.calls, []) - XCTAssertEqual(collectionViewLayout.calls, []) - XCTAssertEqual(delegate.calls, []) + #expect(collectionView.calls == []) + #expect(collectionViewLayout.calls == []) + #expect(delegate.calls == []) } - @MainActor - func testContentFinishedScrollingWihtoutUpcomingItem() { + @Test func contentFinishedScrollingWihtoutUpcomingItem() { // Select an item and enter the scrolling state. dataSource.minIndexBefore = 0 pagingController.select(pagingItem: Item(index: 0), animated: false) @@ -749,13 +729,12 @@ final class PagingControllerTests: XCTestCase { pagingController.contentFinishedScrolling() // Expect it to set the selected item to equal the current paging item. - XCTAssertEqual(pagingController.state, .selected(pagingItem: Item(index: 0))) + #expect(pagingController.state == .selected(pagingItem: Item(index: 0))) } // MARK: - Transition size - @MainActor - func testTransitionSize() { + @Test func transitionSize() { dataSource.minIndexBefore = 0 pagingController.select(pagingItem: Item(index: 0), animated: false) @@ -778,7 +757,7 @@ final class PagingControllerTests: XCTestCase { // Expect it to reload data, update the layout and selects the // current item. - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionView(.reloadData), .collectionViewLayout(.prepare), .collectionView(.contentOffset(.zero)), @@ -792,8 +771,7 @@ final class PagingControllerTests: XCTestCase { ]) } - @MainActor - func testTransitionSizeWhenSelected() { + @Test func transitionSizeWhenSelected() { dataSource.minIndexBefore = 0 pagingController.select(pagingItem: Item(index: 0), animated: false) @@ -806,11 +784,10 @@ final class PagingControllerTests: XCTestCase { pagingController.transitionSize() // Expect it to not update the state. - XCTAssertEqual(pagingController.state, .selected(pagingItem: Item(index: 0))) + #expect(pagingController.state == .selected(pagingItem: Item(index: 0))) } - @MainActor - func testTransitionSizeWhenScrolling() { + @Test func transitionSizeWhenScrolling() { dataSource.minIndexBefore = 0 pagingController.select(pagingItem: Item(index: 0), animated: false) @@ -826,22 +803,21 @@ final class PagingControllerTests: XCTestCase { pagingController.transitionSize() // Expect it to select the current item. - XCTAssertEqual(pagingController.state, .selected(pagingItem: Item(index: 0))) + #expect(pagingController.state == .selected(pagingItem: Item(index: 0))) } // MARK: - Reload data - @MainActor - func testReloadData() { + @Test func reloadData() { pagingController.reloadData(around: Item(index: 2)) // Expect it to select the given item - XCTAssertEqual(pagingController.state, .selected(pagingItem: Item(index: 2))) + #expect(pagingController.state == .selected(pagingItem: Item(index: 2))) // Expect it to generate items around the given item - XCTAssertTrue(pagingController.visibleItems.hasItemsBefore) - XCTAssertTrue(pagingController.visibleItems.hasItemsAfter) - XCTAssertEqual(pagingController.visibleItems.items as? [Item], [ + #expect(pagingController.visibleItems.hasItemsBefore) + #expect(pagingController.visibleItems.hasItemsAfter) + #expect(pagingController.visibleItems.items as? [Item] == [ Item(index: 0), Item(index: 1), Item(index: 2), @@ -860,7 +836,7 @@ final class PagingControllerTests: XCTestCase { // Expect it to reload data in the collection view and update the // content view with the new view controllers. - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionViewLayout(.invalidateLayout), .collectionView(.reloadData), .delegate(.removeContent), @@ -875,17 +851,16 @@ final class PagingControllerTests: XCTestCase { // MARK: - Reload menu - @MainActor - func testReloadMenu() { + @Test func reloadMenu() { pagingController.reloadMenu(around: Item(index: 2)) // Expect it to select the given item - XCTAssertEqual(pagingController.state, .selected(pagingItem: Item(index: 2))) + #expect(pagingController.state == .selected(pagingItem: Item(index: 2))) // Expect it to generate items around the given item - XCTAssertTrue(pagingController.visibleItems.hasItemsBefore) - XCTAssertTrue(pagingController.visibleItems.hasItemsAfter) - XCTAssertEqual(pagingController.visibleItems.items as? [Item], [ + #expect(pagingController.visibleItems.hasItemsBefore) + #expect(pagingController.visibleItems.hasItemsAfter) + #expect(pagingController.visibleItems.items as? [Item] == [ Item(index: 0), Item(index: 1), Item(index: 2), @@ -904,7 +879,7 @@ final class PagingControllerTests: XCTestCase { // Expect it to reload data in the collection view, but leave the // content view unchanged. - XCTAssertEqual(actions, [ + #expect(actions == [ .collectionViewLayout(.invalidateLayout), .collectionView(.reloadData), ]) diff --git a/ParchmentTests/PagingDataStructureTests.swift b/ParchmentTests/PagingDataStructureTests.swift index a98b1ff2..6d1edbd2 100644 --- a/ParchmentTests/PagingDataStructureTests.swift +++ b/ParchmentTests/PagingDataStructureTests.swift @@ -1,11 +1,11 @@ import Foundation +import Testing @testable import Parchment -import XCTest -final class PagingDataTests: XCTestCase { - var visibleItems: PagingItems! +struct PagingDataTests { + private let visibleItems: PagingItems - override func setUp() { + init() { visibleItems = PagingItems(items: [ Item(index: 0), Item(index: 1), @@ -13,33 +13,33 @@ final class PagingDataTests: XCTestCase { ]) } - func testIndexPathForPagingItemFound() { + @Test func indexPathForPagingItemFound() { let indexPath = visibleItems.indexPath(for: Item(index: 0))! - XCTAssertEqual(indexPath.item, 0) + #expect(indexPath.item == 0) } - func testIndexPathForPagingItemMissing() { + @Test func indexPathForPagingItemMissing() { let indexPath = visibleItems.indexPath(for: Item(index: -1)) - XCTAssertNil(indexPath) + #expect(indexPath == nil) } - func testPagingItemForIndexPath() { + @Test func pagingItemForIndexPath() { let indexPath = IndexPath(item: 0, section: 0) let pagingItem = visibleItems.pagingItem(for: indexPath) as! Item - XCTAssertEqual(pagingItem, Item(index: 0)) + #expect(pagingItem == Item(index: 0)) } - func testDirectionForIndexPathForward() { + @Test func directionForIndexPathForward() { let currentPagingItem = Item(index: 0) let upcomingPagingItem = Item(index: 1) let direction = visibleItems.direction(from: currentPagingItem, to: upcomingPagingItem) - XCTAssertEqual(direction, PagingDirection.forward(sibling: true)) + #expect(direction == PagingDirection.forward(sibling: true)) } - func testDirectionForIndexPathReverse() { + @Test func directionForIndexPathReverse() { let currentPagingItem = Item(index: 1) let upcomingPagingItem = Item(index: 0) let direction = visibleItems.direction(from: currentPagingItem, to: upcomingPagingItem) - XCTAssertEqual(direction, PagingDirection.reverse(sibling: true)) + #expect(direction == PagingDirection.reverse(sibling: true)) } } diff --git a/ParchmentTests/PagingDiffTests.swift b/ParchmentTests/PagingDiffTests.swift index 4ba1d1e9..0137ec83 100644 --- a/ParchmentTests/PagingDiffTests.swift +++ b/ParchmentTests/PagingDiffTests.swift @@ -1,53 +1,53 @@ import Foundation +import Testing @testable import Parchment -import XCTest -final class PagingDiffTests: XCTestCase { - func testDetectsAddedItemsBeforeCenter() { +struct PagingDiffTests { + @Test func detectsAddedItemsBeforeCenter() { let from = PagingItems(items: [Item(index: 1)]) let to = PagingItems(items: [Item(index: 0), Item(index: 1)]) let diff = PagingDiff(from: from, to: to) let added = diff.added() let removed = diff.removed() - XCTAssertEqual(added.count, 1) - XCTAssertEqual(added[0], IndexPath(item: 0, section: 0)) - XCTAssertEqual(removed, []) + #expect(added.count == 1) + #expect(added[0] == IndexPath(item: 0, section: 0)) + #expect(removed == []) } - func testIgnoresAddedItemsAfterCenter() { + @Test func ignoresAddedItemsAfterCenter() { let from = PagingItems(items: [Item(index: 0)]) let to = PagingItems(items: [Item(index: 0), Item(index: 1)]) let diff = PagingDiff(from: from, to: to) - XCTAssertEqual(diff.added(), []) - XCTAssertEqual(diff.removed(), []) + #expect(diff.added() == []) + #expect(diff.removed() == []) } - func testIgnoresRemovedItemsAfterCenter() { + @Test func ignoresRemovedItemsAfterCenter() { let from = PagingItems(items: [Item(index: 0), Item(index: 1)]) let to = PagingItems(items: [Item(index: 0)]) let diff = PagingDiff(from: from, to: to) - XCTAssertEqual(diff.removed(), []) - XCTAssertEqual(diff.added(), []) + #expect(diff.removed() == []) + #expect(diff.added() == []) } - func testDetectsRemovedItemsBeforeCenter() { + @Test func detectsRemovedItemsBeforeCenter() { let from = PagingItems(items: [Item(index: 0), Item(index: 1)]) let to = PagingItems(items: [Item(index: 1)]) let diff = PagingDiff(from: from, to: to) let removed = diff.removed() let added = diff.added() - XCTAssertEqual(added, []) - XCTAssertEqual(removed.count, 1) - XCTAssertEqual(removed[0], IndexPath(item: 0, section: 0)) + #expect(added == []) + #expect(removed.count == 1) + #expect(removed[0] == IndexPath(item: 0, section: 0)) } // TODO: Reduce these tests to a minimal test case and update // the descriptions. - func testScenario1() { + @Test func scenario1() { let from = PagingItems(items: [ Item(index: 16), Item(index: 17), @@ -88,18 +88,18 @@ final class PagingDiffTests: XCTestCase { let added = diff.added() let removed = diff.removed() - XCTAssertEqual(removed, []) - XCTAssertEqual(added.count, 7) - XCTAssertEqual(added[0], IndexPath(item: 0, section: 0)) - XCTAssertEqual(added[1], IndexPath(item: 1, section: 0)) - XCTAssertEqual(added[2], IndexPath(item: 2, section: 0)) - XCTAssertEqual(added[3], IndexPath(item: 3, section: 0)) - XCTAssertEqual(added[4], IndexPath(item: 4, section: 0)) - XCTAssertEqual(added[5], IndexPath(item: 5, section: 0)) - XCTAssertEqual(added[6], IndexPath(item: 6, section: 0)) + #expect(removed == []) + #expect(added.count == 7) + #expect(added[0] == IndexPath(item: 0, section: 0)) + #expect(added[1] == IndexPath(item: 1, section: 0)) + #expect(added[2] == IndexPath(item: 2, section: 0)) + #expect(added[3] == IndexPath(item: 3, section: 0)) + #expect(added[4] == IndexPath(item: 4, section: 0)) + #expect(added[5] == IndexPath(item: 5, section: 0)) + #expect(added[6] == IndexPath(item: 6, section: 0)) } - func testScenario2() { + @Test func scenario2() { let from = PagingItems(items: [ Item(index: 0), Item(index: 1), @@ -127,14 +127,14 @@ final class PagingDiffTests: XCTestCase { let diff = PagingDiff(from: from, to: to) let removed = diff.removed() - XCTAssertEqual(removed.count, 4) - XCTAssertEqual(removed[0], IndexPath(item: 0, section: 0)) - XCTAssertEqual(removed[1], IndexPath(item: 1, section: 0)) - XCTAssertEqual(removed[2], IndexPath(item: 2, section: 0)) - XCTAssertEqual(removed[3], IndexPath(item: 3, section: 0)) + #expect(removed.count == 4) + #expect(removed[0] == IndexPath(item: 0, section: 0)) + #expect(removed[1] == IndexPath(item: 1, section: 0)) + #expect(removed[2] == IndexPath(item: 2, section: 0)) + #expect(removed[3] == IndexPath(item: 3, section: 0)) } - func testScenario3() { + @Test func scenario3() { let from = PagingItems(items: [ Item(index: 1), Item(index: 2), @@ -151,8 +151,8 @@ final class PagingDiffTests: XCTestCase { let added = diff.added() let removed = diff.removed() - XCTAssertEqual(added, []) - XCTAssertEqual(removed.count, 1) - XCTAssertEqual(removed[0], IndexPath(item: 0, section: 0)) + #expect(added == []) + #expect(removed.count == 1) + #expect(removed[0] == IndexPath(item: 0, section: 0)) } } diff --git a/ParchmentTests/PagingDistanceCenteredTests.swift b/ParchmentTests/PagingDistanceCenteredTests.swift index 9559433a..3b779097 100644 --- a/ParchmentTests/PagingDistanceCenteredTests.swift +++ b/ParchmentTests/PagingDistanceCenteredTests.swift @@ -1,11 +1,11 @@ +import Testing @testable import Parchment -import XCTest @MainActor -final class PagingDistanceCenteredTests: XCTestCase { - private var sizeCache: PagingSizeCache! +struct PagingDistanceCenteredTests { + private let sizeCache: PagingSizeCache - override func setUp() { + init() { sizeCache = PagingSizeCache(options: PagingOptions()) } @@ -19,7 +19,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 100 /// ``` - func testDistanceCentered() { + @Test func distanceCentered() { let distance = createDistance( bounds: CGRect(x: 100, y: 0, width: 500, height: 50), contentSize: CGSize(width: 1000, height: 50), @@ -33,7 +33,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 100) + #expect(value == 100) } /// Distance from non-centered item to upcoming item. @@ -46,7 +46,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 100 /// ``` - func testDistanceCenteredFromNotCentered() { + @Test func distanceCenteredFromNotCentered() { let distance = createDistance( bounds: CGRect(x: 100, y: 0, width: 400, height: 50), contentSize: CGSize(width: 1000, height: 50), @@ -60,7 +60,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 100) + #expect(value == 100) } /// Distance to already centered item. @@ -73,7 +73,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 100 /// ``` - func testDistanceCenteredToAlreadyCentered() { + @Test func distanceCenteredToAlreadyCentered() { let distance = createDistance( bounds: CGRect(x: 100, y: 0, width: 400, height: 50), contentSize: CGSize(width: 1000, height: 50), @@ -87,7 +87,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 0) + #expect(value == 0) } /// Distance from larger, centered item to smaller item after. @@ -100,7 +100,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └──────────────────────────────────────┘ /// x: 100 /// ``` - func testDistanceCenteredUsingSizeDelegateScrollingForward() { + @Test func distanceCenteredUsingSizeDelegateScrollingForward() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -123,7 +123,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, -50) + #expect(value == -50) } /// Distance from larger, centered item to smaller item before. @@ -136,7 +136,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └──────────────────────────────────────┘ /// x: 100 /// ``` - func testDistanceCenteredUsingSizeDelegateScrollingBackward() { + @Test func distanceCenteredUsingSizeDelegateScrollingBackward() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -159,7 +159,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, -100) + #expect(value == -100) } /// Distance from an item scrolled out of view (so we don't have any @@ -173,7 +173,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └──────────────────────────────────────┘ /// x: 200 /// ``` - func testDistanceCenteredUsingSizeDelegateWithoutFromAttributes() { + @Test func distanceCenteredUsingSizeDelegateWithoutFromAttributes() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -196,7 +196,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 100) + #expect(value == 100) } /// Distance to item at the leading edge so it cannot be centered. @@ -209,7 +209,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 0 /// ``` - func testDistanceCenteredToLeadingEdge() { + @Test func distanceCenteredToLeadingEdge() { let distance = createDistance( bounds: CGRect(x: 0, y: 0, width: 400, height: 50), contentSize: CGSize(width: 400, height: 50), @@ -223,7 +223,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 0) + #expect(value == 0) } /// Distance to item at the leading edge so it cannot be centered, @@ -237,7 +237,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 0 /// ``` - func testDistanceCenteredToLeadingEdgeWhenUsingSizeDelegate() { + @Test func distanceCenteredToLeadingEdgeWhenUsingSizeDelegate() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -260,7 +260,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 0) + #expect(value == 0) } /// Distance to item at the trailing edge so it cannot be centered. @@ -273,7 +273,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └──────────────────────────────────────┘ /// x: 600 /// ``` - func testDistanceCenteredToTrailingEdge() { + @Test func distanceCenteredToTrailingEdge() { let distance = createDistance( bounds: CGRect(x: 600, y: 0, width: 400, height: 50), contentSize: CGSize(width: 1000, height: 50), @@ -287,7 +287,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 0) + #expect(value == 0) } /// Distance to item at the trailing edge so it cannot be centered, @@ -301,7 +301,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └──────────────────────────────────────┘ /// x: 600 /// ``` - func testDistanceCenteredToTrailingEdgeWhenUsingSizeDelegate() { + @Test func distanceCenteredToTrailingEdgeWhenUsingSizeDelegate() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -324,7 +324,7 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 0) + #expect(value == 0) } /// Distance to item at the trailing edge when using the size @@ -339,7 +339,7 @@ final class PagingDistanceCenteredTests: XCTestCase { /// └──────────────────────────────────────┘ /// x: 600 /// ``` - func testDistanceCenteredToTrailingEdgeWhenUsingSizeDelegateWithHugeSelectedWidth() { + @Test func distanceCenteredToTrailingEdgeWhenUsingSizeDelegateWithHugeSelectedWidth() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -362,6 +362,6 @@ final class PagingDistanceCenteredTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, -50) + #expect(value == -50) } } diff --git a/ParchmentTests/PagingDistanceLeftTests.swift b/ParchmentTests/PagingDistanceLeftTests.swift index e0766c94..19dbf6b4 100644 --- a/ParchmentTests/PagingDistanceLeftTests.swift +++ b/ParchmentTests/PagingDistanceLeftTests.swift @@ -1,11 +1,11 @@ +import Testing @testable import Parchment -import XCTest @MainActor -final class PagingDistanceLeftTests: XCTestCase { - private var sizeCache: PagingSizeCache! +struct PagingDistanceLeftTests { + private let sizeCache: PagingSizeCache - override func setUp() { + init() { sizeCache = PagingSizeCache(options: PagingOptions()) } @@ -19,7 +19,7 @@ final class PagingDistanceLeftTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 0 /// ``` - func testDistanceLeft() { + @Test func distanceLeft() { let distance = createDistance( currentItem: Item(index: 0), currentItemBounds: CGRect(x: 0, y: 0, width: 100, height: 100), @@ -31,7 +31,7 @@ final class PagingDistanceLeftTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 100) + #expect(value == 100) } /// Distance from left aligned item to upcoming item with other @@ -45,7 +45,7 @@ final class PagingDistanceLeftTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 0 /// ``` - func testDistanceLeftWithItemsBetween() { + @Test func distanceLeftWithItemsBetween() { let distance = createDistance( currentItem: Item(index: 0), currentItemBounds: CGRect(x: 0, y: 0, width: 100, height: 100), @@ -57,7 +57,7 @@ final class PagingDistanceLeftTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 200) + #expect(value == 200) } /// Distance to upcoming item when scrolled slightly. @@ -70,7 +70,7 @@ final class PagingDistanceLeftTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 50 /// ``` - func testDistanceLeftWithContentOffset() { + @Test func distanceLeftWithContentOffset() { let distance = createDistance( bounds: CGRect(origin: CGPoint(x: 50, y: 0), size: .zero), currentItem: Item(index: 0), @@ -83,7 +83,7 @@ final class PagingDistanceLeftTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 50) + #expect(value == 50) } /// Distance from larger, left-aligned item positioned before @@ -97,7 +97,7 @@ final class PagingDistanceLeftTests: XCTestCase { /// └───────────────────────────────────────┘ /// x: 500 /// ``` - func testDistanceLeftUsingSizeDelegateScrollingForward() { + @Test func distanceLeftUsingSizeDelegateScrollingForward() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -120,7 +120,7 @@ final class PagingDistanceLeftTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 50) + #expect(value == 50) } /// Distance from larger, left-aligned item positioned after @@ -134,7 +134,7 @@ final class PagingDistanceLeftTests: XCTestCase { /// └───────────────────────────────────────┘ /// x: 500 /// ``` - func testDistanceLeftUsingSizeDelegateScrollingBackward() { + @Test func distanceLeftUsingSizeDelegateScrollingBackward() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, _ in // Expects it to ignore this value when scrolling backwards so @@ -155,6 +155,6 @@ final class PagingDistanceLeftTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, -50) + #expect(value == -50) } } diff --git a/ParchmentTests/PagingDistanceRightTests.swift b/ParchmentTests/PagingDistanceRightTests.swift index 5b5057b6..8a117491 100644 --- a/ParchmentTests/PagingDistanceRightTests.swift +++ b/ParchmentTests/PagingDistanceRightTests.swift @@ -1,11 +1,11 @@ +import Testing @testable import Parchment -import XCTest @MainActor -final class PagingDistanceRightTests: XCTestCase { - private var sizeCache: PagingSizeCache! +struct PagingDistanceRightTests { + private let sizeCache: PagingSizeCache - override func setUp() { + init() { sizeCache = PagingSizeCache(options: PagingOptions()) } @@ -19,7 +19,7 @@ final class PagingDistanceRightTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 0 /// ``` - func testDistanceRight() { + @Test func distanceRight() { let distance = createDistance( bounds: CGRect(x: 0, y: 0, width: 500, height: 50), contentSize: CGSize(width: 1000, height: 50), @@ -33,7 +33,7 @@ final class PagingDistanceRightTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 100) + #expect(value == 100) } /// Distance from right aligned item to upcoming item. @@ -46,7 +46,7 @@ final class PagingDistanceRightTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 0 /// ``` - func testDistanceRightWithItemsBetween() { + @Test func distanceRightWithItemsBetween() { let distance = createDistance( bounds: CGRect(x: 0, y: 0, width: 500, height: 50), contentSize: CGSize(width: 1000, height: 50), @@ -60,7 +60,7 @@ final class PagingDistanceRightTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 200) + #expect(value == 200) } /// Distance to upcoming item when scrolled slightly. @@ -73,7 +73,7 @@ final class PagingDistanceRightTests: XCTestCase { /// └────────────────────────────────────┘ /// x: 50 /// ``` - func testDistanceRightWithContentOffset() { + @Test func distanceRightWithContentOffset() { let distance = createDistance( bounds: CGRect(x: 50, y: 0, width: 500, height: 50), contentSize: CGSize(width: 1000, height: 50), @@ -87,7 +87,7 @@ final class PagingDistanceRightTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 50) + #expect(value == 50) } /// Distance from larger, right-aligned item positioned before @@ -101,7 +101,7 @@ final class PagingDistanceRightTests: XCTestCase { /// └───────────────────────────────────────┘ /// x: 0 /// ``` - func testDistanceRightUsingSizeDelegateScrollingForward() { + @Test func distanceRightUsingSizeDelegateScrollingForward() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -124,7 +124,7 @@ final class PagingDistanceRightTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 50) + #expect(value == 50) } /// Distance from larger, right-aligned item positioned after @@ -138,7 +138,7 @@ final class PagingDistanceRightTests: XCTestCase { /// └───────────────────────────────────────┘ /// x: 200 /// ``` - func testDistanceRightUsingSizeDelegateScrollingBackward() { + @Test func distanceRightUsingSizeDelegateScrollingBackward() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -161,7 +161,7 @@ final class PagingDistanceRightTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, -50) + #expect(value == -50) } /// Distance from an item scrolled out of view (so we don't have any @@ -175,7 +175,7 @@ final class PagingDistanceRightTests: XCTestCase { /// └───────────────────────────────────────┘ /// x: 200 /// ``` - func testDistanceRightUsingSizeDelegateWithoutFromAttributes() { + @Test func distanceRightUsingSizeDelegateWithoutFromAttributes() { sizeCache.implementsSizeDelegate = true sizeCache.sizeForPagingItem = { _, isSelected in if isSelected { @@ -198,6 +198,6 @@ final class PagingDistanceRightTests: XCTestCase { ) let value = distance.calculate() - XCTAssertEqual(value, 50) + #expect(value == 50) } } diff --git a/ParchmentTests/PagingIndicatorLayoutAttributesTests.swift b/ParchmentTests/PagingIndicatorLayoutAttributesTests.swift index 569d1671..f313b19b 100644 --- a/ParchmentTests/PagingIndicatorLayoutAttributesTests.swift +++ b/ParchmentTests/PagingIndicatorLayoutAttributesTests.swift @@ -1,12 +1,14 @@ import Foundation +import Testing @testable import Parchment -import XCTest -final class PagingIndicatorLayoutAttributesTests: XCTestCase { - let layoutAttributes = PagingIndicatorLayoutAttributes() - var options = PagingOptions() +@MainActor +struct PagingIndicatorLayoutAttributesTests { + private let layoutAttributes = PagingIndicatorLayoutAttributes() + private let options: PagingOptions - override func setUp() { + init() { + var options = PagingOptions() options.font = UIFont.systemFont(ofSize: 15) options.selectedFont = UIFont.boldSystemFont(ofSize: 15) options.textColor = .blue @@ -18,18 +20,19 @@ final class PagingIndicatorLayoutAttributesTests: XCTestCase { spacing: UIEdgeInsets(), insets: UIEdgeInsets() ) + self.options = options } - func testConfigure() { + @Test func configure() { layoutAttributes.configure(options) - XCTAssertEqual(layoutAttributes.backgroundColor, UIColor.green) - XCTAssertEqual(layoutAttributes.frame.height, 20) - XCTAssertEqual(layoutAttributes.frame.origin.y, 20) - XCTAssertEqual(layoutAttributes.zIndex, Int.max) + #expect(layoutAttributes.backgroundColor == UIColor.green) + #expect(layoutAttributes.frame.height == 20) + #expect(layoutAttributes.frame.origin.y == 20) + #expect(layoutAttributes.zIndex == Int.max) } - func testTweening() { + @Test func tweening() { layoutAttributes.configure(options) let from = PagingIndicatorMetric( @@ -45,12 +48,12 @@ final class PagingIndicatorLayoutAttributesTests: XCTestCase { ) layoutAttributes.update(from: from, to: to, progress: 0) - XCTAssertEqual(layoutAttributes.frame, CGRect(x: 50, y: 20, width: 150, height: 20)) + #expect(layoutAttributes.frame == CGRect(x: 50, y: 20, width: 150, height: 20)) layoutAttributes.update(from: from, to: to, progress: 1) - XCTAssertEqual(layoutAttributes.frame, CGRect(x: 200, y: 20, width: 50, height: 20)) + #expect(layoutAttributes.frame == CGRect(x: 200, y: 20, width: 50, height: 20)) layoutAttributes.update(from: from, to: to, progress: 0.5) - XCTAssertEqual(layoutAttributes.frame, CGRect(x: 125, y: 20, width: 100, height: 20)) + #expect(layoutAttributes.frame == CGRect(x: 125, y: 20, width: 100, height: 20)) } } diff --git a/ParchmentTests/PagingStateTests.swift b/ParchmentTests/PagingStateTests.swift index 75dff04e..7d1e3606 100644 --- a/ParchmentTests/PagingStateTests.swift +++ b/ParchmentTests/PagingStateTests.swift @@ -1,18 +1,18 @@ import Foundation +import Testing @testable import Parchment -import XCTest -final class PagingStateTests: XCTestCase { - func testSelected() { +struct PagingStateTests { + @Test func selected() { let state: PagingState = .selected(pagingItem: Item(index: 0)) - XCTAssertEqual(state.currentPagingItem as? Item?, Item(index: 0)) - XCTAssertNil(state.upcomingPagingItem) - XCTAssertEqual(state.progress, 0) - XCTAssertEqual(state.visuallySelectedPagingItem as? Item?, Item(index: 0)) + #expect(state.currentPagingItem as? Item? == Item(index: 0)) + #expect(state.upcomingPagingItem == nil) + #expect(state.progress == 0) + #expect(state.visuallySelectedPagingItem as? Item? == Item(index: 0)) } - func testScrollingCurrentPagingItem() { + @Test func scrollingCurrentPagingItem() { let state: PagingState = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: Item(index: 1), @@ -21,10 +21,10 @@ final class PagingStateTests: XCTestCase { distance: 0 ) - XCTAssertEqual(state.currentPagingItem as? Item?, Item(index: 0)) + #expect(state.currentPagingItem as? Item? == Item(index: 0)) } - func testProgress() { + @Test func progress() { let state: PagingState = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: Item(index: 1), @@ -33,10 +33,10 @@ final class PagingStateTests: XCTestCase { distance: 0 ) - XCTAssertEqual(state.progress, 0.5) + #expect(state.progress == 0.5) } - func testUpcomingPagingItem() { + @Test func upcomingPagingItem() { let state: PagingState = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: Item(index: 1), @@ -45,10 +45,10 @@ final class PagingStateTests: XCTestCase { distance: 0 ) - XCTAssertEqual(state.upcomingPagingItem as? Item?, Item(index: 1)) + #expect(state.upcomingPagingItem as? Item? == Item(index: 1)) } - func testUpcomingPagingItemNil() { + @Test func upcomingPagingItemNil() { let state: PagingState = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: nil, @@ -57,10 +57,10 @@ final class PagingStateTests: XCTestCase { distance: 0 ) - XCTAssertNil(state.upcomingPagingItem) + #expect(state.upcomingPagingItem == nil) } - func testVisuallySelectedPagingItemProgressLarge() { + @Test func visuallySelectedPagingItemProgressLarge() { let state: PagingState = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: Item(index: 1), @@ -69,10 +69,10 @@ final class PagingStateTests: XCTestCase { distance: 0 ) - XCTAssertEqual(state.visuallySelectedPagingItem as? Item?, Item(index: 1)) + #expect(state.visuallySelectedPagingItem as? Item? == Item(index: 1)) } - func testVisuallySelectedPagingItemProgressSmall() { + @Test func visuallySelectedPagingItemProgressSmall() { let state: PagingState = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: Item(index: 1), @@ -81,10 +81,10 @@ final class PagingStateTests: XCTestCase { distance: 0 ) - XCTAssertEqual(state.visuallySelectedPagingItem as? Item?, Item(index: 0)) + #expect(state.visuallySelectedPagingItem as? Item? == Item(index: 0)) } - func testVisuallySelectedPagingItemUpcomingPagingItemNil() { + @Test func visuallySelectedPagingItemUpcomingPagingItemNil() { let state: PagingState = .scrolling( pagingItem: Item(index: 0), upcomingPagingItem: nil, @@ -93,6 +93,6 @@ final class PagingStateTests: XCTestCase { distance: 0 ) - XCTAssertEqual(state.visuallySelectedPagingItem as? Item?, Item(index: 0)) + #expect(state.visuallySelectedPagingItem as? Item? == Item(index: 0)) } } diff --git a/ParchmentTests/PagingViewControllerDelegateTests.swift b/ParchmentTests/PagingViewControllerDelegateTests.swift index 877aa977..5416e06a 100644 --- a/ParchmentTests/PagingViewControllerDelegateTests.swift +++ b/ParchmentTests/PagingViewControllerDelegateTests.swift @@ -1,75 +1,79 @@ import Foundation -@testable import Parchment import UIKit -import XCTest +import Testing +@testable import Parchment -final class PagingViewControllerDelegateTests: XCTestCase { - func testDidSelectItem() { - let viewController0 = UIViewController() - let viewController1 = UIViewController() - let pagingViewController = PagingViewController(viewControllers: [ - viewController0, - viewController1 - ]) +struct PagingViewControllerDelegateTests { + @Test func didSelectItem() async { + await confirmation { didSelect in + if #available(iOS 13.0, *) { + await MainActor.run { + let viewController0 = UIViewController() + let viewController1 = UIViewController() + let pagingViewController = PagingViewController(viewControllers: [ + viewController0, + viewController1 + ]) - let delegate = Delegate() - let window = UIWindow(frame: UIScreen.main.bounds) - window.rootViewController = pagingViewController - window.makeKeyAndVisible() - pagingViewController.view.layoutIfNeeded() - pagingViewController.delegate = delegate + let delegate = Delegate() + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = pagingViewController + window.makeKeyAndVisible() + pagingViewController.view.layoutIfNeeded() + pagingViewController.delegate = delegate - let expectation = XCTestExpectation() + delegate.didSelectItem = { item in + let upcomingItem = pagingViewController.state.upcomingPagingItem as? PagingIndexItem + let item = item as! PagingIndexItem + #expect(item.index == 1) + #expect(upcomingItem == item) + didSelect() + } - delegate.didSelectItem = { item in - let upcomingItem = pagingViewController.state.upcomingPagingItem as? PagingIndexItem - let item = item as! PagingIndexItem - XCTAssertEqual(item.index, 1) - XCTAssertEqual(upcomingItem, item) - expectation.fulfill() + let indexPath = IndexPath(item: 1, section: 0) + pagingViewController.collectionView.delegate?.collectionView?( + pagingViewController.collectionView, + didSelectItemAt: indexPath + ) + } + } } - - let indexPath = IndexPath(item: 1, section: 0) - pagingViewController.collectionView.delegate?.collectionView?( - pagingViewController.collectionView, - didSelectItemAt: indexPath - ) - - wait(for: [expectation], timeout: 1) } - func testDidScrollToItem() { - let viewController0 = UIViewController() - let viewController1 = UIViewController() - let pagingViewController = PagingViewController(viewControllers: [ - viewController0, - viewController1 - ]) + @Test func didScrollToItem() async { + await confirmation { didSelect in + if #available(iOS 13.0, *) { + await MainActor.run { + let viewController0 = UIViewController() + let viewController1 = UIViewController() + let pagingViewController = PagingViewController(viewControllers: [ + viewController0, + viewController1 + ]) - let delegate = Delegate() - let window = UIWindow(frame: UIScreen.main.bounds) - window.rootViewController = pagingViewController - window.makeKeyAndVisible() - pagingViewController.view.layoutIfNeeded() - pagingViewController.delegate = delegate + let delegate = Delegate() + let window = UIWindow(frame: UIScreen.main.bounds) + window.rootViewController = pagingViewController + window.makeKeyAndVisible() + pagingViewController.view.layoutIfNeeded() + pagingViewController.delegate = delegate - let expectation = XCTestExpectation() + delegate.didSelectItem = { item in + let upcomingItem = pagingViewController.state.upcomingPagingItem as? PagingIndexItem + let item = item as! PagingIndexItem + #expect(item.index == 1) + #expect(upcomingItem == item) + didSelect() + } - delegate.didSelectItem = { item in - let upcomingItem = pagingViewController.state.upcomingPagingItem as? PagingIndexItem - let item = item as! PagingIndexItem - XCTAssertEqual(item.index, 1) - XCTAssertEqual(upcomingItem, item) - expectation.fulfill() + let indexPath = IndexPath(item: 1, section: 0) + pagingViewController.collectionView.delegate?.collectionView?( + pagingViewController.collectionView, + didSelectItemAt: indexPath + ) + } + } } - - let indexPath = IndexPath(item: 1, section: 0) - pagingViewController.collectionView.delegate?.collectionView?( - pagingViewController.collectionView, - didSelectItemAt: indexPath - ) - - wait(for: [expectation], timeout: 1) } } diff --git a/ParchmentTests/PagingViewControllerTests.swift b/ParchmentTests/PagingViewControllerTests.swift index fa5f2230..acfe29f9 100644 --- a/ParchmentTests/PagingViewControllerTests.swift +++ b/ParchmentTests/PagingViewControllerTests.swift @@ -1,10 +1,11 @@ import Foundation -@testable import Parchment import UIKit -import XCTest +import Testing +@testable import Parchment -final class PagingViewControllerTests: XCTestCase { - func testReloadMenu() { +@MainActor +final class PagingViewControllerTests { + @Test func reloadMenu() { // Arrange let viewController0 = UIViewController() let viewController1 = UIViewController() @@ -39,15 +40,15 @@ final class PagingViewControllerTests: XCTestCase { // Updates the cells let cell2 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 0, section: 0)) as? ItemCell let cell3 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 1, section: 0)) as? ItemCell - XCTAssertEqual(pagingViewController.collectionView.numberOfItems(inSection: 0), 2) - XCTAssertEqual(cell2?.item, item2) - XCTAssertEqual(cell3?.item, item3) + #expect(pagingViewController.collectionView.numberOfItems(inSection: 0) == 2) + #expect(cell2?.item == item2) + #expect(cell3?.item == item3) // Should not updated the view controllers - XCTAssertEqual(pagingViewController.pageViewController.selectedViewController, viewController0) + #expect(pagingViewController.pageViewController.selectedViewController == viewController0) } - func testReloadData() { + @Test func reloadData() { // Arrange let dataSource = ReloadingDataSource() let viewController0 = UIViewController() @@ -81,13 +82,13 @@ final class PagingViewControllerTests: XCTestCase { let cell2 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 0, section: 0)) as? ItemCell let cell3 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 1, section: 0)) as? ItemCell - XCTAssertEqual(cell2?.item, item2) - XCTAssertEqual(cell3?.item, item3) - XCTAssertEqual(pagingViewController.state, PagingState.selected(pagingItem: item2)) - XCTAssertEqual(pagingViewController.pageViewController.selectedViewController, viewController2) + #expect(cell2?.item == item2) + #expect(cell3?.item == item3) + #expect(pagingViewController.state == PagingState.selected(pagingItem: item2)) + #expect(pagingViewController.pageViewController.selectedViewController == viewController2) } - func testReloadDataSameItemsUpdatesViewControllers() { + @Test func reloadDataSameItemsUpdatesViewControllers() { // Arrange let dataSource = ReloadingDataSource() let viewController0 = UIViewController() @@ -115,10 +116,10 @@ final class PagingViewControllerTests: XCTestCase { pagingViewController.view.layoutIfNeeded() // Assert - XCTAssertEqual(pagingViewController.pageViewController.selectedViewController, viewController2) + #expect(pagingViewController.pageViewController.selectedViewController == viewController2) } - func testReloadDataSelectsPreviouslySelectedItem() { + @Test func reloadDataSelectsPreviouslySelectedItem() { // Arrange let dataSource = ReloadingDataSource() let item0 = Item(index: 0) @@ -157,13 +158,13 @@ final class PagingViewControllerTests: XCTestCase { let cell1 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 1, section: 0)) as? ItemCell let cell2 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 2, section: 0)) as? ItemCell - XCTAssertEqual(cell0?.item, item0) - XCTAssertEqual(cell1?.item, item1) - XCTAssertEqual(cell2?.item, item2) - XCTAssertEqual(pagingViewController.state, PagingState.selected(pagingItem: item1)) + #expect(cell0?.item == item0) + #expect(cell1?.item == item1) + #expect(cell2?.item == item2) + #expect(pagingViewController.state == PagingState.selected(pagingItem: item1)) } - func testReloadDataSelectsFirstItemForAllNewAllItems() { + @Test func reloadDataSelectsFirstItemForAllNewAllItems() { // Arrange let dataSource = ReloadingDataSource() let viewController0 = UIViewController() @@ -197,12 +198,12 @@ final class PagingViewControllerTests: XCTestCase { let cell2 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 0, section: 0)) as? ItemCell let cell3 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 1, section: 0)) as? ItemCell - XCTAssertEqual(cell2?.item, item2) - XCTAssertEqual(cell3?.item, item3) - XCTAssertEqual(pagingViewController.state, PagingState.selected(pagingItem: item2)) + #expect(cell2?.item == item2) + #expect(cell3?.item == item3) + #expect(pagingViewController.state == PagingState.selected(pagingItem: item2)) } - func testReloadDataDisplayEmptyViewForNoItems() { + @Test func reloadDataDisplayEmptyViewForNoItems() { // Arrange let dataSource = ReloadingDataSource() let pagingViewController = PagingViewController() @@ -218,11 +219,11 @@ final class PagingViewControllerTests: XCTestCase { pagingViewController.reloadData() // Assert - XCTAssertEqual(pagingViewController.pageViewController.scrollView.subviews, []) - XCTAssertEqual(pagingViewController.collectionView.numberOfItems(inSection: 0), 0) + #expect(pagingViewController.pageViewController.scrollView.subviews == []) + #expect(pagingViewController.collectionView.numberOfItems(inSection: 0) == 0) } - func testReloadDataEmptyBeforeUsesWidthDelegate() { + @Test func reloadDataEmptyBeforeUsesWidthDelegate() { // Arrange let dataSource = ReloadingDataSource() let delegate = SizeDelegate() @@ -248,13 +249,13 @@ final class PagingViewControllerTests: XCTestCase { let cell0 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 0, section: 0)) as? ItemCell let cell1 = pagingViewController.collectionView.cellForItem(at: IndexPath(item: 1, section: 0)) as? ItemCell - XCTAssertEqual(cell0?.item, item0) - XCTAssertEqual(cell1?.item, item1) - XCTAssertEqual(cell0?.bounds.width, 100) - XCTAssertEqual(cell1?.bounds.width, 50) + #expect(cell0?.item == item0) + #expect(cell1?.item == item1) + #expect(cell0?.bounds.width == 100) + #expect(cell1?.bounds.width == 50) } - func selectFirstPagingItem() { + @Test func selectFirstPagingItem() { // Arrange let dataSource = DataSource() let pagingViewController = PagingViewController() @@ -262,7 +263,7 @@ final class PagingViewControllerTests: XCTestCase { pagingViewController.menuItemSize = .fixed(width: 100, height: 50) pagingViewController.infiniteDataSource = dataSource - let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 50)) + let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000)) window.rootViewController = pagingViewController window.makeKeyAndVisible() pagingViewController.view.layoutIfNeeded() @@ -272,10 +273,10 @@ final class PagingViewControllerTests: XCTestCase { // Assert let items = pagingViewController.collectionView.numberOfItems(inSection: 0) - XCTAssertEqual(items, 21) + #expect(items == 21) } - func selectCenterPagingItem() { + @Test func selectCenterPagingItem() { // Arrange let dataSource = DataSource() let pagingViewController = PagingViewController() @@ -283,7 +284,7 @@ final class PagingViewControllerTests: XCTestCase { pagingViewController.menuItemSize = .fixed(width: 100, height: 50) pagingViewController.infiniteDataSource = dataSource - let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 50)) + let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000)) window.rootViewController = pagingViewController window.makeKeyAndVisible() pagingViewController.view.layoutIfNeeded() @@ -293,10 +294,10 @@ final class PagingViewControllerTests: XCTestCase { // Assert let items = pagingViewController.collectionView.numberOfItems(inSection: 0) - XCTAssertEqual(items, 21) + #expect(items == 21) } - func selectLastPagingIteme() { + @Test func selectLastPagingItem() { // Arrange let dataSource = DataSource() let pagingViewController = PagingViewController() @@ -304,7 +305,7 @@ final class PagingViewControllerTests: XCTestCase { pagingViewController.menuItemSize = .fixed(width: 100, height: 50) pagingViewController.infiniteDataSource = dataSource - let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 50)) + let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000)) window.rootViewController = pagingViewController window.makeKeyAndVisible() pagingViewController.view.layoutIfNeeded() @@ -314,10 +315,10 @@ final class PagingViewControllerTests: XCTestCase { // Assert let items = pagingViewController.collectionView.numberOfItems(inSection: 0) - XCTAssertEqual(items, 21) + #expect(items == 21) } - func testSelectIndexBeforeInitialRender() { + @Test func selectIndexBeforeInitialRender() { // Arrange let viewController0 = UIViewController() let viewController1 = UIViewController() @@ -341,12 +342,12 @@ final class PagingViewControllerTests: XCTestCase { pagingViewController.view.layoutIfNeeded() // Assert - XCTAssertEqual(pagingViewController.pageViewController.selectedViewController, viewController1) - XCTAssertEqual(pagingViewController.collectionView.indexPathsForSelectedItems, [IndexPath(item: 1, section: 0)]) - XCTAssertEqual(pagingViewController.state, PagingState.selected(pagingItem: item1)) + #expect(pagingViewController.pageViewController.selectedViewController == viewController1) + #expect(pagingViewController.collectionView.indexPathsForSelectedItems == [IndexPath(item: 1, section: 0)]) + #expect(pagingViewController.state == PagingState.selected(pagingItem: item1)) } - func testReloadDataBeforeInitialRender() { + @Test func reloadDataBeforeInitialRender() { // Arrange let viewController0 = UIViewController() let viewController1 = UIViewController() @@ -367,30 +368,15 @@ final class PagingViewControllerTests: XCTestCase { pagingViewController.reloadData() pagingViewController.select(index: 1) - let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 50)) + let window = UIWindow(frame: CGRect(x: 0, y: 0, width: 1000, height: 1000)) window.rootViewController = pagingViewController window.makeKeyAndVisible() pagingViewController.view.layoutIfNeeded() // Assert - XCTAssertEqual(pagingViewController.pageViewController.selectedViewController, viewController1) - XCTAssertEqual(pagingViewController.collectionView.indexPathsForSelectedItems, [IndexPath(item: 1, section: 0)]) - XCTAssertEqual(pagingViewController.state, PagingState.selected(pagingItem: item1)) - } - - // FIXME: Disabled as it fails on CI - func xtestRetainCycles() { - var instance: DeinitPagingViewController? = DeinitPagingViewController() - let expectation = XCTestExpectation() - - instance?.deinitCalled = { - expectation.fulfill() - } - DispatchQueue.global(qos: .background).async { - instance = nil - } - - wait(for: [expectation], timeout: 2) + #expect(pagingViewController.pageViewController.selectedViewController == viewController1) + #expect(pagingViewController.collectionView.indexPathsForSelectedItems == [IndexPath(item: 1, section: 0)]) + #expect(pagingViewController.state == PagingState.selected(pagingItem: item1)) } } @@ -427,11 +413,6 @@ private class SizeDelegate: PagingViewControllerSizeDelegate { } } -private class DeinitPagingViewController: PagingViewController { - var deinitCalled: (() -> Void)? - deinit { deinitCalled?() } -} - private class ReloadingDataSource: PagingViewControllerDataSource { var items: [Item] = [] var viewControllers: [UIViewController] = [] diff --git a/ParchmentTests/PagingViewTests.swift b/ParchmentTests/PagingViewTests.swift index beb1c7ab..97bc1b2a 100644 --- a/ParchmentTests/PagingViewTests.swift +++ b/ParchmentTests/PagingViewTests.swift @@ -1,11 +1,12 @@ +import Testing @testable import Parchment -import XCTest -final class PagingViewTests: XCTestCase { - var pagingView: PagingView! - var collectionView: UICollectionView! +@MainActor +final class PagingViewTests { + private let pagingView: PagingView + private let collectionView: UICollectionView - override func setUp() { + init() { let options = PagingOptions() let pageView = UIView(frame: .zero) @@ -21,13 +22,13 @@ final class PagingViewTests: XCTestCase { ) } - func testMenuBackgroundColor() { + @Test func menuBackgroundColor() { pagingView.configure() var options = PagingOptions() options.menuBackgroundColor = .green pagingView.options = options - XCTAssertEqual(collectionView.backgroundColor, .green) + #expect(collectionView.backgroundColor == .green) } } diff --git a/ParchmentTests/UIColorInterpolationTests.swift b/ParchmentTests/UIColorInterpolationTests.swift index 474e6b01..4ec93dbb 100644 --- a/ParchmentTests/UIColorInterpolationTests.swift +++ b/ParchmentTests/UIColorInterpolationTests.swift @@ -1,17 +1,17 @@ import CoreGraphics +import Testing @testable import Parchment -import XCTest -final class UIColorInterpolationTests: XCTestCase { +final class UIColorInterpolationTests { // Colors initialized with UIColor(patternImage:) have only 1 // color component. This test ensures we don't crash. - func testImageFromPatternImageDefaultToBlack() { + @Test func imageFromPatternImageDefaultToBlack() { let from = UIColor.red let bundle = Bundle(for: Self.self) let image = UIImage(named: "Green", in: bundle, compatibleWith: nil)! let to = UIColor(patternImage: image) let result = UIColor.interpolate(from: from, to: to, with: 1) - XCTAssertEqual(result, UIColor(red: 0, green: 0, blue: 0, alpha: 1)) + #expect(result == UIColor(red: 0, green: 0, blue: 0, alpha: 1)) } } diff --git a/ParchmentUITests/ParchmentUITests.swift b/ParchmentUITests/ParchmentUITests.swift index c05fe3b2..a509a4cf 100644 --- a/ParchmentUITests/ParchmentUITests.swift +++ b/ParchmentUITests/ParchmentUITests.swift @@ -1,16 +1,16 @@ import XCTest +@MainActor final class ParchmentUITests: XCTestCase { - var app: XCUIApplication! - override func setUp() { continueAfterFailure = false - app = XCUIApplication() - app.launchArguments = ["--ui-testing"] - app.launch() } func testSelect() { + let app = XCUIApplication() + app.launchArguments = ["--ui-testing"] + app.launch() + let cell0 = app.collectionViews.cells["View 0"] let cell1 = app.collectionViews.cells["View 1"] @@ -26,6 +26,10 @@ final class ParchmentUITests: XCTestCase { } func testSwipe() { + let app = XCUIApplication() + app.launchArguments = ["--ui-testing"] + app.launch() + app.scrollViews.firstMatch.swipeLeft() let content1 = app.scrollViews.firstMatch.staticTexts["1"] XCTAssertTrue(content1.waitForExistence(timeout: 1))