Skip to content

Commit fa0f13d

Browse files
committed
Add integration tests with compressed test data
- 5 integration tests: DDA Bruker, DIA Bruker, Thermo RAW, missing input, and multi-file conversion - Test data stored as .tar.gz archives in tests/data/ (auto-extracted) - Extracted directories gitignored, archives tracked - tempfile dev-dependency for isolated test output
1 parent 26174d2 commit fa0f13d

7 files changed

Lines changed: 148 additions & 0 deletions

File tree

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,8 @@ target
1616
# Agent-related files
1717
CLAUDE*
1818
.claude/
19+
20+
# Test data: track compressed archives, not extracted directories
21+
tests/data/*/
22+
!tests/data/*.tar.gz
23+
!tests/data/*.raw

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,6 @@ rusqlite = "0.31"
2020
anyhow = "1"
2121
log = "0.4"
2222
env_logger = "0.11"
23+
24+
[dev-dependencies]
25+
tempfile = "3"

tests/data/dia_test.d.tar.gz

76.5 KB
Binary file not shown.

tests/data/test.d.tar.gz

1.48 KB
Binary file not shown.

tests/data/test.raw

136 KB
Binary file not shown.

tests/integration.rs

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
//! Integration tests for mzdata-converter.
2+
//!
3+
//! Test data is stored as `.tar.gz` archives in `tests/data/` and extracted
4+
//! before each test. The archives are tracked in git; extracted directories
5+
//! are gitignored.
6+
7+
use std::path::{Path, PathBuf};
8+
use std::process::Command;
9+
10+
fn mzdata_converter() -> Command {
11+
Command::new(env!("CARGO_BIN_EXE_mzdata-converter"))
12+
}
13+
14+
/// Extract a `.tar.gz` archive if the target directory doesn't exist yet.
15+
/// Returns the path to the extracted directory.
16+
fn ensure_extracted(archive: &str) -> Option<PathBuf> {
17+
let archive_path = Path::new(archive);
18+
if !archive_path.exists() {
19+
eprintln!("Skipping test: {archive} not found");
20+
return None;
21+
}
22+
23+
// Strip .tar.gz to get the directory name
24+
let dir_name = archive
25+
.strip_suffix(".tar.gz")
26+
.expect("archive must end in .tar.gz");
27+
let dir_path = Path::new(dir_name);
28+
29+
if !dir_path.exists() {
30+
let parent = archive_path.parent().unwrap_or(Path::new("."));
31+
let status = Command::new("tar")
32+
.args(["xzf", archive])
33+
.current_dir(parent)
34+
.status()
35+
.expect("Failed to run tar");
36+
assert!(status.success(), "Failed to extract {archive}");
37+
}
38+
39+
Some(dir_path.to_path_buf())
40+
}
41+
42+
fn run_conversion(input: &Path) -> (bool, String, String) {
43+
let output_dir = tempfile::tempdir().unwrap();
44+
let result = mzdata_converter()
45+
.arg(input)
46+
.arg("-o")
47+
.arg(output_dir.path())
48+
.output()
49+
.expect("Failed to run mzdata-converter");
50+
51+
let stdout = String::from_utf8_lossy(&result.stdout).to_string();
52+
let stderr = String::from_utf8_lossy(&result.stderr).to_string();
53+
(result.status.success(), stdout, stderr)
54+
}
55+
56+
#[test]
57+
fn test_dda_bruker_conversion() {
58+
let Some(input) = ensure_extracted("tests/data/test.d.tar.gz") else {
59+
return;
60+
};
61+
62+
let (success, _, stderr) = run_conversion(&input);
63+
assert!(success, "Conversion failed: {stderr}");
64+
}
65+
66+
#[test]
67+
fn test_dia_test_conversion() {
68+
let Some(input) = ensure_extracted("tests/data/dia_test.d.tar.gz") else {
69+
return;
70+
};
71+
72+
let (success, _, stderr) = run_conversion(&input);
73+
assert!(success, "Conversion failed: {stderr}");
74+
}
75+
76+
#[test]
77+
fn test_thermo_raw_conversion() {
78+
let input = Path::new("tests/data/test.raw");
79+
if !input.exists() {
80+
eprintln!("Skipping test: {} not found", input.display());
81+
return;
82+
}
83+
84+
// The test .raw file may be truncated/corrupt — just verify the binary
85+
// runs without crashing (exit code != signal/access violation).
86+
let output_dir = tempfile::tempdir().unwrap();
87+
let result = mzdata_converter()
88+
.arg(input)
89+
.arg("-o")
90+
.arg(output_dir.path())
91+
.output()
92+
.expect("Failed to run mzdata-converter");
93+
94+
let stderr = String::from_utf8_lossy(&result.stderr);
95+
assert!(
96+
result.status.code().is_some(),
97+
"Process crashed (signal): {stderr}"
98+
);
99+
}
100+
101+
#[test]
102+
fn test_missing_input_fails() {
103+
let result = mzdata_converter()
104+
.arg("nonexistent_file.raw")
105+
.output()
106+
.expect("Failed to run mzdata-converter");
107+
108+
assert!(!result.status.success(), "Should fail on missing input");
109+
}
110+
111+
#[test]
112+
fn test_multiple_files() {
113+
let inputs: Vec<PathBuf> = [
114+
ensure_extracted("tests/data/test.d.tar.gz"),
115+
ensure_extracted("tests/data/dia_test.d.tar.gz"),
116+
]
117+
.into_iter()
118+
.flatten()
119+
.collect();
120+
121+
if inputs.is_empty() {
122+
eprintln!("Skipping test: no test files found");
123+
return;
124+
}
125+
126+
let output_dir = tempfile::tempdir().unwrap();
127+
let mut cmd = mzdata_converter();
128+
for input in &inputs {
129+
cmd.arg(input);
130+
}
131+
cmd.arg("-o").arg(output_dir.path());
132+
133+
let result = cmd.output().expect("Failed to run mzdata-converter");
134+
let stderr = String::from_utf8_lossy(&result.stderr);
135+
assert!(
136+
result.status.success(),
137+
"Multi-file conversion failed: {stderr}"
138+
);
139+
}

0 commit comments

Comments
 (0)