File testing fixtures for the provide-io ecosystem.
Standard fixtures for file and directory operations that can be used
across any project that depends on provide.foundation.
Functions
binary_file
binary_file() -> Generator[Path, None, None]
Create a temporary binary file for testing.
Yields:
| Type |
Description |
Path
|
Path to a binary file containing sample binary data.
|
Source code in provide/testkit/file/special_fixtures.py
| @pytest.fixture
def binary_file() -> Generator[Path, None, None]:
"""
Create a temporary binary file for testing.
Yields:
Path to a binary file containing sample binary data.
"""
with foundation_temp_file(suffix=".bin", text=False, cleanup=False) as path:
# Write some binary data
path.write_bytes(
b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09" + b"\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6"
)
yield path
safe_delete(path, missing_ok=True)
|
empty_directory
empty_directory() -> Generator[Path, None, None]
Create an empty temporary directory.
Yields:
| Type |
Description |
Path
|
Path to an empty directory.
|
Source code in provide/testkit/file/directory_fixtures.py
| @pytest.fixture
def empty_directory() -> Generator[Path, None, None]:
"""
Create an empty temporary directory.
Yields:
Path to an empty directory.
"""
with foundation_temp_dir() as temp_dir:
yield temp_dir
|
nested_directory_structure
nested_directory_structure() -> Generator[Path, None, None]
Create a deeply nested directory structure for testing.
Creates
Yields:
| Type |
Description |
Path
|
Path to the root of the structure.
|
Source code in provide/testkit/file/directory_fixtures.py
| @pytest.fixture
def nested_directory_structure() -> Generator[Path, None, None]:
"""
Create a deeply nested directory structure for testing.
Creates:
- level1/
- level2/
- level3/
- deep_file.txt
- file_l2.txt
- file_l1.txt
Yields:
Path to the root of the structure.
"""
with foundation_temp_dir() as root:
# Create nested structure
deep_dir = root / "level1" / "level2" / "level3"
deep_dir.mkdir(parents=True)
# Add files at different levels
(root / "file_l1.txt").write_text("Level 1 file")
(root / "level1" / "file_l2.txt").write_text("Level 2 file")
(deep_dir / "deep_file.txt").write_text("Deep file")
yield root
|
readonly_file
readonly_file() -> Generator[Path, None, None]
Create a read-only file for permission testing.
Yields:
| Type |
Description |
Path
|
Path to a read-only file.
|
Source code in provide/testkit/file/special_fixtures.py
| @pytest.fixture
def readonly_file() -> Generator[Path, None, None]:
"""
Create a read-only file for permission testing.
Yields:
Path to a read-only file.
"""
with foundation_temp_file(suffix=".txt", text=True, cleanup=False) as path:
path.write_text("Read-only content")
# Make file read-only
if sys.platform == "win32":
# Windows: Only read-only bit is meaningful
path.chmod(stat.S_IREAD)
else:
# Unix: Full permission control
path.chmod(0o444)
yield path
# Restore write permission for cleanup
if sys.platform == "win32":
path.chmod(stat.S_IWRITE | stat.S_IREAD)
else:
path.chmod(0o644)
safe_delete(path, missing_ok=True)
|
temp_binary_file
temp_binary_file() -> (
Generator[Callable[..., Path], None, None]
)
Create temporary binary files.
Returns:
| Type |
Description |
None
|
Function that creates binary files.
|
Source code in provide/testkit/file/content_fixtures.py
| @pytest.fixture
def temp_binary_file() -> Generator[Callable[..., Path], None, None]:
"""
Create temporary binary files.
Returns:
Function that creates binary files.
"""
created_files: list[Path] = []
def _make_binary(size: int = 1024, pattern: bytes | None = None, suffix: str = ".bin") -> Path:
"""
Create a temporary binary file.
Args:
size: File size in bytes
pattern: Optional byte pattern to repeat
suffix: File suffix
Returns:
Path to created binary file
"""
if pattern is None:
# Create pseudo-random binary data
content = bytes(random.randint(0, 255) for _ in range(size))
else:
# Repeat pattern to reach size
repetitions = size // len(pattern) + 1
content = (pattern * repetitions)[:size]
with foundation_temp_file(suffix=suffix, text=False, cleanup=False) as path:
path.write_bytes(content)
created_files.append(path)
return path
yield _make_binary
# Cleanup
for path in created_files:
safe_delete(path, missing_ok=True)
|
temp_csv_file
temp_csv_file() -> (
Generator[Callable[..., Path], None, None]
)
Create temporary CSV files for testing.
Returns:
| Type |
Description |
None
|
Function that creates CSV files.
|
Source code in provide/testkit/file/content_fixtures.py
| @pytest.fixture
def temp_csv_file() -> Generator[Callable[..., Path], None, None]:
"""
Create temporary CSV files for testing.
Returns:
Function that creates CSV files.
"""
created_files: list[Path] = []
def _make_csv(
headers: Sequence[str],
rows: Sequence[Sequence[Any]],
suffix: str = ".csv",
) -> Path:
"""
Create a temporary CSV file.
Args:
headers: Column headers
rows: Data rows
suffix: File suffix
Returns:
Path to created CSV file
"""
with (
foundation_temp_file(suffix=suffix, text=True, cleanup=False) as path,
path.open("w", newline="") as f,
):
writer = csv.writer(f)
writer.writerow(headers)
writer.writerows(rows)
created_files.append(path)
return path
yield _make_csv
# Cleanup
for path in created_files:
safe_delete(path, missing_ok=True)
|
temp_directory
temp_directory() -> Generator[Path, None, None]
Create a temporary directory that's cleaned up after test.
Yields:
| Type |
Description |
Path
|
Path to the temporary directory.
|
Source code in provide/testkit/file/directory_fixtures.py
| @pytest.fixture
def temp_directory() -> Generator[Path, None, None]:
"""
Create a temporary directory that's cleaned up after test.
Yields:
Path to the temporary directory.
"""
with foundation_temp_dir() as temp_dir:
yield temp_dir
|
temp_executable_file
temp_executable_file() -> (
Generator[Callable[..., Path], None, None]
)
Create temporary executable files for testing.
Returns:
| Type |
Description |
None
|
Function that creates executable files.
|
Source code in provide/testkit/file/special_fixtures.py
| @pytest.fixture
def temp_executable_file() -> Generator[Callable[..., Path], None, None]:
"""
Create temporary executable files for testing.
Returns:
Function that creates executable files.
"""
created_files: list[Path] = []
def _make_executable(content: str | None = None, suffix: str | None = None) -> Path:
"""
Create a temporary executable file.
Args:
content: Script content (platform-specific default if None)
suffix: File suffix (platform-specific default if None)
Returns:
Path to created executable file
"""
# Platform-specific defaults
if content is None:
content = "@echo off\necho test\n" if sys.platform == "win32" else "#!/bin/sh\necho 'test'\n"
if suffix is None:
suffix = ".bat" if sys.platform == "win32" else ".sh"
with foundation_temp_file(suffix=suffix, text=True, cleanup=False) as path:
path.write_text(content)
# Make executable (Unix only - Windows uses file extension)
if sys.platform != "win32":
current = path.stat().st_mode
path.chmod(current | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
created_files.append(path)
return path
yield _make_executable
# Cleanup
for path in created_files:
safe_delete(path, missing_ok=True)
|
temp_file
temp_file() -> Generator[Callable[..., Path], None, None]
Create a temporary file factory with optional content.
Returns:
| Type |
Description |
None
|
A function that creates temporary files with specified content and suffix.
|
Source code in provide/testkit/file/content_fixtures.py
| @pytest.fixture
def temp_file() -> Generator[Callable[..., Path], None, None]:
"""
Create a temporary file factory with optional content.
Returns:
A function that creates temporary files with specified content and suffix.
"""
created_files: list[Path] = []
def _make_temp_file(content: str = "test content", suffix: str = ".txt") -> Path:
"""
Create a temporary file.
Args:
content: Content to write to the file
suffix: File suffix/extension
Returns:
Path to the created temporary file
"""
with foundation_temp_file(suffix=suffix, text=True, cleanup=False) as path:
path.write_text(content)
created_files.append(path)
return path
yield _make_temp_file
# Cleanup all created files
for path in created_files:
safe_delete(path, missing_ok=True)
|
temp_file_with_content
temp_file_with_content() -> (
Generator[Callable[..., Path], None, None]
)
Create temporary files with specific content.
Returns:
| Type |
Description |
None
|
Function that creates files with content.
|
Source code in provide/testkit/file/content_fixtures.py
| @pytest.fixture
def temp_file_with_content() -> Generator[Callable[..., Path], None, None]:
"""
Create temporary files with specific content.
Returns:
Function that creates files with content.
"""
created_files: list[Path] = []
def _make_file(content: str | bytes, suffix: str = ".txt", encoding: str = "utf-8") -> Path:
"""
Create a temporary file with content.
Args:
content: Content to write
suffix: File suffix
encoding: Text encoding (for str content)
Returns:
Path to created file
"""
# Use Foundation's temp_file
with foundation_temp_file(suffix=suffix, text=not isinstance(content, bytes), cleanup=False) as path:
if isinstance(content, bytes):
path.write_bytes(content)
else:
path.write_text(content, encoding=encoding)
created_files.append(path)
return path
yield _make_file
# Cleanup
for path in created_files:
safe_delete(path, missing_ok=True)
|
temp_json_file
temp_json_file() -> (
Generator[Callable[..., Path], None, None]
)
Create temporary JSON files for testing.
Returns:
| Type |
Description |
None
|
Function that creates JSON files.
|
Source code in provide/testkit/file/content_fixtures.py
| @pytest.fixture
def temp_json_file() -> Generator[Callable[..., Path], None, None]:
"""
Create temporary JSON files for testing.
Returns:
Function that creates JSON files.
"""
created_files: list[Path] = []
def _make_json(data: dict[str, Any] | list[Any], suffix: str = ".json", indent: int = 2) -> Path:
"""
Create a temporary JSON file.
Args:
data: JSON data to write
suffix: File suffix
indent: JSON indentation
Returns:
Path to created JSON file
"""
with foundation_temp_file(suffix=suffix, text=True, cleanup=False) as path, path.open("w") as f:
json.dump(data, f, indent=indent)
created_files.append(path)
return path
yield _make_json
# Cleanup
for path in created_files:
safe_delete(path, missing_ok=True)
|
temp_named_file
temp_named_file() -> (
Generator[Callable[..., Path], None, None]
)
Create a named temporary file factory.
Returns:
| Type |
Description |
None
|
Function that creates named temporary files.
|
Source code in provide/testkit/file/content_fixtures.py
| @pytest.fixture
def temp_named_file() -> Generator[Callable[..., Path], None, None]:
"""
Create a named temporary file factory.
Returns:
Function that creates named temporary files.
"""
created_files: list[Path] = []
def _make_named_file(
content: str | bytes | None = None,
suffix: str = "",
prefix: str = "tmp",
dir: Path | str | None = None,
mode: str = "w+b",
delete: bool = False,
) -> Path:
"""
Create a named temporary file.
Args:
content: Optional content to write
suffix: File suffix
prefix: File prefix
dir: Directory for the file
mode: File mode
delete: Whether to delete on close
Returns:
Path to the created file
"""
if isinstance(dir, Path):
dir = str(dir)
# Use Foundation's temp_file with cleanup=False since we manage cleanup
with foundation_temp_file(
suffix=suffix, prefix=prefix, dir=dir, text="b" not in mode, cleanup=False
) as path:
if content is not None:
if isinstance(content, str):
if "b" in mode:
path.write_bytes(content.encode())
else:
path.write_text(content)
else:
path.write_bytes(content)
if not delete:
created_files.append(path)
return path
yield _make_named_file
# Cleanup
for path in created_files:
safe_delete(path, missing_ok=True)
|
temp_symlink
temp_symlink() -> (
Generator[Callable[..., Path], None, None]
)
Create temporary symbolic links for testing.
Returns:
| Type |
Description |
None
|
Function that creates symbolic links.
|
Source code in provide/testkit/file/special_fixtures.py
| @pytest.fixture
def temp_symlink() -> Generator[Callable[..., Path], None, None]:
"""
Create temporary symbolic links for testing.
Returns:
Function that creates symbolic links.
"""
created_links: list[Path] = []
def _make_symlink(target: Path | str, link_name: Path | str | None = None) -> Path:
"""
Create a temporary symbolic link.
Args:
target: Target path for the symlink
link_name: Optional link name (auto-generated if None)
Returns:
Path to created symlink
Raises:
pytest.skip: On Windows if symlinks require admin/developer mode
"""
target = Path(target)
if link_name is None:
with foundation_temp_file(cleanup=True) as temp_path:
link_name = Path(str(temp_path) + "_link")
else:
link_name = Path(link_name)
# On Windows, symlink creation requires special permissions
if sys.platform == "win32":
try:
link_name.symlink_to(target)
except OSError as e:
pytest.skip(f"Symlink creation requires admin rights or Developer Mode on Windows: {e}")
else:
link_name.symlink_to(target)
created_links.append(link_name)
return link_name
yield _make_symlink
# Cleanup
for link in created_links:
safe_delete(link, missing_ok=True)
|
test_files_structure
test_files_structure() -> (
Generator[tuple[Path, Path], None, None]
)
Create standard test file structure with files and subdirectories.
Creates
- source/
- file1.txt (contains "Content 1")
- file2.txt (contains "Content 2")
- subdir/
- file3.txt (contains "Content 3")
Yields:
| Type |
Description |
tuple[Path, Path]
|
Tuple of (temp_path, source_path)
|
Source code in provide/testkit/file/directory_fixtures.py
| @pytest.fixture
def test_files_structure() -> Generator[tuple[Path, Path], None, None]:
"""
Create standard test file structure with files and subdirectories.
Creates:
- source/
- file1.txt (contains "Content 1")
- file2.txt (contains "Content 2")
- subdir/
- file3.txt (contains "Content 3")
Yields:
Tuple of (temp_path, source_path)
"""
with foundation_temp_dir() as path:
source = path / "source"
source.mkdir()
# Create test files
(source / "file1.txt").write_text("Content 1")
(source / "file2.txt").write_text("Content 2")
# Create subdirectory with files
subdir = source / "subdir"
subdir.mkdir()
(subdir / "file3.txt").write_text("Content 3")
yield path, source
|