Skip to content

Commit

Permalink
refactor(tests): unified testing infrastructure for perseus-cli
Browse files Browse the repository at this point in the history
This allows having shared utilities.
  • Loading branch information
arctic-hen7 committed Jan 29, 2023
1 parent 264a308 commit 5b18efd
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 41 deletions.
7 changes: 7 additions & 0 deletions packages/perseus-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ include = [
"README.proj.md"
]

autotests = false

# Needed because we have shared utilities
[[test]]
name = "integration"
path = "tests/lib.rs"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down
55 changes: 55 additions & 0 deletions packages/perseus-cli/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
mod build;
mod clean;
mod export;
mod export_error_page;
mod help;
mod new;
mod serve;
mod snoop_build;
mod snoop_serve;
mod snoop_wasm_build;
mod tools;

mod utils {
use std::process::Command;

/// Tests a running app by executing the given command. This will safely
/// terminate any child processes in the event of an error.
pub fn test_serve(cmd: &mut Command, path: &str) -> Result<(), Box<dyn std::error::Error>> {
use command_group::CommandGroup;

// We use a group process spawn because the child will spawn the server process,
// which can't be cleaned up if SIGKILL is sent
let mut child = cmd.group_spawn()?;

std::thread::sleep(std::time::Duration::from_millis(5000));

// Check if the child process has failed (this is the only way to catch
// things like binding errors); this will not block trying to wait
let exit_status = child.try_wait()?;
if let Some(status) = exit_status {
panic!("server process returned non-zero exit code '{}'", status);
}

// We don't extensively test things here, since that's what Perseus' testing
// system is for, and that tests *all* the core examples extensively in a
// headless browser, which is more realistic than simple HTTP requests
// anyway
let body = ureq::get(path)
.call()
.map_err(|err| {
let _ = child.kill();
err
})?
.into_string()
.map_err(|err| {
let _ = child.kill();
err
})?;
assert!(body.contains("Welcome to Perseus!"));

let _ = child.kill();

Ok(())
}
}
42 changes: 1 addition & 41 deletions packages/perseus-cli/tests/serve.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::utils::test_serve;
use assert_cmd::prelude::*;
use assert_fs::{
prelude::{PathAssert, PathChild},
Expand Down Expand Up @@ -73,44 +74,3 @@ fn serve_produces_artifacts_and_serves() -> Result<(), Box<dyn std::error::Error

Ok(())
}

/// Tests a running app by executing the given command. This will safely
/// terminate any child processes in the event of an error.
#[cfg(test)]
fn test_serve(cmd: &mut Command, path: &str) -> Result<(), Box<dyn std::error::Error>> {
use command_group::CommandGroup;

// We use a group process spawn because the child will spawn the server process,
// which can't be cleaned up if SIGKILL is sent
let mut child = cmd.group_spawn()?;

std::thread::sleep(std::time::Duration::from_millis(5000));

// Check if the child process has failed (this is the only way to catch
// things like binding errors); this will not block trying to wait
let exit_status = child.try_wait()?;
if let Some(status) = exit_status {
panic!("server process returned non-zero exit code '{}'", status);
}

// We don't extensively test things here, since that's what Perseus' testing
// system is for, and that tests *all* the core examples extensively in a
// headless browser, which is more realistic than simple HTTP requests
// anyway
let body = ureq::get(path)
.call()
.map_err(|err| {
let _ = child.kill();
err
})?
.into_string()
.map_err(|err| {
let _ = child.kill();
err
})?;
assert!(body.contains("Welcome to Perseus!"));

let _ = child.kill();

Ok(())
}

0 comments on commit 5b18efd

Please sign in to comment.