Remove temporary test files after failures

This commit is contained in:
dotCooCoo
2026-11-05 23:25:05 +07:00
committed by bflatastic
parent edf2b78bc0
commit b8155698b5
14 changed files with 131 additions and 102 deletions
Generated
+2
View File
@@ -6100,6 +6100,7 @@ dependencies = [
"serde_json",
"smithay-clipboard",
"socket2",
"tempfile",
"vectorcraft-engine",
"vectorcraft-render",
"vectorcraft-text",
@@ -6163,6 +6164,7 @@ dependencies = [
"objc2-core-foundation",
"objc2-core-text",
"serde_json",
"tempfile",
"vectorcraft-color",
"vectorcraft-doc",
"vectorcraft-engine",
+1
View File
@@ -45,5 +45,6 @@ objc2-core-foundation = { version = "0.3", default-features = false, features =
objc2-core-text = { version = "0.3", default-features = false, features = ["std", "CTFontManager"] }
[dev-dependencies]
tempfile = "3"
vectorcraft-testkit = { workspace = true }
serde_json = { workspace = true }
+1
View File
@@ -119,6 +119,7 @@ zbus = "=5.19.0"
winresource = "0.1"
[dev-dependencies]
tempfile = "3"
# Bound socket buffers in real loopback transport deadline regressions.
socket2 = { workspace = true }
# src/portal_save.rs's tests build and read the portal's D-Bus values on every system.
+17 -8
View File
@@ -978,10 +978,17 @@ mod tests {
use super::*;
fn dir(name: &str) -> PathBuf {
let d = std::env::temp_dir().join(format!("vectorcraft-clipboard-{name}-{}", std::process::id()));
std::fs::create_dir_all(&d).unwrap();
d
fn dir(name: &str) -> tempfile::TempDir {
tempfile::Builder::new().prefix(&format!("vectorcraft-clipboard-{name}-")).tempdir().unwrap()
}
#[test]
fn test_directory_is_removed_when_its_handle_is_dropped() {
let dir = dir("cleanup");
let path = dir.path().to_path_buf();
assert!(path.exists());
drop(dir);
assert!(!path.exists());
}
fn png(w: u32, h: u32) -> Vec<u8> {
@@ -993,12 +1000,12 @@ mod tests {
#[test]
fn the_first_copied_file_that_is_art_pastes() {
let d = dir("art");
let (notes, red, art) = (d.join("notes.txt"), d.join("red image.png"), d.join("art.svg"));
let (notes, red, art) = (d.path().join("notes.txt"), d.path().join("red image.png"), d.path().join("art.svg"));
std::fs::write(&notes, "not art").unwrap();
std::fs::write(&red, png(3, 2)).unwrap();
std::fs::write(&art, "<svg xmlns=\"http://www.w3.org/2000/svg\"/>").unwrap();
// Missing files, folders and text are skipped.
let f = copied_file(vec![d.join("gone.png"), d.clone(), notes.clone(), red.clone(), art.clone()], &PASTE_ORDER).unwrap();
let f = copied_file(vec![d.path().join("gone.png"), d.path().to_path_buf(), notes.clone(), red.clone(), art.clone()], &PASTE_ORDER).unwrap();
assert_eq!((f.mime, f.data), (PNG, png(3, 2)));
assert_eq!(copied_file(vec![art.clone(), red.clone()], &PASTE_ORDER).map(|f| f.mime), Some(SVG));
// Only what Paste asks for.
@@ -1032,7 +1039,8 @@ mod tests {
/// An .eps file copied in a file manager pastes as EPS.
#[test]
fn a_copied_eps_file_pastes() {
let eps = dir("eps").join("equation.eps");
let d = dir("eps");
let eps = d.path().join("equation.eps");
std::fs::write(&eps, "%!PS-Adobe-3.0 EPSF-3.0\n%%BoundingBox: 0 0 10 10\n0 0 10 10 rectfill\n").unwrap();
assert_eq!(copied_file(vec![eps.clone()], &PASTE_ORDER).map(|f| f.mime), Some(EPS));
assert!(copied_file(vec![eps], &[BITMAP, TEXT]).is_none());
@@ -1040,7 +1048,8 @@ mod tests {
#[test]
fn a_crlf_left_by_the_uri_list_is_ignored() {
let red = dir("crlf").join("red.png");
let d = dir("crlf");
let red = d.path().join("red.png");
std::fs::write(&red, png(2, 2)).unwrap();
let with_cr = PathBuf::from(format!("{}\r", red.display()));
assert_eq!(copied_file(vec![with_cr], &PASTE_ORDER).map(|f| f.mime), Some(PNG));
+8 -10
View File
@@ -150,18 +150,16 @@ mod tests {
#[cfg(target_os = "linux")]
#[test]
fn the_gpu_behind_a_device_number_comes_from_sysfs() -> std::io::Result<()> {
let dir = std::env::temp_dir().join(format!("vectorcraft-dev-char-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
let dir = tempfile::Builder::new().prefix("vectorcraft-dev-char-").tempdir()?;
// /sys/dev/char/226:128 links to the render node, whose `device` is the PCI GPU.
std::fs::create_dir_all(dir.join("226:128/device"))?;
std::fs::write(dir.join("226:128/device/vendor"), "0x10de\n")?;
std::fs::write(dir.join("226:128/device/device"), "0x25ac\n")?;
std::fs::create_dir_all(dir.path().join("226:128/device"))?;
std::fs::write(dir.path().join("226:128/device/vendor"), "0x10de\n")?;
std::fs::write(dir.path().join("226:128/device/device"), "0x25ac\n")?;
// A device that isn't a PCI GPU (a virtual one) has no ids.
std::fs::create_dir_all(dir.join("226:0/device"))?;
let render = super::pci_ids(&dir, makedev(226, 128));
let virtual_gpu = super::pci_ids(&dir, makedev(226, 0));
let missing = super::pci_ids(&dir, makedev(226, 1));
std::fs::remove_dir_all(&dir)?;
std::fs::create_dir_all(dir.path().join("226:0/device"))?;
let render = super::pci_ids(dir.path(), makedev(226, 128));
let virtual_gpu = super::pci_ids(dir.path(), makedev(226, 0));
let missing = super::pci_ids(dir.path(), makedev(226, 1));
assert_eq!(render, Some((0x10de, 0x25ac)));
assert_eq!(virtual_gpu, None);
assert_eq!(missing, None);
+24 -14
View File
@@ -242,8 +242,8 @@ fn internal_panels_are_edp_lvds_and_dsi_connectors() {
/// PCI ids. Each GPU is listed once, the one with the panel as primary.
#[test]
fn linux_display_gpus_come_from_the_connected_connectors() -> std::io::Result<()> {
let dir = std::env::temp_dir().join(format!("vectorcraft-drm-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
let temp = tempfile::Builder::new().prefix("vectorcraft-drm-").tempdir()?;
let dir = temp.path();
let card = |name: &str, (vendor, device): (u32, u32)| -> std::io::Result<()> {
std::fs::create_dir_all(dir.join(name).join("device"))?;
std::fs::write(dir.join(name).join("device/vendor"), format!("{vendor:#06x}\n"))?;
@@ -262,11 +262,11 @@ fn linux_display_gpus_come_from_the_connected_connectors() -> std::io::Result<()
connector("card1-DP-2", "connected")?;
connector("card2-Virtual-1", "connected")?;
std::fs::write(dir.join("renderD128"), "")?;
let mut gpus = linux_display_gpus(&dir);
let mut gpus = linux_display_gpus(dir);
gpus.sort_by_key(|g| g.pci);
assert_eq!(gpus, [primary(AMD_IGPU), monitor(NVIDIA_3090)]);
assert!(linux_display_gpus(&dir.join("no such dir")).is_empty());
std::fs::remove_dir_all(&dir)
Ok(())
}
#[test]
@@ -616,11 +616,26 @@ fn a_normal_exit_or_another_failure_does_not_restart() {
/// A log folder of its own for each test, and the guard that keeps other tests from starting a
/// program while it runs: the test releases the start file's lock and takes it again, and a child
/// starting meanwhile would keep it held (`crate::no_spawns`).
fn start_dir(tag: &str) -> (std::path::PathBuf, std::sync::RwLockReadGuard<'static, ()>) {
struct TestDir(tempfile::TempDir);
impl std::ops::Deref for TestDir {
type Target = std::path::Path;
fn deref(&self) -> &Self::Target {
self.0.path()
}
}
impl AsRef<std::path::Path> for TestDir {
fn as_ref(&self) -> &std::path::Path {
self.0.path()
}
}
fn start_dir(tag: &str) -> (TestDir, std::sync::RwLockReadGuard<'static, ()>) {
let spawns = crate::no_spawns();
let d = std::env::temp_dir().join(format!("vectorcraft-gpu-start-{tag}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&d);
(d, spawns)
let dir = tempfile::Builder::new().prefix(&format!("vectorcraft-gpu-start-{tag}-")).tempdir().unwrap();
(TestDir(dir), spawns)
}
/// What a start in `dir` leaves out; it then ends without crashing.
@@ -670,7 +685,6 @@ fn a_start_that_never_showed_a_frame_leaves_its_adapter_out_of_the_next() {
assert_eq!(left_out.adapters, ["Dx12:8086:3184"], "kept");
assert_eq!(left_out.crash, None, "the note is shown once");
third.ended();
let _ = std::fs::remove_dir_all(&dir);
}
/// A start whose first frame reached the screen, or that ended without crashing (a normal exit,
@@ -693,7 +707,6 @@ fn a_start_that_showed_its_first_frame_or_ended_is_cleared() {
assert!(finish(Ok(Ok(())), &first).is_ok());
drop(first);
assert_eq!(next_start(&dir, false), LeftOut::default());
let _ = std::fs::remove_dir_all(&dir);
}
/// The process ended while the adapters were being listed (wgpu's DX12 backend creates a
@@ -721,7 +734,6 @@ fn a_crash_while_listing_lists_opengl_alone() {
second.none_left();
second.ended();
assert_eq!(next_start(&dir, false), LeftOut::default());
let _ = std::fs::remove_dir_all(&dir);
}
/// `WGPU_BACKEND` or `WGPU_ADAPTER_NAME` choose for a start whatever crashed before; when that
@@ -742,7 +754,6 @@ fn wgpu_backend_or_adapter_name_ignores_the_crashes() {
explicit.picked(&c[0].key, &c[0].name, true);
explicit.presented();
assert_eq!(next_start(&dir, false), LeftOut::default(), "a new driver shows the window");
let _ = std::fs::remove_dir_all(&dir);
}
/// A damaged record, a file that can't be opened and one another starting copy of the app holds
@@ -777,10 +788,9 @@ fn a_damaged_or_unreadable_start_file_is_ignored() {
assert_eq!(next_start(&dir, false).adapters, ["Dx12:8086:3184"]);
// A folder in the file's place.
let _ = std::fs::remove_dir_all(&dir);
std::fs::remove_file(dir.join(START_FILE)).unwrap();
std::fs::create_dir_all(dir.join(START_FILE)).unwrap();
assert_eq!(next_start(&dir, false), LeftOut::default());
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
+11 -27
View File
@@ -214,22 +214,9 @@ fn read_file_head(path: &str, max: usize) -> Result<Vec<u8>, String> {
#[test]
fn read_file_head_reads_no_more_than_it_is_asked_for() {
use std::io::Write as _;
/// Removes the file when the test ends, a failed assertion included.
struct Remove(std::path::PathBuf);
impl Drop for Remove {
fn drop(&mut self) {
let _ = std::fs::remove_file(&self.0);
}
}
let path = std::env::temp_dir().join(format!("vectorcraft-read-head-{}", std::process::id()));
// A leftover file or link at the path is removed (never followed), and the new file is created
// exclusively.
let _ = std::fs::remove_file(&path);
let mut f = std::fs::OpenOptions::new().write(true).create_new(true).open(&path).unwrap();
let guard = Remove(path);
let mut f = tempfile::Builder::new().prefix("vectorcraft-read-head-").tempfile().unwrap();
f.write_all(b"0123456789").unwrap();
drop(f);
let p = guard.0.to_string_lossy();
let p = f.path().to_string_lossy();
assert_eq!(read_file_head(&p, 4).unwrap(), b"0123");
assert_eq!(read_file_head(&p, 20).unwrap(), b"0123456789", "a shorter file is read whole");
assert!(read_file_head(&std::env::temp_dir().to_string_lossy(), 4).is_err(), "a folder is not read");
@@ -608,22 +595,20 @@ mod open_with_tests {
use super::{check_app, find_photocraft, photocraft_candidates, registered_path, windows_candidates};
/// A fresh, empty folder under the system's temporary folder.
fn scratch(name: &str) -> std::path::PathBuf {
let d = std::env::temp_dir().join(format!("vc-open-with-{name}-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&d);
std::fs::create_dir_all(&d).unwrap();
d
fn scratch(name: &str) -> tempfile::TempDir {
tempfile::Builder::new().prefix(&format!("vc-open-with-{name}-")).tempdir().unwrap()
}
/// #5236: only an application counts as PhotoCraft, never a document, a folder or a missing
/// path.
#[test]
fn only_applications_are_started() {
let d = scratch("check");
let temp = scratch("check");
let d = temp.path();
let doc = d.join("notes.txt");
std::fs::write(&doc, "hi").unwrap();
assert!(check_app(&doc).is_err(), "a document");
assert!(check_app(&d).is_err(), "a folder");
assert!(check_app(d).is_err(), "a folder");
assert!(check_app(&d.join("Missing.app")).is_err(), "a missing path");
if cfg!(target_os = "macos") {
let app = d.join("Editor.app");
@@ -639,19 +624,19 @@ mod open_with_tests {
std::fs::set_permissions(&tool, std::fs::Permissions::from_mode(0o755)).unwrap();
assert!(check_app(&tool).is_ok(), "an executable file");
}
let _ = std::fs::remove_dir_all(&d);
}
/// PhotoCraft is looked for only where it installs.
#[test]
fn photocraft_is_found_where_it_installs() {
let d = scratch("find");
let temp = scratch("find");
let d = temp.path();
if cfg!(target_os = "macos") {
let candidates = photocraft_candidates(Some(&d), None);
let candidates = photocraft_candidates(Some(d), None);
assert_eq!(candidates.first().map(|p| p.to_string_lossy().into_owned()).as_deref(), Some("/Applications/PhotoCraft.app"));
assert!(candidates.contains(&d.join("Applications/PhotoCraft.app")), "{candidates:?}");
std::fs::create_dir_all(d.join("Applications/PhotoCraft.app")).unwrap();
assert!(find_photocraft(Some(&d), None).unwrap().ends_with("PhotoCraft.app"));
assert!(find_photocraft(Some(d), None).unwrap().ends_with("PhotoCraft.app"));
} else {
let bin = d.join("bin");
std::fs::create_dir_all(&bin).unwrap();
@@ -675,7 +660,6 @@ mod open_with_tests {
assert_eq!(find_photocraft(None, Some(&path_var)), Some(exe));
}
}
let _ = std::fs::remove_dir_all(&d);
}
/// #5327 review: on Windows PhotoCraft is looked for where its installer puts it: the path it
+23 -6
View File
@@ -1,12 +1,29 @@
use super::*;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::time::{Duration, UNIX_EPOCH};
fn temp_dir(tag: &str) -> PathBuf {
static N: AtomicUsize = AtomicUsize::new(0);
let d = std::env::temp_dir().join(format!("vectorcraft-logging-{tag}-{}-{}", std::process::id(), N.fetch_add(1, Ordering::Relaxed)));
let _ = std::fs::remove_dir_all(&d);
d
struct TestPath {
_parent: tempfile::TempDir,
path: PathBuf,
}
impl std::ops::Deref for TestPath {
type Target = Path;
fn deref(&self) -> &Self::Target {
&self.path
}
}
impl AsRef<Path> for TestPath {
fn as_ref(&self) -> &Path {
&self.path
}
}
fn temp_dir(tag: &str) -> TestPath {
let parent = tempfile::Builder::new().prefix(&format!("vectorcraft-logging-{tag}-")).tempdir().unwrap();
let path = parent.path().join("log");
TestPath { _parent: parent, path }
}
fn read(path: &Path) -> String {
+2 -4
View File
@@ -63,11 +63,10 @@ mod tests {
/// fonts, is listed while it is registered.
#[test]
fn fonts_registered_from_other_folders_are_listed() {
let dir = std::env::temp_dir().join(format!("vectorcraft-mac-fonts-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let dir = tempfile::Builder::new().prefix("vectorcraft-mac-fonts-").tempdir().unwrap();
// A space in the name: the URL's escapes are decoded. The bundled serif isn't a font macOS
// installs.
let file = dir.join("Registered Font.ttf");
let file = dir.path().join("Registered Font.ttf");
std::fs::copy(concat!(env!("CARGO_MANIFEST_DIR"), "/../../assets/fonts/SourceSerif4-Regular.ttf"), &file).unwrap();
let want = std::fs::canonicalize(&file).unwrap();
let listed = || super::font_files().iter().any(|f| f.ends_with("/Registered Font.ttf") && std::fs::canonicalize(f).is_ok_and(|p| p == want));
@@ -78,7 +77,6 @@ mod tests {
let registered = listed();
// SAFETY: as above.
unsafe { CTFontManagerUnregisterFontsForURL(&url, CTFontManagerScope::Process, std::ptr::null_mut()) };
std::fs::remove_dir_all(&dir).unwrap();
assert!(registered);
}
}
+2 -4
View File
@@ -335,13 +335,11 @@ mod tests {
#[test]
fn a_kept_preferences_copy_is_owner_only() {
use std::os::unix::fs::PermissionsExt as _;
let dir = std::env::temp_dir().join(format!("vc-prefs-copy-{}", std::process::id()));
let _ = std::fs::remove_dir_all(&dir);
std::fs::create_dir_all(&dir).unwrap();
let temp = tempfile::Builder::new().prefix("vc-prefs-copy-").tempdir().unwrap();
let dir = temp.path();
super::keep_prefs_copy(&dir.join("ui.json"), b"{}", "ui.unreadable");
let mode = std::fs::metadata(dir.join("ui.unreadable.json")).unwrap().permissions().mode() & 0o777;
assert_eq!(mode, 0o600);
let _ = std::fs::remove_dir_all(&dir);
}
#[test]
+18 -7
View File
@@ -192,7 +192,22 @@ fn copy_dir_into(from: &Path, to: &Path, skip: &mut impl FnMut(String)) {
#[cfg(test)]
mod tests {
use super::*;
use std::sync::atomic::{AtomicUsize, Ordering};
struct TestDir(tempfile::TempDir);
impl std::ops::Deref for TestDir {
type Target = Path;
fn deref(&self) -> &Self::Target {
self.0.path()
}
}
impl AsRef<Path> for TestDir {
fn as_ref(&self) -> &Path {
self.0.path()
}
}
fn environment(key: &str) -> Option<OsString> {
match key {
@@ -287,12 +302,8 @@ mod tests {
assert_eq!(install_dir("macos", mounted, &appimage), Some("/tmp/.mount_vc/usr/bin".into()));
}
fn temp(tag: &str) -> PathBuf {
static N: AtomicUsize = AtomicUsize::new(0);
let d = std::env::temp_dir().join(format!("vectorcraft-profile-{tag}-{}-{}", std::process::id(), N.fetch_add(1, Ordering::Relaxed)));
let _ = std::fs::remove_dir_all(&d);
std::fs::create_dir_all(&d).unwrap();
d
fn temp(tag: &str) -> TestDir {
TestDir(tempfile::Builder::new().prefix(&format!("vectorcraft-profile-{tag}-")).tempdir().unwrap())
}
#[test]
+18 -15
View File
@@ -263,15 +263,23 @@ mod tests {
use super::*;
struct TestDir(tempfile::TempDir);
impl std::ops::Deref for TestDir {
type Target = Path;
fn deref(&self) -> &Self::Target {
self.0.path()
}
}
/// A fresh folder for one test, with an existing file in it.
fn folder(name: &str) -> (PathBuf, PathBuf, String) {
let dir = std::env::temp_dir().join(format!("vc-single-instance-{}-{name}", std::process::id()));
let _ = fs::remove_dir_all(&dir);
fs::create_dir_all(&dir).unwrap();
let file = dir.join("a b.svg");
fn folder(name: &str) -> (PathBuf, TestDir, String) {
let dir = tempfile::Builder::new().prefix(&format!("vc-single-instance-{name}-")).tempdir().unwrap();
let file = dir.path().join("a b.svg");
fs::write(&file, "<svg/>").unwrap();
let file = file.to_string_lossy().into_owned();
(dir.join(FILE_NAME), dir, file)
(dir.path().join(FILE_NAME), TestDir(dir), file)
}
fn primary(path: &Path) -> (Primary, mpsc::Receiver<Vec<String>>) {
@@ -303,12 +311,11 @@ mod tests {
assert_eq!(rx.recv_timeout(CLIENT_TIMEOUT).unwrap(), [file]);
drop(primary);
assert!(!path.exists(), "the endpoint file goes with the app");
let _ = fs::remove_dir_all(dir);
}
#[test]
fn a_wrong_token_garbage_and_oversized_messages_are_refused() {
let (path, dir, file) = folder("refused");
let (path, _dir, file) = folder("refused");
let (_primary, rx) = primary(&path);
let token = read_endpoint(&path).unwrap().token;
let wrong = format!("{}\n", json!({ "token": "0".repeat(token.len()), "files": [file] }));
@@ -323,12 +330,11 @@ mod tests {
// The listener still serves a launch with the right token.
forward(&path, std::slice::from_ref(&file)).unwrap();
assert_eq!(rx.recv_timeout(CLIENT_TIMEOUT).unwrap(), [file]);
let _ = fs::remove_dir_all(dir);
}
#[test]
fn a_stale_endpoint_file_is_ignored_and_replaced() {
let (path, dir, file) = folder("stale");
let (path, _dir, file) = folder("stale");
// The recorded app is gone: whatever holds the port closes without a greeting. (A freed
// port can be taken by another test's listener meanwhile, which would then accept this
// connection in place of its own client's.)
@@ -357,18 +363,16 @@ mod tests {
let (_primary, rx) = primary(&path);
forward(&path, std::slice::from_ref(&file)).unwrap();
assert_eq!(rx.recv_timeout(CLIENT_TIMEOUT).unwrap(), [file]);
let _ = fs::remove_dir_all(dir);
}
#[test]
fn a_replaced_endpoint_file_stays_when_the_earlier_app_ends() {
let (path, dir, _) = folder("replaced");
let (path, _dir, _) = folder("replaced");
let (first, _rx1) = primary(&path);
let (_second, _rx2) = primary(&path);
let second_token = read_endpoint(&path).unwrap().token;
drop(first);
assert_eq!(read_endpoint(&path).map(|e| e.token), Some(second_token));
let _ = fs::remove_dir_all(dir);
}
#[test]
@@ -383,9 +387,8 @@ mod tests {
#[test]
fn the_endpoint_file_is_the_users_alone() {
use std::os::unix::fs::PermissionsExt as _;
let (path, dir, _) = folder("mode");
let (path, _dir, _) = folder("mode");
let _primary = primary(&path);
assert_eq!(fs::metadata(&path).unwrap().permissions().mode() & 0o777, 0o600);
let _ = fs::remove_dir_all(dir);
}
}
+2 -3
View File
@@ -284,8 +284,8 @@ mod tests {
#[test]
fn fonts_only_gdi_has_loaded_are_listed_by_their_files() {
use windows::Win32::Graphics::Gdi::{AddFontResourceExW, FR_PRIVATE, RemoveFontResourceExW};
let dir = std::env::temp_dir().join(format!("vc-gdi-fonts-{}", std::process::id()));
std::fs::create_dir_all(&dir).unwrap();
let temp = tempfile::Builder::new().prefix("vc-gdi-fonts-").tempdir().unwrap();
let dir = temp.path();
let file = dir.join("29457");
let source = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("../../assets/fonts/SourceSans3-Regular.ttf");
let mut data = std::fs::read(source).unwrap();
@@ -303,7 +303,6 @@ mod tests {
assert_eq!(unsafe { AddFontResourceExW(&path, FR_PRIVATE, None) }, 1);
let files = super::font_files();
let _ = unsafe { RemoveFontResourceExW(&path, FR_PRIVATE.0, None) };
let _ = std::fs::remove_dir_all(&dir);
let wanted = file.to_string_lossy().to_lowercase();
assert!(files.iter().any(|f| f.to_lowercase() == wanted), "{wanted} not in {} files", files.len());
}
+2 -4
View File
@@ -99,9 +99,8 @@ fn unreadable_saved_docking_keeps_preferences_and_every_workspace() {
#[test]
fn an_unreadable_ui_json_is_kept_beside_it() {
let stamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_nanos();
let dir = std::env::temp_dir().join(format!("vectorcraft-ui-prefs-{}-{stamp}", std::process::id()));
std::fs::create_dir(&dir).unwrap();
let temp = tempfile::Builder::new().prefix("vectorcraft-ui-prefs-").tempdir().unwrap();
let dir = temp.path();
let path = dir.join("ui.json");
super::keep_prefs_copy(&path, b"{\"docking\": {\"root\": {\"FutureNode\": {}}}}", "ui.unreadable");
super::keep_prefs_copy(&path, b"not json", "ui.unreadable");
@@ -109,7 +108,6 @@ fn an_unreadable_ui_json_is_kept_beside_it() {
let first = std::fs::read(dir.join("ui.unreadable.json")).unwrap();
let second = std::fs::read(dir.join("ui.unreadable-2.json")).unwrap();
let before = std::fs::read(dir.join("ui.before-layout-migration.json")).unwrap();
let _ = std::fs::remove_dir_all(&dir);
assert!(first.starts_with(b"{\"docking\""), "the first copy is not replaced");
assert_eq!(second, b"not json");
assert_eq!(before, b"{}");