diff --git a/Sources/Logger/Logger.swift b/Sources/Logger/Logger.swift index f78e439..d782b46 100644 --- a/Sources/Logger/Logger.swift +++ b/Sources/Logger/Logger.swift @@ -5,10 +5,12 @@ import Rainbow struct Logger { var level: LogLevel var out: UnsafeMutablePointer + var showTimestamp: Bool - init(level: LogLevel, out: UnsafeMutablePointer = stdout) { + init(level: LogLevel = .error, out: UnsafeMutablePointer = stdout, showTimestamp: Bool = true) { self.level = level self.out = out + self.showTimestamp = showTimestamp } mutating func setLevel(_ level: LogLevel) { @@ -18,10 +20,14 @@ struct Logger { /// Print message to stdout. /// This function is uses low level API to print correct output colors. func print(_ message: String) { - let timestamp = now().dim - fputs("\(timestamp) \(message)\n", stdout) - fflush(out) - } + var line = "" + if showTimestamp { + line += timestamp() + " " + } + line += message + fputs(line + "\n", out) + fflush(out) + } /// Print information message to stdout. func info(_ message: String) { @@ -51,7 +57,7 @@ struct Logger { } } - private func now() -> String { + private func timestamp() -> String { let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" return dateFormatter.string(from: Date()) diff --git a/Tests/Logger.swift b/Tests/Logger.swift new file mode 100644 index 0000000..d082006 --- /dev/null +++ b/Tests/Logger.swift @@ -0,0 +1,66 @@ +import Testing +import Foundation +@testable import runon + +@Suite struct LoggerSuite { + @Test("check basic logger creation") + func testBasicConstructor() { + let logger = Logger(level: .debug) + #expect(logger.level == .debug) + } + + @Test("check logger set level") + func testSetLevel() { + var logger = Logger(level: .debug) + #expect(logger.level == .debug) + logger.setLevel(.info) + #expect(logger.level == .info) + } + + @Test("check logger print") + func testPrint() { + let out = CStream() + let logger = Logger( + out: out.handle, + showTimestamp: false + ) + logger.print("test") + #expect(out.content == "test\n") + } + + @Test("check logger print levels") + func testPrintLevels() { + let out = CStream() + var logger = Logger( + level: .error, + out: out.handle, + showTimestamp: false + ) + logger.warning("should not be printed") + logger.error("should be printed") + #expect(out.meaningfulLines.count == 1) + logger.setLevel(.info) + logger.debug("should not be printed") + logger.info("should be printed") + logger.warning("should be printed") + #expect(out.meaningfulLines.count == 3) + logger.setLevel(.debug) + logger.debug("should be printed") + logger.info("should be printed") + logger.warning("should be printed") + #expect(out.meaningfulLines.count == 6) + } + + @Test("check logger prints timestamp") + func testPrintsTimestamp() { + let out = CStream() + let logger = Logger( + out: out.handle + ) + logger.print("test") + let parts = out.lines[0].components(separatedBy: " ") + #expect(parts[0].components(separatedBy: "-").count == 3) + #expect(parts[1].components(separatedBy: ":") .count == 3) + #expect(parts[2] == "test") + } +} diff --git a/Tests/TestUtils.swift b/Tests/TestUtils.swift index c14d68a..4b75a04 100644 --- a/Tests/TestUtils.swift +++ b/Tests/TestUtils.swift @@ -1,4 +1,5 @@ import Testing +import Darwin.C @testable import runon func expectEqualActions(_ a: Action?, _ b: Action?) { @@ -16,3 +17,43 @@ func expectEqualActions(_ a: Action?, _ b: Action?) { #expect(a.timeout == b.timeout) #expect(a.group == b.group) } + +class CStream { + var size: UnsafeMutablePointer? + var handle: UnsafeMutablePointer! + var buffer: UnsafeMutablePointer? + + var content: String { read() } + var lines: [String] { content.components(separatedBy: "\n") } + var meaningfulLines: [String] { lines.filter { !$0.isEmpty } } + var isEmpty: Bool { content.isEmpty } + + init() { + allocate() + } + + deinit { + deallocate() + } + + func clear() { + deallocate() + allocate() + } + + private func read() -> String { + String(cString: buffer!) + } + + private func allocate() { + buffer = UnsafeMutablePointer.allocate(capacity: 1) + size = UnsafeMutablePointer.allocate(capacity: 1) + handle = open_memstream(&buffer, size) + } + + private func deallocate() { + fclose(handle) + buffer?.deallocate() + size?.deallocate() + } +}