From 7dcd269a0e16e4aea83c070e4b61d8f8cd0c47cd Mon Sep 17 00:00:00 2001 From: Casper Meijn Date: Wed, 11 Sep 2024 08:01:09 +0200 Subject: [PATCH] tests(prost-build): Validate error texts (#1152) Trigger all errors of `prost-build` and check the produced error text --- prost-build/src/config.rs | 97 +++++++++++++++++++++++++++++++++ prost-build/src/extern_paths.rs | 30 ++++++++++ 2 files changed, 127 insertions(+) diff --git a/prost-build/src/config.rs b/prost-build/src/config.rs index 831e1fca4..48675a316 100644 --- a/prost-build/src/config.rs +++ b/prost-build/src/config.rs @@ -1249,3 +1249,100 @@ pub fn protoc_include_from_env() -> Option { Some(protoc_include) } + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! assert_starts_with { + ($left:expr, $right:expr) => { + match (&$left, &$right) { + (left_val, right_val) => { + if !(left_val.starts_with(right_val)) { + panic!( + "assertion 'starts_with` failed:\nleft: {}\nright: {}", + left_val, right_val + ) + } + } + } + }; + } + + #[test] + fn test_error_protoc_not_found() { + let mut config = Config::new(); + config.protoc_executable("path-does-not-exist"); + + let err = config.load_fds(&[""], &[""]).unwrap_err(); + assert_eq!(err.to_string(), error_message_protoc_not_found()) + } + + #[test] + fn test_error_protoc_not_executable() { + let mut config = Config::new(); + config.protoc_executable("src/lib.rs"); + + let err = config.load_fds(&[""], &[""]).unwrap_err(); + assert_starts_with!(err.to_string(), "failed to invoke protoc (hint: https://docs.rs/prost-build/#sourcing-protoc): (path: \"src/lib.rs\"): ") + } + + #[test] + fn test_error_incorrect_skip_protoc_run() { + let mut config = Config::new(); + config.skip_protoc_run(); + + let err = config.load_fds(&[""], &[""]).unwrap_err(); + assert_eq!( + err.to_string(), + "file_descriptor_set_path is required with skip_protoc_run" + ) + } + + #[test] + fn test_error_protoc_failed() { + let mut config = Config::new(); + + let err = config.load_fds(&[""], &[""]).unwrap_err(); + assert_starts_with!( + err.to_string(), + "protoc failed: You seem to have passed an empty string as one of the arguments to " + ) + } + + #[test] + fn test_error_non_existing_file_descriptor_set() { + let mut config = Config::new(); + config.skip_protoc_run(); + config.file_descriptor_set_path("path-does-not-exist"); + + let err = config.load_fds(&[""], &[""]).unwrap_err(); + assert_starts_with!( + err.to_string(), + "unable to open file_descriptor_set_path: \"path-does-not-exist\", OS: " + ) + } + + #[test] + fn test_error_text_incorrect_file_descriptor_set() { + let mut config = Config::new(); + config.skip_protoc_run(); + config.file_descriptor_set_path("src/lib.rs"); + + let err = config.load_fds(&[""], &[""]).unwrap_err(); + assert_eq!( + err.to_string(), + "invalid FileDescriptorSet: failed to decode Protobuf message: unexpected end group tag" + ) + } + + #[test] + fn test_error_unset_out_dir() { + let mut config = Config::new(); + + let err = config + .compile_fds(FileDescriptorSet::default()) + .unwrap_err(); + assert_eq!(err.to_string(), "OUT_DIR environment variable is not set") + } +} diff --git a/prost-build/src/extern_paths.rs b/prost-build/src/extern_paths.rs index 27c8d6d71..8f6bee784 100644 --- a/prost-build/src/extern_paths.rs +++ b/prost-build/src/extern_paths.rs @@ -167,4 +167,34 @@ mod tests { case(".google.protobuf.Duration", "::prost_types::Duration"); case(".google.protobuf.Empty", "()"); } + + #[test] + fn test_error_fully_qualified() { + let paths = [("foo".to_string(), "bar".to_string())]; + let err = ExternPaths::new(&paths, false).unwrap_err(); + assert_eq!( + err.to_string(), + "Protobuf paths must be fully qualified (begin with a leading '.'): foo" + ) + } + + #[test] + fn test_error_invalid_path() { + let paths = [(".foo.".to_string(), "bar".to_string())]; + let err = ExternPaths::new(&paths, false).unwrap_err(); + assert_eq!( + err.to_string(), + "invalid fully-qualified Protobuf path: .foo." + ) + } + + #[test] + fn test_error_duplicate() { + let paths = [ + (".foo".to_string(), "bar".to_string()), + (".foo".to_string(), "bar".to_string()), + ]; + let err = ExternPaths::new(&paths, false).unwrap_err(); + assert_eq!(err.to_string(), "duplicate extern Protobuf path: .foo") + } }