sweet_cli/commands/
test_server.rs

1use beet::prelude::*;
2use clap::Parser;
3use std::process::Child;
4
5/// Spin up a server, run some tests, then shut it down.
6///
7#[derive(Debug, Parser)]
8pub struct TestServer {
9	/// Blocking command to build the server, ie `cargo build`
10	#[arg(long)]
11	build_server: String,
12	/// Non-blocking command to run the server, ie `cargo run --example test_server`
13	#[arg(long)]
14	run_server: String,
15	/// The test command, ie `cargo test --test integration`
16	#[arg(long)]
17	run_test: String,
18	/// How long to wait in between running the server and running the tests
19	#[arg(short, long)]
20	delay_secs: Option<f32>,
21}
22
23
24
25impl TestServer {
26	pub fn run(self) -> Result {
27		self.build_server()?;
28		let mut server = self.run_server()?;
29		let result = self.run_test();
30		server.kill()?;
31		result
32	}
33	pub fn run_server(&self) -> Result<Child> {
34		let child = CommandExt::from_whitespace(&self.run_server).spawn()?;
35		Ok(child)
36	}
37
38	pub fn build_server(&self) -> Result {
39		let cmd = CommandExt::from_whitespace(&self.build_server);
40		CommandExt::unwrap_status(cmd)
41	}
42
43	pub fn run_test(&self) -> Result {
44		if let Some(delay) = self.delay_secs {
45			std::thread::sleep(std::time::Duration::from_secs_f32(delay));
46		}
47		let cmd = CommandExt::from_whitespace(&self.run_test);
48		CommandExt::unwrap_status(cmd)
49	}
50}
51
52
53
54
55#[cfg(test)]
56mod test {
57	use crate::prelude::*;
58	use std::time::Instant;
59	use sweet::prelude::*;
60
61	#[test]
62	fn works() {
63		let delay = 0.5;
64		let start = Instant::now();
65		TestServer {
66			build_server: "true".into(),
67			run_server: "true".into(),
68			run_test: "true".into(),
69			delay_secs: Some(delay),
70		}
71		.run()
72		.unwrap();
73		start.elapsed().as_secs_f32().xpect_greater_than(delay);
74	}
75}