diff --git a/.gitignore b/.gitignore index 0d026c4..aa2f8aa 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ **/*.rs.bk bunbun.toml out +tarpaulin-report.html \ No newline at end of file diff --git a/code_coverage b/code_coverage new file mode 100755 index 0000000..0f70815 --- /dev/null +++ b/code_coverage @@ -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" \ No newline at end of file diff --git a/src/config.rs b/src/config.rs index e6d5da1..f28e622 100644 --- a/src/config.rs +++ b/src/config.rs @@ -14,6 +14,10 @@ use std::str::FromStr; const CONFIG_FILENAME: &str = "bunbun.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)] pub struct Config { @@ -307,7 +311,7 @@ pub fn read_config( let file_size = config_file.metadata()?.len(); // 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)); } @@ -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()); + } +} diff --git a/src/main.rs b/src/main.rs index 58be7c0..b8df916 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,8 +23,10 @@ use std::time::Duration; mod cli; mod config; +#[cfg(not(tarpaulin_include))] mod error; mod routes; +#[cfg(not(tarpaulin_include))] mod template_args; /// Dynamic variables that either need to be present at runtime, or can be @@ -38,6 +40,7 @@ pub struct State { } #[actix_rt::main] +#[cfg(not(tarpaulin_include))] async fn main() { std::process::exit(match run().await { Ok(_) => 0, @@ -48,6 +51,7 @@ async fn main() { }) } +#[cfg(not(tarpaulin_include))] async fn run() -> Result<(), BunBunError> { 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 /// 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. +#[cfg(not(tarpaulin_include))] fn init_logger( num_verbose_flags: u8, num_quiet_flags: u8, @@ -169,6 +174,7 @@ fn compile_templates() -> Result, TemplateError> { /// /// This watch object should be kept in scope as dropping it releases all /// watches. +#[cfg(not(tarpaulin_include))] fn start_watch( state: Arc>, config_data: ConfigData,