Add tests, use tarpaulin

master
Edward Shen 2020-11-23 17:52:22 -05:00
parent 72ab5f29d8
commit 543c13a500
Signed by: edward
GPG Key ID: 19182661E818369F
4 changed files with 58 additions and 1 deletions

1
.gitignore vendored
View File

@ -2,3 +2,4 @@
**/*.rs.bk **/*.rs.bk
bunbun.toml bunbun.toml
out out
tarpaulin-report.html

11
code_coverage Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -euxo pipefail
if ! cargo tarpaulin -h &> /dev/null; then
echo "Tarpaulin not installed, automatically installing in 3 seconds.";
sleep 3;
cargo install cargo-tarpaulin;
fi;
cargo tarpaulin -o html && xdg-open "tarpaulin-report.html"

View File

@ -14,6 +14,10 @@ use std::str::FromStr;
const CONFIG_FILENAME: &str = "bunbun.yaml"; const CONFIG_FILENAME: &str = "bunbun.yaml";
const DEFAULT_CONFIG: &[u8] = include_bytes!("../bunbun.default.yaml"); const DEFAULT_CONFIG: &[u8] = include_bytes!("../bunbun.default.yaml");
#[cfg(not(test))]
const LARGE_FILE_SIZE_THRESHOLD: u64 = 100_000_000;
#[cfg(test)]
const LARGE_FILE_SIZE_THRESHOLD: u64 = 1_000_000;
#[derive(Deserialize, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
pub struct Config { pub struct Config {
@ -307,7 +311,7 @@ pub fn read_config(
let file_size = config_file.metadata()?.len(); let file_size = config_file.metadata()?.len();
// 100 MB // 100 MB
if file_size > 100_000_000 && !large_config { if file_size > LARGE_FILE_SIZE_THRESHOLD && !large_config {
return Err(BunBunError::ConfigTooLarge(file_size)); return Err(BunBunError::ConfigTooLarge(file_size));
} }
@ -377,3 +381,38 @@ mod route {
); );
} }
} }
#[cfg(test)]
mod read_config {
use super::*;
#[test]
fn empty_file() {
let config_file = tempfile::tempfile().unwrap();
assert!(matches!(
read_config(config_file, false),
Err(BunBunError::ZeroByteConfig)
));
}
#[test]
fn config_too_large() {
let mut config_file = tempfile::tempfile().unwrap();
let size_to_write = (LARGE_FILE_SIZE_THRESHOLD + 1) as usize;
config_file.write(&[0].repeat(size_to_write)).unwrap();
match read_config(config_file, false) {
Err(BunBunError::ConfigTooLarge(size))
if size as usize == size_to_write => {}
Err(BunBunError::ConfigTooLarge(size)) => {
panic!("Mismatched size: {} != {}", size, size_to_write)
}
res => panic!("Wrong result, got {:#?}", res),
}
}
#[test]
fn valid_config() {
let config_file = File::open("bunbun.default.yaml").unwrap();
assert!(read_config(config_file, false).is_ok());
}
}

View File

@ -23,8 +23,10 @@ use std::time::Duration;
mod cli; mod cli;
mod config; mod config;
#[cfg(not(tarpaulin_include))]
mod error; mod error;
mod routes; mod routes;
#[cfg(not(tarpaulin_include))]
mod template_args; mod template_args;
/// Dynamic variables that either need to be present at runtime, or can be /// Dynamic variables that either need to be present at runtime, or can be
@ -38,6 +40,7 @@ pub struct State {
} }
#[actix_rt::main] #[actix_rt::main]
#[cfg(not(tarpaulin_include))]
async fn main() { async fn main() {
std::process::exit(match run().await { std::process::exit(match run().await {
Ok(_) => 0, Ok(_) => 0,
@ -48,6 +51,7 @@ async fn main() {
}) })
} }
#[cfg(not(tarpaulin_include))]
async fn run() -> Result<(), BunBunError> { async fn run() -> Result<(), BunBunError> {
let opts = cli::Opts::parse(); let opts = cli::Opts::parse();
@ -95,6 +99,7 @@ async fn run() -> Result<(), BunBunError> {
/// Initializes the logger based on the number of quiet and verbose flags passed /// Initializes the logger based on the number of quiet and verbose flags passed
/// in. Usually, these values are mutually exclusive, that is, if the number of /// in. Usually, these values are mutually exclusive, that is, if the number of
/// verbose flags is non-zero then the quiet flag is zero, and vice versa. /// verbose flags is non-zero then the quiet flag is zero, and vice versa.
#[cfg(not(tarpaulin_include))]
fn init_logger( fn init_logger(
num_verbose_flags: u8, num_verbose_flags: u8,
num_quiet_flags: u8, num_quiet_flags: u8,
@ -169,6 +174,7 @@ fn compile_templates() -> Result<Handlebars<'static>, TemplateError> {
/// ///
/// This watch object should be kept in scope as dropping it releases all /// This watch object should be kept in scope as dropping it releases all
/// watches. /// watches.
#[cfg(not(tarpaulin_include))]
fn start_watch( fn start_watch(
state: Arc<RwLock<State>>, state: Arc<RwLock<State>>,
config_data: ConfigData, config_data: ConfigData,