mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-03 06:55:59 +00:00
Finish migration of UnitTests target from XCTestCase to Swift Testing (#5129)
* Initial plan * Migrate 3 test files from XCTest to Swift Testing - MediaUploadPreviewScreenViewModelTests: @MainActor @Suite struct with init(), BundleFinder class for Bundle(for:), mutating test/setup functions, [self] capture replacing [weak self] in closures - NotificationManagerTests: @MainActor @Suite final class with init()/deinit, expectation/fulfillment(of:) replaced with confirmation(...), test_ prefix stripped - NotificationSettingsScreenViewModelTests: @MainActor @Suite struct with init() throws, non-optional stored properties, test prefix stripped Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate 3 XCTest files to Swift Testing - NotificationSettingsEditScreenViewModelTests: @MainActor @Suite struct with init() throws, mutating test methods - TimelineViewModelTests: @MainActor @Suite final class with init() async throws + deinit - AttributedStringBuilderTests: @Suite struct with init() async throws All XCT assertions replaced with #expect/#require/Issue.record Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate 4 test files from XCTest to Swift Testing - TimelineMediaPreviewViewModelTests: @Suite struct, mutating @Test funcs, testLoadingItem renamed to loadingItem (called internally by other tests) - ServerConfirmationScreenViewModelTests: @Suite final class with init()/deinit - CompletionSuggestionServiceTests: @Suite struct with init() - RoomFlowCoordinatorTests: @Suite final class with deinit Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate 4 test files from XCTest to Swift Testing - VoiceMessageRecorderTests: @Suite struct with init() async throws, added BundleFinder class for Bundle lookup, migrated all assertions - SpaceScreenViewModelTests: @Suite struct, private mutating setupViewModel, all test funcs mutating, XCTestExpectation → confirmation - RoomNotificationSettingsScreenViewModelTests: @Suite struct with init() throws, cancellable tests marked mutating - JoinRoomScreenViewModelTests: @Suite final class with init()/deinit, XCTestExpectation → confirmation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate 6 test files from XCTestCase to Swift Testing Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com> * Fix trailing blank line in RoomPollsHistoryScreenViewModelTests Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com> * Migrate 3 test files from XCTest to Swift Testing - MediaUploadingPreprocessorTests: @Suite final class with init()/deinit, removed executionTimeAllowance, XCTAssertEqual(accuracy:) → abs(Double) - SecurityAndPrivacyScreenViewModelTests: @MainActor @Suite final class, 5 expectation+fulfillment → await confirmation(...) - CreateRoomViewModelTests: @MainActor @Suite final class, 4 expectation+fulfillment → await confirmation(...) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate RoomScreenViewModelTests and RoomDetailsScreenViewModelTests to Swift Testing - Replace XCTest with Testing framework - RoomScreenViewModelTests: final class with init() async throws + deinit - RoomDetailsScreenViewModelTests: struct with init() and mutating funcs - Convert XCT assertions to #expect / Issue.record - Convert XCTestExpectation patterns to confirmation { confirm in } - Strip 'test' prefix from all test function names Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Migrate ComposerToolbarViewModelTests from XCTest to Swift Testing - Replace import XCTest with import Testing - Convert XCTestCase class to @MainActor @Suite final class - Replace setUp()/tearDown() with init()/deinit - Strip 'test' prefix from all 41 test method names and add @Test - Replace XCTAssert* with #expect()/#require() - Replace try XCTUnwrap() with try #require() - Convert expectation+wait patterns to deferFulfillment with PassthroughSubject - Convert isInverted expectation to boolean flag checked after await - Use deferFulfillment on $viewState for state-transition tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address comments with Copilot. * Fix the failing tests. * Fixed flaky tests (#5137) resolved flaky tests * Tweaks and fixes. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com> Co-authored-by: Doug <douglase@element.io> Co-authored-by: Mauro <34335419+Velin92@users.noreply.github.com>
This commit is contained in:
@@ -9,10 +9,11 @@
|
||||
import Combine
|
||||
@testable import ElementX
|
||||
import Foundation
|
||||
import XCTest
|
||||
import Testing
|
||||
|
||||
@Suite
|
||||
@MainActor
|
||||
class VoiceMessageRecorderTests: XCTestCase {
|
||||
struct VoiceMessageRecorderTests {
|
||||
private var voiceMessageRecorder: VoiceMessageRecorder!
|
||||
|
||||
private var audioRecorder: AudioRecorderMock!
|
||||
@@ -33,7 +34,7 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
|
||||
private let recordingURL = URL("/some/url")
|
||||
|
||||
override func setUp() async throws {
|
||||
init() async throws {
|
||||
audioRecorder = AudioRecorderMock()
|
||||
audioRecorder.underlyingCurrentTime = 0
|
||||
audioRecorder.averagePowerReturnValue = 0
|
||||
@@ -61,7 +62,7 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
|
||||
let deferred = deferFulfillment(voiceMessageRecorder.actions) { action in
|
||||
switch action {
|
||||
case .didStopRecording(_, let url) where url == self.recordingURL:
|
||||
case .didStopRecording(_, let url) where url == recordingURL:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -71,141 +72,153 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testRecordingURL() {
|
||||
@Test
|
||||
func recorderRecordingURL() {
|
||||
audioRecorder.audioFileURL = recordingURL
|
||||
XCTAssertEqual(voiceMessageRecorder.recordingURL, recordingURL)
|
||||
#expect(voiceMessageRecorder.recordingURL == recordingURL)
|
||||
}
|
||||
|
||||
func testRecordingDuration() {
|
||||
@Test
|
||||
func recorderRecordingDuration() {
|
||||
audioRecorder.currentTime = 10.3
|
||||
XCTAssertEqual(voiceMessageRecorder.recordingDuration, 10.3)
|
||||
#expect(voiceMessageRecorder.recordingDuration == 10.3)
|
||||
}
|
||||
|
||||
func testStartRecording() async {
|
||||
@Test
|
||||
func startRecording() async {
|
||||
_ = await voiceMessageRecorder.startRecording()
|
||||
XCTAssert(audioRecorder.recordAudioFileURLCalled)
|
||||
#expect(audioRecorder.recordAudioFileURLCalled)
|
||||
}
|
||||
|
||||
func testStopRecording() async {
|
||||
@Test
|
||||
func stopRecording() async {
|
||||
_ = await voiceMessageRecorder.stopRecording()
|
||||
// Internal audio recorder must have been stopped
|
||||
XCTAssert(audioRecorder.stopRecordingCalled)
|
||||
#expect(audioRecorder.stopRecordingCalled)
|
||||
}
|
||||
|
||||
func testCancelRecording() async {
|
||||
@Test
|
||||
func cancelRecording() async {
|
||||
await voiceMessageRecorder.cancelRecording()
|
||||
// Internal audio recorder must have been stopped
|
||||
XCTAssert(audioRecorder.stopRecordingCalled)
|
||||
#expect(audioRecorder.stopRecordingCalled)
|
||||
// The recording audio file must have been deleted
|
||||
XCTAssert(audioRecorder.deleteRecordingCalled)
|
||||
#expect(audioRecorder.deleteRecordingCalled)
|
||||
}
|
||||
|
||||
func testDeleteRecording() async {
|
||||
@Test
|
||||
func deleteRecording() async {
|
||||
await voiceMessageRecorder.deleteRecording()
|
||||
// The recording audio file must have been deleted
|
||||
XCTAssert(audioRecorder.deleteRecordingCalled)
|
||||
#expect(audioRecorder.deleteRecordingCalled)
|
||||
}
|
||||
|
||||
func testStartPlaybackNoPreview() async {
|
||||
@Test
|
||||
func startPlaybackNoPreview() async {
|
||||
guard case .failure(.previewNotAvailable) = await voiceMessageRecorder.startPlayback() else {
|
||||
XCTFail("An error is expected")
|
||||
Issue.record("An error is expected")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testStartPlayback() async throws {
|
||||
@Test
|
||||
func startPlayback() async throws {
|
||||
try await setRecordingComplete()
|
||||
|
||||
guard case .success = await voiceMessageRecorder.startPlayback() else {
|
||||
XCTFail("Playback should start")
|
||||
Issue.record("Playback should start")
|
||||
return
|
||||
}
|
||||
XCTAssertEqual(voiceMessageRecorder.previewAudioPlayerState?.isAttached, true)
|
||||
XCTAssert(audioPlayer.loadSourceURLPlaybackURLAutoplayCalled)
|
||||
XCTAssertEqual(audioPlayer.loadSourceURLPlaybackURLAutoplayReceivedArguments?.sourceURL, recordingURL)
|
||||
XCTAssertEqual(audioPlayer.loadSourceURLPlaybackURLAutoplayReceivedArguments?.playbackURL, recordingURL)
|
||||
XCTAssertEqual(audioPlayer.loadSourceURLPlaybackURLAutoplayReceivedArguments?.autoplay, true)
|
||||
XCTAssertFalse(audioPlayer.playCalled)
|
||||
#expect(voiceMessageRecorder.previewAudioPlayerState?.isAttached == true)
|
||||
#expect(audioPlayer.loadSourceURLPlaybackURLAutoplayCalled)
|
||||
#expect(audioPlayer.loadSourceURLPlaybackURLAutoplayReceivedArguments?.sourceURL == recordingURL)
|
||||
#expect(audioPlayer.loadSourceURLPlaybackURLAutoplayReceivedArguments?.playbackURL == recordingURL)
|
||||
#expect(audioPlayer.loadSourceURLPlaybackURLAutoplayReceivedArguments?.autoplay == true)
|
||||
#expect(!audioPlayer.playCalled)
|
||||
}
|
||||
|
||||
func testPausePlayback() async throws {
|
||||
@Test
|
||||
func pausePlayback() async throws {
|
||||
try await setRecordingComplete()
|
||||
|
||||
_ = await voiceMessageRecorder.startPlayback()
|
||||
XCTAssertEqual(voiceMessageRecorder.previewAudioPlayerState?.isAttached, true)
|
||||
#expect(voiceMessageRecorder.previewAudioPlayerState?.isAttached == true)
|
||||
|
||||
voiceMessageRecorder.pausePlayback()
|
||||
XCTAssert(audioPlayer.pauseCalled)
|
||||
#expect(audioPlayer.pauseCalled)
|
||||
}
|
||||
|
||||
func testResumePlayback() async throws {
|
||||
@Test
|
||||
func resumePlayback() async throws {
|
||||
try await setRecordingComplete()
|
||||
audioPlayer.playbackURL = recordingURL
|
||||
|
||||
guard case .success = await voiceMessageRecorder.startPlayback() else {
|
||||
XCTFail("Playback should start")
|
||||
Issue.record("Playback should start")
|
||||
return
|
||||
}
|
||||
XCTAssertEqual(voiceMessageRecorder.previewAudioPlayerState?.isAttached, true)
|
||||
#expect(voiceMessageRecorder.previewAudioPlayerState?.isAttached == true)
|
||||
// The media must not have been reloaded
|
||||
XCTAssertFalse(audioPlayer.loadSourceURLPlaybackURLAutoplayCalled)
|
||||
XCTAssertTrue(audioPlayer.playCalled)
|
||||
#expect(!audioPlayer.loadSourceURLPlaybackURLAutoplayCalled)
|
||||
#expect(audioPlayer.playCalled)
|
||||
}
|
||||
|
||||
func testStopPlayback() async throws {
|
||||
@Test
|
||||
func stopPlayback() async throws {
|
||||
try await setRecordingComplete()
|
||||
|
||||
_ = await voiceMessageRecorder.startPlayback()
|
||||
XCTAssertEqual(voiceMessageRecorder.previewAudioPlayerState?.isAttached, true)
|
||||
#expect(voiceMessageRecorder.previewAudioPlayerState?.isAttached == true)
|
||||
|
||||
await voiceMessageRecorder.stopPlayback()
|
||||
XCTAssertEqual(voiceMessageRecorder.previewAudioPlayerState?.isAttached, false)
|
||||
XCTAssert(audioPlayer.stopCalled)
|
||||
#expect(voiceMessageRecorder.previewAudioPlayerState?.isAttached == false)
|
||||
#expect(audioPlayer.stopCalled)
|
||||
}
|
||||
|
||||
func testSeekPlayback() async throws {
|
||||
@Test
|
||||
func seekPlayback() async throws {
|
||||
try await setRecordingComplete()
|
||||
|
||||
_ = await voiceMessageRecorder.startPlayback()
|
||||
XCTAssertEqual(voiceMessageRecorder.previewAudioPlayerState?.isAttached, true)
|
||||
#expect(voiceMessageRecorder.previewAudioPlayerState?.isAttached == true)
|
||||
|
||||
await voiceMessageRecorder.seekPlayback(to: 0.4)
|
||||
XCTAssertEqual(audioPlayer.seekToReceivedProgress, 0.4)
|
||||
#expect(audioPlayer.seekToReceivedProgress == 0.4)
|
||||
}
|
||||
|
||||
func testBuildRecordedWaveform() async {
|
||||
@Test
|
||||
func buildRecordedWaveform() async throws {
|
||||
// If there is no recording file, an error is expected
|
||||
audioRecorder.audioFileURL = nil
|
||||
guard case .failure(.missingRecordingFile) = await voiceMessageRecorder.buildRecordingWaveform() else {
|
||||
XCTFail("An error is expected")
|
||||
Issue.record("An error is expected")
|
||||
return
|
||||
}
|
||||
|
||||
guard let audioFileURL = Bundle(for: Self.self).url(forResource: "test_audio", withExtension: "mp3") else {
|
||||
XCTFail("Test audio file is missing")
|
||||
return
|
||||
}
|
||||
let audioFileURL = try #require(Bundle(for: UnitTestsAppCoordinator.self).url(forResource: "test_audio", withExtension: "mp3"), "Test audio file is missing")
|
||||
audioRecorder.audioFileURL = audioFileURL
|
||||
guard case .success(let data) = await voiceMessageRecorder.buildRecordingWaveform() else {
|
||||
XCTFail("A waveform is expected")
|
||||
Issue.record("A waveform is expected")
|
||||
return
|
||||
}
|
||||
XCTAssert(!data.isEmpty)
|
||||
#expect(!data.isEmpty)
|
||||
}
|
||||
|
||||
func testSendVoiceMessage_NoRecordingFile() async {
|
||||
@Test
|
||||
func sendVoiceMessage_NoRecordingFile() async {
|
||||
let timelineController = MockTimelineController()
|
||||
|
||||
// If there is no recording file, an error is expected
|
||||
audioRecorder.audioFileURL = nil
|
||||
guard case .failure(.missingRecordingFile) = await voiceMessageRecorder.sendVoiceMessage(timelineController: timelineController,
|
||||
audioConverter: audioConverter) else {
|
||||
XCTFail("An error is expected")
|
||||
Issue.record("An error is expected")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testSendVoiceMessage_ConversionError() async {
|
||||
@Test
|
||||
func sendVoiceMessage_ConversionError() async {
|
||||
audioRecorder.audioFileURL = recordingURL
|
||||
// If the converter returns an error
|
||||
audioConverter.convertToOpusOggSourceURLDestinationURLThrowableError = AudioConverterError.conversionFailed(nil)
|
||||
@@ -213,16 +226,14 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
let timelineController = MockTimelineController()
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(timelineController: timelineController,
|
||||
audioConverter: audioConverter) else {
|
||||
XCTFail("An error is expected")
|
||||
Issue.record("An error is expected")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testSendVoiceMessage_InvalidFile() async {
|
||||
guard let audioFileURL = Bundle(for: Self.self).url(forResource: "test_voice_message", withExtension: "m4a") else {
|
||||
XCTFail("Test audio file is missing")
|
||||
return
|
||||
}
|
||||
@Test
|
||||
func sendVoiceMessage_InvalidFile() async throws {
|
||||
let audioFileURL = try #require(Bundle(for: UnitTestsAppCoordinator.self).url(forResource: "test_voice_message", withExtension: "m4a"), "Test audio file is missing")
|
||||
audioRecorder.audioFileURL = audioFileURL
|
||||
audioConverter.convertToOpusOggSourceURLDestinationURLClosure = { _, destination in
|
||||
try? FileManager.default.removeItem(at: destination)
|
||||
@@ -233,16 +244,14 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(timelineController: timelineController,
|
||||
audioConverter: audioConverter) else {
|
||||
XCTFail("An error is expected")
|
||||
Issue.record("An error is expected")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testSendVoiceMessage_WaveformAnlyseFailed() async {
|
||||
guard let imageFileURL = Bundle(for: Self.self).url(forResource: "test_image", withExtension: "png") else {
|
||||
XCTFail("Test audio file is missing")
|
||||
return
|
||||
}
|
||||
@Test
|
||||
func sendVoiceMessage_WaveformAnlyseFailed() async throws {
|
||||
let imageFileURL = try #require(Bundle(for: UnitTestsAppCoordinator.self).url(forResource: "test_image", withExtension: "png"), "Test image file is missing")
|
||||
audioRecorder.audioFileURL = imageFileURL
|
||||
audioConverter.convertToOpusOggSourceURLDestinationURLClosure = { _, destination in
|
||||
try? FileManager.default.removeItem(at: destination)
|
||||
@@ -254,16 +263,14 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(timelineController: timelineController,
|
||||
audioConverter: audioConverter) else {
|
||||
XCTFail("An error is expected")
|
||||
Issue.record("An error is expected")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testSendVoiceMessage_SendError() async {
|
||||
guard let audioFileURL = Bundle(for: Self.self).url(forResource: "test_voice_message", withExtension: "m4a") else {
|
||||
XCTFail("Test audio file is missing")
|
||||
return
|
||||
}
|
||||
@Test
|
||||
func sendVoiceMessage_SendError() async throws {
|
||||
let audioFileURL = try #require(Bundle(for: UnitTestsAppCoordinator.self).url(forResource: "test_voice_message", withExtension: "m4a"), "Test audio file is missing")
|
||||
audioRecorder.audioFileURL = audioFileURL
|
||||
audioConverter.convertToOpusOggSourceURLDestinationURLClosure = { source, destination in
|
||||
try? FileManager.default.removeItem(at: destination)
|
||||
@@ -277,16 +284,14 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(timelineController: timelineController,
|
||||
audioConverter: audioConverter) else {
|
||||
XCTFail("An error is expected")
|
||||
Issue.record("An error is expected")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func testSendVoiceMessage() async {
|
||||
guard let imageFileURL = Bundle(for: Self.self).url(forResource: "test_voice_message", withExtension: "m4a") else {
|
||||
XCTFail("Test audio file is missing")
|
||||
return
|
||||
}
|
||||
@Test
|
||||
func sendVoiceMessage() async throws {
|
||||
let imageFileURL = try #require(Bundle(for: UnitTestsAppCoordinator.self).url(forResource: "test_voice_message", withExtension: "m4a"), "Test audio file is missing")
|
||||
|
||||
let timelineProxy = TimelineProxyMock()
|
||||
let timelineController = MockTimelineController(timelineProxy: timelineProxy)
|
||||
@@ -305,38 +310,39 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
try internalConverter.convertToOpusOgg(sourceURL: source, destinationURL: destination)
|
||||
convertedFileSize = try? UInt64(FileManager.default.sizeForItem(at: destination))
|
||||
// the source URL must be the recorded file
|
||||
XCTAssertEqual(source, imageFileURL)
|
||||
#expect(source == imageFileURL)
|
||||
// check the converted file extension
|
||||
XCTAssertEqual(destination.pathExtension, "ogg")
|
||||
#expect(destination.pathExtension == "ogg")
|
||||
}
|
||||
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleClosure = { url, audioInfo, waveform, _ in
|
||||
XCTAssertEqual(url, convertedFileURL)
|
||||
XCTAssertEqual(audioInfo.duration, self.audioRecorder.currentTime)
|
||||
XCTAssertEqual(audioInfo.size, convertedFileSize)
|
||||
XCTAssertEqual(audioInfo.mimetype, "audio/ogg")
|
||||
XCTAssertFalse(waveform.isEmpty)
|
||||
#expect(url == convertedFileURL)
|
||||
#expect(audioInfo.duration == audioRecorder.currentTime)
|
||||
#expect(audioInfo.size == convertedFileSize)
|
||||
#expect(audioInfo.mimetype == "audio/ogg")
|
||||
#expect(!waveform.isEmpty)
|
||||
|
||||
return .success(())
|
||||
}
|
||||
|
||||
guard case .success = await voiceMessageRecorder.sendVoiceMessage(timelineController: timelineController, audioConverter: audioConverter) else {
|
||||
XCTFail("A success is expected")
|
||||
Issue.record("A success is expected")
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssert(audioConverter.convertToOpusOggSourceURLDestinationURLCalled)
|
||||
XCTAssert(timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleCalled)
|
||||
#expect(audioConverter.convertToOpusOggSourceURLDestinationURLCalled)
|
||||
#expect(timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleCalled)
|
||||
|
||||
// the converted file must have been deleted
|
||||
if let convertedFileURL {
|
||||
XCTAssertFalse(FileManager.default.fileExists(atPath: convertedFileURL.path()))
|
||||
#expect(!FileManager.default.fileExists(atPath: convertedFileURL.path()))
|
||||
} else {
|
||||
XCTFail("converted file URL is missing")
|
||||
Issue.record("converted file URL is missing")
|
||||
}
|
||||
}
|
||||
|
||||
func testAudioRecorderActionHandling_didStartRecording() async throws {
|
||||
@Test
|
||||
func audioRecorderActionHandling_didStartRecording() async throws {
|
||||
let deferred = deferFulfillment(voiceMessageRecorder.actions) { action in
|
||||
switch action {
|
||||
case .didStartRecording:
|
||||
@@ -349,13 +355,14 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testAudioRecorderActionHandling_didStopRecording() async throws {
|
||||
@Test
|
||||
func audioRecorderActionHandling_didStopRecording() async throws {
|
||||
audioRecorder.audioFileURL = recordingURL
|
||||
audioRecorder.currentTime = 5
|
||||
|
||||
let deferred = deferFulfillment(voiceMessageRecorder.actions) { action in
|
||||
switch action {
|
||||
case .didStopRecording(_, let url) where url == self.recordingURL:
|
||||
case .didStopRecording(_, let url) where url == recordingURL:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -365,7 +372,8 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
try await deferred.fulfill()
|
||||
}
|
||||
|
||||
func testAudioRecorderActionHandling_didFailed() async throws {
|
||||
@Test
|
||||
func audioRecorderActionHandling_didFailed() async throws {
|
||||
audioRecorder.audioFileURL = recordingURL
|
||||
|
||||
let deferred = deferFulfillment(voiceMessageRecorder.actions) { action in
|
||||
|
||||
Reference in New Issue
Block a user