FileOtter/FileOtterTests/FileTypeTests.swift

261 lines
9.1 KiB
Swift

//
// FileTypeTests.swift
// FileOtterTests
//
// Created by Sami Samhuri on 2025-08-19.
//
@testable import FileOtter
import XCTest
final class FileTypeTests: XCTestCase {
var tempDir: URL!
var testFile: URL!
var testDir: URL!
override func setUpWithError() throws {
tempDir = URL.temporaryDirectory
.appendingPathComponent("FileTypeTests-\(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)
testDir = tempDir.appendingPathComponent("subdir")
try FileManager.default.createDirectory(at: testDir, withIntermediateDirectories: true)
}
override func tearDownWithError() throws {
if FileManager.default.fileExists(atPath: tempDir.path) {
try FileManager.default.removeItem(at: tempDir)
}
}
// MARK: - Existence Tests
func testExists() throws {
// Test with existing file
XCTAssertTrue(File.exists(testFile))
// Test with existing directory
XCTAssertTrue(File.exists(testDir))
XCTAssertTrue(File.exists(tempDir))
}
func testExistsForNonExistent() throws {
let nonExistent = tempDir.appendingPathComponent("does-not-exist.txt")
XCTAssertFalse(File.exists(nonExistent))
let nonExistentDir = tempDir.appendingPathComponent("no-such-dir")
XCTAssertFalse(File.exists(nonExistentDir))
}
func testExistsForDirectory() throws {
// File.exists returns true for directories (like Ruby)
XCTAssertTrue(File.exists(tempDir))
XCTAssertTrue(File.exists(testDir))
// Also test system directories
XCTAssertTrue(File.exists(URL(fileURLWithPath: "/tmp")))
XCTAssertTrue(File.exists(URL(fileURLWithPath: "/")))
}
// MARK: - File Type Tests
func testIsFile() throws {
// Returns true for regular files
XCTAssertTrue(File.isFile(testFile))
// Create another test file
let anotherFile = tempDir.appendingPathComponent("another.txt")
try "content".write(to: anotherFile, atomically: true, encoding: .utf8)
XCTAssertTrue(File.isFile(anotherFile))
}
func testIsFileForDirectory() throws {
// Returns false for directories
XCTAssertFalse(File.isFile(testDir))
XCTAssertFalse(File.isFile(tempDir))
XCTAssertFalse(File.isFile(URL(fileURLWithPath: "/")))
// Returns false for non-existent paths
let nonExistent = tempDir.appendingPathComponent("no-such-file.txt")
XCTAssertFalse(File.isFile(nonExistent))
}
func testIsDirectory() throws {
// Returns true for directories
XCTAssertTrue(File.isDirectory(testDir))
XCTAssertTrue(File.isDirectory(tempDir))
XCTAssertTrue(File.isDirectory(URL(fileURLWithPath: "/")))
XCTAssertTrue(File.isDirectory(URL(fileURLWithPath: "/tmp")))
}
func testIsDirectoryForFile() throws {
// Returns false for files
XCTAssertFalse(File.isDirectory(testFile))
// Returns false for non-existent paths
let nonExistent = tempDir.appendingPathComponent("no-such-dir")
XCTAssertFalse(File.isDirectory(nonExistent))
}
func testIsSymlink() throws {
// Create symlink to test file
let symlinkURL = tempDir.appendingPathComponent("symlink.txt")
try FileManager.default.createSymbolicLink(at: symlinkURL, withDestinationURL: testFile)
XCTAssertTrue(File.isSymlink(symlinkURL))
// Create symlink to directory
let dirSymlinkURL = tempDir.appendingPathComponent("dirlink")
try FileManager.default.createSymbolicLink(at: dirSymlinkURL, withDestinationURL: testDir)
XCTAssertTrue(File.isSymlink(dirSymlinkURL))
}
func testIsSymlinkForRegularFile() throws {
// Regular files are not symlinks
XCTAssertFalse(File.isSymlink(testFile))
// Directories are not symlinks
XCTAssertFalse(File.isSymlink(testDir))
// Non-existent paths are not symlinks
let nonExistent = tempDir.appendingPathComponent("nonexistent")
XCTAssertFalse(File.isSymlink(nonExistent))
}
func testIsBlockDevice() throws {
// Block devices are rare on macOS, but /dev/disk* exists
// This test might fail in sandboxed environments
if FileManager.default.fileExists(atPath: "/dev/disk0") {
XCTAssertTrue(File.isBlockDevice(URL(fileURLWithPath: "/dev/disk0")))
}
// Regular files are not block devices
XCTAssertFalse(File.isBlockDevice(testFile))
XCTAssertFalse(File.isBlockDevice(testDir))
}
func testIsCharDevice() throws {
// /dev/null is always a character device
let devNull = URL(fileURLWithPath: "/dev/null")
XCTAssertTrue(File.isCharDevice(devNull))
// /dev/random is also a character device
let devRandom = URL(fileURLWithPath: "/dev/random")
if FileManager.default.fileExists(atPath: devRandom.path) {
XCTAssertTrue(File.isCharDevice(devRandom))
}
// Regular files are not character devices
XCTAssertFalse(File.isCharDevice(testFile))
XCTAssertFalse(File.isCharDevice(testDir))
}
func testIsPipe() throws {
// Creating FIFOs requires mkfifo system call
// Skip this test for now as it requires additional implementation
// Regular files are not pipes
XCTAssertFalse(File.isPipe(testFile))
XCTAssertFalse(File.isPipe(testDir))
}
func testIsSocket() throws {
// Unix domain sockets are rare and hard to create in tests
// Regular files are not sockets
XCTAssertFalse(File.isSocket(testFile))
XCTAssertFalse(File.isSocket(testDir))
}
// MARK: - Empty/Zero Tests
func testIsEmpty() throws {
// Create empty file
let emptyFile = tempDir.appendingPathComponent("empty.txt")
try "".write(to: emptyFile, atomically: true, encoding: .utf8)
XCTAssertTrue(try File.isEmpty(emptyFile))
}
func testIsEmptyForNonEmpty() throws {
// testFile has content
XCTAssertFalse(try File.isEmpty(testFile))
// Create another non-empty file
let nonEmptyFile = tempDir.appendingPathComponent("nonempty.txt")
try "Some content".write(to: nonEmptyFile, atomically: true, encoding: .utf8)
XCTAssertFalse(try File.isEmpty(nonEmptyFile))
}
func testIsEmptyThrowsForNonExistent() throws {
let nonExistent = tempDir.appendingPathComponent("does-not-exist.txt")
XCTAssertThrowsError(try File.isEmpty(nonExistent))
}
func testIsZero() throws {
// Create empty file
let emptyFile = tempDir.appendingPathComponent("zero.txt")
try "".write(to: emptyFile, atomically: true, encoding: .utf8)
// isZero is alias for isEmpty
XCTAssertTrue(try File.isZero(emptyFile))
XCTAssertFalse(try File.isZero(testFile))
}
// MARK: - ftype Tests
func testFtypeForFile() throws {
XCTAssertEqual(File.ftype(testFile), .file)
// Create another file to test
let anotherFile = tempDir.appendingPathComponent("another.dat")
try Data().write(to: anotherFile)
XCTAssertEqual(File.ftype(anotherFile), .file)
}
func testFtypeForDirectory() throws {
XCTAssertEqual(File.ftype(testDir), .directory)
XCTAssertEqual(File.ftype(tempDir), .directory)
XCTAssertEqual(File.ftype(URL(fileURLWithPath: "/")), .directory)
}
func testFtypeForSymlink() throws {
let symlinkURL = tempDir.appendingPathComponent("link.txt")
try FileManager.default.createSymbolicLink(at: symlinkURL, withDestinationURL: testFile)
XCTAssertEqual(File.ftype(symlinkURL), .link)
// Symlink to directory
let dirSymlinkURL = tempDir.appendingPathComponent("dirlink")
try FileManager.default.createSymbolicLink(at: dirSymlinkURL, withDestinationURL: testDir)
XCTAssertEqual(File.ftype(dirSymlinkURL), .link)
}
func testFtypeForCharDevice() throws {
// /dev/null is a character device
let devNull = URL(fileURLWithPath: "/dev/null")
XCTAssertEqual(File.ftype(devNull), .characterSpecial)
}
func testFtypeForBlockDevice() throws {
// Block devices are rare on macOS
// This test might fail in sandboxed environments
if FileManager.default.fileExists(atPath: "/dev/disk0") {
XCTAssertEqual(File.ftype(URL(fileURLWithPath: "/dev/disk0")), .blockSpecial)
}
}
func testFtypeForFifo() throws {
// FIFOs require special creation
// Skip for now
}
func testFtypeForSocket() throws {
// Sockets require special creation
// Skip for now
}
func testFtypeForUnknown() throws {
// Non-existent files return unknown
let nonExistent = tempDir.appendingPathComponent("nonexistent")
XCTAssertEqual(File.ftype(nonExistent), .unknown)
}
}