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
@@ -9,18 +9,19 @@
import Combine
@testable import ElementX
import Foundation
import XCTest
import Testing
@MainActor
class VoiceMessageMediaManagerTests: XCTestCase {
private var voiceMessageMediaManager: VoiceMessageMediaManager!
private var voiceMessageCache: VoiceMessageCacheMock!
private var mediaProvider: MediaProviderMock!
@Suite
struct VoiceMessageMediaManagerTests {
private var voiceMessageMediaManager: VoiceMessageMediaManager
private var voiceMessageCache: VoiceMessageCacheMock
private var mediaProvider: MediaProviderMock
private let someURL = URL.mockMXCAudio
private let audioOGGMimeType = "audio/ogg"
override func setUp() async throws {
init() {
voiceMessageCache = VoiceMessageCacheMock()
mediaProvider = MediaProviderMock(configuration: .init())
mediaProvider.loadFileFromSourceFilenameClosure = nil
@@ -29,23 +30,25 @@ class VoiceMessageMediaManagerTests: XCTestCase {
voiceMessageCache: voiceMessageCache)
}
func testLoadVoiceMessageFromSourceUnsupportedMedia() async throws {
@Test
func loadVoiceMessageFromSourceUnsupportedMedia() async throws {
// Only "audio/ogg" file are supported
let unsupportedMediaSource = try MediaSourceProxy(url: someURL, mimeType: "audio/wav")
do {
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(unsupportedMediaSource, body: nil)
XCTFail("A `VoiceMessageMediaManagerError.unsupportedMimeTye` error is expected")
Issue.record("A `VoiceMessageMediaManagerError.unsupportedMimeTye` error is expected")
} catch {
switch error as? VoiceMessageMediaManagerError {
case .unsupportedMimeTye:
break
default:
XCTFail("A `VoiceMessageMediaManagerError.unsupportedMimeTye` error is expected")
Issue.record("A `VoiceMessageMediaManagerError.unsupportedMimeTye` error is expected")
}
}
}
func testLoadVoiceMessageFromSourceMimeTypeWithParameters() async throws {
@Test
mutating func loadVoiceMessageFromSourceMimeTypeWithParameters() async throws {
// URL representing the file loaded by the media provider
let loadedFile = URL("/some/url/loaded_file.ogg")
// URL representing the final cached file
@@ -63,41 +66,44 @@ class VoiceMessageMediaManagerTests: XCTestCase {
do {
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
} catch {
XCTFail("An unexpected error has occured: \(error)")
Issue.record("An unexpected error has occured: \(error)")
}
}
func testLoadVoiceMessageFromSourceAlreadyCached() async throws {
@Test
func loadVoiceMessageFromSourceAlreadyCached() async throws {
// Check if the file is already present in cache
voiceMessageCache.fileURLForReturnValue = URL("/converted_file/url")
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
XCTAssertEqual(url, URL("/converted_file/url"))
#expect(url == URL("/converted_file/url"))
// The file must have be search in the cache
XCTAssertTrue(voiceMessageCache.fileURLForCalled)
XCTAssertEqual(voiceMessageCache.fileURLForReceivedMediaSource, mediaSource)
#expect(voiceMessageCache.fileURLForCalled)
#expect(voiceMessageCache.fileURLForReceivedMediaSource == mediaSource)
// The file must not have been cached again
XCTAssertFalse(voiceMessageCache.cacheMediaSourceUsingMoveCalled)
#expect(!voiceMessageCache.cacheMediaSourceUsingMoveCalled)
}
func testLoadVoiceMessageFromSourceMediaProviderError() async throws {
@Test
func loadVoiceMessageFromSourceMediaProviderError() async throws {
// An error must be reported if the file cannot be retrieved
do {
voiceMessageCache.fileURLForReturnValue = nil
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
_ = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
XCTFail("A `MediaProviderError.failedRetrievingFile` error is expected")
Issue.record("A `MediaProviderError.failedRetrievingFile` error is expected")
} catch {
switch error as? MediaProviderError {
case .failedRetrievingFile:
break
default:
XCTFail("A `MediaProviderError.failedRetrievingFile` error is expected")
Issue.record("A `MediaProviderError.failedRetrievingFile` error is expected")
}
}
}
func testLoadVoiceMessageFromSourceSingleCall() async throws {
@Test
mutating func loadVoiceMessageFromSourceSingleCall() async throws {
// URL representing the file loaded by the media provider
let loadedFile = URL("/some/url/loaded_file")
// URL representing the final cached file
@@ -115,17 +121,18 @@ class VoiceMessageMediaManagerTests: XCTestCase {
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
// The file must have been converted
XCTAssertTrue(audioConverter.convertToMPEG4AACSourceURLDestinationURLCalled)
#expect(audioConverter.convertToMPEG4AACSourceURLDestinationURLCalled)
// The converted file must have been cached
XCTAssert(voiceMessageCache.cacheMediaSourceUsingMoveCalled)
XCTAssertEqual(voiceMessageCache.cacheMediaSourceUsingMoveReceivedArguments?.mediaSource, mediaSource)
XCTAssertEqual(voiceMessageCache.cacheMediaSourceUsingMoveReceivedArguments?.fileURL.pathExtension, "m4a")
XCTAssertTrue(voiceMessageCache.cacheMediaSourceUsingMoveReceivedArguments?.move ?? false)
#expect(voiceMessageCache.cacheMediaSourceUsingMoveCalled)
#expect(voiceMessageCache.cacheMediaSourceUsingMoveReceivedArguments?.mediaSource == mediaSource)
#expect(voiceMessageCache.cacheMediaSourceUsingMoveReceivedArguments?.fileURL.pathExtension == "m4a")
#expect(voiceMessageCache.cacheMediaSourceUsingMoveReceivedArguments?.move ?? false)
// The returned URL must point to the cached converted file
XCTAssertEqual(url, cachedConvertedFileURL)
#expect(url == cachedConvertedFileURL)
}
func testLoadVoiceMessageFromSourceMultipleCalls() async throws {
@Test
mutating func loadVoiceMessageFromSourceMultipleCalls() async throws {
// URL representing the file loaded by the media provider
let loadedFile = URL("/some/url/loaded_file")
// URL representing the final cached file
@@ -151,13 +158,13 @@ class VoiceMessageMediaManagerTests: XCTestCase {
let mediaSource = try MediaSourceProxy(url: someURL, mimeType: audioOGGMimeType)
for _ in 0..<10 {
let url = try await voiceMessageMediaManager.loadVoiceMessageFromSource(mediaSource, body: nil)
XCTAssertEqual(url, cachedConvertedFileURL)
#expect(url == cachedConvertedFileURL)
}
// The file must have been converted only once
XCTAssertEqual(audioConverter.convertToMPEG4AACSourceURLDestinationURLCallsCount, 1)
#expect(audioConverter.convertToMPEG4AACSourceURLDestinationURLCallsCount == 1)
// The converted file must have been cached only once
XCTAssertEqual(voiceMessageCache.cacheMediaSourceUsingMoveCallsCount, 1)
#expect(voiceMessageCache.cacheMediaSourceUsingMoveCallsCount == 1)
}
}