diff --git a/Sources/Library/Protocols/FileServicing.swift b/Sources/Library/Protocols/FileServicing.swift index 9f8d20a..5f85840 100644 --- a/Sources/Library/Protocols/FileServicing.swift +++ b/Sources/Library/Protocols/FileServicing.swift @@ -8,6 +8,7 @@ public protocol FileServicing { // MARK: Functions + func createFolder(at url: URL) async throws (FileServiceError) func delete(at url: URL) async throws (FileServiceError) func exists(at url: URL) async throws (FileServiceError) -> Bool diff --git a/Sources/Library/Services/FileService.swift b/Sources/Library/Services/FileService.swift index d1d6397..3e91ad2 100644 --- a/Sources/Library/Services/FileService.swift +++ b/Sources/Library/Services/FileService.swift @@ -22,6 +22,21 @@ public struct FileService: FileServicing { // MARK: Functions + public func createFolder(at url: URL) async throws (FileServiceError) { + guard try await !exists(at: url) else { + throw FileServiceError.urlAlreadyExists + } + + do { + try fileManager.createDirectory( + at: url, + withIntermediateDirectories: true + ) + } catch { + throw FileServiceError.folderNotCreated + } + } + public func delete(at url: URL) async throws (FileServiceError) { guard try await exists(at: url) else { throw FileServiceError.urlNotExists diff --git a/Tests/Library/Services/FileServiceTests.swift b/Tests/Library/Services/FileServiceTests.swift index 9193264..8a53c0e 100644 --- a/Tests/Library/Services/FileServiceTests.swift +++ b/Tests/Library/Services/FileServiceTests.swift @@ -26,6 +26,41 @@ struct FileServiceTests { #expect(url == .someExistingFolder) #expect(url.isFileURL == true) } + + // MARK: Functions + + @Test(arguments: [URL.someNewFolder, .someNewFile]) + func createFolder(with url: URL) async throws { + // GIVEN + if try await service.exists(at: url) { + try await service.delete(at: url) + } + + // WHEN + try await service.createFolder(at: url) + + // THEN + let result = try await service.exists(at: url) + + #expect(result == true) + + try await service.delete(at: url) + } + + @Test(arguments: zip([URL.someExistingFolder, .someExistingFile, .someRandomURL], + [FileServiceError.urlAlreadyExists, .urlAlreadyExists, .urlNotFileURL])) + func createFolderThrows( + with url: URL, + expects error: FileServiceError + ) async throws { + // GIVEN + // WHEN + // THEN + await #expect(throws: error) { + try await service.createFolder(at: url) + } + } + @Test(arguments: [URL.someNewFolder, .someNewFile]) func delete(with url: URL) async throws { // GIVEN @@ -42,7 +77,7 @@ struct FileServiceTests { #expect(result == false) } - @Test(arguments: zip([URL.someNonExistingFolder, .someNonExistingFile, .someRandomURL], + @Test(arguments: zip([URL.someNewFolder, .someNewFile, .someRandomURL], [FileServiceError.urlNotExists, .urlNotExists, .urlNotFileURL])) func deleteThrows( with url: URL, @@ -56,7 +91,7 @@ struct FileServiceTests { } } - @Test(arguments: zip([URL.someExistingFolder, .someExistingFile, .someNonExistingFolder, .someNonExistingFile], + @Test(arguments: zip([URL.someExistingFolder, .someExistingFile, .someNewFolder, .someNewFile], [true, true, false, false])) func exists( with url: URL, @@ -90,7 +125,5 @@ private extension URL { static let someExistingFile = URL(at: "/etc/ssh/ssh_config") static let someNewFolder = URL(at: "/private/tmp/folder") static let someNewFile = URL(at: "/private/tmp/file.ext") - static let someNonExistingFolder = URL(at: "/some/random/folder") - static let someNonExistingFile = URL(at: "/some/random/file.ext") static let someRandomURL = URL(string: "https://some.random.url")! }