// // FileOperationTests.swift // FileOtterTests // // Created by Sami Samhuri on 2025-08-19. // @testable import FileOtter import XCTest final class FileOperationTests: XCTestCase { var tempDir: URL! var sourceFile: URL! var destFile: URL! override func setUpWithError() throws { tempDir = URL.temporaryDirectory .appendingPathComponent("FileOperationTests-\(UUID().uuidString)") try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true) sourceFile = tempDir.appendingPathComponent("source.txt") try "Source content".write(to: sourceFile, atomically: true, encoding: .utf8) destFile = tempDir.appendingPathComponent("dest.txt") } override func tearDownWithError() throws { if FileManager.default.fileExists(atPath: tempDir.path) { try FileManager.default.removeItem(at: tempDir) } } // MARK: - Link Tests func testLink() throws { // TODO: Implement // File.link(source, destination) creates hard link } func testLinkThrowsIfDestExists() throws { // TODO: Implement // File.link should not overwrite existing file } func testSymlink() throws { // TODO: Implement // File.symlink(source, destination) creates symbolic link } func testSymlinkThrowsIfDestExists() throws { // TODO: Implement } func testReadlink() throws { // TODO: Implement // File.readlink(url) returns target of symlink } func testReadlinkThrowsForNonSymlink() throws { // TODO: Implement } // MARK: - Delete Tests func testUnlink() throws { // TODO: Implement // File.unlink(url) deletes file } func testUnlinkThrowsForNonExistent() throws { // TODO: Implement } func testDelete() throws { // TODO: Implement // File.delete(url) is alias for unlink } // MARK: - Rename Tests func testRename() throws { // TODO: Implement // File.rename(source, destination) moves/renames file } func testRenameOverwritesExisting() throws { // TODO: Implement // rename should overwrite if dest exists } func testRenameThrowsForNonExistent() throws { // TODO: Implement } // MARK: - Truncate Tests func testTruncate() throws { // TODO: Implement // File.truncate(url, size) truncates file to size } func testTruncateExpands() throws { // TODO: Implement // truncate can expand file with zero padding } func testTruncateThrowsForNonExistent() throws { // TODO: Implement } func testInstanceTruncate() throws { // TODO: Implement // file.truncate(size) truncates open file } // MARK: - Touch Tests func testTouch() throws { // TODO: Implement // File.touch(url) updates access/modification times } func testTouchCreatesFile() throws { // TODO: Implement // touch creates file if it doesn't exist } // MARK: - utime Tests func testUtime() throws { // TODO: Implement // File.utime(url, atime, mtime) sets specific times } func testUtimeFollowsSymlinks() throws { // TODO: Implement // utime affects target of symlink } func testLutime() throws { // TODO: Implement // File.lutime(url, atime, mtime) sets symlink times } // MARK: - mkfifo Tests func testMkfifo() throws { // TODO: Implement // File.mkfifo(url) creates named pipe } func testMkfifoWithPermissions() throws { // TODO: Implement // File.mkfifo(url, permissions) creates with specific perms } func testMkfifoThrowsIfExists() throws { // TODO: Implement } // MARK: - identical Tests func testIdentical() throws { // TODO: Implement // File.identical(url1, url2) returns true for same file } func testIdenticalForHardLink() throws { // TODO: Implement // identical returns true for hard links to same file } func testIdenticalForSymlink() throws { // TODO: Implement // identical returns true for symlink and target } func testIdenticalForDifferent() throws { // TODO: Implement // identical returns false for different files } func testIdenticalForSameContent() throws { // TODO: Implement // identical returns false for files with same content but different inodes } }