From 1bb17cfced959fc8e2b0e1d514bd7b80c7a5426e Mon Sep 17 00:00:00 2001 From: Hunter B Date: Fri, 12 Jun 2026 02:53:47 -0700 Subject: [PATCH] test(release,tools): extend helper coverage Harvests focused coverage from #3110, #3111, #3113, #3123, #3125, and #3126. Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Hmbown <101357273+Hmbown@users.noreply.github.com> --- crates/release/src/lib.rs | 47 +++++++++++++++++++++++++++++++++++++++ crates/tools/src/lib.rs | 45 +++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) diff --git a/crates/release/src/lib.rs b/crates/release/src/lib.rs index f47908b8..110c0014 100644 --- a/crates/release/src/lib.rs +++ b/crates/release/src/lib.rs @@ -525,6 +525,53 @@ mod tests { ); } + #[test] + fn update_version_from_env_prefers_primary_then_legacy() { + { + let _env = ReleaseEnvGuard::clear(); + set_release_env(UPDATE_VERSION_ENV, " v1.2.3 "); + + assert_eq!(update_version_from_env().as_deref(), Some("1.2.3")); + } + + { + let _env = ReleaseEnvGuard::clear(); + set_release_env(LEGACY_UPDATE_VERSION_ENV, "v1.2.4"); + + assert_eq!(update_version_from_env().as_deref(), Some("1.2.4")); + } + } + + #[test] + fn update_version_from_env_ignores_missing_or_empty_values() { + let _env = ReleaseEnvGuard::clear(); + assert_eq!(update_version_from_env(), None); + + set_release_env(UPDATE_VERSION_ENV, " "); + set_release_env(LEGACY_UPDATE_VERSION_ENV, ""); + + assert_eq!(update_version_from_env(), None); + } + + #[test] + fn update_network_fallback_hint_mentions_required_mirror_inputs() { + let hint = update_network_fallback_hint(); + + assert!(hint.contains(CNB_REPO_URL), "hint missing CNB_REPO_URL"); + assert!( + hint.contains(RELEASE_BASE_URL_ENV), + "hint missing RELEASE_BASE_URL_ENV" + ); + assert!( + hint.contains(UPDATE_VERSION_ENV), + "hint missing UPDATE_VERSION_ENV" + ); + assert!( + hint.contains(CHECKSUM_MANIFEST_ASSET), + "hint missing CHECKSUM_MANIFEST_ASSET" + ); + } + #[test] fn resolve_release_query_uses_github_without_overrides() { let _env = ReleaseEnvGuard::clear(); diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index 64406154..91fcb3a9 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs @@ -521,6 +521,16 @@ mod tests { use super::*; + #[test] + fn tool_result_success_sets_plain_content() { + let content = "operation completed successfully"; + let result = ToolResult::success(content); + + assert!(result.success); + assert_eq!(result.content, content); + assert!(result.metadata.is_none()); + } + #[test] fn tool_result_json_round_trips_content() { let result = ToolResult::json(&json!({"ok": true})).expect("json"); @@ -532,6 +542,10 @@ mod tests { fn helper_extractors_validate_shape() { let input = json!({"name": "demo", "count": 7, "enabled": true}); assert_eq!(required_str(&input, "name").expect("name"), "demo"); + assert_eq!(optional_str(&input, "name"), Some("demo")); + assert_eq!(optional_str(&input, "missing"), None); + assert_eq!(optional_str(&input, "count"), None); + assert_eq!(optional_str(&json!({"name": null}), "name"), None); assert_eq!(optional_u64(&input, "count", 0), 7); assert!(optional_bool(&input, "enabled", false)); assert!(matches!( @@ -540,6 +554,26 @@ mod tests { )); } + #[test] + fn required_u64_rejects_missing_or_non_integer_values() { + assert!(matches!( + required_u64(&json!({}), "count"), + Err(ToolError::MissingField { .. }) + )); + assert_eq!(required_u64(&json!({"count": 42}), "count").unwrap(), 42); + assert_eq!( + required_u64(&json!({"count": u64::MAX}), "count").unwrap(), + u64::MAX + ); + + for value in [json!(-1), json!(3.14), json!("42")] { + assert!(matches!( + required_u64(&json!({"count": value}), "count"), + Err(ToolError::MissingField { .. }) + )); + } + } + #[test] fn required_str_reports_provided_fields_on_missing_required_field() { let input = json!({"path": "src/lib.rs", "content": "new body"}); @@ -566,6 +600,17 @@ mod tests { assert!(matches!(err, ToolError::MissingField { field } if field == "my_field")); } + #[test] + fn tool_error_not_available_displays_reason() { + let err = ToolError::not_available("custom tool not found"); + + assert!(matches!(err, ToolError::NotAvailable { .. })); + assert_eq!( + err.to_string(), + "Failed to locate tool: custom tool not found" + ); + } + #[test] fn tool_error_invalid_input_creates_correct_variant() { let err = ToolError::invalid_input("test invalid message");