FileOtter/FileOtterTests/FileInfoTests.swift

176 lines
No EOL
5.2 KiB
Swift

//
// FileInfoTests.swift
// FileOtterTests
//
// Created by Sami Samhuri on 2025-08-19.
//
@testable import FileOtter
import XCTest
final class FileInfoTests: XCTestCase {
var tempDir: URL!
var testFile: URL!
override func setUpWithError() throws {
tempDir = URL.temporaryDirectory
.appendingPathComponent("FileInfoTests-\(UUID().uuidString)")
try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true)
testFile = tempDir.appendingPathComponent("test.txt")
try "Test content".write(to: testFile, atomically: true, encoding: .utf8)
}
override func tearDownWithError() throws {
if FileManager.default.fileExists(atPath: tempDir.path) {
try FileManager.default.removeItem(at: tempDir)
}
}
// MARK: - Time-based Tests
func testAtime() throws {
let atime = try File.atime(testFile)
XCTAssertNotNil(atime)
// Access time should be recent (within last hour)
XCTAssertLessThan(Date().timeIntervalSince(atime), 3600)
}
func testMtime() throws {
// Get initial mtime
let initialMtime = try File.mtime(testFile)
// Wait a moment and modify the file
Thread.sleep(forTimeInterval: 0.1)
try "Modified content".write(to: testFile, atomically: true, encoding: .utf8)
// mtime should be updated
let newMtime = try File.mtime(testFile)
XCTAssertGreaterThan(newMtime, initialMtime)
}
func testCtime() throws {
let ctime = try File.ctime(testFile)
XCTAssertNotNil(ctime)
// Status change time should be recent
XCTAssertLessThan(Date().timeIntervalSince(ctime), 3600)
}
func testBirthtime() throws {
// Create a new file
let newFile = tempDir.appendingPathComponent("birthtime-test.txt")
let beforeCreation = Date()
Thread.sleep(forTimeInterval: 0.01)
try "content".write(to: newFile, atomically: true, encoding: .utf8)
Thread.sleep(forTimeInterval: 0.01)
let afterCreation = Date()
let birthtime = try File.birthtime(newFile)
XCTAssertGreaterThanOrEqual(birthtime, beforeCreation)
XCTAssertLessThanOrEqual(birthtime, afterCreation)
}
func testBirthtimeThrowsOnUnsupportedPlatform() throws {
// TODO: Implement if platform doesn't support birthtime
}
// MARK: - Size Tests
func testSize() throws {
// Test with known content
let content = "Test content"
let expectedSize = content.data(using: .utf8)!.count
XCTAssertEqual(try File.size(testFile), expectedSize)
// Test with larger file
let largeFile = tempDir.appendingPathComponent("large.txt")
let largeContent = String(repeating: "Hello World! ", count: 100)
try largeContent.write(to: largeFile, atomically: true, encoding: .utf8)
let largeExpectedSize = largeContent.data(using: .utf8)!.count
XCTAssertEqual(try File.size(largeFile), largeExpectedSize)
}
func testSizeThrowsForNonExistent() throws {
let nonExistent = tempDir.appendingPathComponent("no-such-file.txt")
XCTAssertThrowsError(try File.size(nonExistent))
}
func testSizeForEmptyFile() throws {
let emptyFile = tempDir.appendingPathComponent("empty.txt")
try "".write(to: emptyFile, atomically: true, encoding: .utf8)
XCTAssertEqual(try File.size(emptyFile), 0)
}
// MARK: - Stat Tests
func testStat() throws {
// TODO: Implement
// File.stat(url) returns FileStat object
}
func testStatThrowsForNonExistent() throws {
// TODO: Implement
}
func testLstat() throws {
// TODO: Implement
// File.lstat(url) doesn't follow symlinks
}
func testLstatForSymlink() throws {
// TODO: Implement
// Create symlink and verify lstat returns symlink stats, not target
}
// MARK: - Instance Method Tests
func testInstanceAtime() throws {
// TODO: Implement
// file.atime returns access time
}
func testInstanceMtime() throws {
// TODO: Implement
// file.mtime returns modification time
}
func testInstanceCtime() throws {
// TODO: Implement
// file.ctime returns status change time
}
func testInstanceBirthtime() throws {
// TODO: Implement
// file.birthtime returns creation time
}
func testInstanceSize() throws {
// TODO: Implement
// file.size returns file size
}
func testInstanceStat() throws {
// TODO: Implement
// file.stat() returns FileStat object
}
func testInstanceLstat() throws {
// TODO: Implement
// file.lstat() doesn't follow symlinks
}
// MARK: - FileStat Tests
func testFileStatProperties() throws {
// TODO: Implement
// Verify all FileStat properties are populated correctly
}
func testFileStatForDirectory() throws {
// TODO: Implement
}
func testFileStatForSymlink() throws {
// TODO: Implement
}
}