Skip to content

Commit 36b90d9

Browse files
committed
Fix tests
1 parent 2d4aeb4 commit 36b90d9

File tree

7 files changed

+208
-178
lines changed

7 files changed

+208
-178
lines changed

pysplashsurf/src/lib.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,12 @@ fn pysplashsurf(m: &Bound<'_, PyModule>) -> PyResult<()> {
124124
#[pyfunction]
125125
#[pyo3(name = "run_splashsurf")]
126126
fn run_splashsurf_py<'py>(args: Bound<'py, PyList>) -> PyResult<()> {
127-
let args = args
128-
.iter()
129-
.map(|arg| {
130-
arg.downcast::<PyString>()
131-
.expect("Argument wasn't a string")
132-
.extract()
133-
.unwrap()
134-
})
135-
.map(|s: String| s.into())
136-
.collect::<Vec<std::ffi::OsString>>();
137-
// TODO: Change interface such that OsString is not needed
138-
cli::run_splashsurf(&args)?;
127+
cli::run_splashsurf(args.iter().map(|arg| {
128+
arg.downcast::<PyString>()
129+
.expect("Argument wasn't a string")
130+
.extract::<String>()
131+
.unwrap()
132+
}))?;
139133
Ok(())
140134
}
141135

splashsurf/src/cli.rs

Lines changed: 201 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,61 @@ enum Subcommand {
5050
Convert(convert::ConvertSubcommandArgs),
5151
}
5252

53-
pub fn run_splashsurf(args: &[std::ffi::OsString]) -> Result<(), anyhow::Error> {
53+
/// A simple on/off switch for command line arguments.
54+
///
55+
/// For example an argument defined as:
56+
/// ```rust ignore
57+
/// /// Enable the use of double precision for all computations
58+
/// #[arg(
59+
/// long,
60+
/// default_value = "off",
61+
/// value_name = "off|on",
62+
/// ignore_case = true,
63+
/// require_equals = true
64+
/// )]
65+
/// pub double_precision: Switch,
66+
/// ```
67+
/// can be used in the CLI as `--double-precision=on` or `--double-precision=off`.
68+
#[derive(Copy, Clone, Debug, PartialEq, Eq, clap::ValueEnum)]
69+
pub(crate) enum Switch {
70+
Off,
71+
On,
72+
}
73+
74+
impl Switch {
75+
pub(crate) fn into_bool(self) -> bool {
76+
match self {
77+
Switch::Off => false,
78+
Switch::On => true,
79+
}
80+
}
81+
}
82+
83+
/// Runs the splashsurf CLI with the provided command line arguments.
84+
///
85+
/// This function behaves like the binary `splashsurf` command line tool including output to stdout and stderr.
86+
/// Note that the first argument is always ignored as it is the binary name when called using `std::env::args()`
87+
/// from the command line:
88+
/// ```
89+
/// splashsurf::cli::run_splashsurf([".", "--version"]);
90+
/// ```
91+
/// If no placeholder for the binary name is provided it will return an error (and print a help message):
92+
/// ```should_panic
93+
/// splashsurf::cli::run_splashsurf(["--version"]);
94+
/// ```
95+
pub fn run_splashsurf<I, T>(args: I) -> Result<(), anyhow::Error>
96+
where
97+
I: IntoIterator<Item = T>,
98+
T: Into<std::ffi::OsString> + Clone,
99+
{
54100
run_splashsurf_impl(args).inspect_err(logging::log_error)
55101
}
56102

57-
fn run_splashsurf_impl(args: &[std::ffi::OsString]) -> Result<(), anyhow::Error> {
103+
fn run_splashsurf_impl<I, T>(args: I) -> Result<(), anyhow::Error>
104+
where
105+
I: IntoIterator<Item = T>,
106+
T: Into<std::ffi::OsString> + Clone,
107+
{
58108
let cmd_args = CommandlineArgs::parse_from(args);
59109

60110
let verbosity = VerbosityLevel::from(cmd_args.verbosity);
@@ -125,3 +175,152 @@ impl VerbosityLevel {
125175
}
126176
}
127177
}
178+
179+
#[cfg(test)]
180+
mod cli_args_tests {
181+
use super::*;
182+
183+
#[test]
184+
fn verify_main_cli() {
185+
use clap::CommandFactory;
186+
CommandlineArgs::command().debug_assert()
187+
}
188+
189+
#[test]
190+
fn verify_reconstruct_cli() {
191+
use clap::CommandFactory;
192+
crate::reconstruction::ReconstructSubcommandArgs::command().debug_assert()
193+
}
194+
195+
#[test]
196+
fn verify_convert_cli() {
197+
use clap::CommandFactory;
198+
crate::convert::ConvertSubcommandArgs::command().debug_assert()
199+
}
200+
201+
#[test]
202+
fn test_main_cli() {
203+
use clap::Parser;
204+
205+
// Display help
206+
assert_eq!(
207+
CommandlineArgs::try_parse_from(["splashsurf", "--help",])
208+
.expect_err("this command is supposed to fail")
209+
.kind(),
210+
clap::error::ErrorKind::DisplayHelp
211+
);
212+
213+
// Display help, reconstruct
214+
assert_eq!(
215+
CommandlineArgs::try_parse_from(["splashsurf", "reconstruct", "--help",])
216+
.expect_err("this command is supposed to fail")
217+
.kind(),
218+
clap::error::ErrorKind::DisplayHelp
219+
);
220+
221+
// Display help, convert
222+
assert_eq!(
223+
CommandlineArgs::try_parse_from(["splashsurf", "convert", "--help",])
224+
.expect_err("this command is supposed to fail")
225+
.kind(),
226+
clap::error::ErrorKind::DisplayHelp
227+
);
228+
229+
// Minimum arguments: input file
230+
if let Subcommand::Reconstruct(rec_args) = CommandlineArgs::try_parse_from([
231+
"splashsurf",
232+
"reconstruct",
233+
"test.vtk",
234+
"--particle-radius=0.05",
235+
"--smoothing-length=3.0",
236+
"--cube-size=0.75",
237+
])
238+
.expect("this command is supposed to work")
239+
.subcommand
240+
{
241+
assert_eq!(
242+
rec_args.input_file_or_sequence,
243+
std::path::PathBuf::from("test.vtk")
244+
);
245+
};
246+
247+
// Test on/off switch
248+
if let Subcommand::Reconstruct(rec_args) = CommandlineArgs::try_parse_from([
249+
"splashsurf",
250+
"reconstruct",
251+
"test.vtk",
252+
"--particle-radius=0.05",
253+
"--smoothing-length=3.0",
254+
"--cube-size=0.75",
255+
"--normals=on",
256+
])
257+
.expect("this command is supposed to work")
258+
.subcommand
259+
{
260+
assert_eq!(rec_args.normals, Switch::On);
261+
};
262+
263+
if let Subcommand::Reconstruct(rec_args) = CommandlineArgs::try_parse_from([
264+
"splashsurf",
265+
"reconstruct",
266+
"test.vtk",
267+
"--particle-radius=0.05",
268+
"--smoothing-length=3.0",
269+
"--cube-size=0.75",
270+
"--normals=off",
271+
])
272+
.expect("this command is supposed to work")
273+
.subcommand
274+
{
275+
assert_eq!(rec_args.normals, Switch::Off);
276+
};
277+
278+
// Test domain min/max: correct values
279+
if let Subcommand::Reconstruct(rec_args) = CommandlineArgs::try_parse_from([
280+
"splashsurf",
281+
"reconstruct",
282+
"test.vtk",
283+
"--particle-radius=0.05",
284+
"--smoothing-length=3.0",
285+
"--cube-size=0.75",
286+
"--particle-aabb-min",
287+
"-1.0",
288+
"1.0",
289+
"-1.0",
290+
"--particle-aabb-max",
291+
"-2.0",
292+
"2.0",
293+
"-2.0",
294+
])
295+
.expect("this command is supposed to work")
296+
.subcommand
297+
{
298+
assert_eq!(rec_args.particle_aabb_min, Some(vec![-1.0, 1.0, -1.0]));
299+
assert_eq!(rec_args.particle_aabb_max, Some(vec![-2.0, 2.0, -2.0]));
300+
};
301+
302+
// Test domain min/max: too many values
303+
assert_eq!(
304+
CommandlineArgs::try_parse_from([
305+
"splashsurf",
306+
"reconstruct",
307+
"test.vtk",
308+
"--particle-radius=0.05",
309+
"--smoothing-length=3.0",
310+
"--cube-size=0.75",
311+
"--particle-aabb-min",
312+
"-1.0",
313+
"1.0",
314+
"-1.0",
315+
"2.0",
316+
"--particle-aabb-max",
317+
"-2.0",
318+
"2.0",
319+
"-2.0",
320+
])
321+
.expect_err("this command is supposed to fail")
322+
.kind(),
323+
clap::error::ErrorKind::UnknownArgument
324+
);
325+
}
326+
}

splashsurf/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,5 @@ mod reconstruction;
55
#[macro_use]
66
mod allocator;
77
mod logging;
8-
#[cfg(test)]
9-
mod tests;
108

119
pub(crate) use register_counting_allocator;

splashsurf/src/main.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ mod reconstruction;
55
#[macro_use]
66
mod allocator;
77
mod logging;
8-
#[cfg(test)]
9-
mod tests;
108

119
pub(crate) use register_counting_allocator;
1210

splashsurf/src/reconstruction.rs

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::cli::Switch;
12
use crate::reconstruction::arguments::*;
23
use crate::{io, logging};
34
use anyhow::{Context, anyhow};
@@ -340,21 +341,6 @@ pub struct ReconstructSubcommandArgs {
340341
pub check_mesh_debug: Switch,
341342
}
342343

343-
#[derive(Copy, Clone, Debug, PartialEq, Eq, clap::ValueEnum)]
344-
pub enum Switch {
345-
Off,
346-
On,
347-
}
348-
349-
impl Switch {
350-
fn into_bool(self) -> bool {
351-
match self {
352-
Switch::Off => false,
353-
Switch::On => true,
354-
}
355-
}
356-
}
357-
358344
/// Executes the `reconstruct` subcommand
359345
pub fn reconstruct_subcommand(cmd_args: &ReconstructSubcommandArgs) -> Result<(), anyhow::Error> {
360346
profile!("reconstruct subcommand");

0 commit comments

Comments
 (0)