Template support for input parameters #4
@ -8,7 +8,7 @@ public protocol FileServicing {
|
|||||||
|
|
||||||
// MARK: Functions
|
// MARK: Functions
|
||||||
|
|
||||||
func copyItem(from source: URL, to destination: URL) async throws (FileServiceError)
|
func copyFile(from source: URL, to destination: URL) async throws (FileServiceError)
|
||||||
func createFolder(at location: URL) async throws (FileServiceError)
|
func createFolder(at location: URL) async throws (FileServiceError)
|
||||||
func deleteItem(at location: URL) async throws (FileServiceError)
|
func deleteItem(at location: URL) async throws (FileServiceError)
|
||||||
func isItemExists(at location: URL) async throws (FileServiceError) -> Bool
|
func isItemExists(at location: URL) async throws (FileServiceError) -> Bool
|
||||||
@ -19,8 +19,9 @@ public protocol FileServicing {
|
|||||||
|
|
||||||
public enum FileServiceError: Error, Equatable {
|
public enum FileServiceError: Error, Equatable {
|
||||||
case folderNotCreated
|
case folderNotCreated
|
||||||
case itemNotCopied
|
|
||||||
case itemAlreadyExists
|
case itemAlreadyExists
|
||||||
|
case itemEmptyData
|
||||||
|
case itemNotCopied
|
||||||
case itemNotDeleted
|
case itemNotDeleted
|
||||||
case itemNotExists
|
case itemNotExists
|
||||||
case itemNotFileURL
|
case itemNotFileURL
|
||||||
|
@ -22,7 +22,7 @@ public struct FileService: FileServicing {
|
|||||||
|
|
||||||
// MARK: Functions
|
// MARK: Functions
|
||||||
|
|
||||||
public func copyItem(from source: URL, to destination: URL) async throws (FileServiceError) {
|
public func copyFile(from source: URL, to destination: URL) async throws (FileServiceError) {
|
||||||
guard try await isItemExists(at: source) else {
|
guard try await isItemExists(at: source) else {
|
||||||
throw FileServiceError.itemNotExists
|
throw FileServiceError.itemNotExists
|
||||||
}
|
}
|
||||||
@ -30,8 +30,16 @@ public struct FileService: FileServicing {
|
|||||||
throw FileServiceError.itemAlreadyExists
|
throw FileServiceError.itemAlreadyExists
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var itemData: Data?
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try fileManager.copyItem(at: source, to: destination)
|
itemData = try Data(contentsOf: source)
|
||||||
|
} catch {
|
||||||
|
throw FileServiceError.itemEmptyData
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
try itemData?.write(to: destination, options: .atomic)
|
||||||
} catch {
|
} catch {
|
||||||
throw FileServiceError.itemNotCopied
|
throw FileServiceError.itemNotCopied
|
||||||
}
|
}
|
||||||
|
@ -28,26 +28,26 @@ struct FileServiceTests {
|
|||||||
|
|
||||||
@Test(arguments: zip([URL.someExistingFile, .someExistingFolder],
|
@Test(arguments: zip([URL.someExistingFile, .someExistingFolder],
|
||||||
[URL.someNewFile, .someNewFolder]))
|
[URL.someNewFile, .someNewFolder]))
|
||||||
func copyItem(from source: URL, to destination: URL) async throws {
|
func copyFile(from source: URL, to destination: URL) async throws {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
let service = FileServiceMock(
|
let service = FileServiceMock(
|
||||||
currentFolder: .someCurrentFolder,
|
currentFolder: .someCurrentFolder,
|
||||||
action: .copyItem(source, destination),
|
action: .copyFile(source, destination),
|
||||||
spy: spy
|
spy: spy
|
||||||
)
|
)
|
||||||
|
|
||||||
// WHEN
|
// WHEN
|
||||||
try await service.copyItem(from: source, to: destination)
|
try await service.copyFile(from: source, to: destination)
|
||||||
|
|
||||||
// THENn
|
// THENn
|
||||||
#expect(spy.actions.count == 1)
|
#expect(spy.actions.count == 1)
|
||||||
|
|
||||||
let action = try #require(spy.actions.last)
|
let action = try #require(spy.actions.last)
|
||||||
|
|
||||||
#expect(action == .itemCopied(source, destination))
|
#expect(action == .fileCopied(source, destination))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(arguments: [FileServiceError.itemNotExists, .itemAlreadyExists, .itemNotCopied])
|
@Test(arguments: [FileServiceError.itemNotExists, .itemAlreadyExists, .itemEmptyData, .itemNotCopied])
|
||||||
func copyItem(throws error: FileServiceError) async throws {
|
func copyItem(throws error: FileServiceError) async throws {
|
||||||
// GIVEN
|
// GIVEN
|
||||||
let service = FileServiceMock(
|
let service = FileServiceMock(
|
||||||
@ -59,7 +59,7 @@ struct FileServiceTests {
|
|||||||
// WHEN
|
// WHEN
|
||||||
// THEN
|
// THEN
|
||||||
await #expect(throws: error) {
|
await #expect(throws: error) {
|
||||||
try await service.copyItem(from: .someExistingFile, to: .someNewFile)
|
try await service.copyFile(from: .someExistingFile, to: .someNewFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
#expect(spy.actions.isEmpty == true)
|
#expect(spy.actions.isEmpty == true)
|
||||||
|
@ -51,14 +51,14 @@ extension FileServiceMock: FileServicing {
|
|||||||
|
|
||||||
// MARK: Functions
|
// MARK: Functions
|
||||||
|
|
||||||
func copyItem(from source: URL, to destination: URL) async throws (FileServiceError) {
|
func copyFile(from source: URL, to destination: URL) async throws (FileServiceError) {
|
||||||
guard let nextAction else { return }
|
guard let nextAction else { return }
|
||||||
|
|
||||||
switch nextAction {
|
switch nextAction {
|
||||||
case .error(let error):
|
case .error(let error):
|
||||||
throw error
|
throw error
|
||||||
case let .copyItem(source, destination):
|
case let .copyFile(source, destination):
|
||||||
try await spy?.copyItem(from: source, to: destination)
|
try await spy?.copyFile(from: source, to: destination)
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -126,7 +126,7 @@ private extension FileServiceMock {
|
|||||||
|
|
||||||
extension FileServiceMock {
|
extension FileServiceMock {
|
||||||
enum Action {
|
enum Action {
|
||||||
case copyItem(URL, URL)
|
case copyFile(URL, URL)
|
||||||
case createFolder(URL)
|
case createFolder(URL)
|
||||||
case deleteItem(URL)
|
case deleteItem(URL)
|
||||||
case error(FileServiceError)
|
case error(FileServiceError)
|
||||||
|
@ -18,8 +18,8 @@ extension FileServiceSpy: FileServicing {
|
|||||||
get async { .someCurrentFolder }
|
get async { .someCurrentFolder }
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyItem(from source: URL, to destination: URL) async throws (FileServiceError) {
|
func copyFile(from source: URL, to destination: URL) async throws (FileServiceError) {
|
||||||
actions.append(.itemCopied(source, destination))
|
actions.append(.fileCopied(source, destination))
|
||||||
}
|
}
|
||||||
|
|
||||||
func createFolder(at location: URL) async throws (FileServiceError) {
|
func createFolder(at location: URL) async throws (FileServiceError) {
|
||||||
@ -43,8 +43,8 @@ extension FileServiceSpy: FileServicing {
|
|||||||
|
|
||||||
extension FileServiceSpy {
|
extension FileServiceSpy {
|
||||||
enum Action: Equatable {
|
enum Action: Equatable {
|
||||||
|
case fileCopied(_ source: URL, _ destination: URL)
|
||||||
case folderCreated(_ location: URL)
|
case folderCreated(_ location: URL)
|
||||||
case itemCopied(_ source: URL, _ destination: URL)
|
|
||||||
case itemDeleted(_ location: URL)
|
case itemDeleted(_ location: URL)
|
||||||
case itemExists(_ location: URL)
|
case itemExists(_ location: URL)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user