Improved the naming of the functions for the FileServicing protocol in the library target.

This commit is contained in:
Javier Cicchelli 2025-01-13 23:27:50 +01:00
parent df556f83ab
commit 26fde119ef
6 changed files with 69 additions and 69 deletions

View File

@ -8,9 +8,9 @@ public protocol FileServicing {
// MARK: Functions // MARK: Functions
func createFolder(at url: URL) async throws (FileServiceError) func createFolder(at location: URL) async throws (FileServiceError)
func delete(at url: URL) async throws (FileServiceError) func deleteItem(at location: URL) async throws (FileServiceError)
func exists(at url: URL) async throws (FileServiceError) -> Bool func isItemExists(at location: URL) async throws (FileServiceError) -> Bool
} }
@ -18,8 +18,8 @@ public protocol FileServicing {
public enum FileServiceError: Error, Equatable { public enum FileServiceError: Error, Equatable {
case folderNotCreated case folderNotCreated
case urlAlreadyExists case itemAlreadyExists
case urlNotDeleted case itemNotDeleted
case urlNotExists case itemNotExists
case urlNotFileURL case itemNotFileURL
} }

View File

@ -22,39 +22,36 @@ public struct FileService: FileServicing {
// MARK: Functions // MARK: Functions
public func createFolder(at url: URL) async throws (FileServiceError) { public func createFolder(at location: URL) async throws (FileServiceError) {
guard try await !exists(at: url) else { guard try await !isItemExists(at: location) else {
throw FileServiceError.urlAlreadyExists throw FileServiceError.itemAlreadyExists
} }
do { do {
try fileManager.createDirectory( try fileManager.createDirectory(at: location, withIntermediateDirectories: true)
at: url,
withIntermediateDirectories: true
)
} catch { } catch {
throw FileServiceError.folderNotCreated throw FileServiceError.folderNotCreated
} }
} }
public func delete(at url: URL) async throws (FileServiceError) { public func deleteItem(at location: URL) async throws (FileServiceError) {
guard try await exists(at: url) else { guard try await isItemExists(at: location) else {
throw FileServiceError.urlNotExists throw FileServiceError.itemNotExists
} }
do { do {
try fileManager.removeItem(at: url) try fileManager.removeItem(at: location)
} catch { } catch {
throw FileServiceError.urlNotDeleted throw FileServiceError.itemNotDeleted
} }
} }
public func exists(at url: URL) async throws (FileServiceError) -> Bool { public func isItemExists(at location: URL) async throws (FileServiceError) -> Bool {
guard url.isFileURL else { guard location.isFileURL else {
throw FileServiceError.urlNotFileURL throw FileServiceError.itemNotFileURL
} }
let filePath = url.pathString let filePath = location.pathString
return fileManager.fileExists(atPath: filePath) return fileManager.fileExists(atPath: filePath)
} }

View File

@ -27,29 +27,29 @@ struct FileServiceTests {
// MARK: Functions tests // MARK: Functions tests
@Test(arguments: [URL.someNewFolder, .someNewFile]) @Test(arguments: [URL.someNewFolder, .someNewFile])
func createFolder(with url: URL) async throws { func createFolder(with location: URL) async throws {
// GIVEN // GIVEN
let service = FileServiceMock( let service = FileServiceMock(
currentFolder: .someCurrentFolder, currentFolder: .someCurrentFolder,
action: .createFolder(url), action: .createFolder(location),
spy: spy spy: spy
) )
// WHEN // WHEN
try await service.createFolder(at: url) try await service.createFolder(at: location)
// THEN // THEN
#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 == .folderCreated(url)) #expect(action == .folderCreated(location))
} }
@Test(arguments: zip([URL.someExistingFolder, .someExistingFile, .someRandomURL], @Test(arguments: zip([URL.someExistingFolder, .someExistingFile, .someRandomURL],
[FileServiceError.urlAlreadyExists, .urlAlreadyExists, .urlNotFileURL])) [FileServiceError.itemAlreadyExists, .itemAlreadyExists, .itemNotFileURL]))
func createFolder( func createFolder(
with url: URL, with location: URL,
throws error: FileServiceError throws error: FileServiceError
) async throws { ) async throws {
// GIVEN // GIVEN
@ -62,36 +62,36 @@ struct FileServiceTests {
// WHEN // WHEN
// THEN // THEN
await #expect(throws: error) { await #expect(throws: error) {
try await service.createFolder(at: url) try await service.createFolder(at: location)
} }
#expect(spy.actions.isEmpty == true) #expect(spy.actions.isEmpty == true)
} }
@Test(arguments: [URL.someNewFolder, .someNewFile]) @Test(arguments: [URL.someNewFolder, .someNewFile])
func delete(with url: URL) async throws { func deleteItem(with location: URL) async throws {
// GIVEN // GIVEN
let service = FileServiceMock( let service = FileServiceMock(
currentFolder: .someCurrentFolder, currentFolder: .someCurrentFolder,
action: .delete(url), action: .deleteItem(location),
spy: spy spy: spy
) )
// WHEN // WHEN
try await service.delete(at: url) try await service.deleteItem(at: location)
// THEN // THEN
#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 == .itemDeleted(url)) #expect(action == .itemDeleted(location))
} }
@Test(arguments: zip([URL.someNewFolder, .someNewFile, .someRandomURL], @Test(arguments: zip([URL.someNewFolder, .someNewFile, .someRandomURL],
[FileServiceError.urlNotExists, .urlNotExists, .urlNotFileURL])) [FileServiceError.itemNotExists, .itemNotExists, .itemNotFileURL]))
func delete( func deleteItem(
with url: URL, with location: URL,
throws error: FileServiceError throws error: FileServiceError
) async throws { ) async throws {
// GIVEN // GIVEN
@ -104,7 +104,7 @@ struct FileServiceTests {
// WHEN // WHEN
// THEN // THEN
await #expect(throws: error) { await #expect(throws: error) {
try await service.delete(at: url) try await service.deleteItem(at: location)
} }
#expect(spy.actions.isEmpty == true) #expect(spy.actions.isEmpty == true)
@ -112,31 +112,31 @@ struct FileServiceTests {
@Test(arguments: zip([URL.someExistingFolder, .someExistingFile, .someNewFolder, .someNewFile], @Test(arguments: zip([URL.someExistingFolder, .someExistingFile, .someNewFolder, .someNewFile],
[true, true, false, false])) [true, true, false, false]))
func exists( func isItemExists(
with url: URL, with location: URL,
expects outcome: Bool expects outcome: Bool
) async throws { ) async throws {
// GIVEN // GIVEN
let service = FileServiceMock( let service = FileServiceMock(
currentFolder: .someCurrentFolder, currentFolder: .someCurrentFolder,
action: .exists(url, outcome), action: .isItemExists(location, outcome),
spy: spy spy: spy
) )
// WHEN // WHEN
let result = try await service.exists(at: url) let result = try await service.isItemExists(at: location)
// THEN // THEN
#expect(result == outcome) #expect(result == outcome)
let action = try #require(spy.actions.last) let action = try #require(spy.actions.last)
#expect(action == .itemExists(url)) #expect(action == .itemExists(location))
} }
@Test(arguments: zip([URL.someRandomURL], [FileServiceError.urlNotFileURL])) @Test(arguments: zip([URL.someRandomURL], [FileServiceError.itemNotFileURL]))
func exists( func isItemExists(
with url: URL, with location: URL,
throws error: FileServiceError throws error: FileServiceError
) async throws { ) async throws {
// GIVEN // GIVEN
@ -149,7 +149,7 @@ struct FileServiceTests {
// WHEN // WHEN
// THEN // THEN
await #expect(throws: error) { await #expect(throws: error) {
try await service.exists(at: url) try await service.isItemExists(at: location)
} }
#expect(spy.actions.isEmpty == true) #expect(spy.actions.isEmpty == true)

View File

@ -36,7 +36,7 @@ struct CreateRootFolderTaskTests {
#expect(result.isFileURL == true) #expect(result.isFileURL == true)
} }
@Test(arguments: [String.someProjectName], [FileServiceError.urlAlreadyExists]) @Test(arguments: [String.someProjectName], [FileServiceError.itemAlreadyExists])
func task( func task(
name: String, name: String,
throws error: FileServiceError throws error: FileServiceError

View File

@ -42,7 +42,7 @@ final class FileServiceMock {
// MARK: - FileServicing // MARK: - FileServicing
extension FileServiceMock: FileServicing { extension FileServiceMock: FileServicing {
// MARK: Computed // MARK: Computed
var currentFolder: URL { var currentFolder: URL {
@ -51,40 +51,40 @@ extension FileServiceMock: FileServicing {
// MARK: Functions // MARK: Functions
func createFolder(at url: URL) async throws(FileServiceError) { func createFolder(at location: 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 .createFolder(url): case let .createFolder(location):
try await spy?.createFolder(at: url) try await spy?.createFolder(at: location)
default: default:
break break
} }
} }
func delete(at url: URL) async throws(FileServiceError) { func deleteItem(at location: 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 .delete(url): case let .deleteItem(location):
try await spy?.delete(at: url) try await spy?.deleteItem(at: location)
default: default:
break break
} }
} }
func exists(at url: URL) async throws(FileServiceError) -> Bool { func isItemExists(at location: URL) async throws (FileServiceError) -> Bool {
guard let nextAction else { return false } guard let nextAction else { return false }
switch nextAction { switch nextAction {
case .error(let error): case .error(let error):
throw error throw error
case let .exists(url, exists): case let .isItemExists(location, exists):
try await spy?.exists(at: url) try await spy?.isItemExists(at: location)
return exists return exists
default: default:
return false return false
@ -114,8 +114,8 @@ private extension FileServiceMock {
extension FileServiceMock { extension FileServiceMock {
enum Action { enum Action {
case createFolder(URL) case createFolder(URL)
case delete(URL) case deleteItem(URL)
case error(FileServiceError) case error(FileServiceError)
case exists(URL, Bool) case isItemExists(URL, Bool)
} }
} }

View File

@ -13,21 +13,24 @@ final class FileServiceSpy {
// MARK: - FileServicing // MARK: - FileServicing
extension FileServiceSpy: FileServicing { extension FileServiceSpy: FileServicing {
var currentFolder: URL { var currentFolder: URL {
get async { .someCurrentFolder } get async { .someCurrentFolder }
} }
func createFolder(at url: URL) async throws (FileServiceError) {
actions.append(.folderCreated(url))
} }
func delete(at url: URL) async throws (FileServiceError) { func createFolder(at location: URL) async throws (FileServiceError) {
actions.append(.itemDeleted(url)) actions.append(.folderCreated(location))
}
func deleteItem(at location: URL) async throws (FileServiceError) {
actions.append(.itemDeleted(location))
} }
@discardableResult @discardableResult
func exists(at url: URL) async throws (FileServiceError) -> Bool { func isItemExists(at location: URL) async throws (FileServiceError) -> Bool {
actions.append(.itemExists(url)) actions.append(.itemExists(location))
return .random() return .random()
} }
@ -38,8 +41,8 @@ extension FileServiceSpy: FileServicing {
extension FileServiceSpy { extension FileServiceSpy {
enum Action: Equatable { enum Action: Equatable {
case folderCreated(_ url: URL) case folderCreated(_ location: URL)
case itemDeleted(_ url: URL) case itemDeleted(_ location: URL)
case itemExists(_ url: URL) case itemExists(_ location: URL)
} }
} }