Files
cadcraft/crates/engine/tests/support/temp_dir.rs
T
1d987904f9 Tests remove the temp files they write (#2232)
* Tests remove the temp files they write

Every test run left about 22 folders and files in the system temp
directory: xref, alias, template, insert, linetype, script and
recent-file fixtures, plus the pathless screenshot folder. The PDFBOOK
test also wrote its second book to `$TMPDIR/b.pdf`, because `a^b.pdf`
splits into `<prefix>-a.pdf` and `b.pdf`, and then removed a file that
was never written.

Tests that write files now use a `TempDir` guard
(`tests/support/temp_dir.rs`, shared by the engine's unit and
integration tests and copied for the UI crate). It gives each test its
own folder and removes it on drop, even when an assertion fails. The
PDFBOOK test also checks that both books land in its folder. The five
tests that write pathless screenshots hold a test-only lock, so the
shared screenshot folder can be removed once empty without racing
another test's write.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012FFPi6hJVyaEKV4PyE2fKq

* Pathless screenshot cleanup survives failed tests and writes

The test lock's guard now empties and removes the per-process
screenshot directory when dropped, so a test that panics no longer
leaves files behind, and the per-test remove calls are gone. A failed
PNG write or flush removes the partial file, since the reply carries
no path for anyone else to clean up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: bmh129 <11478682+bmh129@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 21:21:54 -04:00

47 lines
1.6 KiB
Rust

//! A test's own folder in the system temp directory, removed when the test ends, even when an
//! assertion fails. Shared by the integration tests (`#[path]`) and the crate's unit tests.
#![allow(dead_code)]
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicU64, Ordering};
/// `cadcraft-<tag>-<pid>-<n>`: the process id keeps parallel test binaries apart and the counter
/// keeps the tests of one binary apart, so no two tests ever share (or delete) one folder.
pub struct TempDir(PathBuf);
impl TempDir {
pub fn new(tag: &str) -> Self {
static NEXT: AtomicU64 = AtomicU64::new(0);
let n = NEXT.fetch_add(1, Ordering::Relaxed);
let dir = std::env::temp_dir().join(format!("cadcraft-{tag}-{}-{n}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).expect("create the test's temp folder");
Self(dir)
}
/// Write `contents` to `name` in the folder; returns the file's path as text.
pub fn file(&self, name: &str, contents: impl AsRef<[u8]>) -> String {
let p = self.0.join(name);
std::fs::write(&p, contents).expect("write a test file");
p.to_string_lossy().into_owned()
}
/// The path of `name` in the folder as text, without creating it.
pub fn path_str(&self, name: &str) -> String {
self.0.join(name).to_string_lossy().into_owned()
}
}
impl std::ops::Deref for TempDir {
type Target = Path;
fn deref(&self) -> &Path {
&self.0
}
}
impl Drop for TempDir {
fn drop(&mut self) {
let _ = std::fs::remove_dir_all(&self.0);
}
}