diff --git a/Logger.xcodeproj/project.pbxproj b/Logger.xcodeproj/project.pbxproj index 46251ca..317817a 100644 --- a/Logger.xcodeproj/project.pbxproj +++ b/Logger.xcodeproj/project.pbxproj @@ -15,14 +15,15 @@ 2EBF4B4B2122AF53008E4117 /* ConsoleLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B482122AF53008E4117 /* ConsoleLogger.swift */; }; 2EBF4B4C2122AF53008E4117 /* NullLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B492122AF53008E4117 /* NullLogger.swift */; }; 2EBF4B572122B598008E4117 /* DiskLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B542122B598008E4117 /* DiskLogger.swift */; }; - 2EBF4B582122B598008E4117 /* FileWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B552122B598008E4117 /* FileWriter.swift */; }; - 2EBF4B592122B598008E4117 /* FileRotate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B562122B598008E4117 /* FileRotate.swift */; }; + 2EBF4B582122B598008E4117 /* SizeLimitedFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */; }; + 2EBF4B592122B598008E4117 /* Logrotate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EBF4B562122B598008E4117 /* Logrotate.swift */; }; 2ED077D721329CA30058EEFC /* LoggetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D621329CA30058EEFC /* LoggetTests.swift */; }; 2ED077D92132A4820058EEFC /* AgregateLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */; }; - 2ED077DB2132B0320058EEFC /* FileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077DA2132B0320058EEFC /* FileSystem.swift */; }; - 2ED103E12135C61100EB3683 /* FileRotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E02135C61100EB3683 /* FileRotateTests.swift */; }; - 2ED103E32135D3FB00EB3683 /* FileWriterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E22135D3FB00EB3683 /* FileWriterTests.swift */; }; + 2ED077DB2132B0320058EEFC /* OSFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED077DA2132B0320058EEFC /* OSFileManager.swift */; }; + 2ED103E12135C61100EB3683 /* LogrotateTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E02135C61100EB3683 /* LogrotateTests.swift */; }; + 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */; }; 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */; }; + 2ED83781236A19A60008C01F /* OSFileHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ED83780236A19A60008C01F /* OSFileHandle.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -58,14 +59,15 @@ 2EBF4B482122AF53008E4117 /* ConsoleLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsoleLogger.swift; sourceTree = ""; }; 2EBF4B492122AF53008E4117 /* NullLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NullLogger.swift; sourceTree = ""; }; 2EBF4B542122B598008E4117 /* DiskLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiskLogger.swift; sourceTree = ""; }; - 2EBF4B552122B598008E4117 /* FileWriter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileWriter.swift; sourceTree = ""; }; - 2EBF4B562122B598008E4117 /* FileRotate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileRotate.swift; sourceTree = ""; }; + 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SizeLimitedFile.swift; sourceTree = ""; }; + 2EBF4B562122B598008E4117 /* Logrotate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logrotate.swift; sourceTree = ""; }; 2ED077D621329CA30058EEFC /* LoggetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggetTests.swift; sourceTree = ""; }; 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AgregateLoggerTests.swift; sourceTree = ""; }; - 2ED077DA2132B0320058EEFC /* FileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystem.swift; sourceTree = ""; }; - 2ED103E02135C61100EB3683 /* FileRotateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileRotateTests.swift; sourceTree = ""; }; - 2ED103E22135D3FB00EB3683 /* FileWriterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileWriterTests.swift; sourceTree = ""; }; + 2ED077DA2132B0320058EEFC /* OSFileManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSFileManager.swift; sourceTree = ""; }; + 2ED103E02135C61100EB3683 /* LogrotateTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogrotateTests.swift; sourceTree = ""; }; + 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeLimitedFileTests.swift; sourceTree = ""; }; 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DiskLoggerTests.swift; sourceTree = ""; }; + 2ED83780236A19A60008C01F /* OSFileHandle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OSFileHandle.swift; sourceTree = ""; }; 2EDA8AE8213ACCFF00FE5840 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; /* End PBXFileReference section */ @@ -95,8 +97,8 @@ 2ED077D621329CA30058EEFC /* LoggetTests.swift */, 2ED077D82132A4820058EEFC /* AgregateLoggerTests.swift */, 2ED103E42138553B00EB3683 /* DiskLoggerTests.swift */, - 2ED103E22135D3FB00EB3683 /* FileWriterTests.swift */, - 2ED103E02135C61100EB3683 /* FileRotateTests.swift */, + 2ED103E22135D3FB00EB3683 /* SizeLimitedFileTests.swift */, + 2ED103E02135C61100EB3683 /* LogrotateTests.swift */, 2E58D35E21316C3500BEF81A /* Info.plist */, ); path = UnitTests; @@ -146,9 +148,10 @@ isa = PBXGroup; children = ( 2EBF4B542122B598008E4117 /* DiskLogger.swift */, - 2EBF4B552122B598008E4117 /* FileWriter.swift */, - 2EBF4B562122B598008E4117 /* FileRotate.swift */, - 2ED077DA2132B0320058EEFC /* FileSystem.swift */, + 2EBF4B552122B598008E4117 /* SizeLimitedFile.swift */, + 2EBF4B562122B598008E4117 /* Logrotate.swift */, + 2ED077DA2132B0320058EEFC /* OSFileManager.swift */, + 2ED83780236A19A60008C01F /* OSFileHandle.swift */, ); path = DiskLogger; sourceTree = ""; @@ -246,10 +249,10 @@ buildActionMask = 2147483647; files = ( 2E58D35D21316C3500BEF81A /* LogStringConvertibleTests.swift in Sources */, - 2ED103E32135D3FB00EB3683 /* FileWriterTests.swift in Sources */, + 2ED103E32135D3FB00EB3683 /* SizeLimitedFileTests.swift in Sources */, 2ED103E52138553B00EB3683 /* DiskLoggerTests.swift in Sources */, 2ED077D92132A4820058EEFC /* AgregateLoggerTests.swift in Sources */, - 2ED103E12135C61100EB3683 /* FileRotateTests.swift in Sources */, + 2ED103E12135C61100EB3683 /* LogrotateTests.swift in Sources */, 2ED077D721329CA30058EEFC /* LoggetTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -258,14 +261,15 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 2EBF4B582122B598008E4117 /* FileWriter.swift in Sources */, + 2EBF4B582122B598008E4117 /* SizeLimitedFile.swift in Sources */, + 2ED83781236A19A60008C01F /* OSFileHandle.swift in Sources */, 2EBF4B572122B598008E4117 /* DiskLogger.swift in Sources */, 2EBF4B4C2122AF53008E4117 /* NullLogger.swift in Sources */, 2EBF4B3E2122AA34008E4117 /* Logger.swift in Sources */, 2EBF4B4B2122AF53008E4117 /* ConsoleLogger.swift in Sources */, - 2ED077DB2132B0320058EEFC /* FileSystem.swift in Sources */, + 2ED077DB2132B0320058EEFC /* OSFileManager.swift in Sources */, 2EBF4B4A2122AF53008E4117 /* AgregateLogger.swift in Sources */, - 2EBF4B592122B598008E4117 /* FileRotate.swift in Sources */, + 2EBF4B592122B598008E4117 /* Logrotate.swift in Sources */, 2EBF4B452122ACD6008E4117 /* LogStringConvertible.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Logger/Loggers/DiskLogger/DiskLogger.swift b/Logger/Loggers/DiskLogger/DiskLogger.swift index 340fa48..9e14117 100644 --- a/Logger/Loggers/DiskLogger/DiskLogger.swift +++ b/Logger/Loggers/DiskLogger/DiskLogger.swift @@ -24,23 +24,6 @@ import Foundation -/// Write failed as allowed size limit would be exceeded. -public struct SizeLimitedFileQuotaReached: Error {} - -/// Allows writing to a file while respecting allowed size limit. -protocol SizeLimitedFile { - - /// Synchronously writes `data` at the end of the file. - /// - /// - Parameter data: The data to be written. - /// - Throws: Throws an error if no free space is left on the file system, or if any other writing error occurs. - /// Throws `SizeLimitedFileQuotaReached` if allowed size limit would be exceeded. - func write(_ data: Data) throws - - /// Writes all in-memory data to permanent storage and closes the file. - func synchronizeAndCloseFile() -} - protocol SizeLimitedFileFactory { /// Returns newly initialized SizeLimitedFile instance. @@ -52,20 +35,6 @@ protocol SizeLimitedFileFactory { func makeInstance(fileURL: URL, fileSizeLimit: UInt64) throws -> SizeLimitedFile } -/// Allows log files rotation. -protocol Logrotate { - - /// Rotates log files `rotations` number of times. - /// - /// First deletes file at `.`. - /// Next moves files located at: - /// - /// `, .1, .2 ... .` - /// - /// to `.1, .2 ... .` - func rotate() throws -} - protocol LogrotateFactory { /// Returns newly initialized Logrotate instance. @@ -82,7 +51,7 @@ public final class DiskLogger: Logger { private let fileURL: URL private let fileSizeLimit: UInt64 private let rotations: Int - private let fileSystem: FileSystem + private let fileManager: OSFileManager private let sizeLimitedFileFactory: SizeLimitedFileFactory private let logrotateFactory: LogrotateFactory private let formatter: DateFormatter @@ -97,14 +66,14 @@ public final class DiskLogger: Logger { /// - fileSizeLimit: Maximum size log file can reach in bytes. Attempt to exceeding that limit triggers log files rotation. /// - rotations: Number of times log files are rotated before being removed. public convenience init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int) { - self.init(fileURL: fileURL, fileSizeLimit: fileSizeLimit, rotations: rotations, fileSystem: FileManager.default, sizeLimitedFileFactory: FileWriterFactory(), logrotateFactory: FileRotateFactory()) + self.init(fileURL: fileURL, fileSizeLimit: fileSizeLimit, rotations: rotations, fileManager: FileManager.default, sizeLimitedFileFactory: SizeLimitedFileFactoryImpl(), logrotateFactory: LogrotateFactoryImpl()) } - init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int, fileSystem: FileSystem, sizeLimitedFileFactory: SizeLimitedFileFactory, logrotateFactory: LogrotateFactory) { + init(fileURL: URL, fileSizeLimit: UInt64, rotations: Int, fileManager: OSFileManager, sizeLimitedFileFactory: SizeLimitedFileFactory, logrotateFactory: LogrotateFactory) { self.fileURL = fileURL self.fileSizeLimit = fileSizeLimit self.rotations = rotations - self.fileSystem = fileSystem + self.fileManager = fileManager self.sizeLimitedFileFactory = sizeLimitedFileFactory self.logrotateFactory = logrotateFactory formatter = DateFormatter() @@ -144,8 +113,8 @@ public final class DiskLogger: Logger { private func openSizeLimitedFile() throws { guard sizeLimitedFile == nil else { return } - if fileSystem.itemExists(at: fileURL) == false { - _ = fileSystem.createFile(at: fileURL) + if fileManager.itemExists(at: fileURL) == false { + _ = fileManager.createFile(at: fileURL) } sizeLimitedFile = try sizeLimitedFileFactory.makeInstance(fileURL: fileURL, fileSizeLimit: fileSizeLimit) } @@ -166,27 +135,20 @@ public final class DiskLogger: Logger { } } -private class FileRotateFactory: LogrotateFactory { +private class LogrotateFactoryImpl: LogrotateFactory { func makeInstance(fileURL: URL, rotations: Int) -> Logrotate { - return FileRotate(fileURL: fileURL, rotations: rotations, fileSystem: FileManager.default) + return LogrotateImpl(fileURL: fileURL, rotations: rotations, fileManager: FileManager.default) } } -private class FileWriterFactory: SizeLimitedFileFactory { +private class SizeLimitedFileFactoryImpl: SizeLimitedFileFactory { func makeInstance(fileURL: URL, fileSizeLimit: UInt64) throws -> SizeLimitedFile { - return try FileWriter(fileURL: fileURL, fileSizeLimit: fileSizeLimit, fileFactory: FileHandleFactory()) + return try SizeLimitedFileImpl(fileURL: fileURL, fileSizeLimit: fileSizeLimit, fileFactory: FileHandleFactoryImpl()) } } -private class FileHandleFactory: FileFactory { - func makeInstance(forWritingTo: URL) throws -> File { +private class FileHandleFactoryImpl: FileHandleFactory { + func makeInstance(forWritingTo: URL) throws -> OSFileHandle { return try FileHandle(forWritingTo: forWritingTo) } } - -extension FileHandle: File { - - func swift_write(_ data: Data) throws { - try __write(data, error: ()) - } -} diff --git a/Logger/Loggers/DiskLogger/Filerotate.swift b/Logger/Loggers/DiskLogger/Logrotate.swift similarity index 70% rename from Logger/Loggers/DiskLogger/Filerotate.swift rename to Logger/Loggers/DiskLogger/Logrotate.swift index 0963cfa..4d640c7 100644 --- a/Logger/Loggers/DiskLogger/Filerotate.swift +++ b/Logger/Loggers/DiskLogger/Logrotate.swift @@ -24,26 +24,40 @@ import Foundation -final class FileRotate { +/// Allows log files rotation. +protocol Logrotate { + + /// Rotates log files `rotations` number of times. + /// + /// First deletes file at `.`. + /// Next moves files located at: + /// + /// `, .1, .2 ... .` + /// + /// to `.1, .2 ... .` + func rotate() throws +} + +final class LogrotateImpl { private let fileURL: URL private let rotations: Int - private let fileSystem: FileSystem + private let fileManager: OSFileManager /// Initializes new Logrotate instance. /// /// - Parameters: /// - fileURL: URL of the log file. /// - rotations: Number of times log files are rotated before being removed. - init(fileURL: URL, rotations: Int, fileSystem: FileSystem) { + init(fileURL: URL, rotations: Int, fileManager: OSFileManager) { precondition(rotations > 0) self.fileURL = fileURL self.rotations = rotations - self.fileSystem = fileSystem + self.fileManager = fileManager } } -extension FileRotate: Logrotate { +extension LogrotateImpl: Logrotate { func rotate() throws { let range = 1...rotations @@ -54,12 +68,12 @@ extension FileRotate: Logrotate { let toDelete = rotatedURLs.last! let toMove = zip(allURLs, rotatedURLs).reversed() - if fileSystem.itemExists(at: toDelete) { - try fileSystem.removeItem(at: toDelete) + if fileManager.itemExists(at: toDelete) { + try fileManager.removeItem(at: toDelete) } for (oldURL, newURL) in toMove { - guard fileSystem.itemExists(at: oldURL) else { continue } - try fileSystem.moveItem(at: oldURL, to: newURL) + guard fileManager.itemExists(at: oldURL) else { continue } + try fileManager.moveItem(at: oldURL, to: newURL) } } } diff --git a/Logger/Loggers/DiskLogger/OSFileHandle.swift b/Logger/Loggers/DiskLogger/OSFileHandle.swift new file mode 100644 index 0000000..dfe5bb9 --- /dev/null +++ b/Logger/Loggers/DiskLogger/OSFileHandle.swift @@ -0,0 +1,23 @@ +// +// OSFileHandle.swift +// Logger +// +// Created by Wojciech Nagrodzki on 30/10/2019. +// Copyright © 2019 Wojciech Nagrodzki. All rights reserved. +// + +import Foundation + +protocol OSFileHandle { + func seekToEndOfFile() -> UInt64 + func swift_write(_ data: Data) throws + func synchronizeFile() + func closeFile() +} + +extension FileHandle: OSFileHandle { + + func swift_write(_ data: Data) throws { + try __write(data, error: ()) + } +} diff --git a/Logger/Loggers/DiskLogger/FileSystem.swift b/Logger/Loggers/DiskLogger/OSFileManager.swift similarity index 95% rename from Logger/Loggers/DiskLogger/FileSystem.swift rename to Logger/Loggers/DiskLogger/OSFileManager.swift index b47b316..02ae5be 100644 --- a/Logger/Loggers/DiskLogger/FileSystem.swift +++ b/Logger/Loggers/DiskLogger/OSFileManager.swift @@ -24,14 +24,14 @@ import Foundation -public protocol FileSystem { +public protocol OSFileManager { func itemExists(at URL: URL) -> Bool func removeItem(at URL: URL) throws func moveItem(at srcURL: URL, to dstURL: URL) throws func createFile(at URL: URL) -> Bool } -extension FileManager: FileSystem { +extension FileManager: OSFileManager { public func itemExists(at URL: URL) -> Bool { return fileExists(atPath: URL.path) diff --git a/Logger/Loggers/DiskLogger/FileWriter.swift b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift similarity index 66% rename from Logger/Loggers/DiskLogger/FileWriter.swift rename to Logger/Loggers/DiskLogger/SizeLimitedFile.swift index be1ff30..d95e5f4 100644 --- a/Logger/Loggers/DiskLogger/FileWriter.swift +++ b/Logger/Loggers/DiskLogger/SizeLimitedFile.swift @@ -24,38 +24,48 @@ import Foundation -protocol File { - func seekToEndOfFile() -> UInt64 - func swift_write(_ data: Data) throws - func synchronizeFile() - func closeFile() +protocol FileHandleFactory { + func makeInstance(forWritingTo: URL) throws -> OSFileHandle } -protocol FileFactory { - func makeInstance(forWritingTo: URL) throws -> File +/// Write failed as allowed size limit would be exceeded. +public struct SizeLimitedFileQuotaReached: Error {} + +/// Allows writing to a file while respecting allowed size limit. +protocol SizeLimitedFile { + + /// Synchronously writes `data` at the end of the file. + /// + /// - Parameter data: The data to be written. + /// - Throws: Throws an error if no free space is left on the file system, or if any other writing error occurs. + /// Throws `SizeLimitedFileQuotaReached` if allowed size limit would be exceeded. + func write(_ data: Data) throws + + /// Writes all in-memory data to permanent storage and closes the file. + func synchronizeAndCloseFile() } /// Allows writing to a file while respecting allowed size limit. -final class FileWriter { +final class SizeLimitedFileImpl { - private let file: File + private let file: OSFileHandle private let sizeLimit: UInt64 private var currentSize: UInt64 - /// Initializes new FileWriter instance. + /// Initializes new SizeLimitedFileImpl instance. /// /// - Parameters: /// - fileURL: URL of the file. /// - fileSizeLimit: Maximum size the file can reach in bytes. /// - Throws: An error that may occur while the file is being opened for writing. - init(fileURL: URL, fileSizeLimit: UInt64, fileFactory: FileFactory) throws { + init(fileURL: URL, fileSizeLimit: UInt64, fileFactory: FileHandleFactory) throws { file = try fileFactory.makeInstance(forWritingTo: fileURL) self.sizeLimit = fileSizeLimit currentSize = file.seekToEndOfFile() } } -extension FileWriter: SizeLimitedFile { +extension SizeLimitedFileImpl: SizeLimitedFile { func write(_ data: Data) throws { let dataSize = UInt64(data.count) diff --git a/UnitTests/DiskLoggerTests.swift b/UnitTests/DiskLoggerTests.swift index aaededc..4a08210 100644 --- a/UnitTests/DiskLoggerTests.swift +++ b/UnitTests/DiskLoggerTests.swift @@ -33,13 +33,13 @@ class DiskLoggerTests: XCTestCase { let expectation = XCTestExpectation(description: "write(_:) was called on SizeLimitedFile") expectation.expectedFulfillmentCount = 1 - let filesystem = FileSystemStub() + let fimeManager = FileManagerStub() let sizeLimitedFileFactory = SizeLimitedFileMockFactory(writeCall: expectation) let logrotateFactory = LogrotateMockFactory() let logger = DiskLogger(fileURL: logURL, fileSizeLimit: 1024, rotations: 1, - fileSystem: filesystem, + fileManager: fimeManager, sizeLimitedFileFactory: sizeLimitedFileFactory, logrotateFactory: logrotateFactory) @@ -61,13 +61,13 @@ class DiskLoggerTests: XCTestCase { let expectation = XCTestExpectation(description: "write(_:) was called on SizeLimitedFile") expectation.expectedFulfillmentCount = 2 - let filesystem = FileSystemStub() + let fimeManager = FileManagerStub() let sizeLimitedFileFactory = SizeLimitedFileMockFactory(writeCall: expectation) let logrotateFactory = LogrotateMockFactory() let logger = DiskLogger(fileURL: logURL, fileSizeLimit: 91, rotations: 1, - fileSystem: filesystem, + fileManager: fimeManager, sizeLimitedFileFactory: sizeLimitedFileFactory, logrotateFactory: logrotateFactory) @@ -90,13 +90,13 @@ class DiskLoggerTests: XCTestCase { let expectation = XCTestExpectation(description: "write(_:) was called on SizeLimitedFile") expectation.expectedFulfillmentCount = 2 - let filesystem = FileSystemStub() + let fimeManager = FileManagerStub() let sizeLimitedFileFactory = UnwritableFileStubFactory(writeCall: expectation) let logrotateFactory = LogrotateMockFactory() let logger = DiskLogger(fileURL: logURL, fileSizeLimit: 91, rotations: 1, - fileSystem: filesystem, + fileManager: fimeManager, sizeLimitedFileFactory: sizeLimitedFileFactory, logrotateFactory: logrotateFactory) @@ -116,7 +116,7 @@ class DiskLoggerTests: XCTestCase { } } -private class FileSystemStub: FileSystem { +private class FileManagerStub: OSFileManager { func itemExists(at URL: URL) -> Bool { return false } diff --git a/UnitTests/FileRotateTests.swift b/UnitTests/LogrotateTests.swift similarity index 66% rename from UnitTests/FileRotateTests.swift rename to UnitTests/LogrotateTests.swift index 13ca7c0..0aa968b 100644 --- a/UnitTests/FileRotateTests.swift +++ b/UnitTests/LogrotateTests.swift @@ -25,7 +25,7 @@ import XCTest @testable import Logger -class FileRotateTests: XCTestCase { +class LogrotateTests: XCTestCase { let logURL = URL(fileURLWithPath: "/var/log/application.log") let log1URL = URL(fileURLWithPath: "/var/log/application.log.1") @@ -33,98 +33,98 @@ class FileRotateTests: XCTestCase { let log3URL = URL(fileURLWithPath: "/var/log/application.log.3") func test_1rotation_0files() { - let fileSystem = FileSystemMock(files: []) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: []) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set() XCTAssertEqual(actual, expected) } func test_1rotation_1file() { - let fileSystem = FileSystemMock(files: [logURL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL]) XCTAssertEqual(actual, expected) } func test_1rotation_2files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL]) XCTAssertEqual(actual, expected) } func test_1rotation_3files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL, log2URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL]) XCTAssertEqual(actual, expected) } func test_2rotations_0files() { - let fileSystem = FileSystemMock(files: []) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: []) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set() XCTAssertEqual(actual, expected) } func test_2rotations_1file() { - let fileSystem = FileSystemMock(files: [logURL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL]) XCTAssertEqual(actual, expected) } func test_2rotations_2files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL]) XCTAssertEqual(actual, expected) } func test_2rotations_3files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL, log2URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL]) XCTAssertEqual(actual, expected) } func test_2rotations_4files() { - let fileSystem = FileSystemMock(files: [logURL, log1URL, log2URL, log3URL]) - let logrotate = FileRotate(fileURL: logURL, rotations: 2, fileSystem: fileSystem) + let fimeManager = FileManagerMock(files: [logURL, log1URL, log2URL, log3URL]) + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 2, fileManager: fimeManager) try? logrotate.rotate() - let actual = fileSystem.files + let actual = fimeManager.files let expected = Set([log1URL, log2URL, log3URL]) XCTAssertEqual(actual, expected) } func testErrorPropagation() { - let fileSystem = BrokenFileSystem() - let logrotate = FileRotate(fileURL: logURL, rotations: 1, fileSystem: fileSystem) + let fimeManager = BrokenFileSystem() + let logrotate = LogrotateImpl(fileURL: logURL, rotations: 1, fileManager: fimeManager) XCTAssertThrowsError(try logrotate.rotate(), "An error when removing or moving an item") { (error) in XCTAssertTrue(error is BrokenFileSystem.IOError) @@ -132,7 +132,7 @@ class FileRotateTests: XCTestCase { } } -private class FileSystemMock: FileSystem { +private class FileManagerMock: OSFileManager { private(set) var files = Set() @@ -159,7 +159,7 @@ private class FileSystemMock: FileSystem { } } -private class BrokenFileSystem: FileSystem { +private class BrokenFileSystem: OSFileManager { struct IOError: Error { } diff --git a/UnitTests/FileWriterTests.swift b/UnitTests/SizeLimitedFileTests.swift similarity index 78% rename from UnitTests/FileWriterTests.swift rename to UnitTests/SizeLimitedFileTests.swift index 222991c..a51f3fc 100644 --- a/UnitTests/FileWriterTests.swift +++ b/UnitTests/SizeLimitedFileTests.swift @@ -25,20 +25,20 @@ import XCTest @testable import Logger -class FileWriterTests: XCTestCase { +class SizeLimitedFileTests: XCTestCase { let logURL = URL(fileURLWithPath: "/var/log/application.log") func testFileOpeningFailure() { let factory = UnopenableFileFactory() - XCTAssertThrowsError(try FileWriter(fileURL: logURL, fileSizeLimit: 0, fileFactory: factory), "file open failure") { (error) in + XCTAssertThrowsError(try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 0, fileFactory: factory), "file open failure") { (error) in XCTAssertTrue(error is UnopenableFileFactory.OpenFileError) } } func testKeepingFileSizeLimit() throws { let factory = FileMockFactory() - let writer = try FileWriter(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) + let writer = try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) let data = Data([0]) try writer.write(data) @@ -47,7 +47,7 @@ class FileWriterTests: XCTestCase { func testExceedingFileSizeLimit() throws { let factory = FileMockFactory() - let writer = try FileWriter(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) + let writer = try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) let data = Data([0, 0]) XCTAssertThrowsError(try writer.write(data), "file size limit exceeded") { (error) in @@ -59,31 +59,31 @@ class FileWriterTests: XCTestCase { func testSynchronizingAndClosingFile() throws { let factory = FileMockFactory() - let writer = try FileWriter(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) + let writer = try SizeLimitedFileImpl(fileURL: logURL, fileSizeLimit: 1, fileFactory: factory) writer.synchronizeAndCloseFile() XCTAssertTrue(factory.mock.synchronizeFileCallCount == 1 && factory.mock.closeFileCallCount == 1) } } -private class UnopenableFileFactory: FileFactory { +private class UnopenableFileFactory: FileHandleFactory { struct OpenFileError: Error {} - func makeInstance(forWritingTo: URL) throws -> File { + func makeInstance(forWritingTo: URL) throws -> OSFileHandle { throw OpenFileError() } } -private class FileMockFactory: FileFactory { +private class FileMockFactory: FileHandleFactory { let mock = FileMock() - func makeInstance(forWritingTo: URL) throws -> File { + func makeInstance(forWritingTo: URL) throws -> OSFileHandle { return mock } } -private class FileMock: File { +private class FileMock: OSFileHandle { private(set) var writtenData = Data() private(set) var synchronizeFileCallCount = 0