Files
markitect-main/capabilities/markitect-utils/tests/test_file_utils.py

210 lines
7.1 KiB
Python

"""
Test suite for file utility functions.
"""
import os
import tempfile
from pathlib import Path
import pytest
from markitect_utils.file_utils import (
safe_filename,
ensure_extension,
get_file_size,
is_text_file,
normalize_path,
)
class TestSafeFilename:
"""Test cases for the safe_filename function."""
def test_basic_sanitization(self):
"""Test basic filename sanitization."""
assert safe_filename("normal_file.txt") == "normal_file.txt"
assert safe_filename("file with spaces.txt") == "file with spaces.txt"
def test_unsafe_characters(self):
"""Test removal of unsafe characters."""
assert safe_filename("file<>name.txt") == "file__name.txt"
assert safe_filename('file"name.txt') == "file_name.txt"
assert safe_filename("file/path\\name.txt") == "file_path_name.txt"
assert safe_filename("file|name.txt") == "file_name.txt"
def test_custom_replacement(self):
"""Test custom replacement character."""
assert safe_filename("file<>name.txt", "-") == "file--name.txt"
assert safe_filename("file/path\\name.txt", "") == "filepathname.txt"
def test_reserved_names(self):
"""Test handling of Windows reserved names."""
assert safe_filename("CON") == "file_CON"
assert safe_filename("PRN.txt") == "file_PRN.txt"
assert safe_filename("COM1") == "file_COM1"
assert safe_filename("con") == "file_con" # case insensitive
def test_edge_cases(self):
"""Test edge cases."""
assert safe_filename("") == "" # Empty input returns empty
assert safe_filename(" ") == "file_" # Whitespace only gets prefix
assert safe_filename("...") == "file_" # Dots only gets prefix
assert safe_filename(".hidden") == "hidden" # Leading dot gets stripped
class TestEnsureExtension:
"""Test cases for the ensure_extension function."""
def test_add_extension(self):
"""Test adding extension to filename."""
assert ensure_extension("document", ".md") == "document.md"
assert ensure_extension("file", "txt") == "file.txt"
def test_existing_extension(self):
"""Test when extension already exists."""
assert ensure_extension("document.md", ".md") == "document.md"
assert ensure_extension("file.txt", "txt") == "file.txt"
def test_different_extension(self):
"""Test adding extension when different one exists."""
assert ensure_extension("document.txt", ".md") == "document.txt.md"
assert ensure_extension("file.doc", "pdf") == "file.doc.pdf"
def test_edge_cases(self):
"""Test edge cases."""
assert ensure_extension("", ".md") == ""
assert ensure_extension("file", "") == "file"
assert ensure_extension("file.md", "") == "file.md"
class TestGetFileSize:
"""Test cases for the get_file_size function."""
def test_existing_file(self):
"""Test getting size of existing file."""
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
f.write("Hello, World!")
temp_path = f.name
try:
size = get_file_size(temp_path)
assert size is not None
assert size > 0
finally:
os.unlink(temp_path)
def test_nonexistent_file(self):
"""Test getting size of non-existent file."""
assert get_file_size("/path/that/does/not/exist") is None
def test_empty_file(self):
"""Test getting size of empty file."""
with tempfile.NamedTemporaryFile(delete=False) as f:
temp_path = f.name
try:
size = get_file_size(temp_path)
assert size == 0
finally:
os.unlink(temp_path)
def test_path_object(self):
"""Test with Path object."""
with tempfile.NamedTemporaryFile(mode='w', delete=False) as f:
f.write("test content")
temp_path = Path(f.name)
try:
size = get_file_size(temp_path)
assert size is not None
assert size > 0
finally:
os.unlink(temp_path)
class TestIsTextFile:
"""Test cases for the is_text_file function."""
def test_text_file(self):
"""Test with actual text file."""
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.txt') as f:
f.write("This is a text file with some content.")
temp_path = f.name
try:
assert is_text_file(temp_path) is True
finally:
os.unlink(temp_path)
def test_binary_file(self):
"""Test with binary file."""
with tempfile.NamedTemporaryFile(mode='wb', delete=False, suffix='.bin') as f:
f.write(b'\x00\x01\x02\x03\x04\x05')
temp_path = f.name
try:
assert is_text_file(temp_path) is False
finally:
os.unlink(temp_path)
def test_empty_file(self):
"""Test with empty file."""
with tempfile.NamedTemporaryFile(delete=False) as f:
temp_path = f.name
try:
assert is_text_file(temp_path) is True # Empty files are considered text
finally:
os.unlink(temp_path)
def test_unicode_file(self):
"""Test with Unicode text file."""
with tempfile.NamedTemporaryFile(mode='w', delete=False, encoding='utf-8') as f:
f.write("Hello 世界! This is UTF-8 text.")
temp_path = f.name
try:
assert is_text_file(temp_path) is True
finally:
os.unlink(temp_path)
def test_nonexistent_file(self):
"""Test with non-existent file."""
assert is_text_file("/path/that/does/not/exist") is False
class TestNormalizePath:
"""Test cases for the normalize_path function."""
def test_relative_path(self):
"""Test normalizing relative paths."""
# Note: These tests are environment-dependent
result = normalize_path("./test")
assert os.path.isabs(result)
assert result.endswith("test")
def test_path_with_dots(self):
"""Test path with dot components."""
result = normalize_path("./dir/../file.txt")
assert os.path.isabs(result)
assert result.endswith("file.txt")
def test_already_absolute(self):
"""Test already absolute path."""
abs_path = "/tmp/test/file.txt"
result = normalize_path(abs_path)
assert result == abs_path
def test_path_object(self):
"""Test with Path object."""
path_obj = Path("./test/file.txt")
result = normalize_path(path_obj)
assert os.path.isabs(result)
assert isinstance(result, str)
def test_edge_cases(self):
"""Test edge cases."""
assert normalize_path("") == ""
# Current directory should normalize to absolute path
result = normalize_path(".")
assert os.path.isabs(result)