49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
"""Tests for atomic file writes."""
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from src.fileutil import atomic_write_text
|
|
|
|
|
|
def test_writes_content(tmp_path: Path) -> None:
|
|
target = tmp_path / "out.json"
|
|
atomic_write_text(target, '{"a": 1}')
|
|
assert target.read_text(encoding="utf-8") == '{"a": 1}'
|
|
|
|
|
|
def test_creates_parent_dirs(tmp_path: Path) -> None:
|
|
target = tmp_path / "nested" / "deep" / "out.txt"
|
|
atomic_write_text(target, "hi")
|
|
assert target.read_text(encoding="utf-8") == "hi"
|
|
|
|
|
|
def test_overwrites_existing(tmp_path: Path) -> None:
|
|
target = tmp_path / "out.txt"
|
|
target.write_text("old", encoding="utf-8")
|
|
atomic_write_text(target, "new")
|
|
assert target.read_text(encoding="utf-8") == "new"
|
|
|
|
|
|
def test_leaves_no_temp_files_on_success(tmp_path: Path) -> None:
|
|
target = tmp_path / "out.txt"
|
|
atomic_write_text(target, "data")
|
|
assert [p.name for p in tmp_path.iterdir()] == ["out.txt"]
|
|
|
|
|
|
def test_original_intact_when_write_fails(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
target = tmp_path / "out.txt"
|
|
target.write_text("original", encoding="utf-8")
|
|
|
|
def boom(*args: object, **kwargs: object) -> None:
|
|
raise OSError("disk full")
|
|
|
|
monkeypatch.setattr("os.replace", boom)
|
|
with pytest.raises(OSError):
|
|
atomic_write_text(target, "new")
|
|
|
|
# Original file is untouched and no temp file is left behind.
|
|
assert target.read_text(encoding="utf-8") == "original"
|
|
assert sorted(p.name for p in tmp_path.iterdir()) == ["out.txt"]
|