Swift Testing for Unit Tests PART 1 (#5119)

* migrated a lot of unit tests to Swift Testing and added a new implementation for deferred fulfillment

more tests migration

Cleaned the code manually to establish some good patterns

more code improvements

some more code improvements

removed empty tests

update project

* more pr suggestions and cleanups

* removed the TestSetup pattern

* fixing claude not reusing tests

* pr suggestion + added indent rule to swiftformat so that we can prevent AIs to change that
This commit is contained in:
Mauro
2026-02-19 16:20:47 +01:00
committed by GitHub
parent fc03e05697
commit 7982aef855
118 changed files with 4630 additions and 4129 deletions
@@ -8,21 +8,19 @@
import Combine
@testable import ElementX
import XCTest
import Testing
@MainActor
class StaticLocationScreenViewModelTests: XCTestCase {
let timelineProxy = TimelineProxyMock(.init())
@Suite
struct StaticLocationScreenViewModelTests {
private let timelineProxy = TimelineProxyMock(.init())
private var viewModel: StaticLocationScreenViewModelProtocol
var viewModel: StaticLocationScreenViewModelProtocol!
var context: StaticLocationScreenViewModel.Context {
private var context: StaticLocationScreenViewModel.Context {
viewModel.context
}
private var cancellables = Set<AnyCancellable>()
override func setUpWithError() throws {
cancellables.removeAll()
init() {
let viewModel = StaticLocationScreenViewModel(interactionMode: .picker,
mapURLBuilder: ServiceLocator.shared.settings.mapTilerConfiguration,
timelineController: MockTimelineController(timelineProxy: timelineProxy),
@@ -32,81 +30,92 @@ class StaticLocationScreenViewModelTests: XCTestCase {
self.viewModel = viewModel
}
func testUserDidPan() {
XCTAssertTrue(context.viewState.isSharingUserLocation)
XCTAssertEqual(context.showsUserLocationMode, .showAndFollow)
@Test
func userDidPan() {
#expect(context.viewState.isSharingUserLocation)
#expect(context.showsUserLocationMode == .showAndFollow)
context.send(viewAction: .userDidPan)
XCTAssertFalse(context.viewState.isSharingUserLocation)
XCTAssertEqual(context.showsUserLocationMode, .show)
#expect(!context.viewState.isSharingUserLocation)
#expect(context.showsUserLocationMode == .show)
}
func testCenterOnUser() {
XCTAssertTrue(context.viewState.isSharingUserLocation)
@Test
func centerOnUser() {
#expect(context.viewState.isSharingUserLocation)
context.showsUserLocationMode = .show
XCTAssertFalse(context.viewState.isSharingUserLocation)
#expect(!context.viewState.isSharingUserLocation)
context.send(viewAction: .centerToUser)
XCTAssertTrue(context.viewState.isSharingUserLocation)
XCTAssertEqual(context.showsUserLocationMode, .showAndFollow)
#expect(context.viewState.isSharingUserLocation)
#expect(context.showsUserLocationMode == .showAndFollow)
}
func testCenterOnUserWithoutAuth() {
@Test
func centerOnUserWithoutAuth() {
context.showsUserLocationMode = .hide
context.isLocationAuthorized = nil
context.send(viewAction: .centerToUser)
XCTAssertEqual(context.showsUserLocationMode, .showAndFollow)
#expect(context.showsUserLocationMode == .showAndFollow)
}
func testCenterOnUserWithDeniedAuth() {
@Test
func centerOnUserWithDeniedAuth() {
context.isLocationAuthorized = false
context.showsUserLocationMode = .hide
context.send(viewAction: .centerToUser)
XCTAssertNotEqual(context.showsUserLocationMode, .showAndFollow)
XCTAssertNotNil(context.alertInfo)
#expect(context.showsUserLocationMode != .showAndFollow)
#expect(context.alertInfo != nil)
}
func testErrorMapping() {
@Test
func errorMapping() {
let mapError = AlertInfo(locationSharingViewError: .mapError(.failedLoadingMap))
XCTAssertEqual(mapError.message, L10n.errorFailedLoadingMap(InfoPlistReader.main.bundleDisplayName))
#expect(mapError.message == L10n.errorFailedLoadingMap(InfoPlistReader.main.bundleDisplayName))
let locationError = AlertInfo(locationSharingViewError: .mapError(.failedLocatingUser))
XCTAssertEqual(locationError.message, L10n.errorFailedLocatingUser(InfoPlistReader.main.bundleDisplayName))
#expect(locationError.message == L10n.errorFailedLocatingUser(InfoPlistReader.main.bundleDisplayName))
let authorizationError = AlertInfo(locationSharingViewError: .missingAuthorization)
XCTAssertEqual(authorizationError.message, L10n.dialogPermissionLocationDescriptionIos)
#expect(authorizationError.message == L10n.dialogPermissionLocationDescriptionIos)
}
func testSendUserLocation() async throws {
@Test
func sendUserLocation() async throws {
context.mapCenterLocation = .init(latitude: 0, longitude: 0)
context.geolocationUncertainty = 10
let deferred = deferFulfillment(viewModel.actions) { $0 == .close }
let expectation = XCTestExpectation(description: "sendLocation")
timelineProxy.sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure = { _, geoURI, _, _, assetType in
XCTAssertEqual(geoURI.uncertainty, 10)
XCTAssertEqual(assetType, .sender)
expectation.fulfill()
return .success(())
}
context.send(viewAction: .selectLocation)
await fulfillment(of: [expectation], timeout: 1)
try await deferred.fulfill()
try await confirmation { confirmation in
timelineProxy.sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure = { _, geoURI, _, _, assetType in
#expect(geoURI.uncertainty == 10)
#expect(assetType == .sender)
confirmation()
return .success(())
}
context.send(viewAction: .selectLocation)
try await deferred.fulfill()
}
}
func testSendPickedLocation() async throws {
@Test
func sendPickedLocation() async throws {
context.mapCenterLocation = .init(latitude: 0, longitude: 0)
context.isLocationAuthorized = nil
context.geolocationUncertainty = 10
let deferred = deferFulfillment(viewModel.actions) { $0 == .close }
let expectation = XCTestExpectation(description: "sendLocation")
timelineProxy.sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure = { _, geoURI, _, _, assetType in
XCTAssertEqual(geoURI.uncertainty, nil)
XCTAssertEqual(assetType, .pin)
expectation.fulfill()
return .success(())
}
context.send(viewAction: .selectLocation)
await fulfillment(of: [expectation], timeout: 1)
try await deferred.fulfill()
try await confirmation { confirmation in
timelineProxy.sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure = { _, geoURI, _, _, assetType in
#expect(geoURI.uncertainty == nil)
#expect(assetType == .pin)
confirmation()
return .success(())
}
context.send(viewAction: .selectLocation)
try await deferred.fulfill()
}
}
}