import ColibriLibrary import Foundation final class FileServiceMock { // MARK: Properties private let folder: URL private var actions: [Action] = [] private weak var spy: FileServiceSpy? // MARK: Initialisers init( currentFolder: URL, action: Action? = nil, spy: FileServiceSpy? = nil ) { self.actions = if let action { [action] } else { [] } self.folder = currentFolder self.spy = spy } init( currentFolder: URL, actions: [Action], spy: FileServiceSpy? = nil ) { self.actions = actions self.folder = currentFolder self.spy = spy } } // MARK: - FileServicing extension FileServiceMock: FileServicing { // MARK: Computed var currentFolder: URL { get async { folder } } // MARK: Functions func createFolder(at url: URL) async throws(FileServiceError) { guard let nextAction else { return } switch nextAction { case .error(let error): throw error case let .createFolder(url): try await spy?.createFolder(at: url) default: break } } func delete(at url: URL) async throws(FileServiceError) { guard let nextAction else { return } switch nextAction { case .error(let error): throw error case let .delete(url): try await spy?.delete(at: url) default: break } } func exists(at url: URL) async throws(FileServiceError) -> Bool { guard let nextAction else { return false } switch nextAction { case .error(let error): throw error case let .exists(url, exists): try await spy?.exists(at: url) return exists default: return false } } } // MARK: - Helpers private extension FileServiceMock { // MARK: Computed var nextAction: Action? { guard !actions.isEmpty else { return nil } return actions.removeFirst() } } // MARK: - Actions extension FileServiceMock { enum Action { case createFolder(URL) case delete(URL) case error(FileServiceError) case exists(URL, Bool) } }