From e752f7b4aeeb7a163e531a10c9763a7771d48119 Mon Sep 17 00:00:00 2001 From: pakrym-oai Date: Mon, 15 Jun 2026 21:53:47 -0700 Subject: [PATCH] [codex] Use expect in integration tests (#28441) The workspace denies `clippy::expect_used` in production. Although `clippy.toml` allows `expect` in tests, Bazel Clippy compiles integration-test helper code in a way that does not receive that exemption, which encouraged verbose `unwrap_or_else(... panic!(...))` and equivalent `match`/`let else` forms. This allows `clippy::expect_used` once at each integration-test crate root (including aggregated suites and test-support libraries), then replaces manual panic-based Result and Option unwraps with `expect`/`expect_err`. Standalone `tests/*.rs` files remain their own crate roots. Intentional assertion and unexpected-variant panics remain unchanged, and the production `expect_used = "deny"` lint remains in place. The cleanup is mechanical and net-negative in line count. --- codex-rs/app-server/tests/all.rs | 2 + codex-rs/app-server/tests/common/config.rs | 2 +- codex-rs/app-server/tests/common/lib.rs | 2 + .../tests/common/mock_model_server.rs | 9 +- .../tests/suite/v2/client_metadata.rs | 21 +- .../app-server/tests/suite/v2/compaction.rs | 8 +- codex-rs/app-server/tests/suite/v2/fs.rs | 1 - .../app-server/tests/suite/v2/plan_item.rs | 2 +- .../tests/suite/v2/realtime_conversation.rs | 4 +- .../tests/suite/v2/thread_shell_command.rs | 2 +- .../app-server/tests/suite/v2/turn_start.rs | 2 +- .../tests/suite/v2/turn_start_zsh_fork.rs | 2 +- codex-rs/codex-api/tests/clients.rs | 22 +- .../codex-api/tests/realtime_websocket_e2e.rs | 31 +- codex-rs/codex-api/tests/sse_end_to_end.rs | 3 +- codex-rs/codex-client/tests/ca_env.rs | 54 ++-- codex-rs/core/tests/all.rs | 2 + .../core/tests/common/apps_test_server.rs | 3 +- codex-rs/core/tests/common/hooks.rs | 31 +- codex-rs/core/tests/common/lib.rs | 8 +- codex-rs/core/tests/common/responses.rs | 45 +-- codex-rs/core/tests/common/test_codex.rs | 60 ++-- codex-rs/core/tests/common/test_codex_exec.rs | 1 - .../core/tests/common/test_environment.rs | 2 +- codex-rs/core/tests/suite/agent_jobs.rs | 8 +- codex-rs/core/tests/suite/apply_patch_cli.rs | 2 - codex-rs/core/tests/suite/approvals.rs | 2 +- codex-rs/core/tests/suite/auto_review.rs | 2 - codex-rs/core/tests/suite/cli_stream.rs | 21 +- codex-rs/core/tests/suite/client.rs | 40 +-- .../core/tests/suite/client_websockets.rs | 14 +- codex-rs/core/tests/suite/code_mode.rs | 6 +- codex-rs/core/tests/suite/compact.rs | 44 +-- codex-rs/core/tests/suite/compact_remote.rs | 5 +- .../core/tests/suite/compact_remote_parity.rs | 2 - .../core/tests/suite/compact_resume_fork.rs | 16 +- codex-rs/core/tests/suite/exec.rs | 1 - codex-rs/core/tests/suite/exec_policy.rs | 16 +- codex-rs/core/tests/suite/fork_thread.rs | 18 +- codex-rs/core/tests/suite/hooks.rs | 277 +++++++----------- codex-rs/core/tests/suite/hooks_mcp.rs | 61 ++-- codex-rs/core/tests/suite/live_cli.rs | 2 - .../core/tests/suite/mcp_turn_metadata.rs | 2 +- .../core/tests/suite/model_visible_layout.rs | 2 - codex-rs/core/tests/suite/openai_file_mcp.rs | 20 +- codex-rs/core/tests/suite/pending_input.rs | 52 ++-- codex-rs/core/tests/suite/plugins.rs | 2 +- codex-rs/core/tests/suite/prompt_caching.rs | 2 +- .../core/tests/suite/realtime_conversation.rs | 19 +- codex-rs/core/tests/suite/remote_env.rs | 5 +- codex-rs/core/tests/suite/remote_models.rs | 4 +- .../core/tests/suite/request_permissions.rs | 26 +- .../tests/suite/request_permissions_tool.rs | 6 +- .../tests/suite/request_plugin_install.rs | 5 +- .../core/tests/suite/request_user_input.rs | 39 +-- codex-rs/core/tests/suite/resume_warning.rs | 2 +- codex-rs/core/tests/suite/review.rs | 2 - codex-rs/core/tests/suite/rmcp_client.rs | 58 ++-- .../core/tests/suite/rollout_list_find.rs | 2 +- codex-rs/core/tests/suite/search_tool.rs | 6 +- codex-rs/core/tests/suite/shell_command.rs | 1 - .../core/tests/suite/shell_serialization.rs | 1 - codex-rs/core/tests/suite/shell_snapshot.rs | 5 - codex-rs/core/tests/suite/skills.rs | 2 +- .../tests/suite/spawn_agent_description.rs | 2 +- .../tests/suite/subagent_notifications.rs | 23 +- codex-rs/core/tests/suite/tool_harness.rs | 24 +- codex-rs/core/tests/suite/tool_parallelism.rs | 1 - codex-rs/core/tests/suite/tools.rs | 2 +- codex-rs/core/tests/suite/truncation.rs | 2 +- codex-rs/core/tests/suite/turn_state.rs | 2 +- codex-rs/core/tests/suite/unified_exec.rs | 33 ++- .../tests/suite/unstable_features_warning.rs | 2 +- codex-rs/core/tests/suite/web_search.rs | 1 - codex-rs/core/tests/suite/window_headers.rs | 6 +- .../exec-server/tests/file_system/shared.rs | 10 +- .../exec-server/tests/file_system/support.rs | 5 +- .../exec-server/tests/file_system_unix.rs | 6 +- .../exec-server/tests/file_system_windows.rs | 1 + codex-rs/exec/tests/all.rs | 2 + codex-rs/exec/tests/suite/add_dir.rs | 2 +- codex-rs/exec/tests/suite/agents_md.rs | 2 +- codex-rs/exec/tests/suite/apply_patch.rs | 8 +- codex-rs/exec/tests/suite/approval_policy.rs | 2 +- codex-rs/exec/tests/suite/auth_env.rs | 2 +- codex-rs/exec/tests/suite/ephemeral.rs | 2 +- codex-rs/exec/tests/suite/hooks.rs | 1 - .../exec/tests/suite/mcp_required_exit.rs | 2 +- codex-rs/exec/tests/suite/originator.rs | 2 +- codex-rs/exec/tests/suite/output_schema.rs | 2 +- codex-rs/exec/tests/suite/prompt_stdin.rs | 2 +- codex-rs/exec/tests/suite/resume.rs | 2 +- codex-rs/exec/tests/suite/sandbox.rs | 1 - .../exec/tests/suite/server_error_exit.rs | 2 +- codex-rs/execpolicy/tests/basic.rs | 4 +- codex-rs/ext/extension-api/tests/registry.rs | 8 +- .../ext/goal/tests/goal_extension_backend.rs | 6 +- codex-rs/linux-sandbox/tests/all.rs | 2 + .../linux-sandbox/tests/suite/landlock.rs | 4 - .../tests/suite/managed_proxy.rs | 23 +- codex-rs/login/tests/all.rs | 2 + codex-rs/login/tests/suite/auth_refresh.rs | 10 +- .../login/tests/suite/login_server_e2e.rs | 2 +- codex-rs/mcp-server/tests/all.rs | 2 + codex-rs/mcp-server/tests/common/lib.rs | 2 + .../tests/common/mock_model_server.rs | 13 +- codex-rs/mcp-server/tests/suite/codex_tool.rs | 21 +- codex-rs/otel/tests/harness/mod.rs | 16 +- .../tests/suite/otel_export_routing_policy.rs | 4 +- .../otel/tests/suite/otlp_http_loopback.rs | 63 +--- codex-rs/otel/tests/suite/send.rs | 11 +- codex-rs/otel/tests/suite/timing.rs | 17 +- codex-rs/otel/tests/tests.rs | 2 + .../tests/json_schema_policy_fixtures.rs | 16 +- codex-rs/tui/tests/all.rs | 2 + .../tests/manager_dependency_regression.rs | 13 +- codex-rs/tui/tests/suite/vt100_history.rs | 2 - codex-rs/tui/tests/suite/vt100_live_commit.rs | 6 +- 118 files changed, 608 insertions(+), 916 deletions(-) diff --git a/codex-rs/app-server/tests/all.rs b/codex-rs/app-server/tests/all.rs index 7e136e4cc..fdf98aa94 100644 --- a/codex-rs/app-server/tests/all.rs +++ b/codex-rs/app-server/tests/all.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + // Single integration test binary that aggregates all test modules. // The submodules live in `tests/suite/`. mod suite; diff --git a/codex-rs/app-server/tests/common/config.rs b/codex-rs/app-server/tests/common/config.rs index 1ac2572fa..f3291d95e 100644 --- a/codex-rs/app-server/tests/common/config.rs +++ b/codex-rs/app-server/tests/common/config.rs @@ -24,7 +24,7 @@ pub fn write_mock_responses_config_toml( .iter() .find(|spec| spec.id == feature) .map(|spec| spec.key) - .unwrap_or_else(|| panic!("missing feature key for {feature:?}")); + .expect("feature should have a config key"); format!("{key} = {enabled}") }) .collect::>() diff --git a/codex-rs/app-server/tests/common/lib.rs b/codex-rs/app-server/tests/common/lib.rs index 2285907ad..76c4c85f2 100644 --- a/codex-rs/app-server/tests/common/lib.rs +++ b/codex-rs/app-server/tests/common/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + mod analytics_server; mod auth_fixtures; mod config; diff --git a/codex-rs/app-server/tests/common/mock_model_server.rs b/codex-rs/app-server/tests/common/mock_model_server.rs index 24edcba93..d70736cf5 100644 --- a/codex-rs/app-server/tests/common/mock_model_server.rs +++ b/codex-rs/app-server/tests/common/mock_model_server.rs @@ -57,10 +57,11 @@ struct SeqResponder { impl Respond for SeqResponder { fn respond(&self, _: &wiremock::Request) -> ResponseTemplate { let call_num = self.num_calls.fetch_add(1, Ordering::SeqCst); - match self.responses.get(call_num) { - Some(response) => responses::sse_response(response.clone()), - None => panic!("no response for {call_num}"), - } + let response = self + .responses + .get(call_num) + .expect("mock model response should exist"); + responses::sse_response(response.clone()) } } diff --git a/codex-rs/app-server/tests/suite/v2/client_metadata.rs b/codex-rs/app-server/tests/suite/v2/client_metadata.rs index 681e11ae3..6b95c036d 100644 --- a/codex-rs/app-server/tests/suite/v2/client_metadata.rs +++ b/codex-rs/app-server/tests/suite/v2/client_metadata.rs @@ -107,7 +107,7 @@ async fn turn_start_forwards_client_metadata_to_responses_request_v2() -> Result .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("missing x-codex-turn-metadata header")); + .expect("x-codex-turn-metadata header should be present"); assert_eq!(metadata["fiber_run_id"].as_str(), Some("fiber-start-123")); assert_eq!(metadata["origin"].as_str(), Some("gaas")); assert_eq!(metadata["thread_source"].as_str(), Some("client-supplied")); @@ -188,7 +188,7 @@ async fn turn_start_sends_fork_lineage_in_turn_metadata_for_thread_fork_v2() -> .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("missing x-codex-turn-metadata header")); + .expect("x-codex-turn-metadata header should be present"); assert_eq!( metadata["forked_from_thread_id"].as_str(), Some(source_thread_id.as_str()) @@ -273,7 +273,7 @@ async fn review_start_sends_parent_lineage_in_turn_metadata_for_thread_fork_v2() .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("missing x-codex-turn-metadata header")); + .expect("x-codex-turn-metadata header should be present"); assert_eq!( request.header("x-openai-subagent").as_deref(), Some("review") @@ -285,7 +285,7 @@ async fn review_start_sends_parent_lineage_in_turn_metadata_for_thread_fork_v2() ); let review_request_thread_id = metadata["thread_id"] .as_str() - .unwrap_or_else(|| panic!("missing review request thread_id")); + .expect("review request thread_id should be present"); assert!(review_request_thread_id != review_thread_id.as_str()); assert_eq!( request @@ -384,7 +384,7 @@ async fn turn_start_sends_other_subagent_lineage_after_cold_thread_resume_v2() - .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("missing x-codex-turn-metadata header")); + .expect("x-codex-turn-metadata header should be present"); assert_eq!( metadata["parent_thread_id"].as_str(), Some(parent_thread_id_str.as_str()) @@ -502,7 +502,7 @@ async fn turn_steer_updates_client_metadata_on_follow_up_responses_request_v2() .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("missing first x-codex-turn-metadata header")); + .expect("first x-codex-turn-metadata header should be present"); assert_eq!( first_metadata["fiber_run_id"].as_str(), Some("fiber-start-123") @@ -513,7 +513,7 @@ async fn turn_steer_updates_client_metadata_on_follow_up_responses_request_v2() .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("missing second x-codex-turn-metadata header")); + .expect("second x-codex-turn-metadata header should be present"); assert_eq!( second_metadata["fiber_run_id"].as_str(), Some("fiber-steer-456") @@ -608,7 +608,7 @@ async fn turn_start_forwards_client_metadata_to_responses_websocket_request_body let metadata = request["client_metadata"]["x-codex-turn-metadata"] .as_str() .map(parse_json_header) - .unwrap_or_else(|| panic!("missing websocket x-codex-turn-metadata client metadata")); + .expect("websocket x-codex-turn-metadata client metadata should be present"); assert_eq!(metadata["fiber_run_id"].as_str(), Some("fiber-start-123")); assert_eq!(metadata["origin"].as_str(), Some("gaas")); assert_eq!(metadata["turn_id"].as_str(), Some(turn.id.as_str())); @@ -670,10 +670,7 @@ async fn fork_fake_rollout_thread( } fn parse_json_header(value: &str) -> serde_json::Value { - match serde_json::from_str(value) { - Ok(value) => value, - Err(err) => panic!("metadata header should be valid json: {err}"), - } + serde_json::from_str(value).expect("metadata header should contain valid JSON") } async fn wait_for_request_count( diff --git a/codex-rs/app-server/tests/suite/v2/compaction.rs b/codex-rs/app-server/tests/suite/v2/compaction.rs index e949daa33..865330be5 100644 --- a/codex-rs/app-server/tests/suite/v2/compaction.rs +++ b/codex-rs/app-server/tests/suite/v2/compaction.rs @@ -5,8 +5,6 @@ //! 2) Act: start a thread and submit multiple turns to trigger auto-compaction. //! 3) Assert: verify item/started + item/completed notifications for context compaction. -#![expect(clippy::expect_used)] - use anyhow::Result; use app_test_support::ChatGptAuthFixture; use app_test_support::TestAppServer; @@ -201,7 +199,7 @@ async fn auto_compaction_remote_emits_started_and_completed_items() -> Result<() .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("turn request should include turn metadata")) + .expect("turn request should include turn metadata") }) .collect::>(); for (request, metadata) in response_requests.iter().zip(&turn_metadata) { @@ -223,7 +221,7 @@ async fn auto_compaction_remote_emits_started_and_completed_items() -> Result<() .header("x-codex-turn-metadata") .as_deref() .map(parse_json_header) - .unwrap_or_else(|| panic!("compact request should include turn metadata")); + .expect("compact request should include turn metadata"); assert_eq!( compact_metadata["request_kind"].as_str(), Some("compaction") @@ -470,5 +468,5 @@ async fn wait_for_context_compaction_completed( } fn parse_json_header(value: &str) -> serde_json::Value { - serde_json::from_str(value).unwrap_or_else(|err| panic!("turn metadata should be json: {err}")) + serde_json::from_str(value).expect("turn metadata should be JSON") } diff --git a/codex-rs/app-server/tests/suite/v2/fs.rs b/codex-rs/app-server/tests/suite/v2/fs.rs index 1f04c847d..1f4a4dec3 100644 --- a/codex-rs/app-server/tests/suite/v2/fs.rs +++ b/codex-rs/app-server/tests/suite/v2/fs.rs @@ -56,7 +56,6 @@ async fn expect_error_message( Ok(()) } -#[allow(clippy::expect_used)] fn absolute_path(path: PathBuf) -> AbsolutePathBuf { assert!( path.is_absolute(), diff --git a/codex-rs/app-server/tests/suite/v2/plan_item.rs b/codex-rs/app-server/tests/suite/v2/plan_item.rs index b5464231d..230e514ad 100644 --- a/codex-rs/app-server/tests/suite/v2/plan_item.rs +++ b/codex-rs/app-server/tests/suite/v2/plan_item.rs @@ -259,7 +259,7 @@ fn create_config_toml(codex_home: &Path, server_uri: &str) -> std::io::Result<() .iter() .find(|spec| spec.id == feature) .map(|spec| spec.key) - .unwrap_or_else(|| panic!("missing feature key for {feature:?}")); + .expect("feature should have a config key"); format!("{key} = {enabled}") }) .collect::>() diff --git a/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs b/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs index df49f2fad..f88ed799a 100644 --- a/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs +++ b/codex-rs/app-server/tests/suite/v2/realtime_conversation.rs @@ -389,9 +389,7 @@ impl RealtimeE2eHarness { .wait_for_request(/*connection_index*/ 0, request_index), ) .await - .unwrap_or_else(|_| { - panic!("timed out waiting for realtime sideband request {request_index}") - }) + .expect("realtime sideband request should arrive before timeout") .body_json() } diff --git a/codex-rs/app-server/tests/suite/v2/thread_shell_command.rs b/codex-rs/app-server/tests/suite/v2/thread_shell_command.rs index 312267d0a..df7b4991d 100644 --- a/codex-rs/app-server/tests/suite/v2/thread_shell_command.rs +++ b/codex-rs/app-server/tests/suite/v2/thread_shell_command.rs @@ -494,7 +494,7 @@ fn create_config_toml( .iter() .find(|spec| spec.id == *feature) .map(|spec| spec.key) - .unwrap_or_else(|| panic!("missing feature key for {feature:?}")); + .expect("feature should have a config key"); format!("{key} = {enabled}") }) .collect::>() diff --git a/codex-rs/app-server/tests/suite/v2/turn_start.rs b/codex-rs/app-server/tests/suite/v2/turn_start.rs index 7fc0d8c71..6567b06be 100644 --- a/codex-rs/app-server/tests/suite/v2/turn_start.rs +++ b/codex-rs/app-server/tests/suite/v2/turn_start.rs @@ -4309,7 +4309,7 @@ fn create_config_toml_with_sandbox( .iter() .find(|spec| spec.id == feature) .map(|spec| spec.key) - .unwrap_or_else(|| panic!("missing feature key for {feature:?}")); + .expect("feature should have a config key"); format!("{key} = {enabled}") }) .collect::>() diff --git a/codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs b/codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs index dfb76ecbc..15072c1cc 100644 --- a/codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs +++ b/codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs @@ -810,7 +810,7 @@ fn create_config_toml( .iter() .find(|spec| spec.id == feature) .map(|spec| spec.key) - .unwrap_or_else(|| panic!("missing feature key for {feature:?}")); + .expect("feature should have a config key"); format!("{key} = {enabled}") }) .collect::>() diff --git a/codex-rs/codex-api/tests/clients.rs b/codex-rs/codex-api/tests/clients.rs index e362560ca..d8489ed74 100644 --- a/codex-rs/codex-api/tests/clients.rs +++ b/codex-rs/codex-api/tests/clients.rs @@ -1,3 +1,4 @@ +#![allow(clippy::expect_used)] use std::sync::Arc; use std::sync::Mutex; use std::time::Duration; @@ -53,7 +54,7 @@ impl RecordingState { let mut guard = self .stream_requests .lock() - .unwrap_or_else(|err| panic!("mutex poisoned: {err}")); + .expect("stream requests mutex should not be poisoned"); guard.push(req); } @@ -61,7 +62,7 @@ impl RecordingState { let mut guard = self .stream_requests .lock() - .unwrap_or_else(|err| panic!("mutex poisoned: {err}")); + .expect("stream requests mutex should not be poisoned"); std::mem::take(&mut *guard) } } @@ -172,14 +173,14 @@ impl FlakyTransport { fn attempts(&self) -> i64 { self.state .lock() - .unwrap_or_else(|err| panic!("mutex poisoned: {err}")) + .expect("flaky transport state mutex should not be poisoned") .attempts } fn requests(&self) -> Vec<(RequestBody, HeaderMap, codex_client::RequestCompression)> { self.state .lock() - .unwrap_or_else(|err| panic!("mutex poisoned: {err}")) + .expect("flaky transport state mutex should not be poisoned") .requests .clone() } @@ -212,14 +213,14 @@ impl FailsOnceAuth { *self .attempts .lock() - .unwrap_or_else(|err| panic!("mutex poisoned: {err}")) + .expect("auth attempts mutex should not be poisoned") } async fn apply_auth(&self, request: Request) -> Result { let mut attempts = self .attempts .lock() - .unwrap_or_else(|err| panic!("mutex poisoned: {err}")); + .expect("auth attempts mutex should not be poisoned"); *attempts += 1; if *attempts == 1 { @@ -253,7 +254,7 @@ impl HttpTransport for FlakyTransport { let mut state = self .state .lock() - .unwrap_or_else(|err| panic!("mutex poisoned: {err}")); + .expect("flaky transport state mutex should not be poisoned"); state.attempts += 1; state .requests @@ -486,10 +487,9 @@ async fn streaming_client_does_not_retry_auth_build_error() -> Result<()> { /*turn_state*/ None, ) .await; - let err = match result { - Ok(_) => panic!("auth build errors should fail without retry"), - Err(err) => err, - }; + let err = result + .err() + .expect("auth build errors should fail without retry"); assert!(matches!( err, diff --git a/codex-rs/codex-api/tests/realtime_websocket_e2e.rs b/codex-rs/codex-api/tests/realtime_websocket_e2e.rs index cb9d7122f..3aaf3f5f5 100644 --- a/codex-rs/codex-api/tests/realtime_websocket_e2e.rs +++ b/codex-rs/codex-api/tests/realtime_websocket_e2e.rs @@ -1,3 +1,4 @@ +#![allow(clippy::expect_used)] use std::collections::HashMap; use std::future::Future; use std::time::Duration; @@ -34,24 +35,22 @@ where Handler: FnOnce(RealtimeWsStream) -> Fut + Send + 'static, Fut: Future + Send + 'static, { - let listener = match TcpListener::bind("127.0.0.1:0").await { - Ok(listener) => listener, - Err(err) => panic!("failed to bind test websocket listener: {err}"), - }; - let addr = match listener.local_addr() { - Ok(addr) => addr.to_string(), - Err(err) => panic!("failed to read local websocket listener address: {err}"), - }; + let listener = TcpListener::bind("127.0.0.1:0") + .await + .expect("test websocket listener should bind"); + let addr = listener + .local_addr() + .expect("test websocket listener should have a local address") + .to_string(); let server = tokio::spawn(async move { - let (stream, _) = match listener.accept().await { - Ok(stream) => stream, - Err(err) => panic!("failed to accept test websocket connection: {err}"), - }; - let ws = match accept_async(stream).await { - Ok(ws) => ws, - Err(err) => panic!("failed to complete websocket handshake: {err}"), - }; + let (stream, _) = listener + .accept() + .await + .expect("test websocket connection should be accepted"); + let ws = accept_async(stream) + .await + .expect("test websocket handshake should complete"); handler(ws).await; }); diff --git a/codex-rs/codex-api/tests/sse_end_to_end.rs b/codex-rs/codex-api/tests/sse_end_to_end.rs index eef8c8823..2526de281 100644 --- a/codex-rs/codex-api/tests/sse_end_to_end.rs +++ b/codex-rs/codex-api/tests/sse_end_to_end.rs @@ -1,3 +1,4 @@ +#![allow(clippy::expect_used)] use std::sync::Arc; use std::time::Duration; @@ -78,7 +79,7 @@ fn build_responses_body(events: Vec) -> String { let kind = e .get("type") .and_then(|v| v.as_str()) - .unwrap_or_else(|| panic!("fixture event missing type in SSE fixture: {e}")); + .expect("SSE fixture event should have a type"); if e.as_object().map(|o| o.len() == 1).unwrap_or(false) { body.push_str(&format!("event: {kind}\n\n")); } else { diff --git a/codex-rs/codex-client/tests/ca_env.rs b/codex-rs/codex-client/tests/ca_env.rs index 6a3a0e0ca..7ddd138a3 100644 --- a/codex-rs/codex-client/tests/ca_env.rs +++ b/codex-rs/codex-client/tests/ca_env.rs @@ -1,3 +1,4 @@ +#![allow(clippy::expect_used)] //! Subprocess coverage for custom CA behavior that must build a real reqwest client. //! //! These tests intentionally run through `custom_ca_probe` and @@ -82,16 +83,13 @@ struct TlsInterceptingProxy { fn write_cert_file(temp_dir: &TempDir, name: &str, contents: &str) -> PathBuf { let path = temp_dir.path().join(name); - fs::write(&path, contents).unwrap_or_else(|error| { - panic!("write cert fixture failed for {}: {error}", path.display()) - }); + fs::write(&path, contents).expect("certificate fixture should be writable"); path } fn probe_command() -> Command { let mut cmd = Command::new( - cargo_bin("custom_ca_probe") - .unwrap_or_else(|error| panic!("failed to locate custom_ca_probe: {error}")), + cargo_bin("custom_ca_probe").expect("custom_ca_probe binary should be available"), ); // `Command` inherits the parent environment by default, so scrub CA-related variables first or // these tests can accidentally pass/fail based on the developer shell or CI runner. @@ -111,8 +109,7 @@ fn run_probe(envs: &[(&str, &Path)]) -> std::process::Output { for (key, value) in envs { cmd.env(key, value); } - cmd.output() - .unwrap_or_else(|error| panic!("failed to run custom_ca_probe: {error}")) + cmd.output().expect("custom_ca_probe should run") } fn run_probe_posting_to_tls13_server(envs: &[(&str, &Path)], url: &str) -> std::process::Output { @@ -122,8 +119,7 @@ fn run_probe_posting_to_tls13_server(envs: &[(&str, &Path)], url: &str) -> std:: } cmd.env(PROBE_TLS13_ENV, "1"); cmd.env(PROBE_URL_ENV, url); - cmd.output() - .unwrap_or_else(|error| panic!("failed to run custom_ca_probe: {error}")) + cmd.output().expect("custom_ca_probe should run") } fn run_probe_posting_through_tls_intercepting_proxy( @@ -138,27 +134,25 @@ fn run_probe_posting_through_tls_intercepting_proxy( cmd.env(PROBE_PROXY_ENV, proxy_url); cmd.env(PROBE_TLS13_ENV, "1"); cmd.env(PROBE_URL_ENV, url); - cmd.output() - .unwrap_or_else(|error| panic!("failed to run custom_ca_probe: {error}")) + cmd.output().expect("custom_ca_probe should run") } fn spawn_tls13_test_server() -> Tls13TestServer { codex_utils_rustls_provider::ensure_rustls_crypto_provider(); let material = generate_tls13_material(); - let listener = TcpListener::bind(("127.0.0.1", 0)) - .unwrap_or_else(|error| panic!("bind TLS test server: {error}")); + let listener = TcpListener::bind(("127.0.0.1", 0)).expect("TLS test server should bind"); listener .set_nonblocking(true) - .unwrap_or_else(|error| panic!("set TLS test server nonblocking: {error}")); + .expect("TLS test server should become nonblocking"); let port = listener .local_addr() - .unwrap_or_else(|error| panic!("TLS test server addr: {error}")) + .expect("TLS test server should have a local address") .port(); let config = Arc::new( rustls::ServerConfig::builder_with_protocol_versions(&[&rustls::version::TLS13]) .with_no_client_auth() .with_single_cert(vec![material.server_cert], material.server_key) - .unwrap_or_else(|error| panic!("TLS 1.3 server config: {error}")), + .expect("TLS 1.3 server config should be valid"), ); let (request_tx, request_rx) = mpsc::channel(); @@ -175,14 +169,13 @@ fn spawn_tls13_test_server() -> Tls13TestServer { } fn spawn_plain_http_origin() -> PlainHttpOrigin { - let listener = TcpListener::bind(("127.0.0.1", 0)) - .unwrap_or_else(|error| panic!("bind plain HTTP origin: {error}")); + let listener = TcpListener::bind(("127.0.0.1", 0)).expect("plain HTTP origin should bind"); listener .set_nonblocking(true) - .unwrap_or_else(|error| panic!("set plain HTTP origin nonblocking: {error}")); + .expect("plain HTTP origin should become nonblocking"); let port = listener .local_addr() - .unwrap_or_else(|error| panic!("plain HTTP origin addr: {error}")) + .expect("plain HTTP origin should have a local address") .port(); let (request_tx, request_rx) = mpsc::channel(); @@ -200,20 +193,19 @@ fn spawn_plain_http_origin() -> PlainHttpOrigin { fn spawn_tls_intercepting_proxy() -> TlsInterceptingProxy { codex_utils_rustls_provider::ensure_rustls_crypto_provider(); let material = generate_tls13_material(); - let listener = TcpListener::bind(("127.0.0.1", 0)) - .unwrap_or_else(|error| panic!("bind TLS intercepting proxy: {error}")); + let listener = TcpListener::bind(("127.0.0.1", 0)).expect("TLS intercepting proxy should bind"); listener .set_nonblocking(true) - .unwrap_or_else(|error| panic!("set TLS intercepting proxy nonblocking: {error}")); + .expect("TLS intercepting proxy should become nonblocking"); let port = listener .local_addr() - .unwrap_or_else(|error| panic!("TLS intercepting proxy addr: {error}")) + .expect("TLS intercepting proxy should have a local address") .port(); let config = Arc::new( rustls::ServerConfig::builder_with_protocol_versions(&[&rustls::version::TLS13]) .with_no_client_auth() .with_single_cert(vec![material.server_cert], material.server_key) - .unwrap_or_else(|error| panic!("TLS intercepting proxy config: {error}")), + .expect("TLS intercepting proxy config should be valid"), ); let (request_tx, request_rx) = mpsc::channel(); @@ -236,24 +228,24 @@ fn generate_tls13_material() -> Tls13Material { let mut ca_distinguished_name = DistinguishedName::new(); ca_distinguished_name.push(DnType::CommonName, "codex test CA"); ca_params.distinguished_name = ca_distinguished_name; - let ca_key_pair = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256) - .unwrap_or_else(|error| panic!("generate test CA key pair: {error}")); + let ca_key_pair = + KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256).expect("test CA key pair should generate"); let ca = CertifiedIssuer::self_signed(ca_params, ca_key_pair) - .unwrap_or_else(|error| panic!("generate test CA certificate: {error}")); + .expect("test CA certificate should generate"); let mut server_params = CertificateParams::new(vec!["localhost".to_string(), "127.0.0.1".to_string()]) - .unwrap_or_else(|error| panic!("create test server certificate params: {error}")); + .expect("test server certificate params should be valid"); server_params.extended_key_usages = vec![ExtendedKeyUsagePurpose::ServerAuth]; server_params.key_usages = vec![ KeyUsagePurpose::DigitalSignature, KeyUsagePurpose::KeyEncipherment, ]; let server_key_pair = KeyPair::generate_for(&PKCS_ECDSA_P256_SHA256) - .unwrap_or_else(|error| panic!("generate test server key pair: {error}")); + .expect("test server key pair should generate"); let server_cert = server_params .signed_by(&server_key_pair, &ca) - .unwrap_or_else(|error| panic!("generate test server certificate: {error}")); + .expect("test server certificate should generate"); Tls13Material { ca_cert_pem: ca.pem(), diff --git a/codex-rs/core/tests/all.rs b/codex-rs/core/tests/all.rs index ed4ead10e..0ee0cd986 100644 --- a/codex-rs/core/tests/all.rs +++ b/codex-rs/core/tests/all.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + // Single integration test binary that aggregates all test modules. // The submodules live in `tests/all/`. pub use codex_protocol::error; diff --git a/codex-rs/core/tests/common/apps_test_server.rs b/codex-rs/core/tests/common/apps_test_server.rs index 7f7873e30..0e7141281 100644 --- a/codex-rs/core/tests/common/apps_test_server.rs +++ b/codex-rs/core/tests/common/apps_test_server.rs @@ -119,8 +119,7 @@ impl AppsTestServer { } pub fn configure_search_capable_model(config: &mut Config) { - let mut model_catalog = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let mut model_catalog = bundled_models_response().expect("bundled models.json should parse"); let model = model_catalog .models .iter_mut() diff --git a/codex-rs/core/tests/common/hooks.rs b/codex-rs/core/tests/common/hooks.rs index d549e04b2..d1b7059b5 100644 --- a/codex-rs/core/tests/common/hooks.rs +++ b/codex-rs/core/tests/common/hooks.rs @@ -7,9 +7,10 @@ use codex_hooks::HookListEntry; use codex_utils_absolute_path::AbsolutePathBuf; pub fn trust_discovered_hooks(config: &mut Config) { - if let Err(err) = config.features.enable(Feature::CodexHooks) { - panic!("test config should allow feature update: {err}"); - } + config + .features + .enable(Feature::CodexHooks) + .expect("test config should allow feature update"); let listed = codex_hooks::list_hooks(codex_hooks::HooksConfig { feature_enabled: true, @@ -37,28 +38,24 @@ pub fn trusted_config_layer_stack( .get_active_user_layer() .map(|layer| layer.config.clone()) .unwrap_or_else(|| TomlValue::Table(Default::default())); - let Some(user_table) = user_config.as_table_mut() else { - panic!("user config should be a table"); - }; - let Some(hooks_table) = user_table + let user_table = user_config + .as_table_mut() + .expect("user config should be a table"); + let hooks_table = user_table .entry("hooks") .or_insert_with(|| TomlValue::Table(Default::default())) .as_table_mut() - else { - panic!("hooks config should be a table"); - }; - let Some(state_table) = hooks_table + .expect("hooks config should be a table"); + let state_table = hooks_table .entry("state") .or_insert_with(|| TomlValue::Table(Default::default())) .as_table_mut() - else { - panic!("hook state config should be a table"); - }; + .expect("hook state config should be a table"); for hook in hooks { let mut hook_state = TomlValue::Table(Default::default()); - let Some(hook_state_table) = hook_state.as_table_mut() else { - panic!("hook state should be a table"); - }; + let hook_state_table = hook_state + .as_table_mut() + .expect("hook state should be a table"); hook_state_table.insert( "trusted_hash".to_string(), TomlValue::String(hook.current_hash), diff --git a/codex-rs/core/tests/common/lib.rs b/codex-rs/core/tests/common/lib.rs index f23522777..523d7f854 100644 --- a/codex-rs/core/tests/common/lib.rs +++ b/codex-rs/core/tests/common/lib.rs @@ -1,4 +1,4 @@ -#![expect(clippy::expect_used)] +#![allow(clippy::expect_used)] use anyhow::Context as _; use anyhow::ensure; @@ -75,12 +75,10 @@ fn configure_insta_workspace_root_for_snapshot_tests() { #[track_caller] pub fn assert_regex_match<'s>(pattern: &str, actual: &'s str) -> regex_lite::Captures<'s> { - let regex = Regex::new(pattern).unwrap_or_else(|err| { - panic!("failed to compile regex {pattern:?}: {err}"); - }); + let regex = Regex::new(pattern).expect("failed to compile regex"); regex .captures(actual) - .unwrap_or_else(|| panic!("regex {pattern:?} did not match {actual:?}")) + .expect("regex did not match actual value") } pub fn test_path_buf_with_windows(unix_path: &str, windows_path: Option<&str>) -> PathBuf { diff --git a/codex-rs/core/tests/common/responses.rs b/codex-rs/core/tests/common/responses.rs index 6e5405e4b..9eb0c6f30 100644 --- a/codex-rs/core/tests/common/responses.rs +++ b/codex-rs/core/tests/common/responses.rs @@ -91,9 +91,8 @@ fn is_zstd_encoding(value: &str) -> bool { fn decode_body_bytes(body: &[u8], content_encoding: Option<&str>) -> Vec { if content_encoding.is_some_and(is_zstd_encoding) { - zstd::stream::decode_all(std::io::Cursor::new(body)).unwrap_or_else(|err| { - panic!("failed to decode zstd request body: {err}"); - }) + zstd::stream::decode_all(std::io::Cursor::new(body)) + .expect("failed to decode zstd request body") } else { body.to_vec() } @@ -222,7 +221,7 @@ impl ResponsesRequest { item.get("type").unwrap() == call_type && item.get("call_id").unwrap() == call_id }) .cloned() - .unwrap_or_else(|| panic!("function call output {call_id} item not found in request")) + .expect("function call output item not found in request") } /// Returns true if this request's `input` contains a `function_call` with @@ -1061,9 +1060,10 @@ pub async fn mount_compact_user_history_with_summary_sequence( impl Respond for UserHistorySummaryResponder { fn respond(&self, request: &wiremock::Request) -> ResponseTemplate { let call_num = self.num_calls.fetch_add(1, Ordering::SeqCst); - let Some(summary_text) = self.summary_texts.get(call_num) else { - panic!("no summary text for compact request {call_num}"); - }; + let summary_text = self + .summary_texts + .get(call_num) + .expect("missing summary text for compact request"); let body_bytes = decode_body_bytes( &request.body, request @@ -1071,8 +1071,8 @@ pub async fn mount_compact_user_history_with_summary_sequence( .get("content-encoding") .and_then(|value| value.to_str().ok()), ); - let body_json: Value = serde_json::from_slice(&body_bytes) - .unwrap_or_else(|err| panic!("failed to parse compact request body: {err}")); + let body_json: Value = + serde_json::from_slice(&body_bytes).expect("failed to parse compact request body"); let mut output = body_json .get("input") .and_then(Value::as_array) @@ -1447,12 +1447,14 @@ pub async fn mount_sse_sequence(server: &MockServer, bodies: Vec) -> Res impl Respond for SeqResponder { fn respond(&self, _: &wiremock::Request) -> ResponseTemplate { let call_num = self.num_calls.fetch_add(1, Ordering::SeqCst); - match self.responses.get(call_num) { - Some(body) => ResponseTemplate::new(200) - .insert_header("content-type", "text/event-stream") - .set_body_string(body.clone()), - None => panic!("no response for {call_num}"), - } + let missing_response_message = format!("no response for {call_num}"); + let body = self + .responses + .get(call_num) + .expect(&missing_response_message); + ResponseTemplate::new(200) + .insert_header("content-type", "text/event-stream") + .set_body_string(body.clone()) } } @@ -1491,7 +1493,7 @@ pub async fn mount_response_sequence( let call_num = self.num_calls.fetch_add(1, Ordering::SeqCst); self.responses .get(call_num) - .unwrap_or_else(|| panic!("no response for {call_num}")) + .expect("missing response for call") .clone() } } @@ -1536,9 +1538,10 @@ fn validate_request_body_invariants(request: &wiremock::Request) { let Ok(body): Result = serde_json::from_slice(&body_bytes) else { return; }; - let Some(items) = body.get("input").and_then(Value::as_array) else { - panic!("input array not found in request"); - }; + let items = body + .get("input") + .and_then(Value::as_array) + .expect("input array not found in request"); use std::collections::HashSet; @@ -1562,9 +1565,7 @@ fn validate_request_body_invariants(request: &wiremock::Request) { .iter() .filter(|item| item.get("type").and_then(Value::as_str) == Some(kind)) .map(|item| { - let Some(id) = get_call_id(item) else { - panic!("{missing_msg}"); - }; + let id = get_call_id(item).expect(missing_msg); id.to_string() }) .collect() diff --git a/codex-rs/core/tests/common/test_codex.rs b/codex-rs/core/tests/common/test_codex.rs index 1d9585652..bdac7fddc 100644 --- a/codex-rs/core/tests/common/test_codex.rs +++ b/codex-rs/core/tests/common/test_codex.rs @@ -287,14 +287,13 @@ impl TestCodexBuilder { let model = model.to_string(); self.with_config(move |config| { let model_catalog = config.model_catalog.get_or_insert_with(|| { - bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")) + bundled_models_response().expect("bundled models.json should parse") }); let model_info = model_catalog .models .iter_mut() .find(|model_info| model_info.slug == model) - .unwrap_or_else(|| panic!("{model} should exist in the configured model catalog")); + .expect("model should exist in the configured model catalog"); override_model_info(model_info); config.model = Some(model); }) @@ -672,14 +671,13 @@ fn ensure_test_model_catalog(config: &mut Config) -> Result<()> { return Ok(()); } - let bundled_models = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let bundled_models = bundled_models_response().expect("bundled models.json should parse"); let mut model = bundled_models .models .iter() .find(|candidate| candidate.slug == "gpt-5.2") .cloned() - .unwrap_or_else(|| panic!("missing bundled model gpt-5.2")); + .expect("missing bundled model gpt-5.2"); model.slug = TEST_MODEL_WITH_EXPERIMENTAL_TOOLS.to_string(); model.display_name = TEST_MODEL_WITH_EXPERIMENTAL_TOOLS.to_string(); model.experimental_supported_tools = vec!["test_sync_tool".to_string()]; @@ -1094,41 +1092,37 @@ impl TestCodexHarness { } fn custom_tool_call_output<'a>(bodies: &'a [Value], call_id: &str) -> &'a Value { - for body in bodies { - if let Some(items) = body.get("input").and_then(Value::as_array) { - for item in items { - if item.get("type").and_then(Value::as_str) == Some("custom_tool_call_output") - && item.get("call_id").and_then(Value::as_str) == Some(call_id) - { - return item; - } - } - } - } - panic!("custom_tool_call_output {call_id} not found"); + let missing_output = format!("custom_tool_call_output {call_id} not found"); + bodies + .iter() + .filter_map(|body| body.get("input").and_then(Value::as_array)) + .flatten() + .find(|item| { + item.get("type").and_then(Value::as_str) == Some("custom_tool_call_output") + && item.get("call_id").and_then(Value::as_str) == Some(call_id) + }) + .expect(&missing_output) } fn custom_tool_call_output_text(bodies: &[Value], call_id: &str) -> String { + let missing_output = format!("custom_tool_call_output {call_id} missing output"); let output = custom_tool_call_output(bodies, call_id) .get("output") - .unwrap_or_else(|| panic!("custom_tool_call_output {call_id} missing output")); - output_value_to_text(output) - .unwrap_or_else(|| panic!("custom_tool_call_output {call_id} missing text output")) + .expect(&missing_output); + output_value_to_text(output).expect("custom tool call output missing text output") } fn function_call_output<'a>(bodies: &'a [Value], call_id: &str) -> &'a Value { - for body in bodies { - if let Some(items) = body.get("input").and_then(Value::as_array) { - for item in items { - if item.get("type").and_then(Value::as_str) == Some("function_call_output") - && item.get("call_id").and_then(Value::as_str) == Some(call_id) - { - return item; - } - } - } - } - panic!("function_call_output {call_id} not found"); + let missing_output = format!("function_call_output {call_id} not found"); + bodies + .iter() + .filter_map(|body| body.get("input").and_then(Value::as_array)) + .flatten() + .find(|item| { + item.get("type").and_then(Value::as_str) == Some("function_call_output") + && item.get("call_id").and_then(Value::as_str) == Some(call_id) + }) + .expect(&missing_output) } pub fn test_codex() -> TestCodexBuilder { diff --git a/codex-rs/core/tests/common/test_codex_exec.rs b/codex-rs/core/tests/common/test_codex_exec.rs index ad32bcb02..4020a4d9a 100644 --- a/codex-rs/core/tests/common/test_codex_exec.rs +++ b/codex-rs/core/tests/common/test_codex_exec.rs @@ -1,4 +1,3 @@ -#![allow(clippy::expect_used)] use codex_login::CODEX_API_KEY_ENV_VAR; use std::path::Path; use tempfile::TempDir; diff --git a/codex-rs/core/tests/common/test_environment.rs b/codex-rs/core/tests/common/test_environment.rs index addc3b0b7..386e4a0ee 100644 --- a/codex-rs/core/tests/common/test_environment.rs +++ b/codex-rs/core/tests/common/test_environment.rs @@ -61,7 +61,7 @@ pub fn test_environment() -> TestEnvironment { std::env::var_os(LEGACY_REMOTE_ENV_ENV_VAR).as_deref(), std::env::var_os(DOCKER_CONTAINER_ENV_VAR).as_deref(), ) - .unwrap_or_else(|error| panic!("invalid test environment configuration: {error}")); + .expect("invalid test environment configuration"); if matches!(environment, TestEnvironment::WineExec) && !cfg!(target_os = "linux") { panic!("{TEST_ENVIRONMENT_ENV_VAR}=wine-exec is only supported on Linux"); diff --git a/codex-rs/core/tests/suite/agent_jobs.rs b/codex-rs/core/tests/suite/agent_jobs.rs index b275b1878..252b47307 100644 --- a/codex-rs/core/tests/suite/agent_jobs.rs +++ b/codex-rs/core/tests/suite/agent_jobs.rs @@ -75,9 +75,7 @@ impl Respond for StopAfterFirstResponder { "result": { "item_id": item_id }, "stop": stop, }); - let args_json = serde_json::to_string(&args).unwrap_or_else(|err| { - panic!("worker args serialize: {err}"); - }); + let args_json = serde_json::to_string(&args).expect("worker args should serialize"); return sse_response(sse(vec![ ev_response_created("resp-worker"), ev_function_call(&call_id, "report_agent_job_result", &args_json), @@ -122,9 +120,7 @@ impl Respond for AgentJobsResponder { "item_id": item_id, "result": { "item_id": item_id } }); - let args_json = serde_json::to_string(&args).unwrap_or_else(|err| { - panic!("worker args serialize: {err}"); - }); + let args_json = serde_json::to_string(&args).expect("worker args should serialize"); return sse_response(sse(vec![ ev_response_created("resp-worker"), ev_function_call(&call_id, "report_agent_job_result", &args_json), diff --git a/codex-rs/core/tests/suite/apply_patch_cli.rs b/codex-rs/core/tests/suite/apply_patch_cli.rs index 294321910..2527e4cb9 100644 --- a/codex-rs/core/tests/suite/apply_patch_cli.rs +++ b/codex-rs/core/tests/suite/apply_patch_cli.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - use anyhow::Result; use base64::Engine; use base64::engine::general_purpose::STANDARD as BASE64_STANDARD; diff --git a/codex-rs/core/tests/suite/approvals.rs b/codex-rs/core/tests/suite/approvals.rs index 927b1f18f..422fd2826 100644 --- a/codex-rs/core/tests/suite/approvals.rs +++ b/codex-rs/core/tests/suite/approvals.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Context; use anyhow::Result; diff --git a/codex-rs/core/tests/suite/auto_review.rs b/codex-rs/core/tests/suite/auto_review.rs index 7dae7c4c6..4dd3effe4 100644 --- a/codex-rs/core/tests/suite/auto_review.rs +++ b/codex-rs/core/tests/suite/auto_review.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - use anyhow::Result; use codex_features::Feature; use codex_login::CodexAuth; diff --git a/codex-rs/core/tests/suite/cli_stream.rs b/codex-rs/core/tests/suite/cli_stream.rs index 1ef7c82c3..d2eac6fb3 100644 --- a/codex-rs/core/tests/suite/cli_stream.rs +++ b/codex-rs/core/tests/suite/cli_stream.rs @@ -32,7 +32,6 @@ const CLOUD_CONFIG_BUNDLE_PATH: &str = "/backend-api/wham/config/bundle"; const CLI_TIMEOUT: Duration = Duration::from_secs(30); fn repo_root() -> std::path::PathBuf { - #[expect(clippy::expect_used)] codex_utils_cargo_bin::repo_root().expect("failed to resolve repo root") } @@ -515,10 +514,9 @@ async fn integration_creates_and_checks_session_file() -> anyhow::Result<()> { .await?; // Basic sanity checks on location and metadata. - let rel = match path.strip_prefix(&sessions_dir) { - Ok(r) => r, - Err(_) => panic!("session file should live under sessions/"), - }; + let rel = path + .strip_prefix(&sessions_dir) + .expect("session file should live under sessions/"); let comps: Vec = rel .components() .map(|c| c.as_os_str().to_string_lossy().into_owned()) @@ -550,22 +548,19 @@ async fn integration_creates_and_checks_session_file() -> anyhow::Result<()> { assert!((1..=31).contains(&d), "Day out of range: {d}"); } - let content = - std::fs::read_to_string(&path).unwrap_or_else(|_| panic!("Failed to read session file")); + let content = std::fs::read_to_string(&path).expect("failed to read session file"); let mut lines = content.lines(); let meta_line = lines .next() .ok_or("missing session meta line") - .unwrap_or_else(|_| panic!("missing session meta line")); - let meta: serde_json::Value = serde_json::from_str(meta_line) - .unwrap_or_else(|_| panic!("Failed to parse session meta line as JSON")); + .expect("missing session meta line"); + let meta: serde_json::Value = + serde_json::from_str(meta_line).expect("failed to parse session meta line as JSON"); assert_eq!( meta.get("type").and_then(|v| v.as_str()), Some("session_meta") ); - let payload = meta - .get("payload") - .unwrap_or_else(|| panic!("Missing payload in meta line")); + let payload = meta.get("payload").expect("Missing payload in meta line"); assert!(payload.get("id").is_some(), "SessionMeta missing id"); assert!( payload.get("timestamp").is_some(), diff --git a/codex-rs/core/tests/suite/client.rs b/codex-rs/core/tests/suite/client.rs index 144daeffd..c5dfd96cf 100644 --- a/codex-rs/core/tests/suite/client.rs +++ b/codex-rs/core/tests/suite/client.rs @@ -147,12 +147,11 @@ fn assert_codex_client_metadata( ); assert_eq!(client_metadata["session_id"].as_str(), Some(session_id)); assert_eq!(client_metadata["thread_id"].as_str(), Some(thread_id)); - let Some(turn_metadata_str) = client_metadata["x-codex-turn-metadata"].as_str() else { - panic!("missing x-codex-turn-metadata client metadata"); - }; - let Ok(turn_metadata) = serde_json::from_str::(turn_metadata_str) else { - panic!("invalid x-codex-turn-metadata json"); - }; + let turn_metadata_str = client_metadata["x-codex-turn-metadata"] + .as_str() + .expect("missing x-codex-turn-metadata client metadata"); + let turn_metadata = serde_json::from_str::(turn_metadata_str) + .expect("invalid x-codex-turn-metadata json"); assert_eq!( turn_metadata["installation_id"].as_str(), Some(installation_id) @@ -352,19 +351,14 @@ move /y tokens.next tokens.txt >nul // Match the model-provider default to avoid brittle shell-startup timing in CI. timeout_ms: non_zero_u64(/*value*/ 5_000), refresh_interval_ms: 60_000, - cwd: match codex_utils_absolute_path::AbsolutePathBuf::try_from(self.tempdir.path()) { - Ok(cwd) => cwd, - Err(err) => panic!("tempdir should be absolute: {err}"), - }, + cwd: codex_utils_absolute_path::AbsolutePathBuf::try_from(self.tempdir.path()) + .expect("tempdir should be absolute"), } } } fn non_zero_u64(value: u64) -> NonZeroU64 { - match NonZeroU64::new(value) { - Some(value) => value, - None => panic!("expected non-zero value: {value}"), - } + NonZeroU64::new(value).expect("expected non-zero value") } #[tokio::test(flavor = "multi_thread", worker_threads = 2)] @@ -968,7 +962,7 @@ async fn provider_auth_command_refreshes_after_401() { /// /// The caller owns the server-side assertions, so this helper only validates that the request /// reaches `Completed` without surfacing an auth or transport error to the client. -#[expect(clippy::expect_used, clippy::unwrap_used)] +#[expect(clippy::unwrap_used)] async fn send_provider_auth_request(server: &MockServer, auth: ModelProviderAuthInfo) { let provider = ModelProviderInfo { name: "corp".into(), @@ -1237,18 +1231,16 @@ async fn prefers_apikey_when_config_prefers_apikey_even_with_chatgpt_tokens() { let mut config = load_default_config_for_test(&codex_home).await; config.model_provider = model_provider; - let auth_manager = match CodexAuth::from_auth_storage( + let auth = CodexAuth::from_auth_storage( codex_home.path(), AuthCredentialsStoreMode::File, /*chatgpt_base_url*/ None, AuthKeyringBackendKind::default(), ) .await - { - Ok(Some(auth)) => codex_core::test_support::auth_manager_from_auth(auth), - Ok(None) => panic!("No CodexAuth found in codex_home"), - Err(e) => panic!("Failed to load CodexAuth: {e}"), - }; + .expect("Failed to load CodexAuth") + .expect("No CodexAuth found in codex_home"); + let auth_manager = codex_core::test_support::auth_manager_from_auth(auth); let installation_id = resolve_installation_id(&config.codex_home) .await .expect("resolve installation id"); @@ -2050,8 +2042,7 @@ async fn user_turn_explicit_reasoning_summary_overrides_model_catalog_default() ) .await; - let mut model_catalog = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let mut model_catalog = bundled_models_response().expect("bundled models.json should parse"); let model = model_catalog .models .iter_mut() @@ -2173,8 +2164,7 @@ async fn reasoning_summary_none_overrides_model_catalog_default() -> anyhow::Res ) .await; - let mut model_catalog = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let mut model_catalog = bundled_models_response().expect("bundled models.json should parse"); let model = model_catalog .models .iter_mut() diff --git a/codex-rs/core/tests/suite/client_websockets.rs b/codex-rs/core/tests/suite/client_websockets.rs index 1f9175d7a..cee54e24b 100755 --- a/codex-rs/core/tests/suite/client_websockets.rs +++ b/codex-rs/core/tests/suite/client_websockets.rs @@ -1,4 +1,4 @@ -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use codex_api::WS_REQUEST_HEADER_TRACEPARENT_CLIENT_METADATA_KEY; use codex_api::WS_REQUEST_HEADER_TRACESTATE_CLIENT_METADATA_KEY; use codex_core::CodexResponsesMetadata; @@ -2241,13 +2241,11 @@ async fn stream_until_complete_with_model_info( .expect("websocket stream failed"); while let Some(event) = stream.next().await { - match event { - Ok(ResponseEvent::Completed { response_id, .. }) => { - assert_eq!(response_id, expected_response_id); - return; - } - Ok(_) => {} - Err(err) => panic!("websocket stream failed: {err}"), + if let ResponseEvent::Completed { response_id, .. } = + event.expect("websocket stream failed") + { + assert_eq!(response_id, expected_response_id); + return; } } panic!("websocket stream ended before completion"); diff --git a/codex-rs/core/tests/suite/code_mode.rs b/codex-rs/core/tests/suite/code_mode.rs index 829928002..e436b6fa9 100644 --- a/codex-rs/core/tests/suite/code_mode.rs +++ b/codex-rs/core/tests/suite/code_mode.rs @@ -1,4 +1,4 @@ -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use base64::Engine; @@ -572,8 +572,8 @@ if (!tool) { .features .enable(Feature::CodeModeOnly) .expect("test config should allow feature update"); - let mut model_catalog = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let mut model_catalog = + bundled_models_response().expect("bundled models.json should parse"); let model = model_catalog .models .iter_mut() diff --git a/codex-rs/core/tests/suite/compact.rs b/codex-rs/core/tests/suite/compact.rs index 56738a09a..cff88f57a 100644 --- a/codex-rs/core/tests/suite/compact.rs +++ b/codex-rs/core/tests/suite/compact.rs @@ -1,4 +1,3 @@ -#![allow(clippy::expect_used)] use anyhow::Result; use anyhow::anyhow; use codex_core::compact::SUMMARIZATION_PROMPT; @@ -169,14 +168,10 @@ fn json_fragment(text: &str) -> String { } fn read_hook_inputs(path: &Path) -> Vec { - let text = fs::read_to_string(path) - .unwrap_or_else(|err| panic!("failed to read hook input log {}: {err}", path.display())); + let text = fs::read_to_string(path).expect("failed to read hook input log"); text.lines() .filter(|line| !line.trim().is_empty()) - .map(|line| { - serde_json::from_str(line) - .unwrap_or_else(|err| panic!("failed to parse hook input log line: {err}")) - }) + .map(|line| serde_json::from_str(line).expect("failed to parse hook input log line")) .collect() } @@ -364,13 +359,12 @@ fn local_compaction_provider(server: &wiremock::MockServer) -> ModelProviderInfo } fn model_info_with_context_window(slug: &str, context_window: i64) -> ModelInfo { - let models_response = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let models_response = bundled_models_response().expect("bundled models.json should parse"); let mut model_info = models_response .models .into_iter() .find(|model| model.slug == slug) - .unwrap_or_else(|| panic!("model `{slug}` missing from models.json")); + .expect("model missing from models.json"); model_info.context_window = Some(context_window); model_info } @@ -641,12 +635,7 @@ async fn summarize_context_three_requests_and_instructions() { // Verify rollout contains user-turn TurnContext entries and a Compacted entry. println!("rollout path: {}", rollout_path.display()); - let text = std::fs::read_to_string(&rollout_path).unwrap_or_else(|e| { - panic!( - "failed to read rollout file {}: {e}", - rollout_path.display() - ) - }); + let text = std::fs::read_to_string(&rollout_path).expect("failed to read rollout file"); let mut regular_turn_context_count = 0usize; let mut saw_compacted_summary = false; for line in text.lines() { @@ -2984,12 +2973,7 @@ async fn auto_compact_persists_rollout_entries() { wait_for_event(&codex, |ev| matches!(ev, EventMsg::ShutdownComplete)).await; let rollout_path = session_configured.rollout_path.expect("rollout path"); - let text = std::fs::read_to_string(&rollout_path).unwrap_or_else(|e| { - panic!( - "failed to read rollout file {}: {e}", - rollout_path.display() - ) - }); + let text = std::fs::read_to_string(&rollout_path).expect("failed to read rollout file"); let mut turn_context_count = 0usize; for line in text.lines() { @@ -3089,10 +3073,10 @@ async fn manual_compact_retries_after_context_window_error() { let compact_input = compact_attempt["input"] .as_array() - .unwrap_or_else(|| panic!("compact attempt missing input array: {compact_attempt}")); + .expect("compact attempt missing input array"); let retry_input = retry_attempt["input"] .as_array() - .unwrap_or_else(|| panic!("retry attempt missing input array: {retry_attempt}")); + .expect("retry attempt missing input array"); let compact_contains_prompt = body_contains_text(&compact_attempt.to_string(), SUMMARIZATION_PROMPT); let retry_contains_prompt = @@ -3415,7 +3399,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { let first_turn_user_index = first_request_user_texts .len() .checked_sub(1) - .unwrap_or_else(|| panic!("first turn request missing user messages")); + .expect("first turn request missing user messages"); assert_eq!( first_request_user_texts[first_turn_user_index], first_user_message, "first turn request should end with the submitted user message" @@ -3424,7 +3408,7 @@ async fn manual_compact_twice_preserves_latest_user_messages() { let final_request_user_texts = requests .last() - .unwrap_or_else(|| panic!("final turn request missing for {final_user_message}")) + .expect("final turn request missing") .message_input_texts("user"); assert!( !initial_seeded_user_prefix.is_empty(), @@ -3432,18 +3416,14 @@ async fn manual_compact_twice_preserves_latest_user_messages() { ); let (final_request_last_user_text, final_request_before_last_user) = final_request_user_texts .split_last() - .unwrap_or_else(|| panic!("final turn request missing user messages")); + .expect("final turn request missing user messages"); assert_eq!( final_request_last_user_text, final_user_message, "final turn request should end with the submitted user message" ); let history_before_seeded_prefix = final_request_before_last_user .strip_suffix(initial_seeded_user_prefix) - .unwrap_or_else(|| { - panic!( - "final request should end with the seeded user prefix from the first request: {initial_seeded_user_prefix:?}" - ) - }); + .expect("final request should end with the seeded user prefix from the first request"); let expected_history = vec![ first_user_message.to_string(), second_user_message.to_string(), diff --git a/codex-rs/core/tests/suite/compact_remote.rs b/codex-rs/core/tests/suite/compact_remote.rs index 3aa4b21a3..f9b35f686 100644 --- a/codex-rs/core/tests/suite/compact_remote.rs +++ b/codex-rs/core/tests/suite/compact_remote.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - use core_test_support::test_codex::local_selections; use std::fs; @@ -16,7 +14,6 @@ use codex_protocol::items::TurnItem; use codex_protocol::models::ContentItem; use codex_protocol::models::ResponseItem; use codex_protocol::protocol::ConversationStartParams; -use codex_protocol::protocol::ErrorEvent; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::ItemCompletedEvent; use codex_protocol::protocol::ItemStartedEvent; @@ -225,7 +222,7 @@ async fn start_realtime_conversation(codex: &codex_core::CodexThread) -> Result< _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation start failed: {err:?}")); + .expect("conversation start failed"); wait_for_event_match(codex, |msg| match msg { EventMsg::RealtimeConversationRealtime(RealtimeConversationRealtimeEvent { diff --git a/codex-rs/core/tests/suite/compact_remote_parity.rs b/codex-rs/core/tests/suite/compact_remote_parity.rs index 87f771b74..432e5815a 100644 --- a/codex-rs/core/tests/suite/compact_remote_parity.rs +++ b/codex-rs/core/tests/suite/compact_remote_parity.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - use std::fs; use std::path::Path; use std::path::PathBuf; diff --git a/codex-rs/core/tests/suite/compact_resume_fork.rs b/codex-rs/core/tests/suite/compact_resume_fork.rs index 06ef8f62a..909dfb8c8 100644 --- a/codex-rs/core/tests/suite/compact_resume_fork.rs +++ b/codex-rs/core/tests/suite/compact_resume_fork.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - //! Integration tests that cover compacting, resuming, and forking conversations. //! //! Each test sets up a mocked SSE conversation and drives the conversation through @@ -74,7 +72,7 @@ fn extract_summary_user_text(request: &Value, summary_text: &str) -> String { json_message_input_texts(request, "user") .into_iter() .find(|text| text.contains(summary_text)) - .unwrap_or_else(|| panic!("expected summary message {summary_text}")) + .expect("expected summary message") } fn json_message_input_texts(request: &Value, role: &str) -> Vec { @@ -201,7 +199,7 @@ async fn compact_resume_and_fork_preserve_model_history_view() { let first_turn_user_index = first_request_user_texts .len() .checked_sub(1) - .unwrap_or_else(|| panic!("first turn request missing user messages")); + .expect("first turn request missing user messages"); assert_eq!( first_request_user_texts[first_turn_user_index], "hello world" @@ -226,7 +224,7 @@ async fn compact_resume_and_fork_preserve_model_history_view() { let after_resume_user_texts = json_message_input_texts(&requests[3], "user"); let (after_resume_last, after_resume_prefix) = after_resume_user_texts .split_last() - .unwrap_or_else(|| panic!("after-resume request missing user messages")); + .expect("after-resume request missing user messages"); assert_eq!(after_resume_last, "AFTER_RESUME"); assert!( after_resume_prefix.starts_with(&expected_after_resume_user_texts), @@ -256,7 +254,7 @@ async fn compact_resume_and_fork_preserve_model_history_view() { expected_after_fork_history_prefix.push("AFTER_COMPACT".to_string()); let (after_fork_last, after_fork_prefix) = after_fork_user_texts .split_last() - .unwrap_or_else(|| panic!("after-fork request missing user messages")); + .expect("after-fork request missing user messages"); assert_eq!(after_fork_last, "AFTER_FORK"); assert!( after_fork_prefix.starts_with(&expected_after_fork_history_prefix), @@ -360,7 +358,7 @@ async fn compact_resume_after_second_compaction_preserves_history() -> Result<() let first_turn_user_index = first_request_user_texts .len() .checked_sub(1) - .unwrap_or_else(|| panic!("first turn request missing user messages")); + .expect("first turn request missing user messages"); assert_eq!( first_request_user_texts[first_turn_user_index], "hello world" @@ -384,7 +382,7 @@ async fn compact_resume_after_second_compaction_preserves_history() -> Result<() let final_user_texts = json_message_input_texts(&requests[requests.len() - 1], "user"); let (final_last, final_prefix) = final_user_texts .split_last() - .unwrap_or_else(|| panic!("after-second-resume request missing user messages")); + .expect("after-second-resume request missing user messages"); assert_eq!(final_last, AFTER_SECOND_RESUME); let matched_prefix_len = if let Some(start) = final_prefix .windows(expected_after_second_compact_user_texts.len()) @@ -475,7 +473,7 @@ async fn snapshot_rollback_past_compaction_replays_append_only_history() -> Resu let after_rollback_user_texts = requests[3].message_input_texts("user"); let after_rollback_last = after_rollback_user_texts .last() - .unwrap_or_else(|| panic!("post-rollback request missing user messages")); + .expect("post-rollback request missing user messages"); assert_eq!(after_rollback_last, AFTER_ROLLBACK); assert!( requests[3].body_contains_text("hello world"), diff --git a/codex-rs/core/tests/suite/exec.rs b/codex-rs/core/tests/suite/exec.rs index d3ee65871..84d7408b8 100644 --- a/codex-rs/core/tests/suite/exec.rs +++ b/codex-rs/core/tests/suite/exec.rs @@ -24,7 +24,6 @@ fn skip_test() -> bool { false } -#[expect(clippy::expect_used)] async fn run_test_cmd(tmp: TempDir, command: I) -> Result where I: IntoIterator, diff --git a/codex-rs/core/tests/suite/exec_policy.rs b/codex-rs/core/tests/suite/exec_policy.rs index e0d198771..4e64c66b0 100644 --- a/codex-rs/core/tests/suite/exec_policy.rs +++ b/codex-rs/core/tests/suite/exec_policy.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use codex_features::Feature; @@ -78,9 +78,10 @@ async fn submit_user_turn( } fn assert_no_matched_rules_invariant(output_item: &Value) { - let Some(output) = output_item.get("output").and_then(Value::as_str) else { - panic!("function_call_output should include string output payload: {output_item:?}"); - }; + let output = output_item + .get("output") + .and_then(Value::as_str) + .expect("function call output should include a string output payload"); assert!( !output.contains("invariant failed: matched_rules must be non-empty"), "unexpected invariant panic surfaced in output: {output}" @@ -147,9 +148,10 @@ async fn unified_exec_disabled_windows_sandbox_rejects_managed_read_only_command .await; let output_item = results_mock.single_request().function_call_output(call_id); - let Some(output) = output_item.get("output").and_then(Value::as_str) else { - panic!("function_call_output should include string output payload: {output_item:?}"); - }; + let output = output_item + .get("output") + .and_then(Value::as_str) + .expect("function call output should include a string output payload"); assert!( output.contains("cmd.exe /c dir") && output.contains("rejected: blocked by policy"), "unexpected output: {output}", diff --git a/codex-rs/core/tests/suite/fork_thread.rs b/codex-rs/core/tests/suite/fork_thread.rs index b4898ea82..a1fdf79a8 100644 --- a/codex-rs/core/tests/suite/fork_thread.rs +++ b/codex-rs/core/tests/suite/fork_thread.rs @@ -222,23 +222,17 @@ async fn fork_thread_from_history_does_not_require_source_rollout_path() { } fn read_rollout_items(path: &std::path::Path) -> Vec { - let text = match std::fs::read_to_string(path) { - Ok(text) => text, - Err(err) => panic!("failed to read rollout file {}: {err}", path.display()), - }; + let read_message = format!("failed to read rollout file {}", path.display()); + let text = std::fs::read_to_string(path).expect(&read_message); let mut items: Vec = Vec::new(); for line in text.lines() { if line.trim().is_empty() { continue; } - let v: serde_json::Value = match serde_json::from_str(line) { - Ok(value) => value, - Err(err) => panic!("failed to parse rollout JSON line `{line}`: {err}"), - }; - let rl: RolloutLine = match serde_json::from_value(v) { - Ok(line) => line, - Err(err) => panic!("failed to parse rollout line `{line}`: {err}"), - }; + let parse_json_message = format!("failed to parse rollout JSON line `{line}`"); + let v: serde_json::Value = serde_json::from_str(line).expect(&parse_json_message); + let parse_line_message = format!("failed to parse rollout line `{line}`"); + let rl: RolloutLine = serde_json::from_value(v).expect(&parse_line_message); match rl.item { RolloutItem::SessionMeta(_) => {} other => items.push(other), diff --git a/codex-rs/core/tests/suite/hooks.rs b/codex-rs/core/tests/suite/hooks.rs index 0127dd74b..f0ad29fd6 100644 --- a/codex-rs/core/tests/suite/hooks.rs +++ b/codex-rs/core/tests/suite/hooks.rs @@ -104,9 +104,10 @@ fn non_openai_model_provider(server: &wiremock::MockServer) -> ModelProviderInfo } fn trust_plugin_hooks(config: &mut Config, plugin_hook_sources: Vec) { - if let Err(err) = config.features.enable(Feature::CodexHooks) { - panic!("test config should allow feature update: {err}"); - } + config + .features + .enable(Feature::CodexHooks) + .expect("test config should allow feature update"); let listed = codex_hooks::list_hooks(codex_hooks::HooksConfig { feature_enabled: true, config_layer_stack: Some(config.config_layer_stack.clone()), @@ -1050,10 +1051,7 @@ fn sse_event(event: Value) -> String { } fn request_message_input_texts(body: &[u8], role: &str) -> Vec { - let body: Value = match serde_json::from_slice(body) { - Ok(body) => body, - Err(error) => panic!("parse request body: {error}"), - }; + let body: Value = serde_json::from_slice(body).expect("parse request body"); body.get("input") .and_then(Value::as_array) .into_iter() @@ -1096,12 +1094,11 @@ async fn stop_hook_can_block_multiple_times_in_same_turn() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_stop_hook( + write_stop_hook( home, &[FIRST_CONTINUATION_PROMPT, SECOND_CONTINUATION_PROMPT], - ) { - panic!("failed to write stop hook test fixture: {error}"); - } + ) + .expect("failed to write stop hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -1193,9 +1190,8 @@ async fn session_start_hook_sees_materialized_transcript_path() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_session_start_hook_recording_transcript(home) { - panic!("failed to write session start hook test fixture: {error}"); - } + write_session_start_hook_recording_transcript(home) + .expect("failed to write session start hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -1233,9 +1229,8 @@ async fn session_start_runs_before_user_prompt_submit_on_first_turn() -> Result< let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_session_start_and_user_prompt_submit_order_hooks(home) { - panic!("failed to write hook ordering fixtures: {error}"); - } + write_session_start_and_user_prompt_submit_order_hooks(home) + .expect("failed to write hook ordering fixtures"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -1284,10 +1279,8 @@ async fn session_start_hook_spills_large_additional_context() -> Result<()> { .with_pre_build_hook({ let additional_context = additional_context.clone(); move |home| { - if let Err(error) = write_session_start_hook_with_context(home, &additional_context) - { - panic!("failed to write session start hook test fixture: {error}"); - } + write_session_start_hook_with_context(home, &additional_context) + .expect("failed to write session start hook test fixture"); } }) .with_config(trust_discovered_hooks); @@ -1342,11 +1335,8 @@ async fn pre_tool_use_hook_spills_large_additional_context() -> Result<()> { .with_pre_build_hook({ let additional_context = additional_context.clone(); move |home| { - if let Err(error) = - write_pre_tool_use_hook(home, Some("^Bash$"), "context", &additional_context) - { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^Bash$"), "context", &additional_context) + .expect("failed to write pre tool use hook test fixture"); } }) .with_config(trust_discovered_hooks); @@ -1400,11 +1390,8 @@ async fn compact_session_start_hook_records_additional_context_for_next_turn() - let mut builder = test_codex() .with_pre_build_hook(move |home| { - if let Err(error) = - write_compact_session_start_hook_with_context(home, additional_context) - { - panic!("failed to write compact session start hook fixture: {error}"); - } + write_compact_session_start_hook_with_context(home, additional_context) + .expect("failed to write compact session start hook fixture"); }) .with_config(move |config| { config.model_provider = model_provider; @@ -1486,13 +1473,12 @@ async fn resumed_thread_runs_resume_then_compact_session_start_hooks() -> Result let mut builder = test_codex() .with_pre_build_hook(move |home| { - if let Err(error) = write_resume_and_compact_session_start_hook_with_context( + write_resume_and_compact_session_start_hook_with_context( home, resume_context, compact_context, - ) { - panic!("failed to write resume/compact session start hook fixture: {error}"); - } + ) + .expect("failed to write resume/compact session start hook fixture"); }) .with_config(move |config| { config.model_auto_compact_token_limit = Some(limit); @@ -1573,9 +1559,8 @@ async fn stop_hook_spills_large_continuation_prompt() -> Result<()> { .with_pre_build_hook({ let continuation_prompt = continuation_prompt.clone(); move |home| { - if let Err(error) = write_stop_hook(home, &[&continuation_prompt]) { - panic!("failed to write stop hook test fixture: {error}"); - } + write_stop_hook(home, &[&continuation_prompt]) + .expect("failed to write stop hook test fixture"); } }) .with_config(trust_discovered_hooks); @@ -1619,9 +1604,8 @@ async fn resumed_thread_keeps_stop_continuation_prompt_in_history() -> Result<() let mut initial_builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_stop_hook(home, &[FIRST_CONTINUATION_PROMPT]) { - panic!("failed to write stop hook test fixture: {error}"); - } + write_stop_hook(home, &[FIRST_CONTINUATION_PROMPT]) + .expect("failed to write stop hook test fixture"); }) .with_config(trust_discovered_hooks); let initial = initial_builder.build(&server).await?; @@ -1685,12 +1669,11 @@ async fn multiple_blocking_stop_hooks_persist_multiple_hook_prompt_fragments() - let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_parallel_stop_hooks( + write_parallel_stop_hooks( home, &[FIRST_CONTINUATION_PROMPT, SECOND_CONTINUATION_PROMPT], - ) { - panic!("failed to write parallel stop hook fixtures: {error}"); - } + ) + .expect("failed to write parallel stop hook fixtures"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -1739,11 +1722,8 @@ async fn blocked_user_prompt_submit_persists_additional_context_for_next_turn() let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_user_prompt_submit_hook(home, "blocked first prompt", BLOCKED_PROMPT_CONTEXT) - { - panic!("failed to write user prompt submit hook test fixture: {error}"); - } + write_user_prompt_submit_hook(home, "blocked first prompt", BLOCKED_PROMPT_CONTEXT) + .expect("failed to write user prompt submit hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -1841,11 +1821,8 @@ async fn blocked_queued_prompt_does_not_strand_earlier_accepted_prompt() -> Resu let mut builder = test_codex() .with_model("gpt-5.4") .with_pre_build_hook(|home| { - if let Err(error) = - write_user_prompt_submit_hook(home, "blocked queued prompt", BLOCKED_PROMPT_CONTEXT) - { - panic!("failed to write user prompt submit hook test fixture: {error}"); - } + write_user_prompt_submit_hook(home, "blocked queued prompt", BLOCKED_PROMPT_CONTEXT) + .expect("failed to write user prompt submit hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build_with_streaming_server(&server).await?; @@ -1994,9 +1971,8 @@ async fn permission_request_hook_allows_shell_command_without_user_approval() -> let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = install_allow_permission_request_hook(home) { - panic!("failed to write permission request hook test fixture: {error}"); - } + install_allow_permission_request_hook(home) + .expect("failed to write permission request hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -2069,14 +2045,13 @@ async fn permission_request_hook_allows_apply_patch_with_write_alias() -> Result let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_permission_request_hook( + write_permission_request_hook( home, Some("^Write$"), "allow", PERMISSION_REQUEST_ALLOW_REASON, - ) { - panic!("failed to write permission request hook test fixture: {error}"); - } + ) + .expect("failed to write permission request hook test fixture"); }) .with_config(|config| { trust_discovered_hooks(config); @@ -2147,9 +2122,8 @@ async fn permission_request_hook_sees_raw_exec_command_input() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = install_allow_permission_request_hook(home) { - panic!("failed to write permission request hook test fixture: {error}"); - } + install_allow_permission_request_hook(home) + .expect("failed to write permission request hook test fixture"); }) .with_config(|config| { config.use_experimental_unified_exec_tool = true; @@ -2232,9 +2206,8 @@ allow_local_binding = true let test = test_codex() .with_home(Arc::clone(&home)) .with_pre_build_hook(|home| { - if let Err(error) = install_allow_permission_request_hook(home) { - panic!("failed to write permission request hook test fixture: {error}"); - } + install_allow_permission_request_hook(home) + .expect("failed to write permission request hook test fixture"); }) .with_cloud_config_bundle(managed_network_requirements_loader()) .with_config(move |config| { @@ -2343,9 +2316,8 @@ async fn permission_request_hook_sees_retry_context_after_sandbox_denial() -> Re let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = install_allow_permission_request_hook(home) { - panic!("failed to write permission request hook test fixture: {error}"); - } + install_allow_permission_request_hook(home) + .expect("failed to write permission request hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -2408,11 +2380,8 @@ async fn pre_tool_use_blocks_shell_command_before_execution() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_pre_tool_use_hook(home, Some("^Bash$"), "json_deny", "blocked by pre hook") - { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^Bash$"), "json_deny", "blocked by pre hook") + .expect("failed to write pre tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -2505,11 +2474,8 @@ async fn pre_tool_use_records_additional_context_for_shell_command() -> Result<( let pre_context = "Remember the bash pre-tool note."; let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_pre_tool_use_hook(home, Some("^Bash$"), "context", pre_context) - { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^Bash$"), "context", pre_context) + .expect("failed to write pre tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -2571,11 +2537,8 @@ async fn blocked_pre_tool_use_records_additional_context_for_shell_command() -> let pre_context = "blocked by pre hook with context"; let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_pre_tool_use_hook(home, Some("^Bash$"), "json_deny_with_context", pre_context) - { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^Bash$"), "json_deny_with_context", pre_context) + .expect("failed to write pre tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -2663,9 +2626,10 @@ impl BashRewriteSurface { trust_discovered_hooks(config); if matches!(self, BashRewriteSurface::ExecCommand) { config.use_experimental_unified_exec_tool = true; - if let Err(error) = config.features.enable(Feature::UnifiedExec) { - panic!("test config should allow feature update: {error}"); - } + config + .features + .enable(Feature::UnifiedExec) + .expect("test config should allow feature update"); } } } @@ -2700,9 +2664,8 @@ async fn assert_pre_tool_use_rewrites_bash_surface(surface: BashRewriteSurface) let updated_input = serde_json::json!({ "command": rewritten_command }); let mut builder = test_codex() .with_pre_build_hook(move |home| { - if let Err(error) = write_updating_pre_tool_use_hook(home, "^Bash$", &updated_input) { - panic!("failed to write updating pre tool use hook fixture: {error}"); - } + write_updating_pre_tool_use_hook(home, "^Bash$", &updated_input) + .expect("failed to write updating pre tool use hook fixture"); }) .with_config(move |config| surface.configure(config)); let test = builder.build(&server).await?; @@ -2795,9 +2758,8 @@ text(output.output); let mut builder = test_codex() .with_model("test-gpt-5.1-codex") .with_pre_build_hook(move |home| { - if let Err(error) = write_updating_pre_tool_use_hook(home, "^Bash$", &updated_input) { - panic!("failed to write updating pre tool use hook fixture: {error}"); - } + write_updating_pre_tool_use_hook(home, "^Bash$", &updated_input) + .expect("failed to write updating pre tool use hook fixture"); }) .with_config(|config| { let _ = config.features.enable(Feature::CodeMode); @@ -2881,9 +2843,8 @@ try {{ let mut builder = test_codex() .with_model("test-gpt-5.1-codex") .with_pre_build_hook(move |home| { - if let Err(error) = write_pre_tool_use_hook(home, Some("^Bash$"), "json_deny", reason) { - panic!("failed to write blocking pre tool use hook fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^Bash$"), "json_deny", reason) + .expect("failed to write blocking pre tool use hook fixture"); }) .with_config(|config| { let _ = config.features.enable(Feature::CodeMode); @@ -2961,9 +2922,8 @@ try {{ let mut builder = test_codex() .with_model("test-gpt-5.1-codex") .with_pre_build_hook(move |home| { - if let Err(error) = write_post_tool_use_hook(home, Some("^Bash$"), hook_mode, reason) { - panic!("failed to write blocking post tool use hook fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^Bash$"), hook_mode, reason) + .expect("failed to write blocking post tool use hook fixture"); }) .with_config(|config| { let _ = config.features.enable(Feature::CodeMode); @@ -3203,16 +3163,15 @@ async fn pre_tool_use_blocks_shell_when_defined_in_config_toml() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_pre_tool_use_hook_toml( + write_pre_tool_use_hook_toml( home, "pre_tool_use_config_hook.py", "pre_tool_use_config_hook_log.jsonl", Some("^Bash$"), "json_deny", "blocked by config toml hook", - ) { - panic!("failed to write config.toml hook test fixture: {error}"); - } + ) + .expect("failed to write config.toml hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -3287,19 +3246,17 @@ async fn pre_tool_use_merges_hooks_json_and_config_toml() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_pre_tool_use_hook(home, Some("^Bash$"), "allow", "unused") { - panic!("failed to write hooks.json hook fixture: {error}"); - } - if let Err(error) = write_pre_tool_use_hook_toml( + write_pre_tool_use_hook(home, Some("^Bash$"), "allow", "unused") + .expect("failed to write hooks.json hook fixture"); + write_pre_tool_use_hook_toml( home, "pre_tool_use_toml_hook.py", "pre_tool_use_toml_hook_log.jsonl", Some("^Bash$"), "allow", "unused", - ) { - panic!("failed to write config.toml hook fixture: {error}"); - } + ) + .expect("failed to write config.toml hook fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -3391,11 +3348,8 @@ async fn pre_tool_use_blocks_exec_command_before_execution() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_pre_tool_use_hook(home, Some("^Bash$"), "exit_2", "blocked exec command") - { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^Bash$"), "exit_2", "blocked exec command") + .expect("failed to write pre tool use hook test fixture"); }) .with_config(|config| { config.use_experimental_unified_exec_tool = true; @@ -3475,14 +3429,13 @@ async fn pre_tool_use_blocks_apply_patch_before_execution() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_pre_tool_use_hook( + write_pre_tool_use_hook( home, Some("^apply_patch$"), "json_deny", "blocked apply_patch", - ) { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + ) + .expect("failed to write pre tool use hook test fixture"); }) .with_config(|config| { trust_discovered_hooks(config); @@ -3556,11 +3509,8 @@ async fn pre_tool_use_rewrites_apply_patch_before_execution() -> Result<()> { let updated_input = serde_json::json!({ "command": rewritten_patch }); let mut builder = test_codex() .with_pre_build_hook(move |home| { - if let Err(error) = - write_updating_pre_tool_use_hook(home, "^apply_patch$", &updated_input) - { - panic!("failed to write updating pre tool use hook fixture: {error}"); - } + write_updating_pre_tool_use_hook(home, "^apply_patch$", &updated_input) + .expect("failed to write updating pre tool use hook fixture"); }) .with_config(|config| { trust_discovered_hooks(config); @@ -3621,11 +3571,8 @@ async fn pre_tool_use_blocks_apply_patch_with_write_alias() -> Result<()> { let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_pre_tool_use_hook(home, Some("^Write$"), "json_deny", "blocked write alias") - { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^Write$"), "json_deny", "blocked write alias") + .expect("failed to write pre tool use hook test fixture"); }) .with_config(|config| { trust_discovered_hooks(config); @@ -3688,11 +3635,8 @@ async fn pre_tool_use_blocks_local_function_tool_before_execution() -> Result<() let mut builder = test_codex() .with_model("test-gpt-5.1-codex") .with_pre_build_hook(|home| { - if let Err(error) = - write_pre_tool_use_hook(home, Some("^test_sync_tool$"), "json_deny", reason) - { - panic!("failed to write pre tool use hook test fixture: {error}"); - } + write_pre_tool_use_hook(home, Some("^test_sync_tool$"), "json_deny", reason) + .expect("failed to write pre tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -3761,11 +3705,8 @@ async fn pre_tool_use_rewrites_local_function_tool_before_execution() -> Result< let mut builder = test_codex() .with_model("test-gpt-5.1-codex") .with_pre_build_hook(move |home| { - if let Err(error) = - write_updating_pre_tool_use_hook(home, "^test_sync_tool$", &updated_input) - { - panic!("failed to write updating pre tool use hook test fixture: {error}"); - } + write_updating_pre_tool_use_hook(home, "^test_sync_tool$", &updated_input) + .expect("failed to write updating pre tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -3821,11 +3762,8 @@ async fn post_tool_use_records_additional_context_for_shell_command() -> Result< let post_context = "Remember the bash post-tool note."; let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_post_tool_use_hook(home, Some("^Bash$"), "context", post_context) - { - panic!("failed to write post tool use hook test fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^Bash$"), "context", post_context) + .expect("failed to write post tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -3913,11 +3851,8 @@ async fn post_tool_use_block_decision_replaces_shell_command_output_with_reason( let reason = "bash output looked sketchy"; let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_post_tool_use_hook(home, Some("^Bash$"), "decision_block", reason) - { - panic!("failed to write post tool use hook test fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^Bash$"), "decision_block", reason) + .expect("failed to write post tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -3977,11 +3912,8 @@ async fn post_tool_use_continue_false_replaces_shell_command_output_with_stop_re let stop_reason = "Execution halted by post-tool hook"; let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_post_tool_use_hook(home, Some("^Bash$"), "continue_false", stop_reason) - { - panic!("failed to write post tool use hook test fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^Bash$"), "continue_false", stop_reason) + .expect("failed to write post tool use hook test fixture"); }) .with_config(trust_discovered_hooks); let test = builder.build(&server).await?; @@ -4040,11 +3972,8 @@ async fn post_tool_use_exit_two_replaces_one_shot_exec_command_output_with_feedb let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_post_tool_use_hook(home, Some("^Bash$"), "exit_2", "blocked by post hook") - { - panic!("failed to write post tool use hook test fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^Bash$"), "exit_2", "blocked by post hook") + .expect("failed to write post tool use hook test fixture"); }) .with_config(|config| { config.use_experimental_unified_exec_tool = true; @@ -4114,11 +4043,8 @@ async fn post_tool_use_spills_large_feedback_message() -> Result<()> { .with_pre_build_hook({ let feedback = feedback.clone(); move |home| { - if let Err(error) = - write_post_tool_use_hook(home, Some("^Bash$"), "exit_2", &feedback) - { - panic!("failed to write post tool use hook test fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^Bash$"), "exit_2", &feedback) + .expect("failed to write post tool use hook test fixture"); } }) .with_config(|config| { @@ -4202,9 +4128,8 @@ async fn post_tool_use_blocks_when_exec_session_completes_via_write_stdin() -> R let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_logging_pre_and_blocking_post_tool_use_hooks(home, feedback) { - panic!("failed to write tool use hook test fixture: {error}"); - } + write_logging_pre_and_blocking_post_tool_use_hooks(home, feedback) + .expect("failed to write tool use hook test fixture"); }) .with_config(|config| { config.use_experimental_unified_exec_tool = true; @@ -4284,11 +4209,8 @@ async fn post_tool_use_records_additional_context_for_apply_patch() -> Result<() let post_context = "Remember the apply_patch post-tool note."; let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_post_tool_use_hook(home, Some("^apply_patch$"), "context", post_context) - { - panic!("failed to write post tool use hook test fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^apply_patch$"), "context", post_context) + .expect("failed to write post tool use hook test fixture"); }) .with_config(|config| { trust_discovered_hooks(config); @@ -4358,11 +4280,8 @@ async fn post_tool_use_records_apply_patch_context_with_edit_alias() -> Result<( let post_context = "Remember the edit alias post-tool note."; let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_post_tool_use_hook(home, Some("^Edit$"), "context", post_context) - { - panic!("failed to write post tool use hook test fixture: {error}"); - } + write_post_tool_use_hook(home, Some("^Edit$"), "context", post_context) + .expect("failed to write post tool use hook test fixture"); }) .with_config(|config| { trust_discovered_hooks(config); diff --git a/codex-rs/core/tests/suite/hooks_mcp.rs b/codex-rs/core/tests/suite/hooks_mcp.rs index 00f1546a7..db35577b0 100644 --- a/codex-rs/core/tests/suite/hooks_mcp.rs +++ b/codex-rs/core/tests/suite/hooks_mcp.rs @@ -207,9 +207,10 @@ fn insert_rmcp_test_server(config: &mut Config, command: String, approval_mode: tools: HashMap::new(), }, ); - if let Err(err) = config.mcp_servers.set(servers) { - panic!("test mcp servers should accept any configuration: {err}"); - } + config + .mcp_servers + .set(servers) + .expect("test mcp servers should accept any configuration"); } fn enable_hooks_and_rmcp_server( @@ -271,9 +272,8 @@ async fn pre_tool_use_blocks_mcp_tool_before_execution( let rmcp_test_server_bin = stdio_server_bin()?; let test = test_codex() .with_pre_build_hook(move |home| { - if let Err(error) = write_pre_tool_use_hook(home, block_reason) { - panic!("failed to write MCP pre tool use hook fixture: {error}"); - } + write_pre_tool_use_hook(home, block_reason) + .expect("failed to write MCP pre tool use hook fixture"); }) .with_config(move |config| { enable_hooks_and_rmcp_server( @@ -293,9 +293,10 @@ async fn pre_tool_use_blocks_mcp_tool_before_execution( let requests = responses.requests(); assert_eq!(requests.len(), 2); let output_item = requests[1].function_call_output(call_id); - let Some(output) = output_item.get("output").and_then(Value::as_str) else { - panic!("blocked MCP tool output should be a string: {output_item:?}"); - }; + let output = output_item + .get("output") + .and_then(Value::as_str) + .expect("blocked MCP tool output should be a string"); assert!( output.contains(&format!( "Tool call blocked by PreToolUse hook: {block_reason}. Tool: {RMCP_ECHO_TOOL_NAME}" @@ -319,12 +320,9 @@ async fn pre_tool_use_blocks_mcp_tool_before_execution( "tool_input": { "message": RMCP_ECHO_MESSAGE }, }) ); - let Some(transcript_path) = hook_inputs[0]["transcript_path"].as_str() else { - panic!( - "pre tool use hook transcript_path should be a string: {:?}", - hook_inputs[0]["transcript_path"] - ); - }; + let transcript_path = hook_inputs[0]["transcript_path"] + .as_str() + .expect("pre tool use hook transcript_path should be a string"); assert!( Path::new(transcript_path).exists(), "pre tool use hook transcript_path should be materialized on disk", @@ -363,9 +361,8 @@ async fn pre_tool_use_rewrites_mcp_tool_before_execution() -> Result<()> { let rmcp_test_server_bin = stdio_server_bin()?; let test = test_codex() .with_pre_build_hook(move |home| { - if let Err(error) = write_updating_pre_tool_use_hook(home, rewritten_message) { - panic!("failed to write MCP updating pre tool use hook fixture: {error}"); - } + write_updating_pre_tool_use_hook(home, rewritten_message) + .expect("failed to write MCP updating pre tool use hook fixture"); }) .with_config(move |config| { enable_hooks_and_rmcp_server( @@ -384,9 +381,10 @@ async fn pre_tool_use_rewrites_mcp_tool_before_execution() -> Result<()> { let final_request = final_mock.single_request(); let output_item = final_request.function_call_output(call_id); - let Some(output) = output_item.get("output").and_then(Value::as_str) else { - panic!("MCP tool output should be a string: {output_item:?}"); - }; + let output = output_item + .get("output") + .and_then(Value::as_str) + .expect("MCP tool output should be a string"); assert!( output.contains(&format!("ECHOING: {rewritten_message}")), "MCP tool should execute the rewritten input", @@ -460,9 +458,8 @@ async fn post_tool_use_records_mcp_tool_payload_and_context( let rmcp_test_server_bin = stdio_server_bin()?; let test = test_codex() .with_pre_build_hook(move |home| { - if let Err(error) = write_post_tool_use_hook(home, post_context) { - panic!("failed to write MCP post tool use hook fixture: {error}"); - } + write_post_tool_use_hook(home, post_context) + .expect("failed to write MCP post tool use hook fixture"); }) .with_config(move |config| { enable_hooks_and_rmcp_server( @@ -487,9 +484,10 @@ async fn post_tool_use_records_mcp_tool_payload_and_context( "follow-up request should include MCP post tool use additional context", ); let output_item = final_request.function_call_output(call_id); - let Some(output) = output_item.get("output").and_then(Value::as_str) else { - panic!("MCP tool output should be a string: {output_item:?}"); - }; + let output = output_item + .get("output") + .and_then(Value::as_str) + .expect("MCP tool output should be a string"); assert!( output.contains(&format!("ECHOING: {RMCP_ECHO_MESSAGE}")), "MCP tool output should still reach the model", @@ -520,12 +518,9 @@ async fn post_tool_use_records_mcp_tool_payload_and_context( }, }) ); - let Some(transcript_path) = hook_inputs[0]["transcript_path"].as_str() else { - panic!( - "post tool use hook transcript_path should be a string: {:?}", - hook_inputs[0]["transcript_path"] - ); - }; + let transcript_path = hook_inputs[0]["transcript_path"] + .as_str() + .expect("post tool use hook transcript_path should be a string"); assert!( Path::new(transcript_path).exists(), "post tool use hook transcript_path should be materialized on disk", diff --git a/codex-rs/core/tests/suite/live_cli.rs b/codex-rs/core/tests/suite/live_cli.rs index 6273cd15e..334ef4563 100644 --- a/codex-rs/core/tests/suite/live_cli.rs +++ b/codex-rs/core/tests/suite/live_cli.rs @@ -1,5 +1,3 @@ -#![expect(clippy::expect_used)] - //! Optional smoke tests that hit the real OpenAI /v1/responses endpoint. They are `#[ignore]` by //! default so CI stays deterministic and free. Developers can run them locally with //! `just test -p codex-core --test all --run-ignored only live_cli` provided they set a valid diff --git a/codex-rs/core/tests/suite/mcp_turn_metadata.rs b/codex-rs/core/tests/suite/mcp_turn_metadata.rs index 21b277bca..7fe0a95f4 100644 --- a/codex-rs/core/tests/suite/mcp_turn_metadata.rs +++ b/codex-rs/core/tests/suite/mcp_turn_metadata.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use codex_config::types::AppToolApproval; diff --git a/codex-rs/core/tests/suite/model_visible_layout.rs b/codex-rs/core/tests/suite/model_visible_layout.rs index 15501148d..ba20da039 100644 --- a/codex-rs/core/tests/suite/model_visible_layout.rs +++ b/codex-rs/core/tests/suite/model_visible_layout.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - use core_test_support::test_codex::local_selections; use std::fs; use std::sync::Arc; diff --git a/codex-rs/core/tests/suite/openai_file_mcp.rs b/codex-rs/core/tests/suite/openai_file_mcp.rs index a25cc36a8..1f7d26be5 100644 --- a/codex-rs/core/tests/suite/openai_file_mcp.rs +++ b/codex-rs/core/tests/suite/openai_file_mcp.rs @@ -147,9 +147,8 @@ async fn codex_apps_file_params_upload_local_paths_before_mcp_tool_call() -> Res let mut builder = apps_enabled_builder(apps_server.chatgpt_base_url.clone()) .with_pre_build_hook(move |home| { - if let Err(error) = write_post_tool_use_hook(home) { - panic!("failed to write apps file post tool use hook fixture: {error}"); - } + write_post_tool_use_hook(home) + .expect("failed to write apps file post tool use hook fixture"); }) .with_config(move |config| { trust_discovered_hooks(config); @@ -165,14 +164,13 @@ async fn codex_apps_file_params_upload_local_paths_before_mcp_tool_call() -> Res .await?; let requests = mock.requests(); - let Some(extract_tool) = - requests[0].tool_by_name(DOCUMENT_EXTRACT_NAMESPACE, DOCUMENT_EXTRACT_TOOL) - else { - let body = requests[0].body_json(); - panic!( - "missing tool {DOCUMENT_EXTRACT_NAMESPACE}{DOCUMENT_EXTRACT_TOOL} in /v1/responses request: {body:?}" - ) - }; + let body = requests[0].body_json(); + let missing_tool_message = format!( + "missing tool {DOCUMENT_EXTRACT_NAMESPACE}{DOCUMENT_EXTRACT_TOOL} in /v1/responses request: {body:?}" + ); + let extract_tool = requests[0] + .tool_by_name(DOCUMENT_EXTRACT_NAMESPACE, DOCUMENT_EXTRACT_TOOL) + .expect(&missing_tool_message); assert_eq!( extract_tool.pointer("/parameters/properties/file"), Some(&json!({ diff --git a/codex-rs/core/tests/suite/pending_input.rs b/codex-rs/core/tests/suite/pending_input.rs index 6736ebc8b..269beae63 100644 --- a/codex-rs/core/tests/suite/pending_input.rs +++ b/codex-rs/core/tests/suite/pending_input.rs @@ -122,7 +122,7 @@ async fn build_codex(server: &StreamingSseServer) -> Arc { .with_model("gpt-5.4") .build_with_streaming_server(server) .await - .unwrap_or_else(|err| panic!("build streaming Codex test session: {err}")) + .expect("build streaming Codex test session") .codex } @@ -139,7 +139,7 @@ async fn submit_user_input(codex: &CodexThread, text: &str) { thread_settings: Default::default(), }) .await - .unwrap_or_else(|err| panic!("submit user input: {err}")); + .expect("submit user input"); } async fn submit_danger_full_access_user_turn(test: &TestCodex, text: &str) { @@ -171,7 +171,7 @@ async fn submit_danger_full_access_user_turn(test: &TestCodex, text: &str) { }, }) .await - .unwrap_or_else(|err| panic!("submit user turn: {err}")); + .expect("submit user turn"); } async fn steer_user_input(codex: &CodexThread, text: &str) { @@ -187,15 +187,14 @@ async fn steer_user_input(codex: &CodexThread, text: &str) { /*responsesapi_client_metadata*/ None, ) .await - .unwrap_or_else(|err| panic!("steer user input: {err:?}")); + .expect("steer user input"); } async fn submit_queue_only_agent_mail(codex: &CodexThread, text: &str) { codex .submit(Op::InterAgentCommunication { communication: InterAgentCommunication::new( - AgentPath::try_from("/root/worker") - .unwrap_or_else(|err| panic!("worker path should parse: {err}")), + AgentPath::try_from("/root/worker").expect("worker path should parse"), AgentPath::root(), Vec::new(), text.to_string(), @@ -203,11 +202,11 @@ async fn submit_queue_only_agent_mail(codex: &CodexThread, text: &str) { ), }) .await - .unwrap_or_else(|err| panic!("submit queue-only agent mail: {err}")); + .expect("submit queue-only agent mail"); codex .submit(Op::RealtimeConversationListVoices) .await - .unwrap_or_else(|err| panic!("submit list-voices barrier: {err}")); + .expect("submit list-voices barrier"); wait_for_event(codex, |event| { matches!(event, EventMsg::RealtimeConversationListVoicesResponse(_)) }) @@ -459,17 +458,15 @@ async fn any_new_input_interrupts_sleep() { fn assert_two_responses_input_snapshot(snapshot_name: &str, requests: &[Vec]) { assert_eq!(requests.len(), 2); let options = ContextSnapshotOptions::default().strip_capability_instructions(); - let first: Value = - from_slice(&requests[0]).unwrap_or_else(|err| panic!("parse first request: {err}")); - let second: Value = - from_slice(&requests[1]).unwrap_or_else(|err| panic!("parse second request: {err}")); + let first: Value = from_slice(&requests[0]).expect("parse first request"); + let second: Value = from_slice(&requests[1]).expect("parse second request"); let first_items = first["input"] .as_array() - .unwrap_or_else(|| panic!("first request input")) + .expect("first request input") .clone(); let second_items = second["input"] .as_array() - .unwrap_or_else(|| panic!("second request input")) + .expect("second request input") .clone(); let snapshot = context_snapshot::format_labeled_items_snapshot( "/responses POST bodies (input only, redacted like other suite snapshots)", @@ -807,7 +804,7 @@ async fn steered_user_input_waits_for_model_continuation_after_mid_turn_compact( }) .build_with_streaming_server(&server) .await - .unwrap_or_else(|err| panic!("build streaming Codex test session: {err}")) + .expect("build streaming Codex test session") .codex; submit_user_input(&codex, "first prompt").await; @@ -819,10 +816,8 @@ async fn steered_user_input_waits_for_model_continuation_after_mid_turn_compact( let requests = server.requests().await; assert_eq!(requests.len(), 4); - let post_compact_body: Value = - from_slice(&requests[2]).unwrap_or_else(|err| panic!("parse post-compact request: {err}")); - let steered_body: Value = - from_slice(&requests[3]).unwrap_or_else(|err| panic!("parse steered request: {err}")); + let post_compact_body: Value = from_slice(&requests[2]).expect("parse post-compact request"); + let steered_body: Value = from_slice(&requests[3]).expect("parse steered request"); let post_compact_user_texts = message_input_texts(&post_compact_body, "user"); assert!( @@ -894,7 +889,7 @@ async fn steered_user_input_follows_compact_when_only_the_steer_needs_follow_up( }) .build_with_streaming_server(&server) .await - .unwrap_or_else(|err| panic!("build streaming Codex test session: {err}")) + .expect("build streaming Codex test session") .codex; submit_user_input(&codex, "first prompt").await; @@ -908,10 +903,8 @@ async fn steered_user_input_follows_compact_when_only_the_steer_needs_follow_up( let requests = server.requests().await; assert_eq!(requests.len(), 3); - let compact_body: Value = - from_slice(&requests[1]).unwrap_or_else(|err| panic!("parse compact request: {err}")); - let steered_body: Value = - from_slice(&requests[2]).unwrap_or_else(|err| panic!("parse steered request: {err}")); + let compact_body: Value = from_slice(&requests[1]).expect("parse compact request"); + let steered_body: Value = from_slice(&requests[2]).expect("parse steered request"); let compact_user_texts = message_input_texts(&compact_body, "user"); assert!( @@ -1013,7 +1006,7 @@ async fn steered_user_input_waits_when_tool_output_triggers_compact_before_next_ }) .build_with_streaming_server(&server) .await - .unwrap_or_else(|err| panic!("build streaming Codex test session: {err}")); + .expect("build streaming Codex test session"); let codex = test.codex.clone(); submit_danger_full_access_user_turn(&test, "first prompt").await; @@ -1026,12 +1019,9 @@ async fn steered_user_input_waits_when_tool_output_triggers_compact_before_next_ let requests = server.requests().await; assert_eq!(requests.len(), 4); - let compact_body: Value = - from_slice(&requests[1]).unwrap_or_else(|err| panic!("parse compact request: {err}")); - let post_compact_body: Value = - from_slice(&requests[2]).unwrap_or_else(|err| panic!("parse post-compact request: {err}")); - let steered_body: Value = - from_slice(&requests[3]).unwrap_or_else(|err| panic!("parse steered request: {err}")); + let compact_body: Value = from_slice(&requests[1]).expect("parse compact request"); + let post_compact_body: Value = from_slice(&requests[2]).expect("parse post-compact request"); + let steered_body: Value = from_slice(&requests[3]).expect("parse steered request"); let compact_user_texts = message_input_texts(&compact_body, "user"); assert!( diff --git a/codex-rs/core/tests/suite/plugins.rs b/codex-rs/core/tests/suite/plugins.rs index f13c2302f..198db86d8 100644 --- a/codex-rs/core/tests/suite/plugins.rs +++ b/codex-rs/core/tests/suite/plugins.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use std::sync::Arc; use std::time::Duration; diff --git a/codex-rs/core/tests/suite/prompt_caching.rs b/codex-rs/core/tests/suite/prompt_caching.rs index 809cb0ea3..a45551232 100644 --- a/codex-rs/core/tests/suite/prompt_caching.rs +++ b/codex-rs/core/tests/suite/prompt_caching.rs @@ -36,7 +36,7 @@ use tempfile::TempDir; fn write_global_instructions(home: &Path) { fs::write(home.join("AGENTS.md"), "be consistent and helpful") - .unwrap_or_else(|err| panic!("write global instructions: {err}")); + .expect("write global instructions"); } fn text_user_input(text: String) -> serde_json::Value { diff --git a/codex-rs/core/tests/suite/realtime_conversation.rs b/codex-rs/core/tests/suite/realtime_conversation.rs index 1a5d4d7fa..61fc38e8b 100644 --- a/codex-rs/core/tests/suite/realtime_conversation.rs +++ b/codex-rs/core/tests/suite/realtime_conversation.rs @@ -14,7 +14,6 @@ use codex_protocol::protocol::ConversationStartParams; use codex_protocol::protocol::ConversationStartTransport; use codex_protocol::protocol::ConversationTextParams; use codex_protocol::protocol::ConversationTextRole; -use codex_protocol::protocol::ErrorEvent; use codex_protocol::protocol::EventMsg; use codex_protocol::protocol::InitialHistory; use codex_protocol::protocol::Op; @@ -304,7 +303,7 @@ async fn conversation_start_audio_text_close_round_trip() -> Result<()> { _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation start failed: {err:?}")); + .expect("conversation start failed"); assert!(started.realtime_session_id.is_some()); assert_eq!(started.version, RealtimeConversationVersion::V1); @@ -449,7 +448,7 @@ async fn conversation_start_defaults_to_v2_and_gpt_realtime_1_5() -> Result<()> _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation start failed: {err:?}")); + .expect("conversation start failed"); assert!( realtime_server @@ -547,7 +546,7 @@ async fn conversation_webrtc_start_posts_generated_session() -> Result<()> { _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation call create failed: {err:?}")); + .expect("conversation call create failed"); assert_eq!(created.sdp, "v=answer\r\n"); assert!( realtime_server.handshakes().is_empty(), @@ -728,7 +727,7 @@ async fn conversation_webrtc_start_uses_avas_architecture_query() -> Result<()> _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation call create failed: {err:?}")); + .expect("conversation call create failed"); assert_eq!(created.sdp, "v=answer\r\n"); let request = capture.single_request(); @@ -829,7 +828,7 @@ async fn conversation_webrtc_start_uses_configured_call_base_url_for_avas() -> R _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation call create failed: {err:?}")); + .expect("conversation call create failed"); assert_eq!(created.sdp, "v=answer\r\n"); let request = capture.single_request(); @@ -1102,7 +1101,7 @@ async fn conversation_start_uses_openai_env_key_fallback_with_chatgpt_auth() -> _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation start failed: {err:?}")); + .expect("conversation start failed"); assert!(started.realtime_session_id.is_some()); let session_updated = wait_for_event_match(&test.codex, |msg| match msg { @@ -1174,7 +1173,7 @@ async fn conversation_transport_close_emits_closed_event() -> Result<()> { _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("conversation start failed: {err:?}")); + .expect("conversation start failed"); assert!(started.realtime_session_id.is_some()); let session_updated = wait_for_event_match(&test.codex, |msg| match msg { @@ -1423,7 +1422,7 @@ async fn conversation_second_start_replaces_runtime() -> Result<()> { _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("first conversation start failed: {err:?}")); + .expect("first conversation start failed"); test.codex .submit(Op::RealtimeConversationStart(ConversationStartParams { @@ -1452,7 +1451,7 @@ async fn conversation_second_start_replaces_runtime() -> Result<()> { _ => None, }) .await - .unwrap_or_else(|err: ErrorEvent| panic!("second conversation start failed: {err:?}")); + .expect("second conversation start failed"); test.codex .submit(Op::RealtimeConversationAudio(ConversationAudioParams { diff --git a/codex-rs/core/tests/suite/remote_env.rs b/codex-rs/core/tests/suite/remote_env.rs index d0a0916f3..311485c11 100644 --- a/codex-rs/core/tests/suite/remote_env.rs +++ b/codex-rs/core/tests/suite/remote_env.rs @@ -229,10 +229,7 @@ async fn remote_test_env_exposes_target_shell_to_model() -> Result<()> { } fn absolute_path(path: PathBuf) -> AbsolutePathBuf { - match AbsolutePathBuf::try_from(path) { - Ok(path) => path, - Err(error) => panic!("path should be absolute: {error}"), - } + AbsolutePathBuf::try_from(path).expect("path should be absolute") } fn read_only_sandbox(readable_root: PathBuf) -> FileSystemSandboxContext { diff --git a/codex-rs/core/tests/suite/remote_models.rs b/codex-rs/core/tests/suite/remote_models.rs index b3fc9b9db..b63aff540 100644 --- a/codex-rs/core/tests/suite/remote_models.rs +++ b/codex-rs/core/tests/suite/remote_models.rs @@ -1,5 +1,4 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used)] use anyhow::Result; use codex_login::CodexAuth; use codex_model_provider_info::ModelProviderInfo; @@ -1166,8 +1165,7 @@ async fn wait_for_model_available(manager: &SharedModelsManager, slug: &str) -> } fn bundled_model_slug() -> String { - let response = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let response = bundled_models_response().expect("bundled models.json should parse"); response .models .first() diff --git a/codex-rs/core/tests/suite/request_permissions.rs b/codex-rs/core/tests/suite/request_permissions.rs index f78ccf1ac..1b0458284 100644 --- a/codex-rs/core/tests/suite/request_permissions.rs +++ b/codex-rs/core/tests/suite/request_permissions.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use codex_core::config::Constrained; @@ -1148,7 +1148,7 @@ async fn request_permissions_grants_apply_to_later_exec_command_calls() -> Resul let exec_output = responses .function_call_output_text("exec-call") .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected exec-call output")); + .expect("expected exec-call output"); let result = parse_result(&exec_output); assert_eq!(result.exit_code, Some(0)); assert_eq!(result.stdout.trim(), "sticky-grant-ok"); @@ -1262,7 +1262,7 @@ async fn request_permissions_preapprove_explicit_exec_permissions_outside_on_req let exec_output = responses .function_call_output_text("exec-call") .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected exec-call output")); + .expect("expected exec-call output"); let result = parse_result(&exec_output); assert!( result.exit_code.is_none_or(|exit_code| exit_code == 0), @@ -1379,7 +1379,7 @@ async fn request_permissions_grants_apply_to_later_shell_command_calls() -> Resu let shell_output = responses .function_call_output_text("shell-call") .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected shell-call output")); + .expect("expected shell-call output"); let result = parse_result(&shell_output); assert!( result.exit_code.is_none_or(|exit_code| exit_code == 0), @@ -1492,7 +1492,7 @@ async fn request_permissions_grants_apply_to_later_shell_command_calls_without_i let shell_output = responses .function_call_output_text("shell-call") .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected shell-call output")); + .expect("expected shell-call output"); let result = parse_result(&shell_output); assert!( result.exit_code.is_none_or(|exit_code| exit_code == 0), @@ -1632,15 +1632,15 @@ async fn partial_request_permissions_grants_do_not_preapprove_new_permissions() let approval_permissions = approval .additional_permissions .clone() - .unwrap_or_else(|| panic!("expected merged additional permissions")); + .expect("expected merged additional permissions"); assert_eq!(approval_permissions.network, None); let approval_file_system = approval_permissions .file_system - .unwrap_or_else(|| panic!("expected filesystem permissions")); + .expect("expected filesystem permissions"); let (approval_reads, approval_writes) = approval_file_system .legacy_read_write_roots() - .unwrap_or_else(|| panic!("expected legacy-compatible permissions")); + .expect("expected legacy-compatible permissions"); assert!(approval_reads.as_ref().is_none_or(Vec::is_empty)); let mut approval_writes = approval_writes.unwrap_or_default(); @@ -1648,9 +1648,9 @@ async fn partial_request_permissions_grants_do_not_preapprove_new_permissions() let (_, expected_writes) = merged_permissions .file_system - .unwrap_or_else(|| panic!("expected merged filesystem permissions")) + .expect("expected merged filesystem permissions") .legacy_read_write_roots() - .unwrap_or_else(|| panic!("expected legacy-compatible permissions")); + .expect("expected legacy-compatible permissions"); let mut expected_writes = expected_writes.unwrap_or_default(); expected_writes.sort_by_key(|path| path.display().to_string()); @@ -1667,7 +1667,7 @@ async fn partial_request_permissions_grants_do_not_preapprove_new_permissions() let exec_output = responses .function_call_output_text("exec-call") .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected exec-call output")); + .expect("expected exec-call output"); let result = parse_result(&exec_output); assert_eq!(result.exit_code, Some(0)); assert_eq!(result.stdout.trim(), "partial-grant-ok"); @@ -1785,7 +1785,7 @@ async fn request_permissions_grants_do_not_carry_across_turns() -> Result<()> { let output = second_turn .function_call_output_text("exec-call") - .unwrap_or_else(|| panic!("expected exec-call output")); + .expect("expected exec-call output"); assert!(output.contains("missing `additional_permissions`")); Ok(()) @@ -1921,7 +1921,7 @@ async fn request_permissions_session_grants_carry_across_turns() -> Result<()> { let exec_output = second_turn .function_call_output_text("exec-call") .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected exec-call output")); + .expect("expected exec-call output"); let result = parse_result(&exec_output); assert_eq!(result.exit_code, Some(0)); assert_eq!(result.stdout.trim(), "session-sticky-ok"); diff --git a/codex-rs/core/tests/suite/request_permissions_tool.rs b/codex-rs/core/tests/suite/request_permissions_tool.rs index dc08160d7..e8434896e 100644 --- a/codex-rs/core/tests/suite/request_permissions_tool.rs +++ b/codex-rs/core/tests/suite/request_permissions_tool.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] #![cfg(target_os = "macos")] use anyhow::Result; @@ -315,7 +315,7 @@ async fn approved_folder_write_request_permissions_unblocks_later_exec_without_s let exec_output = responses .function_call_output_text("exec-call") .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected exec-call output")); + .expect("expected exec-call output"); let (exit_code, stdout) = parse_result(&exec_output); assert!(exit_code.is_none() || exit_code == Some(0)); assert!(stdout.contains("folder-grant-ok")); @@ -498,7 +498,7 @@ async fn apply_patch_after_request_permissions(strict_auto_review: bool) -> Resu }) }) .map(|output| json!({ "output": output })) - .unwrap_or_else(|| panic!("expected apply-patch-call output")); + .expect("expected apply-patch-call output"); let (exit_code, stdout) = parse_result(&patch_output); assert!(exit_code.is_none() || exit_code == Some(0)); assert!( diff --git a/codex-rs/core/tests/suite/request_plugin_install.rs b/codex-rs/core/tests/suite/request_plugin_install.rs index 60db47b2f..b35ecbc22 100644 --- a/codex-rs/core/tests/suite/request_plugin_install.rs +++ b/codex-rs/core/tests/suite/request_plugin_install.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use codex_config::types::ToolSuggestDiscoverable; @@ -72,8 +72,7 @@ fn configure_apps_without_search_tool(config: &mut Config, apps_base_url: &str) .features .enable(Feature::ToolSuggest) .expect("test config should allow feature update"); - let mut model_catalog = bundled_models_response() - .unwrap_or_else(|err| panic!("bundled models.json should parse: {err}")); + let mut model_catalog = bundled_models_response().expect("bundled models.json should parse"); let model = model_catalog .models .iter_mut() diff --git a/codex-rs/core/tests/suite/request_user_input.rs b/codex-rs/core/tests/suite/request_user_input.rs index 88be80c88..1348a8718 100644 --- a/codex-rs/core/tests/suite/request_user_input.rs +++ b/codex-rs/core/tests/suite/request_user_input.rs @@ -43,14 +43,10 @@ fn call_output(req: &ResponsesRequest, call_id: &str) -> String { Some(call_id), "mismatched call_id in function_call_output" ); - let (content_opt, _success) = match req.function_call_output_content_and_success(call_id) { - Some(values) => values, - None => panic!("function_call_output present"), - }; - match content_opt { - Some(content) => content, - None => panic!("function_call_output content present"), - } + let (content_opt, _success) = req + .function_call_output_content_and_success(call_id) + .expect("function_call_output present"); + content_opt.expect("function_call_output content present") } fn call_output_content_and_success( @@ -63,14 +59,10 @@ fn call_output_content_and_success( Some(call_id), "mismatched call_id in function_call_output" ); - let (content_opt, success) = match req.function_call_output_content_and_success(call_id) { - Some(values) => values, - None => panic!("function_call_output present"), - }; - let content = match content_opt { - Some(content) => content, - None => panic!("function_call_output content present"), - }; + let (content_opt, success) = req + .function_call_output_content_and_success(call_id) + .expect("function_call_output present"); + let content = content_opt.expect("function_call_output content present"); (content, success) } @@ -93,7 +85,6 @@ async fn request_user_input_round_trip_for_mode( let server = start_mock_server().await; let builder = test_codex(); - #[allow(clippy::expect_used)] let TestCodex { codex, cwd, @@ -127,9 +118,9 @@ async fn request_user_input_round_trip_for_mode( }] }); if let Some(auto_resolution_ms) = auto_resolution_ms { - let Some(request_args) = request_args.as_object_mut() else { - panic!("request_user_input args should be a JSON object"); - }; + let request_args = request_args + .as_object_mut() + .expect("request_user_input args should be a JSON object"); request_args.insert("autoResolutionMs".to_string(), json!(auto_resolution_ms)); } let request_args = request_args.to_string(); @@ -190,10 +181,10 @@ async fn request_user_input_round_trip_for_mode( assert!( timeout(Duration::from_millis(200), async { loop { - let event = match codex.next_event().await { - Ok(event) => event, - Err(err) => panic!("event stream should stay open: {err}"), - }; + let event = codex + .next_event() + .await + .expect("event stream should stay open"); if matches!(event.msg, EventMsg::TokenCount(_)) { return; } diff --git a/codex-rs/core/tests/suite/resume_warning.rs b/codex-rs/core/tests/suite/resume_warning.rs index 212055975..0ba392298 100644 --- a/codex-rs/core/tests/suite/resume_warning.rs +++ b/codex-rs/core/tests/suite/resume_warning.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use codex_core::NewThread; use codex_login::CodexAuth; diff --git a/codex-rs/core/tests/suite/review.rs b/codex-rs/core/tests/suite/review.rs index 6a3887297..6b0f8552a 100644 --- a/codex-rs/core/tests/suite/review.rs +++ b/codex-rs/core/tests/suite/review.rs @@ -890,7 +890,6 @@ async fn start_responses_server_with_sse( } /// Create a conversation configured to talk to the provided mock server. -#[expect(clippy::expect_used)] async fn new_conversation_for_server( server: &MockServer, codex_home: Arc, @@ -914,7 +913,6 @@ where } /// Create a conversation resuming from a rollout file, configured to talk to the provided mock server. -#[expect(clippy::expect_used)] async fn resume_conversation_for_server( server: &MockServer, codex_home: Arc, diff --git a/codex-rs/core/tests/suite/rmcp_client.rs b/codex-rs/core/tests/suite/rmcp_client.rs index 0c8cd8cb5..2be014b3f 100644 --- a/codex-rs/core/tests/suite/rmcp_client.rs +++ b/codex-rs/core/tests/suite/rmcp_client.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - use anyhow::Context as _; use anyhow::ensure; use base64::Engine; @@ -85,20 +83,18 @@ fn assert_wall_time_line(line: &str) { } fn split_wall_time_wrapped_output(output: &str) -> &str { - let Some((wall_time, rest)) = output.split_once('\n') else { - panic!("wall-time output should contain an Output section: {output}"); - }; + let (wall_time, rest) = output + .split_once('\n') + .expect("wall-time output should contain an Output section"); assert_wall_time_line(wall_time); - let Some(output) = rest.strip_prefix("Output:\n") else { - panic!("wall-time output should contain Output marker: {output}"); - }; - output + rest.strip_prefix("Output:\n") + .expect("wall-time output should contain Output marker") } fn assert_wall_time_header(output: &str) { - let Some((wall_time, marker)) = output.split_once('\n') else { - panic!("wall-time header should contain an Output marker: {output}"); - }; + let (wall_time, marker) = output + .split_once('\n') + .expect("wall-time header should contain an Output marker"); assert_wall_time_line(wall_time); assert_eq!(marker, "Output:"); } @@ -332,9 +328,10 @@ fn insert_mcp_server( tools: HashMap::new(), }, ); - if let Err(err) = config.mcp_servers.set(servers) { - panic!("test mcp servers should accept any configuration: {err}"); - } + config + .mcp_servers + .set(servers) + .expect("test mcp servers should accept any configuration"); } async fn call_cwd_tool( @@ -522,9 +519,9 @@ async fn stdio_server_round_trip() -> anyhow::Result<()> { .structured_content .as_ref() .expect("structured content"); - let Value::Object(map) = structured else { - panic!("structured content should be an object: {structured:?}"); - }; + let map = structured + .as_object() + .expect("structured content should be an object"); let echo_value = map .get("echo") .and_then(Value::as_str) @@ -811,9 +808,9 @@ async fn stdio_mcp_tool_call_includes_sandbox_state_meta() -> anyhow::Result<()> let wrapped_payload = split_wall_time_wrapped_output(output_text); let output_json: Value = serde_json::from_str(wrapped_payload) .expect("wrapped MCP output should preserve sandbox metadata JSON"); - let Value::Object(meta) = output_json else { - panic!("sandbox_meta should return metadata object: {output_json:?}"); - }; + let meta = output_json + .as_object() + .expect("sandbox_meta should return metadata object"); let sandbox_meta = meta .get(MCP_SANDBOX_STATE_META_CAPABILITY) @@ -1748,9 +1745,9 @@ async fn stdio_server_propagates_whitelisted_env_vars() -> anyhow::Result<()> { .structured_content .as_ref() .expect("structured content"); - let Value::Object(map) = structured else { - panic!("structured content should be an object: {structured:?}"); - }; + let map = structured + .as_object() + .expect("structured content should be an object"); let echo_value = map .get("echo") .and_then(Value::as_str) @@ -2162,9 +2159,9 @@ async fn streamable_http_tool_call_round_trip() -> anyhow::Result<()> { .structured_content .as_ref() .expect("structured content"); - let Value::Object(map) = structured else { - panic!("structured content should be an object: {structured:?}"); - }; + let map = structured + .as_object() + .expect("structured content should be an object"); let echo_value = map .get("echo") .and_then(Value::as_str) @@ -2213,7 +2210,6 @@ fn streamable_http_with_oauth_round_trip() -> anyhow::Result<()> { } } -#[allow(clippy::expect_used)] async fn streamable_http_with_oauth_round_trip_impl() -> anyhow::Result<()> { skip_if_no_network!(Ok(())); @@ -2352,9 +2348,9 @@ async fn streamable_http_with_oauth_round_trip_impl() -> anyhow::Result<()> { .structured_content .as_ref() .expect("structured content"); - let Value::Object(map) = structured else { - panic!("structured content should be an object: {structured:?}"); - }; + let map = structured + .as_object() + .expect("structured content should be an object"); let echo_value = map .get("echo") .and_then(Value::as_str) diff --git a/codex-rs/core/tests/suite/rollout_list_find.rs b/codex-rs/core/tests/suite/rollout_list_find.rs index 4ff35449c..680301d9f 100644 --- a/codex-rs/core/tests/suite/rollout_list_find.rs +++ b/codex-rs/core/tests/suite/rollout_list_find.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use std::io::Write; use std::path::Path; use std::path::PathBuf; diff --git a/codex-rs/core/tests/suite/search_tool.rs b/codex-rs/core/tests/suite/search_tool.rs index f2360a730..284ee49b8 100644 --- a/codex-rs/core/tests/suite/search_tool.rs +++ b/codex-rs/core/tests/suite/search_tool.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use codex_config::types::McpServerConfig; @@ -843,9 +843,7 @@ async fn tool_search_returns_deferred_v1_multi_agent_tools() -> Result<()> { ); let output = tool_search_output_item(&requests[1], call_id); let spawn_agent = namespace_child_tool(&output, "multi_agent_v1", "spawn_agent") - .unwrap_or_else(|| { - panic!("expected tool_search to return multi_agent_v1.spawn_agent: {output:?}") - }); + .expect("tool_search should return multi_agent_v1.spawn_agent"); assert_eq!( spawn_agent.get("defer_loading").and_then(Value::as_bool), Some(true) diff --git a/codex-rs/core/tests/suite/shell_command.rs b/codex-rs/core/tests/suite/shell_command.rs index eb545fce0..6c865425f 100644 --- a/codex-rs/core/tests/suite/shell_command.rs +++ b/codex-rs/core/tests/suite/shell_command.rs @@ -38,7 +38,6 @@ fn shell_responses_with_timeout( "login": login, }); - #[allow(clippy::expect_used)] let arguments = serde_json::to_string(&args).expect("serialize shell command arguments"); vec![ diff --git a/codex-rs/core/tests/suite/shell_serialization.rs b/codex-rs/core/tests/suite/shell_serialization.rs index 77a6d153a..47faf4c8b 100644 --- a/codex-rs/core/tests/suite/shell_serialization.rs +++ b/codex-rs/core/tests/suite/shell_serialization.rs @@ -1,5 +1,4 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used)] use anyhow::Result; use codex_protocol::models::PermissionProfile; diff --git a/codex-rs/core/tests/suite/shell_snapshot.rs b/codex-rs/core/tests/suite/shell_snapshot.rs index b6f38b29b..04576f081 100644 --- a/codex-rs/core/tests/suite/shell_snapshot.rs +++ b/codex-rs/core/tests/suite/shell_snapshot.rs @@ -106,12 +106,10 @@ fn command_asserting_policy_after_snapshot() -> String { ) } -#[allow(clippy::expect_used)] async fn run_snapshot_command(command: &str) -> Result { run_snapshot_command_with_options(command, SnapshotRunOptions::default()).await } -#[allow(clippy::expect_used)] async fn run_snapshot_command_with_options( command: &str, options: SnapshotRunOptions, @@ -211,12 +209,10 @@ async fn run_snapshot_command_with_options( }) } -#[allow(clippy::expect_used)] async fn run_shell_command_snapshot(command: &str) -> Result { run_shell_command_snapshot_with_options(command, SnapshotRunOptions::default()).await } -#[allow(clippy::expect_used)] async fn run_shell_command_snapshot_with_options( command: &str, options: SnapshotRunOptions, @@ -311,7 +307,6 @@ async fn run_shell_command_snapshot_with_options( }) } -#[allow(clippy::expect_used)] async fn run_tool_turn_on_harness( harness: &TestCodexHarness, prompt: &str, diff --git a/codex-rs/core/tests/suite/skills.rs b/codex-rs/core/tests/suite/skills.rs index adc0b5ccc..2de9bf26c 100644 --- a/codex-rs/core/tests/suite/skills.rs +++ b/codex-rs/core/tests/suite/skills.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use codex_exec_server::CreateDirectoryOptions; diff --git a/codex-rs/core/tests/suite/spawn_agent_description.rs b/codex-rs/core/tests/suite/spawn_agent_description.rs index cb029ed3a..fb493c1b1 100644 --- a/codex-rs/core/tests/suite/spawn_agent_description.rs +++ b/codex-rs/core/tests/suite/spawn_agent_description.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use codex_features::Feature; diff --git a/codex-rs/core/tests/suite/subagent_notifications.rs b/codex-rs/core/tests/suite/subagent_notifications.rs index 40ac2c797..a78e1fbc0 100644 --- a/codex-rs/core/tests/suite/subagent_notifications.rs +++ b/codex-rs/core/tests/suite/subagent_notifications.rs @@ -410,7 +410,6 @@ async fn setup_turn_one_with_custom_spawned_child( ) .await; - #[allow(clippy::expect_used)] let mut builder = configure_test(test_codex().with_config(|config| { config .features @@ -528,11 +527,8 @@ async fn subagent_start_replaces_session_start_and_injects_context() -> Result<( let test = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = - write_subagent_lifecycle_hooks(home, /*stop_prompts*/ &[], "worker") - { - panic!("failed to write subagent hook fixture: {error}"); - } + write_subagent_lifecycle_hooks(home, /*stop_prompts*/ &[], "worker") + .expect("failed to write subagent hook fixture"); }) .with_config(|config| { trust_discovered_hooks(config); @@ -675,13 +671,12 @@ async fn subagent_stop_replaces_stop_and_skips_internal_subagents() -> Result<() let test = test_codex() .with_pre_build_hook(|home| { - if let Err(error) = write_subagent_lifecycle_hooks( + write_subagent_lifecycle_hooks( home, /*stop_prompts*/ &[SUBAGENT_STOP_CONTINUATION], "", - ) { - panic!("failed to write subagent hook fixture: {error}"); - } + ) + .expect("failed to write subagent hook fixture"); }) .with_config(|config| { trust_discovered_hooks(config); @@ -1260,9 +1255,7 @@ async fn skills_toggle_skips_instructions_for_parent_and_spawned_child() -> Resu let mut builder = test_codex() .with_pre_build_hook(|home| { - if let Err(err) = write_home_skill(home, "demo", "demo-skill", "demo skill") { - panic!("write home skill: {err}"); - } + write_home_skill(home, "demo", "demo-skill", "demo skill").expect("write home skill"); }) .with_config(|config| { config @@ -1394,9 +1387,7 @@ async fn spawn_agent_tool_description_mentions_role_locked_settings() -> Result< assert_eq!(requests.len(), 2); let output = requests[1].tool_search_output(call_id); let spawn_agent = namespace_child_tool(&output, "multi_agent_v1", "spawn_agent") - .unwrap_or_else(|| { - panic!("expected tool_search to return multi_agent_v1.spawn_agent: {output:?}") - }); + .expect("tool_search should return multi_agent_v1.spawn_agent"); let agent_type_description = tool_parameter_description(spawn_agent, "agent_type") .expect("spawn_agent agent_type description"); let custom_role_description = diff --git a/codex-rs/core/tests/suite/tool_harness.rs b/codex-rs/core/tests/suite/tool_harness.rs index 7b3f2a690..963123b59 100644 --- a/codex-rs/core/tests/suite/tool_harness.rs +++ b/codex-rs/core/tests/suite/tool_harness.rs @@ -36,14 +36,10 @@ fn call_output(req: &ResponsesRequest, call_id: &str) -> (String, Option) Some(call_id), "mismatched call_id in function_call_output" ); - let (content_opt, success) = match req.function_call_output_content_and_success(call_id) { - Some(values) => values, - None => panic!("function_call_output present"), - }; - let content = match content_opt { - Some(c) => c, - None => panic!("function_call_output content present"), - }; + let (content_opt, success) = req + .function_call_output_content_and_success(call_id) + .expect("function_call_output present"); + let content = content_opt.expect("function_call_output content present"); (content, success) } @@ -54,14 +50,10 @@ fn custom_call_output(req: &ResponsesRequest, call_id: &str) -> (String, Option< Some(call_id), "mismatched call_id in custom_tool_call_output" ); - let (content_opt, success) = match req.custom_tool_call_output_content_and_success(call_id) { - Some(values) => values, - None => panic!("custom_tool_call_output present"), - }; - let content = match content_opt { - Some(c) => c, - None => panic!("custom_tool_call_output content present"), - }; + let (content_opt, success) = req + .custom_tool_call_output_content_and_success(call_id) + .expect("custom_tool_call_output present"); + let content = content_opt.expect("custom_tool_call_output content present"); (content, success) } diff --git a/codex-rs/core/tests/suite/tool_parallelism.rs b/codex-rs/core/tests/suite/tool_parallelism.rs index 8a9db0680..a11ee5c2e 100644 --- a/codex-rs/core/tests/suite/tool_parallelism.rs +++ b/codex-rs/core/tests/suite/tool_parallelism.rs @@ -75,7 +75,6 @@ async fn run_turn_and_measure(test: &TestCodex, prompt: &str) -> anyhow::Result< Ok(start.elapsed()) } -#[allow(clippy::expect_used)] async fn build_codex_with_test_tool(server: &wiremock::MockServer) -> anyhow::Result { let mut builder = test_codex().with_model("test-gpt-5.1-codex"); builder.build(server).await diff --git a/codex-rs/core/tests/suite/tools.rs b/codex-rs/core/tests/suite/tools.rs index fd19a18c7..83584b8ec 100644 --- a/codex-rs/core/tests/suite/tools.rs +++ b/codex-rs/core/tests/suite/tools.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use std::fs; use std::time::Duration; diff --git a/codex-rs/core/tests/suite/truncation.rs b/codex-rs/core/tests/suite/truncation.rs index 89ce0013e..cc942cbc1 100644 --- a/codex-rs/core/tests/suite/truncation.rs +++ b/codex-rs/core/tests/suite/truncation.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Context; use anyhow::Result; diff --git a/codex-rs/core/tests/suite/turn_state.rs b/codex-rs/core/tests/suite/turn_state.rs index 6a9c70714..8eda5bc44 100644 --- a/codex-rs/core/tests/suite/turn_state.rs +++ b/codex-rs/core/tests/suite/turn_state.rs @@ -1,4 +1,4 @@ -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use anyhow::Result; use core_test_support::responses::WebSocketConnectionConfig; diff --git a/codex-rs/core/tests/suite/unified_exec.rs b/codex-rs/core/tests/suite/unified_exec.rs index 500b8cb75..9f8d931da 100644 --- a/codex-rs/core/tests/suite/unified_exec.rs +++ b/codex-rs/core/tests/suite/unified_exec.rs @@ -68,7 +68,6 @@ struct ParsedUnifiedExecOutput { output: String, } -#[allow(clippy::expect_used)] fn parse_unified_exec_output(raw: &str) -> Result { static OUTPUT_REGEX: OnceLock = OnceLock::new(); let regex = OUTPUT_REGEX.get_or_init(|| { @@ -249,9 +248,10 @@ async fn unified_exec_intercepts_apply_patch_exec_command() -> Result<()> { let builder = test_codex().with_config(|config| { config.use_experimental_unified_exec_tool = true; - if let Err(err) = config.features.enable(Feature::UnifiedExec) { - panic!("test config should allow feature update: {err}"); - } + config + .features + .enable(Feature::UnifiedExec) + .expect("test config should allow feature update"); }); let harness = TestCodexHarness::with_builder(builder).await?; @@ -908,7 +908,6 @@ async fn unified_exec_short_lived_network_denial_emits_failed_end_event() -> Res Ok(()) } -#[allow(clippy::expect_used)] async fn unified_exec_network_denial_test( server: &wiremock::MockServer, ) -> Result<(TestCodex, PermissionProfile)> { @@ -999,14 +998,15 @@ async fn wait_for_unified_exec_end( response_mock.requests().len() ); } - let event = match tokio::time::timeout(remaining, test.codex.next_event()).await { - Ok(Ok(event)) => event.msg, - Ok(Err(err)) => panic!("event stream ended unexpectedly: {err}"), - Err(_) => panic!( - "timed out waiting for network denial end event; observed {observed_events:?}; response requests: {}", - response_mock.requests().len() - ), - }; + let timeout_message = format!( + "timed out waiting for network denial end event; observed {observed_events:?}; response requests: {}", + response_mock.requests().len() + ); + let event = tokio::time::timeout(remaining, test.codex.next_event()) + .await + .expect(&timeout_message) + .expect("event stream ended unexpectedly") + .msg; turn_completed |= matches!(event, EventMsg::TurnComplete(_)); observed_events.push(format!("{event:?}")); if let EventMsg::ExecCommandEnd(ev) = event @@ -2075,9 +2075,10 @@ async fn assert_write_stdin_ctrl_c_interrupts_non_tty_session( let server = start_mock_server().await; let mut builder = test_codex().with_config(|config| { - if let Err(err) = config.features.enable(Feature::UnifiedExec) { - panic!("test config should allow feature update: {err}"); - } + config + .features + .enable(Feature::UnifiedExec) + .expect("test config should allow feature update"); }); let test = builder.build_with_remote_env(&server).await?; diff --git a/codex-rs/core/tests/suite/unstable_features_warning.rs b/codex-rs/core/tests/suite/unstable_features_warning.rs index 2bc75a7c5..e66c674f9 100644 --- a/codex-rs/core/tests/suite/unstable_features_warning.rs +++ b/codex-rs/core/tests/suite/unstable_features_warning.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use codex_config::CONFIG_TOML_FILE; use codex_core::NewThread; diff --git a/codex-rs/core/tests/suite/web_search.rs b/codex-rs/core/tests/suite/web_search.rs index 065711a37..529cee8b8 100644 --- a/codex-rs/core/tests/suite/web_search.rs +++ b/codex-rs/core/tests/suite/web_search.rs @@ -12,7 +12,6 @@ use serde_json::Value; use serde_json::json; use std::sync::Arc; -#[allow(clippy::expect_used)] fn find_web_search_tool(body: &Value) -> &Value { body["tools"] .as_array() diff --git a/codex-rs/core/tests/suite/window_headers.rs b/codex-rs/core/tests/suite/window_headers.rs index 7c28eb80a..8a2a09784 100644 --- a/codex-rs/core/tests/suite/window_headers.rs +++ b/codex-rs/core/tests/suite/window_headers.rs @@ -1,5 +1,3 @@ -#![allow(clippy::expect_used)] - use super::compact::COMPACT_WARNING_MESSAGE; use anyhow::Result; use codex_core::CodexThread; @@ -141,9 +139,9 @@ fn window_id_parts(request: &ResponsesRequest) -> (String, u64) { .expect("missing x-codex-window-id header"); let (thread_id, generation) = window_id .rsplit_once(':') - .unwrap_or_else(|| panic!("invalid window id header: {window_id}")); + .expect("window id header should contain a generation"); let generation = generation .parse::() - .unwrap_or_else(|err| panic!("invalid window generation in {window_id}: {err}")); + .expect("window generation should be a valid integer"); (thread_id.to_string(), generation) } diff --git a/codex-rs/exec-server/tests/file_system/shared.rs b/codex-rs/exec-server/tests/file_system/shared.rs index 37870812e..e8ed8dfe0 100644 --- a/codex-rs/exec-server/tests/file_system/shared.rs +++ b/codex-rs/exec-server/tests/file_system/shared.rs @@ -397,10 +397,7 @@ async fn file_system_copy_rejects_directory_without_recursive( /*sandbox*/ None, ) .await; - let error = match error { - Ok(()) => panic!("copy should fail"), - Err(error) => error, - }; + let error = error.expect_err("copying a directory without recursion should fail"); assert_eq!(error.kind(), std::io::ErrorKind::InvalidInput); assert_eq!( error.to_string(), @@ -585,10 +582,7 @@ async fn file_system_copy_rejects_copying_directory_into_descendant( /*sandbox*/ None, ) .await; - let error = match error { - Ok(()) => panic!("copy should fail"), - Err(error) => error, - }; + let error = error.expect_err("copying a directory into itself should fail"); assert_eq!(error.kind(), std::io::ErrorKind::InvalidInput); assert_eq!( error.to_string(), diff --git a/codex-rs/exec-server/tests/file_system/support.rs b/codex-rs/exec-server/tests/file_system/support.rs index 715faa996..d7e454d30 100644 --- a/codex-rs/exec-server/tests/file_system/support.rs +++ b/codex-rs/exec-server/tests/file_system/support.rs @@ -76,10 +76,7 @@ pub(crate) fn absolute_path(path: std::path::PathBuf) -> AbsolutePathBuf { "path must be absolute: {}", path.display() ); - match AbsolutePathBuf::try_from(path) { - Ok(path) => path, - Err(err) => panic!("path should be absolute: {err}"), - } + AbsolutePathBuf::try_from(path).expect("path should be absolute") } pub(crate) fn read_only_sandbox(readable_root: std::path::PathBuf) -> FileSystemSandboxContext { diff --git a/codex-rs/exec-server/tests/file_system_unix.rs b/codex-rs/exec-server/tests/file_system_unix.rs index 3c4dfa99a..57c3a82e9 100644 --- a/codex-rs/exec-server/tests/file_system_unix.rs +++ b/codex-rs/exec-server/tests/file_system_unix.rs @@ -1,4 +1,5 @@ #![cfg(unix)] +#![allow(clippy::expect_used)] mod common; @@ -842,10 +843,7 @@ async fn file_system_copy_rejects_standalone_fifo_source( /*sandbox*/ None, ) .await; - let error = match error { - Ok(()) => panic!("copy should fail"), - Err(error) => error, - }; + let error = error.expect_err("copying a FIFO should fail"); assert_eq!(error.kind(), std::io::ErrorKind::InvalidInput); assert_eq!( error.to_string(), diff --git a/codex-rs/exec-server/tests/file_system_windows.rs b/codex-rs/exec-server/tests/file_system_windows.rs index 68d826ced..9dd25343a 100644 --- a/codex-rs/exec-server/tests/file_system_windows.rs +++ b/codex-rs/exec-server/tests/file_system_windows.rs @@ -1,4 +1,5 @@ #![cfg(windows)] +#![allow(clippy::expect_used)] mod common; diff --git a/codex-rs/exec/tests/all.rs b/codex-rs/exec/tests/all.rs index 6fd2c163a..6582e12b2 100644 --- a/codex-rs/exec/tests/all.rs +++ b/codex-rs/exec/tests/all.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + // Single integration test binary that aggregates all test modules. // The submodules live in `tests/suite/`. mod suite; diff --git a/codex-rs/exec/tests/suite/add_dir.rs b/codex-rs/exec/tests/suite/add_dir.rs index 2093c46ac..f95433d1f 100644 --- a/codex-rs/exec/tests/suite/add_dir.rs +++ b/codex-rs/exec/tests/suite/add_dir.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/exec/tests/suite/agents_md.rs b/codex-rs/exec/tests/suite/agents_md.rs index 2891721ae..3cc47f095 100644 --- a/codex-rs/exec/tests/suite/agents_md.rs +++ b/codex-rs/exec/tests/suite/agents_md.rs @@ -1,4 +1,4 @@ -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/exec/tests/suite/apply_patch.rs b/codex-rs/exec/tests/suite/apply_patch.rs index 3b0006695..808968871 100644 --- a/codex-rs/exec/tests/suite/apply_patch.rs +++ b/codex-rs/exec/tests/suite/apply_patch.rs @@ -1,4 +1,4 @@ -#![allow(clippy::expect_used, clippy::unwrap_used, unused_imports)] +#![allow(clippy::unwrap_used, unused_imports)] use anyhow::Context; use assert_cmd::prelude::*; @@ -87,8 +87,7 @@ async fn test_apply_patch_tool() -> anyhow::Result<()> { .success(); let final_path = tmp_path.join("test.md"); - let contents = std::fs::read_to_string(&final_path) - .unwrap_or_else(|e| panic!("failed reading {}: {e}", final_path.display())); + let contents = std::fs::read_to_string(&final_path).expect("final file should be readable"); assert_eq!(contents, "Final text\n"); Ok(()) } @@ -139,8 +138,7 @@ async fn test_apply_patch_freeform_tool() -> anyhow::Result<()> { // Verify final file contents let final_path = test.cwd_path().join("app.py"); - let contents = std::fs::read_to_string(&final_path) - .unwrap_or_else(|e| panic!("failed reading {}: {e}", final_path.display())); + let contents = std::fs::read_to_string(&final_path).expect("final file should be readable"); assert_eq!( contents, include_str!("../fixtures/apply_patch_freeform_final.txt") diff --git a/codex-rs/exec/tests/suite/approval_policy.rs b/codex-rs/exec/tests/suite/approval_policy.rs index 1097d6084..b04bf9a6b 100644 --- a/codex-rs/exec/tests/suite/approval_policy.rs +++ b/codex-rs/exec/tests/suite/approval_policy.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/exec/tests/suite/auth_env.rs b/codex-rs/exec/tests/suite/auth_env.rs index d55da946e..179f40fbd 100644 --- a/codex-rs/exec/tests/suite/auth_env.rs +++ b/codex-rs/exec/tests/suite/auth_env.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses::ev_completed; use core_test_support::responses::mount_sse_once_match; use core_test_support::responses::sse; diff --git a/codex-rs/exec/tests/suite/ephemeral.rs b/codex-rs/exec/tests/suite/ephemeral.rs index ee3016fa6..83522e4bd 100644 --- a/codex-rs/exec/tests/suite/ephemeral.rs +++ b/codex-rs/exec/tests/suite/ephemeral.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::skip_if_no_network; diff --git a/codex-rs/exec/tests/suite/hooks.rs b/codex-rs/exec/tests/suite/hooks.rs index 52784a3e1..7be9480d1 100644 --- a/codex-rs/exec/tests/suite/hooks.rs +++ b/codex-rs/exec/tests/suite/hooks.rs @@ -1,5 +1,4 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/exec/tests/suite/mcp_required_exit.rs b/codex-rs/exec/tests/suite/mcp_required_exit.rs index 8acd426fc..738dc3a5d 100644 --- a/codex-rs/exec/tests/suite/mcp_required_exit.rs +++ b/codex-rs/exec/tests/suite/mcp_required_exit.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/exec/tests/suite/originator.rs b/codex-rs/exec/tests/suite/originator.rs index e63f57ab0..d2a1f829f 100644 --- a/codex-rs/exec/tests/suite/originator.rs +++ b/codex-rs/exec/tests/suite/originator.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use codex_login::default_client::CODEX_INTERNAL_ORIGINATOR_OVERRIDE_ENV_VAR; use core_test_support::responses; diff --git a/codex-rs/exec/tests/suite/output_schema.rs b/codex-rs/exec/tests/suite/output_schema.rs index 89a23147b..bfc9e8e58 100644 --- a/codex-rs/exec/tests/suite/output_schema.rs +++ b/codex-rs/exec/tests/suite/output_schema.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/exec/tests/suite/prompt_stdin.rs b/codex-rs/exec/tests/suite/prompt_stdin.rs index 1f9244b6c..4789fa42a 100644 --- a/codex-rs/exec/tests/suite/prompt_stdin.rs +++ b/codex-rs/exec/tests/suite/prompt_stdin.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/exec/tests/suite/resume.rs b/codex-rs/exec/tests/suite/resume.rs index 904c6a8f1..25e3b6597 100644 --- a/codex-rs/exec/tests/suite/resume.rs +++ b/codex-rs/exec/tests/suite/resume.rs @@ -1,4 +1,4 @@ -#![allow(clippy::unwrap_used, clippy::expect_used)] +#![allow(clippy::unwrap_used)] use anyhow::Context; use core_test_support::responses; use core_test_support::skip_if_no_network; diff --git a/codex-rs/exec/tests/suite/sandbox.rs b/codex-rs/exec/tests/suite/sandbox.rs index 5f6584aa4..4b8cecc51 100644 --- a/codex-rs/exec/tests/suite/sandbox.rs +++ b/codex-rs/exec/tests/suite/sandbox.rs @@ -522,7 +522,6 @@ async fn allow_unix_socketpair_recvfrom() { const IN_SANDBOX_ENV_VAR: &str = "IN_SANDBOX"; -#[expect(clippy::expect_used)] pub async fn run_code_under_sandbox( test_selector: &str, permission_profile: &PermissionProfile, diff --git a/codex-rs/exec/tests/suite/server_error_exit.rs b/codex-rs/exec/tests/suite/server_error_exit.rs index 909f48be3..bd0fad698 100644 --- a/codex-rs/exec/tests/suite/server_error_exit.rs +++ b/codex-rs/exec/tests/suite/server_error_exit.rs @@ -1,5 +1,5 @@ #![cfg(not(target_os = "windows"))] -#![allow(clippy::expect_used, clippy::unwrap_used)] +#![allow(clippy::unwrap_used)] use core_test_support::responses; use core_test_support::test_codex_exec::test_codex_exec; diff --git a/codex-rs/execpolicy/tests/basic.rs b/codex-rs/execpolicy/tests/basic.rs index 50c3f5361..f6a86adb2 100644 --- a/codex-rs/execpolicy/tests/basic.rs +++ b/codex-rs/execpolicy/tests/basic.rs @@ -1,3 +1,4 @@ +#![allow(clippy::expect_used)] use std::any::Any; use std::fs; use std::path::PathBuf; @@ -35,8 +36,7 @@ fn prompt_all(_: &[String]) -> Decision { } fn absolute_path(path: &str) -> AbsolutePathBuf { - AbsolutePathBuf::try_from(path.to_string()) - .unwrap_or_else(|error| panic!("expected absolute path `{path}`: {error}")) + AbsolutePathBuf::try_from(path.to_string()).expect("path should be absolute") } fn host_absolute_path(segments: &[&str]) -> String { diff --git a/codex-rs/ext/extension-api/tests/registry.rs b/codex-rs/ext/extension-api/tests/registry.rs index 42cb18af6..79773a98c 100644 --- a/codex-rs/ext/extension-api/tests/registry.rs +++ b/codex-rs/ext/extension-api/tests/registry.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + use std::sync::Arc; use std::sync::Mutex; @@ -171,7 +173,7 @@ impl TurnItemContributor for RecordingTurnItemContributor { Box::pin(async move { self.calls .lock() - .unwrap_or_else(|error| panic!("turn item calls lock poisoned: {error}")) + .expect("turn item calls lock should not be poisoned") .push(self.name); Ok(()) }) @@ -250,7 +252,7 @@ impl ApprovalReviewContributor for RecordingApprovalContributor { Box::pin(async move { self.calls .lock() - .unwrap_or_else(|error| panic!("approval calls lock poisoned: {error}")) + .expect("approval calls lock should not be poisoned") .push(ApprovalCall { contributor: self.name, session_id: session_store.level_id().to_string(), @@ -319,7 +321,7 @@ impl ExtensionEventSink for RecordingEventSink { }; self.events .lock() - .unwrap_or_else(|error| panic!("recording event sink lock poisoned: {error}")) + .expect("recording event sink lock should not be poisoned") .push((event.id, warning.message)); } } diff --git a/codex-rs/ext/goal/tests/goal_extension_backend.rs b/codex-rs/ext/goal/tests/goal_extension_backend.rs index 16992f31e..32043c980 100644 --- a/codex-rs/ext/goal/tests/goal_extension_backend.rs +++ b/codex-rs/ext/goal/tests/goal_extension_backend.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + use std::sync::Arc; use std::sync::Mutex; use std::sync::PoisonError; @@ -1320,7 +1322,7 @@ impl GoalExtensionHarness { fn runtime_handle(&self) -> Arc { self.thread_store .get::() - .unwrap_or_else(|| panic!("goal runtime handle should exist")) + .expect("goal runtime handle should exist") } } @@ -1331,7 +1333,7 @@ fn tool_by_name<'a>( tools .iter() .find(|tool| tool.tool_name().namespace.is_none() && tool.tool_name().name == name) - .unwrap_or_else(|| panic!("missing tool {name}")) + .expect("requested goal tool should exist") } fn tool_call(tool_name: &str, call_id: &str, arguments: serde_json::Value) -> ToolCall { diff --git a/codex-rs/linux-sandbox/tests/all.rs b/codex-rs/linux-sandbox/tests/all.rs index 7e136e4cc..fdf98aa94 100644 --- a/codex-rs/linux-sandbox/tests/all.rs +++ b/codex-rs/linux-sandbox/tests/all.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + // Single integration test binary that aggregates all test modules. // The submodules live in `tests/suite/`. mod suite; diff --git a/codex-rs/linux-sandbox/tests/suite/landlock.rs b/codex-rs/linux-sandbox/tests/suite/landlock.rs index 729a3bee0..3e6d82111 100644 --- a/codex-rs/linux-sandbox/tests/suite/landlock.rs +++ b/codex-rs/linux-sandbox/tests/suite/landlock.rs @@ -65,7 +65,6 @@ async fn run_cmd(cmd: &[&str], writable_roots: &[PathBuf], timeout_ms: u64) { } } -#[expect(clippy::expect_used)] async fn run_cmd_output( cmd: &[&str], writable_roots: &[PathBuf], @@ -111,7 +110,6 @@ async fn run_cmd_result_with_writable_roots( .await } -#[expect(clippy::expect_used)] async fn run_cmd_result_with_permission_profile( cmd: &[&str], permission_profile: PermissionProfile, @@ -129,7 +127,6 @@ async fn run_cmd_result_with_permission_profile( .await } -#[expect(clippy::expect_used)] async fn run_cmd_result_with_cwd_and_writable_roots( cmd: &[&str], cwd: &std::path::Path, @@ -423,7 +420,6 @@ async fn test_timeout() { /// does NOT succeed (i.e. returns a non‑zero exit code) **unless** the binary /// is missing in which case we silently treat it as an accepted skip so the /// suite remains green on leaner CI images. -#[expect(clippy::expect_used)] async fn assert_network_blocked(cmd: &[&str]) { let cwd = AbsolutePathBuf::current_dir().expect("cwd should exist"); let sandbox_cwd = cwd.clone(); diff --git a/codex-rs/linux-sandbox/tests/suite/managed_proxy.rs b/codex-rs/linux-sandbox/tests/suite/managed_proxy.rs index 71ed97150..6c9a6a0c6 100644 --- a/codex-rs/linux-sandbox/tests/suite/managed_proxy.rs +++ b/codex-rs/linux-sandbox/tests/suite/managed_proxy.rs @@ -119,14 +119,9 @@ async fn run_linux_sandbox_direct( env: HashMap, timeout_ms: u64, ) -> Output { - let cwd = match std::env::current_dir() { - Ok(cwd) => cwd, - Err(err) => panic!("cwd should exist: {err}"), - }; - let permission_profile_json = match serde_json::to_string(permission_profile) { - Ok(permission_profile_json) => permission_profile_json, - Err(err) => panic!("permission profile should serialize: {err}"), - }; + let cwd = std::env::current_dir().expect("current directory should exist"); + let permission_profile_json = + serde_json::to_string(permission_profile).expect("permission profile should serialize"); let mut args = vec![ "--sandbox-policy-cwd".to_string(), @@ -148,14 +143,10 @@ async fn run_linux_sandbox_direct( .stdin(Stdio::null()) .stdout(Stdio::piped()) .stderr(Stdio::piped()); - let output = match tokio::time::timeout(Duration::from_millis(timeout_ms), cmd.output()).await { - Ok(output) => output, - Err(err) => panic!("sandbox command should not time out: {err}"), - }; - match output { - Ok(output) => output, - Err(err) => panic!("sandbox command should execute: {err}"), - } + tokio::time::timeout(Duration::from_millis(timeout_ms), cmd.output()) + .await + .expect("sandbox command should not time out") + .expect("sandbox command should execute") } #[tokio::test] diff --git a/codex-rs/login/tests/all.rs b/codex-rs/login/tests/all.rs index 7e136e4cc..fdf98aa94 100644 --- a/codex-rs/login/tests/all.rs +++ b/codex-rs/login/tests/all.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + // Single integration test binary that aggregates all test modules. // The submodules live in `tests/suite/`. mod suite; diff --git a/codex-rs/login/tests/suite/auth_refresh.rs b/codex-rs/login/tests/suite/auth_refresh.rs index 82fba7800..406572229 100644 --- a/codex-rs/login/tests/suite/auth_refresh.rs +++ b/codex-rs/login/tests/suite/auth_refresh.rs @@ -1295,14 +1295,8 @@ fn jwt_with_payload(payload: serde_json::Value) -> String { base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(data) } - let header_bytes = match serde_json::to_vec(&header) { - Ok(bytes) => bytes, - Err(err) => panic!("serialize header: {err}"), - }; - let payload_bytes = match serde_json::to_vec(&payload) { - Ok(bytes) => bytes, - Err(err) => panic!("serialize payload: {err}"), - }; + let header_bytes = serde_json::to_vec(&header).expect("header should serialize"); + let payload_bytes = serde_json::to_vec(&payload).expect("payload should serialize"); let header_b64 = b64(&header_bytes); let payload_b64 = b64(&payload_bytes); let signature_b64 = b64(b"sig"); diff --git a/codex-rs/login/tests/suite/login_server_e2e.rs b/codex-rs/login/tests/suite/login_server_e2e.rs index 74a9b430f..3d7c5a180 100644 --- a/codex-rs/login/tests/suite/login_server_e2e.rs +++ b/codex-rs/login/tests/suite/login_server_e2e.rs @@ -75,7 +75,7 @@ fn start_mock_issuer(chatgpt_account_id: &str) -> (SocketAddr, thread::JoinHandl let mut resp = tiny_http::Response::from_data(data); resp.add_header( tiny_http::Header::from_bytes(&b"Content-Type"[..], &b"application/json"[..]) - .unwrap_or_else(|_| panic!("header bytes")), + .expect("header bytes should be valid"), ); let _ = req.respond(resp); } else { diff --git a/codex-rs/mcp-server/tests/all.rs b/codex-rs/mcp-server/tests/all.rs index 7e136e4cc..fdf98aa94 100644 --- a/codex-rs/mcp-server/tests/all.rs +++ b/codex-rs/mcp-server/tests/all.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + // Single integration test binary that aggregates all test modules. // The submodules live in `tests/suite/`. mod suite; diff --git a/codex-rs/mcp-server/tests/common/lib.rs b/codex-rs/mcp-server/tests/common/lib.rs index d2ed896ce..201155725 100644 --- a/codex-rs/mcp-server/tests/common/lib.rs +++ b/codex-rs/mcp-server/tests/common/lib.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + mod mcp_process; mod mock_model_server; mod responses; diff --git a/codex-rs/mcp-server/tests/common/mock_model_server.rs b/codex-rs/mcp-server/tests/common/mock_model_server.rs index a1cec2a22..7734ae12c 100644 --- a/codex-rs/mcp-server/tests/common/mock_model_server.rs +++ b/codex-rs/mcp-server/tests/common/mock_model_server.rs @@ -37,11 +37,12 @@ struct SeqResponder { impl Respond for SeqResponder { fn respond(&self, _: &wiremock::Request) -> ResponseTemplate { let call_num = self.num_calls.fetch_add(1, Ordering::SeqCst); - match self.responses.get(call_num) { - Some(response) => ResponseTemplate::new(200) - .insert_header("content-type", "text/event-stream") - .set_body_raw(response.clone(), "text/event-stream"), - None => panic!("no response for {call_num}"), - } + let response = self + .responses + .get(call_num) + .expect("mock model response should exist"); + ResponseTemplate::new(200) + .insert_header("content-type", "text/event-stream") + .set_body_raw(response.clone(), "text/event-stream") } } diff --git a/codex-rs/mcp-server/tests/suite/codex_tool.rs b/codex-rs/mcp-server/tests/suite/codex_tool.rs index d9f290c3c..0b9d43f90 100644 --- a/codex-rs/mcp-server/tests/suite/codex_tool.rs +++ b/codex-rs/mcp-server/tests/suite/codex_tool.rs @@ -47,9 +47,9 @@ async fn test_shell_command_approval_triggers_elicitation() { // Apparently `#[tokio::test]` must return `()`, so we create a helper // function that returns `Result` so we can use `?` in favor of `unwrap`. - if let Err(err) = shell_command_approval_triggers_elicitation().await { - panic!("failure: {err}"); - } + shell_command_approval_triggers_elicitation() + .await + .expect("shell command approval should trigger elicitation"); } async fn shell_command_approval_triggers_elicitation() -> anyhow::Result<()> { @@ -146,7 +146,6 @@ async fn shell_command_approval_triggers_elicitation() -> anyhow::Result<()> { .await?; // Verify task_complete notification arrives before the tool call completes. - #[expect(clippy::expect_used)] let _task_complete = timeout( DEFAULT_READ_TIMEOUT, mcp_process.read_stream_until_legacy_task_complete_notification(), @@ -225,9 +224,9 @@ async fn test_patch_approval_triggers_elicitation() { return; } - if let Err(err) = patch_approval_triggers_elicitation().await { - panic!("failure: {err}"); - } + patch_approval_triggers_elicitation() + .await + .expect("patch approval should trigger elicitation"); } async fn patch_approval_triggers_elicitation() -> anyhow::Result<()> { @@ -356,13 +355,13 @@ async fn test_codex_tool_passes_base_instructions() { // Apparently `#[tokio::test]` must return `()`, so we create a helper // function that returns `Result` so we can use `?` in favor of `unwrap`. - if let Err(err) = codex_tool_passes_base_instructions().await { - panic!("failure: {err}"); - } + codex_tool_passes_base_instructions() + .await + .expect("codex tool should pass base instructions"); } async fn codex_tool_passes_base_instructions() -> anyhow::Result<()> { - #![expect(clippy::expect_used, clippy::unwrap_used)] + #![expect(clippy::unwrap_used)] let server = create_mock_responses_server(vec![create_final_assistant_message_sse_response("Enjoy!")?]) diff --git a/codex-rs/otel/tests/harness/mod.rs b/codex-rs/otel/tests/harness/mod.rs index fbba56411..af15cbf0d 100644 --- a/codex-rs/otel/tests/harness/mod.rs +++ b/codex-rs/otel/tests/harness/mod.rs @@ -27,13 +27,12 @@ pub(crate) fn build_metrics_with_defaults( } pub(crate) fn latest_metrics(exporter: &InMemoryMetricExporter) -> ResourceMetrics { - let Ok(metrics) = exporter.get_finished_metrics() else { - panic!("finished metrics error"); - }; - let Some(metrics) = metrics.into_iter().last() else { - panic!("metrics export missing"); - }; - metrics + exporter + .get_finished_metrics() + .expect("finished metrics should be available") + .into_iter() + .last() + .expect("metrics export should exist") } pub(crate) fn find_metric<'a>( @@ -62,8 +61,7 @@ pub(crate) fn histogram_data( resource_metrics: &ResourceMetrics, name: &str, ) -> (Vec, Vec, f64, u64) { - let metric = - find_metric(resource_metrics, name).unwrap_or_else(|| panic!("metric {name} missing")); + let metric = find_metric(resource_metrics, name).expect("metric should exist"); match metric.data() { AggregatedMetrics::F64(data) => match data { MetricData::Histogram(histogram) => { diff --git a/codex-rs/otel/tests/suite/otel_export_routing_policy.rs b/codex-rs/otel/tests/suite/otel_export_routing_policy.rs index 582d9792c..7432aaaa0 100644 --- a/codex-rs/otel/tests/suite/otel_export_routing_policy.rs +++ b/codex-rs/otel/tests/suite/otel_export_routing_policy.rs @@ -63,7 +63,7 @@ fn find_log_by_event_name<'a>( .get("event.name") .is_some_and(|value| value == event_name) }) - .unwrap_or_else(|| panic!("missing log event: {event_name}")) + .expect("log event should exist") } fn find_span_event_by_name_attr<'a>( @@ -77,7 +77,7 @@ fn find_span_event_by_name_attr<'a>( .get("event.name") .is_some_and(|value| value == event_name) }) - .unwrap_or_else(|| panic!("missing span event: {event_name}")) + .expect("span event should exist") } fn auth_env_metadata() -> AuthEnvTelemetryMetadata { diff --git a/codex-rs/otel/tests/suite/otlp_http_loopback.rs b/codex-rs/otel/tests/suite/otlp_http_loopback.rs index ede2dcc09..3ba491797 100644 --- a/codex-rs/otel/tests/suite/otlp_http_loopback.rs +++ b/codex-rs/otel/tests/suite/otlp_http_loopback.rs @@ -200,17 +200,7 @@ fn otlp_http_exporter_sends_metrics_to_collector() -> Result<()> { let request = captured .iter() .find(|req| req.path == "/v1/metrics") - .unwrap_or_else(|| { - let paths = captured - .iter() - .map(|req| req.path.as_str()) - .collect::>() - .join(", "); - panic!( - "missing /v1/metrics request; got {}: {paths}", - captured.len() - ); - }); + .expect("/v1/metrics request should be captured"); let content_type = request .content_type .as_deref() @@ -313,14 +303,7 @@ fn otlp_http_exporter_sends_logs_to_collector() let request = captured .iter() .find(|req| req.path == "/v1/logs") - .unwrap_or_else(|| { - let paths = captured - .iter() - .map(|req| req.path.as_str()) - .collect::>() - .join(", "); - panic!("missing /v1/logs request; got {}: {paths}", captured.len()); - }); + .expect("/v1/logs request should be captured"); let content_type = request .content_type .as_deref() @@ -362,9 +345,9 @@ fn otel_provider_rejects_header_unsafe_configured_tracestate() { )]), }); - let Err(err) = result else { - panic!("expected header-unsafe configured tracestate to be rejected"); - }; + let err = result + .err() + .expect("header-unsafe configured tracestate should be rejected"); assert!(err.to_string().contains("configured tracestate value")); } @@ -478,17 +461,7 @@ fn otlp_http_exporter_sends_traces_to_collector() let request = captured .iter() .find(|req| req.path == "/v1/traces") - .unwrap_or_else(|| { - let paths = captured - .iter() - .map(|req| req.path.as_str()) - .collect::>() - .join(", "); - panic!( - "missing /v1/traces request; got {}: {paths}", - captured.len() - ); - }); + .expect("/v1/traces request should be captured"); let content_type = request .content_type .as_deref() @@ -601,17 +574,7 @@ async fn otlp_http_exporter_sends_traces_to_collector_in_tokio_runtime() let request = captured .iter() .find(|req| req.path == "/v1/traces") - .unwrap_or_else(|| { - let paths = captured - .iter() - .map(|req| req.path.as_str()) - .collect::>() - .join(", "); - panic!( - "missing /v1/traces request; got {}: {paths}", - captured.len() - ); - }); + .expect("/v1/traces request should be captured"); let content_type = request .content_type .as_deref() @@ -733,17 +696,7 @@ fn otlp_http_exporter_sends_traces_to_collector_in_current_thread_tokio_runtime( let request = captured .iter() .find(|req| req.path == "/v1/traces") - .unwrap_or_else(|| { - let paths = captured - .iter() - .map(|req| req.path.as_str()) - .collect::>() - .join(", "); - panic!( - "missing /v1/traces request; got {}: {paths}", - captured.len() - ); - }); + .expect("/v1/traces request should be captured"); let content_type = request .content_type .as_deref() diff --git a/codex-rs/otel/tests/suite/send.rs b/codex-rs/otel/tests/suite/send.rs index e2b8f2103..c3e2027a6 100644 --- a/codex-rs/otel/tests/suite/send.rs +++ b/codex-rs/otel/tests/suite/send.rs @@ -64,8 +64,8 @@ fn send_builds_payload_with_tags_and_histograms() -> Result<()> { assert_eq!(count, 1); let histogram_attrs = attributes_to_map( - match find_metric(&resource_metrics, "codex.tool_latency").and_then(|metric| { - match metric.data() { + find_metric(&resource_metrics, "codex.tool_latency") + .and_then(|metric| match metric.data() { opentelemetry_sdk::metrics::data::AggregatedMetrics::F64( opentelemetry_sdk::metrics::data::MetricData::Histogram(histogram), ) => histogram @@ -73,11 +73,8 @@ fn send_builds_payload_with_tags_and_histograms() -> Result<()> { .next() .map(opentelemetry_sdk::metrics::data::HistogramDataPoint::attributes), _ => None, - } - }) { - Some(attrs) => attrs, - None => panic!("histogram attributes missing"), - }, + }) + .expect("codex.tool_latency histogram attributes should exist"), ); let expected_histogram_attributes = BTreeMap::from([ ("service".to_string(), "codex-cli".to_string()), diff --git a/codex-rs/otel/tests/suite/timing.rs b/codex-rs/otel/tests/suite/timing.rs index 5955979f8..72156b526 100644 --- a/codex-rs/otel/tests/suite/timing.rs +++ b/codex-rs/otel/tests/suite/timing.rs @@ -26,7 +26,7 @@ fn record_duration_records_histogram() -> Result<()> { assert_eq!(sum, 15.0); assert_eq!(count, 1); let metric = crate::harness::find_metric(&resource_metrics, "codex.request_latency") - .unwrap_or_else(|| panic!("metric codex.request_latency missing")); + .expect("codex.request_latency metric should exist"); assert_eq!(metric.unit(), "ms"); assert_eq!(metric.description(), "Duration in milliseconds."); @@ -67,7 +67,7 @@ fn record_duration_seconds_uses_fractional_seconds_and_scaled_buckets() -> Resul assert!((sum - 6.1).abs() < f64::EPSILON * 8.0); assert_eq!(count, 3); let metric = crate::harness::find_metric(&resource_metrics, "codex.request_duration_seconds") - .unwrap_or_else(|| panic!("metric codex.request_duration_seconds missing")); + .expect("codex.request_duration_seconds metric should exist"); assert_eq!(metric.unit(), "s"); assert_eq!( metric.description(), @@ -96,12 +96,12 @@ fn timer_result_records_success() -> Result<()> { assert_eq!(count, 1); assert_eq!(bucket_counts.iter().sum::(), 1); let metric = crate::harness::find_metric(&resource_metrics, "codex.request_latency") - .unwrap_or_else(|| panic!("metric codex.request_latency missing")); + .expect("codex.request_latency metric should exist"); assert_eq!(metric.unit(), "ms"); assert_eq!(metric.description(), "Duration in milliseconds."); let attrs = attributes_to_map( - match crate::harness::find_metric(&resource_metrics, "codex.request_latency").and_then( - |metric| match metric.data() { + crate::harness::find_metric(&resource_metrics, "codex.request_latency") + .and_then(|metric| match metric.data() { opentelemetry_sdk::metrics::data::AggregatedMetrics::F64( opentelemetry_sdk::metrics::data::MetricData::Histogram(histogram), ) => histogram @@ -109,11 +109,8 @@ fn timer_result_records_success() -> Result<()> { .next() .map(opentelemetry_sdk::metrics::data::HistogramDataPoint::attributes), _ => None, - }, - ) { - Some(attrs) => attrs, - None => panic!("attributes missing"), - }, + }) + .expect("codex.request_latency attributes should exist"), ); assert_eq!(attrs.get("route").map(String::as_str), Some("chat")); diff --git a/codex-rs/otel/tests/tests.rs b/codex-rs/otel/tests/tests.rs index 92f88b95f..120bfe4d8 100644 --- a/codex-rs/otel/tests/tests.rs +++ b/codex-rs/otel/tests/tests.rs @@ -1,2 +1,4 @@ +#![allow(clippy::expect_used)] + mod harness; mod suite; diff --git a/codex-rs/tools/tests/json_schema_policy_fixtures.rs b/codex-rs/tools/tests/json_schema_policy_fixtures.rs index 71ea94a5d..8ebd6ca8e 100644 --- a/codex-rs/tools/tests/json_schema_policy_fixtures.rs +++ b/codex-rs/tools/tests/json_schema_policy_fixtures.rs @@ -1,3 +1,4 @@ +#![allow(clippy::expect_used)] use codex_tools::ToolName; use codex_tools::mcp_tool_to_responses_api_tool; use pretty_assertions::assert_eq; @@ -183,12 +184,9 @@ fn json_schema_policy_oversized_golden_schema_triggers_compaction() { } fn load_fixture(path: &str) -> T { - let path = codex_utils_cargo_bin::find_resource!(path) - .unwrap_or_else(|err| panic!("resolve fixture {path}: {err}")); - let fixture = fs::read_to_string(&path) - .unwrap_or_else(|err| panic!("read fixture {}: {err}", path.display())); - serde_json::from_str(&fixture) - .unwrap_or_else(|err| panic!("parse fixture {}: {err}", path.display())) + let path = codex_utils_cargo_bin::find_resource!(path).expect("fixture should resolve"); + let fixture = fs::read_to_string(&path).expect("fixture should be readable"); + serde_json::from_str(&fixture).expect("fixture should contain valid JSON") } fn convert_fixture_tool( @@ -199,7 +197,7 @@ fn convert_fixture_tool( let input_schema = fixture_tool .input_schema .as_object() - .unwrap_or_else(|| panic!("{name} input_schema should be an object")) + .expect("tool input_schema should be an object") .clone(); let tool = rmcp::model::Tool::new( name.to_string(), @@ -208,11 +206,11 @@ fn convert_fixture_tool( ); mcp_tool_to_responses_api_tool(&ToolName::namespaced(&fixture.source, name), &tool) - .unwrap_or_else(|err| panic!("convert {name} from {}: {err}", fixture.source)) + .expect("fixture tool should convert to a responses API tool") } fn compact_json_len(value: &Value) -> usize { serde_json::to_vec(value) - .unwrap_or_else(|err| panic!("serialize compact JSON: {err}")) + .expect("value should serialize to compact JSON") .len() } diff --git a/codex-rs/tui/tests/all.rs b/codex-rs/tui/tests/all.rs index afc037b8e..83b528c91 100644 --- a/codex-rs/tui/tests/all.rs +++ b/codex-rs/tui/tests/all.rs @@ -1,3 +1,5 @@ +#![allow(clippy::expect_used)] + // Single integration test binary that aggregates all test modules. // The submodules live in `tests/suite/`. mod test_backend; diff --git a/codex-rs/tui/tests/manager_dependency_regression.rs b/codex-rs/tui/tests/manager_dependency_regression.rs index 908b054e0..b3f09f760 100644 --- a/codex-rs/tui/tests/manager_dependency_regression.rs +++ b/codex-rs/tui/tests/manager_dependency_regression.rs @@ -1,13 +1,13 @@ +#![allow(clippy::expect_used)] use std::fs; use std::path::Path; use std::path::PathBuf; fn rust_sources_under(dir: &Path) -> Vec { let mut files = Vec::new(); - let entries = - fs::read_dir(dir).unwrap_or_else(|err| panic!("failed to read {}: {err}", dir.display())); + let entries = fs::read_dir(dir).expect("source directory should be readable"); for entry in entries { - let entry = entry.unwrap_or_else(|err| panic!("failed to read dir entry: {err}")); + let entry = entry.expect("source directory entry should be readable"); let path = entry.path(); if path.is_dir() { files.extend(rust_sources_under(&path)); @@ -22,10 +22,10 @@ fn rust_sources_under(dir: &Path) -> Vec { #[test] fn tui_runtime_source_does_not_depend_on_manager_escape_hatches() { let src_file = codex_utils_cargo_bin::find_resource!("src/chatwidget.rs") - .unwrap_or_else(|err| panic!("failed to resolve src runfile: {err}")); + .expect("chatwidget source runfile should resolve"); let src_dir = src_file .parent() - .unwrap_or_else(|| panic!("source file has no parent: {}", src_file.display())); + .expect("chatwidget source file should have a parent"); let sources = rust_sources_under(src_dir); let forbidden = [ "AuthManager", @@ -37,8 +37,7 @@ fn tui_runtime_source_does_not_depend_on_manager_escape_hatches() { let violations: Vec = sources .iter() .flat_map(|path| { - let contents = fs::read_to_string(path) - .unwrap_or_else(|err| panic!("failed to read {}: {err}", path.display())); + let contents = fs::read_to_string(path).expect("Rust source file should be readable"); let path_display = path.display().to_string(); forbidden .iter() diff --git a/codex-rs/tui/tests/suite/vt100_history.rs b/codex-rs/tui/tests/suite/vt100_history.rs index 609671cc3..6243b2d72 100644 --- a/codex-rs/tui/tests/suite/vt100_history.rs +++ b/codex-rs/tui/tests/suite/vt100_history.rs @@ -1,5 +1,3 @@ -#![expect(clippy::expect_used)] - use crate::test_backend::VT100Backend; use ratatui::layout::Rect; use ratatui::style::Stylize; diff --git a/codex-rs/tui/tests/suite/vt100_live_commit.rs b/codex-rs/tui/tests/suite/vt100_live_commit.rs index 01b3f7257..e0375ad6c 100644 --- a/codex-rs/tui/tests/suite/vt100_live_commit.rs +++ b/codex-rs/tui/tests/suite/vt100_live_commit.rs @@ -5,10 +5,8 @@ use ratatui::text::Line; #[test] fn live_001_commit_on_overflow() { let backend = VT100Backend::new(/*width*/ 20, /*height*/ 6); - let mut term = match codex_tui::Terminal::with_options(backend) { - Ok(t) => t, - Err(e) => panic!("failed to construct terminal: {e}"), - }; + let mut term = + codex_tui::Terminal::with_options(backend).expect("terminal should be constructed"); let area = Rect::new( /*x*/ 0, /*y*/ 5, /*width*/ 20, /*height*/ 1, );