mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-27 11:17:01 -06:00
* CI: line tables only for workspace crates, no debug info for dependencies * CI: one integration-test binary per crate Each crate's tests/*.rs files become modules of tests/it/main.rs. Files that change process-wide state (Color Settings, the font database, installed plug-ins, the working directory), the fuzz sweeps and the test targets the Affinity corpus workflow names stay their own binaries. * Docs: name the integration tests' new paths * CI: xtask test with nextest and doctests, one wasm check, clippy --keep-going cargo xtask ci runs the tests with cargo nextest (cargo test when it is not installed), builds them with --lib --bins --tests, runs the doctests as their own step, and checks the wasm crates in one cargo check --keep-going call.
61 lines
2.4 KiB
Rust
61 lines
2.4 KiB
Rust
//! `vectorcraft --help` prints the usage and exits before the app starts (#2110): run from a
|
|
//! terminal, SSH or an agent's shell it used to open the window (or hang without a display).
|
|
|
|
use std::process::{Command, Output, Stdio};
|
|
use std::time::{Duration, Instant};
|
|
|
|
const BIN: &str = env!("CARGO_BIN_EXE_vectorcraft");
|
|
|
|
/// Runs the desktop binary without a display, so a regression fails instead of opening a window.
|
|
fn run(args: &[&str], env: &[(&str, &str)]) -> Output {
|
|
let mut child = Command::new(BIN)
|
|
.args(args)
|
|
.env_remove("DISPLAY")
|
|
.env_remove("WAYLAND_DISPLAY")
|
|
.env_remove("WAYLAND_SOCKET")
|
|
.env_remove("VECTORCRAFT_CONTROL_PORT")
|
|
.env("VECTORCRAFT_NO_PREFS", "1")
|
|
.envs(env.iter().copied())
|
|
.stdin(Stdio::null())
|
|
.stdout(Stdio::piped())
|
|
.stderr(Stdio::piped())
|
|
.spawn()
|
|
.unwrap();
|
|
let deadline = Instant::now() + Duration::from_secs(5);
|
|
while child.try_wait().unwrap().is_none() {
|
|
if Instant::now() >= deadline {
|
|
child.kill().unwrap();
|
|
panic!("{args:?}: the app started instead of printing its usage");
|
|
}
|
|
std::thread::sleep(Duration::from_millis(10));
|
|
}
|
|
child.wait_with_output().unwrap()
|
|
}
|
|
|
|
fn prints_usage(args: &[&str], env: &[(&str, &str)]) {
|
|
let out = run(args, env);
|
|
let stdout = String::from_utf8(out.stdout).unwrap();
|
|
assert!(out.status.success(), "{args:?}: {}", String::from_utf8_lossy(&out.stderr));
|
|
assert!(out.stderr.is_empty(), "{args:?}: {}", String::from_utf8_lossy(&out.stderr));
|
|
assert!(stdout.starts_with("Usage: vectorcraft "), "{args:?}: {stdout}");
|
|
for flag in ["--control", "--automation-read-root", "--automation-write-root", "--in-window-menus", "--version", "--help"] {
|
|
assert!(stdout.contains(flag), "{args:?}: usage doesn't mention {flag}: {stdout}");
|
|
}
|
|
// Headless work is the CLI's: the usage says where to go.
|
|
assert!(stdout.contains("vectorcraft-cli"), "{args:?}: {stdout}");
|
|
}
|
|
|
|
#[test]
|
|
fn help_prints_usage_and_exits_before_startup() {
|
|
prints_usage(&["--help"], &[]);
|
|
prints_usage(&["-h"], &[]);
|
|
// After a file or a flag, too: nothing is opened.
|
|
prints_usage(&["drawing.svg", "--help"], &[]);
|
|
prints_usage(&["--in-window-menus", "-h"], &[]);
|
|
}
|
|
|
|
#[test]
|
|
fn help_wins_over_a_bad_control_port_variable() {
|
|
prints_usage(&["--help"], &[("VECTORCRAFT_CONTROL_PORT", "abc")]);
|
|
}
|