diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 059f786087..5bced9c94a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,7 +63,7 @@ jobs: - name: Cargo Fmt run: cargo +nightly fmt --all --check - name: Cargo Clippy - run: cargo +nightly clippy --all-features --workspace + run: cargo +nightly clippy --all-features --all-targets --workspace draft_release: needs: - build diff --git a/crates/forge_app/src/operation.rs b/crates/forge_app/src/operation.rs index cd129fe87b..f92afa45b2 100644 --- a/crates/forge_app/src/operation.rs +++ b/crates/forge_app/src/operation.rs @@ -1536,7 +1536,7 @@ mod tests { assert!( !actual .values - .get(0) + .first() .unwrap() .as_str() .unwrap() diff --git a/crates/forge_app/src/orch_spec/mod.rs b/crates/forge_app/src/orch_spec/mod.rs index c64ac6868a..aa011b1ddf 100644 --- a/crates/forge_app/src/orch_spec/mod.rs +++ b/crates/forge_app/src/orch_spec/mod.rs @@ -1,3 +1,4 @@ +#![allow(clippy::module_inception)] mod orch_runner; mod orch_setup; mod orch_spec; diff --git a/crates/forge_app/src/orch_spec/orch_setup.rs b/crates/forge_app/src/orch_spec/orch_setup.rs index 1ecbef7c11..bd8e22e8bf 100644 --- a/crates/forge_app/src/orch_spec/orch_setup.rs +++ b/crates/forge_app/src/orch_spec/orch_setup.rs @@ -13,7 +13,7 @@ use url::Url; use crate::orch_spec::orch_runner::Runner; // User prompt -const USER_PROMPT: &'static str = r#" +const USER_PROMPT: &str = r#" {{#if (eq event.name 'forge/user_task_update')}} {{event.value}} {{else}} diff --git a/crates/forge_app/src/orch_spec/orch_spec.rs b/crates/forge_app/src/orch_spec/orch_spec.rs index 437bb2a43c..44735c5d0d 100644 --- a/crates/forge_app/src/orch_spec/orch_spec.rs +++ b/crates/forge_app/src/orch_spec/orch_spec.rs @@ -47,7 +47,7 @@ async fn test_rendered_user_message() { let mut ctx = TestContext::default().mock_assistant_responses(vec![ ChatCompletionMessage::assistant(Content::full("Hello!")).finish_reason(FinishReason::Stop), ]); - let current_time = ctx.current_time.clone(); + let current_time = ctx.current_time; ctx.run("Hi").await.unwrap(); let messages = ctx.output.context_messages(); @@ -70,7 +70,7 @@ async fn test_followup_does_not_trigger_session_summary() { ToolResult::new("followup").output(Ok(ToolOutput::text("Follow-up question sent"))); let mut ctx = TestContext::default() - .mock_tool_call_responses(vec![(followup_call.clone().into(), followup_result)]) + .mock_tool_call_responses(vec![(followup_call.clone(), followup_result)]) .mock_assistant_responses(vec![ ChatCompletionMessage::assistant("I need more information") .tool_calls(vec![followup_call.into()]), @@ -85,7 +85,7 @@ async fn test_followup_does_not_trigger_session_summary() { .chat_responses .iter() .flatten() - .any(|response| matches!(response, ChatResponse::TaskComplete { .. })); + .any(|response| matches!(response, ChatResponse::TaskComplete)); assert!( !has_chat_complete, @@ -128,7 +128,7 @@ async fn test_tool_call_start_end_responses_for_non_agent_tools() { let tool_result = ToolResult::new("fs_read").output(Ok(ToolOutput::text("file content"))); let mut ctx = TestContext::default() - .mock_tool_call_responses(vec![(tool_call.clone().into(), tool_result.clone())]) + .mock_tool_call_responses(vec![(tool_call.clone(), tool_result.clone())]) .mock_assistant_responses(vec![ ChatCompletionMessage::assistant("Reading file") .tool_calls(vec![tool_call.clone().into()]), @@ -197,10 +197,7 @@ async fn test_no_tool_call_start_end_responses_for_agent_tools() { ToolResult::new("forge").output(Ok(ToolOutput::text("analysis complete"))); let mut ctx = TestContext::default() - .mock_tool_call_responses(vec![( - agent_tool_call.clone().into(), - agent_tool_result.clone(), - )]) + .mock_tool_call_responses(vec![(agent_tool_call.clone(), agent_tool_result.clone())]) .mock_assistant_responses(vec![ ChatCompletionMessage::assistant("Analyzing code") .tool_calls(vec![agent_tool_call.into()]), @@ -250,8 +247,8 @@ async fn test_mixed_agent_and_non_agent_tool_calls() { let mut ctx = TestContext::default() .mock_tool_call_responses(vec![ - (fs_tool_call.clone().into(), fs_tool_result.clone()), - (agent_tool_call.clone().into(), agent_tool_result.clone()), + (fs_tool_call.clone(), fs_tool_result.clone()), + (agent_tool_call.clone(), agent_tool_result.clone()), ]) .mock_assistant_responses(vec![ ChatCompletionMessage::assistant("Reading and analyzing") diff --git a/crates/forge_app/src/truncation/truncate_shell.rs b/crates/forge_app/src/truncation/truncate_shell.rs index 94410fd8ed..182b6ff259 100644 --- a/crates/forge_app/src/truncation/truncate_shell.rs +++ b/crates/forge_app/src/truncation/truncate_shell.rs @@ -208,8 +208,8 @@ mod tests { #[test] fn test_no_truncation_needed() { - let stdout = vec!["line 1", "line 2", "line 3"].join("\n"); - let stderr = vec!["error 1", "error 2"].join("\n"); + let stdout = ["line 1", "line 2", "line 3"].join("\n"); + let stderr = ["error 1", "error 2"].join("\n"); let actual = truncate_shell_output(&stdout, &stderr, 5, 5, 2000); let expected = TruncatedShellOutput::default() @@ -231,11 +231,11 @@ mod tests { #[test] fn test_truncation_with_prefix_and_suffix() { - let stdout = vec![ + let stdout = [ "line 1", "line 2", "line 3", "line 4", "line 5", "line 6", "line 7", ] .join("\n"); - let stderr = vec!["error 1", "error 2", "error 3", "error 4", "error 5"].join("\n"); + let stderr = ["error 1", "error 2", "error 3", "error 4", "error 5"].join("\n"); let actual = truncate_shell_output(&stdout, &stderr, 2, 2, 2000); let expected = TruncatedShellOutput::default() @@ -297,8 +297,8 @@ mod tests { #[test] fn test_only_prefix_lines() { - let stdout = vec!["line 1", "line 2", "line 3", "line 4", "line 5"].join("\n"); - let stderr = vec!["error 1", "error 2", "error 3"].join("\n"); + let stdout = ["line 1", "line 2", "line 3", "line 4", "line 5"].join("\n"); + let stderr = ["error 1", "error 2", "error 3"].join("\n"); let actual = truncate_shell_output(&stdout, &stderr, 2, 0, 2000); let expected = TruncatedShellOutput::default() @@ -324,8 +324,8 @@ mod tests { #[test] fn test_only_suffix_lines() { - let stdout = vec!["line 1", "line 2", "line 3", "line 4", "line 5"].join("\n"); - let stderr = vec!["error 1", "error 2", "error 3"].join("\n"); + let stdout = ["line 1", "line 2", "line 3", "line 4", "line 5"].join("\n"); + let stderr = ["error 1", "error 2", "error 3"].join("\n"); let actual = truncate_shell_output(&stdout, &stderr, 0, 2, 2000); let expected = TruncatedShellOutput::default() @@ -351,7 +351,7 @@ mod tests { #[test] fn test_long_line() { - let stdout = vec![ + let stdout = [ "line 1 ", "line abcdefghijklmnopqrstuvwxyz", "line 2", @@ -361,7 +361,7 @@ mod tests { ] .join("\n"); - let actual = truncate_shell_output(&stdout, "", usize::max_value(), usize::max_value(), 10); + let actual = truncate_shell_output(&stdout, "", usize::MAX, usize::MAX, 10); let expected = TruncatedShellOutput::default().stdout( Stdout::default() .head("line 1 \nline abcde...[21 more chars truncated]\nline 2\nline 3\nline 4\nline 5") @@ -375,7 +375,7 @@ mod tests { #[test] fn test_line_truncation_with_multiple_long_lines() { - let stdout = vec![ + let stdout = [ "short", "this is a very long line that exceeds limit", "another very long line that also exceeds the limit", @@ -383,7 +383,7 @@ mod tests { ] .join("\n"); - let actual = truncate_shell_output(&stdout, "", usize::max_value(), usize::max_value(), 15); + let actual = truncate_shell_output(&stdout, "", usize::MAX, usize::MAX, 15); let expected = TruncatedShellOutput::default().stdout( Stdout::default() .head("short\nthis is a very ...[28 more chars truncated]\nanother very lo...[35 more chars truncated]\nshort again") @@ -397,7 +397,7 @@ mod tests { #[test] fn test_line_truncation_with_line_count_truncation() { - let stdout = vec![ + let stdout = [ "line 1", "very long line that will be truncated", "line 3", @@ -425,15 +425,14 @@ mod tests { #[test] fn test_no_line_truncation_when_limit_not_set() { - let stdout = vec![ + let stdout = [ "line 1", "very long line that will not be truncated because no limit is set", "line 3", ] .join("\n"); - let actual = - truncate_shell_output(&stdout, "", usize::max_value(), usize::max_value(), 2000); + let actual = truncate_shell_output(&stdout, "", usize::MAX, usize::MAX, 2000); let expected = TruncatedShellOutput::default().stdout( Stdout::default() .head("line 1\nvery long line that will not be truncated because no limit is set\nline 3") @@ -445,7 +444,7 @@ mod tests { } #[test] fn test_clip_by_lines_with_unicode_chars() { - let fixture = vec![ + let fixture = [ "emoji 😀 line", "Unicode café résumé naïve", "Regular ASCII line", diff --git a/crates/forge_ci/src/workflows/ci.rs b/crates/forge_ci/src/workflows/ci.rs index 02cef58175..7919229861 100644 --- a/crates/forge_ci/src/workflows/ci.rs +++ b/crates/forge_ci/src/workflows/ci.rs @@ -25,7 +25,8 @@ pub fn generate_ci_workflow() { ) .add_step(Step::new("Cargo Fmt").run("cargo +nightly fmt --all --check")) .add_step( - Step::new("Cargo Clippy").run("cargo +nightly clippy --all-features --workspace"), + Step::new("Cargo Clippy") + .run("cargo +nightly clippy --all-features --all-targets --workspace"), ); let draft_release_job = jobs::create_draft_release_job("build"); diff --git a/crates/forge_display/src/diff.rs b/crates/forge_display/src/diff.rs index e9fb69de0b..9b25f80393 100644 --- a/crates/forge_display/src/diff.rs +++ b/crates/forge_display/src/diff.rs @@ -154,7 +154,7 @@ mod tests { let old = "line 1\nline 2\nline 3\nline 4\nline 5"; let new = "line 1\nline 2\nline 3"; let diff = DiffFormat::format(old, new); - let clean_diff = strip_ansi_codes(&diff.diff()); + let clean_diff = strip_ansi_codes(diff.diff()); assert_eq!(diff.lines_added(), 1); assert_eq!(diff.lines_removed(), 3); assert_snapshot!(clean_diff); @@ -165,7 +165,7 @@ mod tests { let old = "line 1\nline 2\nline 3\nline 5\nline 6\nline 7\nline 8\nline 9"; let new = "line 1\nmodified line\nline 3\nline 5\nline 6\nline 7\nline 8\nline 9"; let diff = DiffFormat::format(old, new); - let clean_diff = strip_ansi_codes(&diff.diff()); + let clean_diff = strip_ansi_codes(diff.diff()); assert_eq!(diff.lines_added(), 1); assert_eq!(diff.lines_removed(), 1); assert_snapshot!(clean_diff); @@ -181,7 +181,7 @@ mod tests { let old = old_lines.join("\n"); let new = new_lines.join("\n"); let diff = DiffFormat::format(&old, &new); - let clean_diff = strip_ansi_codes(&diff.diff()); + let clean_diff = strip_ansi_codes(diff.diff()); // With 150 lines, width should be 3 (for numbers like "100") // Verify the format includes proper spacing @@ -201,7 +201,7 @@ mod tests { let old = old_lines.join("\n"); let new = new_lines.join("\n"); let diff = DiffFormat::format(&old, &new); - let clean_diff = strip_ansi_codes(&diff.diff()); + let clean_diff = strip_ansi_codes(diff.diff()); // Diff only shows lines 3-8 (context), so width should be 1 (for single digit // numbers) NOT 4 (which would be needed for line 1000) diff --git a/crates/forge_domain/src/agent.rs b/crates/forge_domain/src/agent.rs index edf18ee3a8..fadd46d4c0 100644 --- a/crates/forge_domain/src/agent.rs +++ b/crates/forge_domain/src/agent.rs @@ -747,7 +747,7 @@ mod tests { let mut fixture = Agent::new("test-agent"); fixture.add_subscription("string_literal"); fixture.add_subscription(String::from("owned_string")); - fixture.add_subscription(&"string_ref".to_string()); + fixture.add_subscription("string_ref".to_string()); let actual = fixture.subscribe.as_ref().unwrap(); let expected = vec![ diff --git a/crates/forge_domain/src/attachment.rs b/crates/forge_domain/src/attachment.rs index d78e0d0e43..d3f12a072d 100644 --- a/crates/forge_domain/src/attachment.rs +++ b/crates/forge_domain/src/attachment.rs @@ -178,7 +178,7 @@ mod tests { let paths = Attachment::parse_all(text); assert_eq!(paths.len(), 1); - let path_found = paths.iter().next().unwrap(); + let path_found = paths.first().unwrap(); assert_eq!(path_found.path, "/path/to/file.txt"); } @@ -188,7 +188,7 @@ mod tests { let paths = Attachment::parse_all(text); assert_eq!(paths.len(), 1); - let path_found = paths.iter().next().unwrap(); + let path_found = paths.first().unwrap(); assert_eq!(path_found.path, "/path/with spaces/file.txt"); } @@ -250,7 +250,7 @@ mod tests { loc: Some(Location { start: Some(10), end: Some(20) }), symbol: None, }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -265,7 +265,7 @@ mod tests { loc: None, symbol: Some("my_function".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -280,7 +280,7 @@ mod tests { loc: Some(Location { start: Some(5), end: Some(15) }), symbol: Some("main_function".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -327,7 +327,7 @@ mod tests { loc: None, symbol: Some("function_with_underscore_123".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -342,7 +342,7 @@ mod tests { loc: Some(Location { start: Some(0), end: Some(999999) }), symbol: None, }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -357,7 +357,7 @@ mod tests { loc: Some(Location { start: Some(12), end: None }), symbol: Some("main()".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -372,7 +372,7 @@ mod tests { loc: Some(Location { start: Some(12), end: None }), symbol: Some("main()".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -387,7 +387,7 @@ mod tests { loc: Some(Location { start: Some(10), end: Some(20) }), symbol: None, }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -398,7 +398,7 @@ mod tests { assert_eq!(paths.len(), 1); let expected = FileTag { path: "D:\\file.txt".to_string(), loc: None, symbol: None }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -413,7 +413,7 @@ mod tests { loc: None, symbol: Some("function_name".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -428,7 +428,7 @@ mod tests { loc: Some(Location { start: Some(42), end: None }), symbol: None, }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -443,7 +443,7 @@ mod tests { loc: Some(Location { start: Some(5), end: Some(15) }), symbol: Some("test_function".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -458,7 +458,7 @@ mod tests { loc: Some(Location { start: Some(25), end: Some(30) }), symbol: None, }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -473,7 +473,7 @@ mod tests { loc: Some(Location { start: Some(100), end: None }), symbol: None, }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -488,7 +488,7 @@ mod tests { loc: None, symbol: None, }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -503,7 +503,7 @@ mod tests { loc: None, symbol: Some("main".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } @@ -518,7 +518,7 @@ mod tests { loc: Some(Location { start: Some(10), end: None }), symbol: Some("setup_function".to_string()), }; - let actual = paths.iter().next().unwrap(); + let actual = paths.first().unwrap(); assert_eq!(actual, &expected); } diff --git a/crates/forge_domain/src/compact.rs b/crates/forge_domain/src/compact.rs index f3c126ce54..6109d45c80 100644 --- a/crates/forge_domain/src/compact.rs +++ b/crates/forge_domain/src/compact.rs @@ -197,8 +197,8 @@ mod tests { /// Creates a Context from a condensed string pattern where: /// - 'u' = User message /// - 'a' = Assistant message - /// - 's' = System message - /// Example: ctx("uau") creates User -> Assistant -> User messages + /// - 's' = System message Example: ctx("uau") creates User -> Assistant -> + /// User messages fn ctx(pattern: &str) -> Context { let messages: Vec = pattern .chars() diff --git a/crates/forge_domain/src/context.rs b/crates/forge_domain/src/context.rs index 2febc7b844..af1589cbee 100644 --- a/crates/forge_domain/src/context.rs +++ b/crates/forge_domain/src/context.rs @@ -712,14 +712,12 @@ mod tests { assert_eq!(actual, expected); // case 2: context with usage - since total_tokens present return that. - let mut usage = Usage::default(); - usage.total_tokens = TokenCount::Actual(100); + let usage = Usage { total_tokens: TokenCount::Actual(100), ..Default::default() }; let fixture = Context::default().usage(usage); assert_eq!(fixture.token_count(), TokenCount::Actual(100)); // case 3: context with usage - since total_tokens present return that. - let mut usage = Usage::default(); - usage.total_tokens = TokenCount::Actual(80); + let usage = Usage { total_tokens: TokenCount::Actual(80), ..Default::default() }; let fixture = Context::default().usage(usage); assert_eq!(fixture.token_count(), TokenCount::Actual(80)); diff --git a/crates/forge_domain/src/conversation_html.rs b/crates/forge_domain/src/conversation_html.rs index 25364545e5..9858c0aa5b 100644 --- a/crates/forge_domain/src/conversation_html.rs +++ b/crates/forge_domain/src/conversation_html.rs @@ -245,6 +245,40 @@ fn create_conversation_context_section(conversation: &Conversation) -> Element { } } +fn create_reasoning_config_section(conversation: &Conversation) -> Element { + let section = + Element::new("div.section").append(Element::new("h2").text("Reasoning Configuration")); + + if let Some(context) = &conversation.context { + if let Some(reasoning_config) = &context.reasoning { + section + .append( + Element::new("p") + .append(Element::new("strong").text("Status: ")) + .text(match reasoning_config.enabled { + Some(true) => "Enabled", + Some(false) => "Disabled", + None => "Not specified", + }), + ) + .append( + Element::new("p") + .append(Element::new("strong").text("Effort: ")) + .text(format!("{:?}", reasoning_config.effort)), + ) + .append(reasoning_config.max_tokens.map(|max_tokens| { + Element::new("p") + .append(Element::new("strong").text("Max Tokens: ")) + .text(format!("{:?}", max_tokens)) + })) + } else { + section.append(Element::new("p").text("No reasoning configuration found")) + } + } else { + section.append(Element::new("p").text("No context available")) + } +} + #[cfg(test)] mod tests { use super::*; @@ -312,37 +346,3 @@ mod tests { assert!(actual.contains("🧠 Reasoning")); } } - -fn create_reasoning_config_section(conversation: &Conversation) -> Element { - let section = - Element::new("div.section").append(Element::new("h2").text("Reasoning Configuration")); - - if let Some(context) = &conversation.context { - if let Some(reasoning_config) = &context.reasoning { - section - .append( - Element::new("p") - .append(Element::new("strong").text("Status: ")) - .text(match reasoning_config.enabled { - Some(true) => "Enabled", - Some(false) => "Disabled", - None => "Not specified", - }), - ) - .append( - Element::new("p") - .append(Element::new("strong").text("Effort: ")) - .text(format!("{:?}", reasoning_config.effort)), - ) - .append(reasoning_config.max_tokens.map(|max_tokens| { - Element::new("p") - .append(Element::new("strong").text("Max Tokens: ")) - .text(format!("{:?}", max_tokens)) - })) - } else { - section.append(Element::new("p").text("No reasoning configuration found")) - } - } else { - section.append(Element::new("p").text("No context available")) - } -} diff --git a/crates/forge_domain/src/error.rs b/crates/forge_domain/src/error.rs index d59b06d91f..478541dec3 100644 --- a/crates/forge_domain/src/error.rs +++ b/crates/forge_domain/src/error.rs @@ -115,7 +115,7 @@ mod test { #[test] fn test_debug_serde_error() { let args = "{a: 1}"; - let serde_error = serde_json::from_str::(&args).unwrap_err(); + let serde_error = serde_json::from_str::(args).unwrap_err(); let a = Error::ToolCallArgument { error: JsonRepairError::from(serde_error), args: args.to_string(), diff --git a/crates/forge_domain/src/http_config.rs b/crates/forge_domain/src/http_config.rs index d2dd9a1466..58a264c9bd 100644 --- a/crates/forge_domain/src/http_config.rs +++ b/crates/forge_domain/src/http_config.rs @@ -235,10 +235,10 @@ mod tests { fn test_http_config_http2_defaults() { let config = HttpConfig::default(); - assert_eq!(config.adaptive_window, true); + assert!(config.adaptive_window); assert_eq!(config.keep_alive_interval, Some(60)); assert_eq!(config.keep_alive_timeout, 10); - assert_eq!(config.keep_alive_while_idle, true); + assert!(config.keep_alive_while_idle); } #[test] @@ -251,22 +251,22 @@ mod tests { ..HttpConfig::default() }; - assert_eq!(config.adaptive_window, false); + assert!(!config.adaptive_window); assert_eq!(config.keep_alive_interval, None); assert_eq!(config.keep_alive_timeout, 30); - assert_eq!(config.keep_alive_while_idle, false); + assert!(!config.keep_alive_while_idle); } #[test] fn test_http_config_accept_invalid_certs_defaults() { let config = HttpConfig::default(); - assert_eq!(config.accept_invalid_certs, false); + assert!(!config.accept_invalid_certs); } #[test] fn test_http_config_accept_invalid_certs_custom() { let config = HttpConfig { accept_invalid_certs: true, ..HttpConfig::default() }; - assert_eq!(config.accept_invalid_certs, true); + assert!(config.accept_invalid_certs); } #[test] diff --git a/crates/forge_domain/src/mcp.rs b/crates/forge_domain/src/mcp.rs index 0dd6ed07dc..96813d32cc 100644 --- a/crates/forge_domain/src/mcp.rs +++ b/crates/forge_domain/src/mcp.rs @@ -256,14 +256,12 @@ mod tests { #[test] fn test_mcp_server_config_disabled() { - let mut server = McpStdioServer::default(); - server.disable = true; + let server = McpStdioServer { disable: true, ..Default::default() }; let config = McpServerConfig::Stdio(server); assert!(config.is_disabled()); - let mut sse_server = McpSseServer::default(); - sse_server.disable = false; + let sse_server = McpSseServer { disable: false, ..Default::default() }; let config = McpServerConfig::Sse(sse_server); assert!(!config.is_disabled()); diff --git a/crates/forge_domain/src/policies/config.rs b/crates/forge_domain/src/policies/config.rs index c86fc5513e..4829f5474b 100644 --- a/crates/forge_domain/src/policies/config.rs +++ b/crates/forge_domain/src/policies/config.rs @@ -47,6 +47,17 @@ impl PolicyConfig { } } +impl Display for PolicyConfig { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if self.policies.is_empty() { + write!(f, "No policies defined") + } else { + let policies: Vec = self.policies.iter().map(|p| format!("• {p}")).collect(); + write!(f, "Policies:\n{}", policies.join("\n")) + } + } +} + #[cfg(test)] mod tests { use std::path::PathBuf; @@ -118,14 +129,3 @@ mod tests { } } } - -impl Display for PolicyConfig { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if self.policies.is_empty() { - write!(f, "No policies defined") - } else { - let policies: Vec = self.policies.iter().map(|p| format!("• {p}")).collect(); - write!(f, "Policies:\n{}", policies.join("\n")) - } - } -} diff --git a/crates/forge_domain/src/policies/engine.rs b/crates/forge_domain/src/policies/engine.rs index cade24a3d7..dde65473a1 100644 --- a/crates/forge_domain/src/policies/engine.rs +++ b/crates/forge_domain/src/policies/engine.rs @@ -94,43 +94,38 @@ mod tests { use crate::{ExecuteRule, Fetch, Permission, Policy, PolicyConfig, ReadRule, Rule, WriteRule}; fn fixture_workflow_with_read_policy() -> PolicyConfig { - let policies = PolicyConfig::new().add_policy(Policy::Simple { + PolicyConfig::new().add_policy(Policy::Simple { permission: Permission::Allow, rule: Rule::Read(ReadRule { read: "src/**/*.rs".to_string(), dir: None }), - }); - policies + }) } fn fixture_workflow_with_write_policy() -> PolicyConfig { - let policies = PolicyConfig::new().add_policy(Policy::Simple { + PolicyConfig::new().add_policy(Policy::Simple { permission: Permission::Deny, rule: Rule::Write(WriteRule { write: "**/*.rs".to_string(), dir: None }), - }); - policies + }) } fn fixture_workflow_with_execute_policy() -> PolicyConfig { - let policies = PolicyConfig::new().add_policy(Policy::Simple { + PolicyConfig::new().add_policy(Policy::Simple { permission: Permission::Allow, rule: Rule::Execute(ExecuteRule { command: "cargo *".to_string(), dir: None }), - }); - policies + }) } fn fixture_workflow_with_write_policy_confirm() -> PolicyConfig { - let policies = PolicyConfig::new().add_policy(Policy::Simple { + PolicyConfig::new().add_policy(Policy::Simple { permission: Permission::Confirm, rule: Rule::Write(WriteRule { write: "src/**/*.rs".to_string(), dir: None }), - }); - policies + }) } fn fixture_workflow_with_net_fetch_policy() -> PolicyConfig { - let policies = PolicyConfig::new().add_policy(Policy::Simple { + PolicyConfig::new().add_policy(Policy::Simple { permission: Permission::Allow, rule: Rule::Fetch(Fetch { url: "https://api.example.com/*".to_string(), dir: None }), - }); - policies + }) } #[test] diff --git a/crates/forge_domain/src/policies/rule.rs b/crates/forge_domain/src/policies/rule.rs index cdd645f109..9488684df9 100644 --- a/crates/forge_domain/src/policies/rule.rs +++ b/crates/forge_domain/src/policies/rule.rs @@ -113,6 +113,57 @@ fn match_pattern>(pattern: &str, target: P) -> bool { } } +impl Display for WriteRule { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if let Some(wd) = &self.dir { + write!(f, "write '{}' in '{}'", self.write, wd) + } else { + write!(f, "write '{}'", self.write) + } + } +} + +impl Display for ReadRule { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if let Some(wd) = &self.dir { + write!(f, "read '{}' in '{}'", self.read, wd) + } else { + write!(f, "read '{}'", self.read) + } + } +} + +impl Display for ExecuteRule { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if let Some(wd) = &self.dir { + write!(f, "execute '{}' in '{}'", self.command, wd) + } else { + write!(f, "execute '{}'", self.command) + } + } +} + +impl Display for Fetch { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if let Some(wd) = &self.dir { + write!(f, "fetch '{}' in '{}'", self.url, wd) + } else { + write!(f, "fetch '{}'", self.url) + } + } +} + +impl Display for Rule { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Rule::Write(rule) => write!(f, "{rule}"), + Rule::Read(rule) => write!(f, "{rule}"), + Rule::Execute(rule) => write!(f, "{rule}"), + Rule::Fetch(rule) => write!(f, "{rule}"), + } + } +} + #[cfg(test)] mod tests { use std::path::PathBuf; @@ -279,54 +330,3 @@ mod tests { assert_eq!(actual, true); } } - -impl Display for WriteRule { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if let Some(wd) = &self.dir { - write!(f, "write '{}' in '{}'", self.write, wd) - } else { - write!(f, "write '{}'", self.write) - } - } -} - -impl Display for ReadRule { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if let Some(wd) = &self.dir { - write!(f, "read '{}' in '{}'", self.read, wd) - } else { - write!(f, "read '{}'", self.read) - } - } -} - -impl Display for ExecuteRule { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if let Some(wd) = &self.dir { - write!(f, "execute '{}' in '{}'", self.command, wd) - } else { - write!(f, "execute '{}'", self.command) - } - } -} - -impl Display for Fetch { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if let Some(wd) = &self.dir { - write!(f, "fetch '{}' in '{}'", self.url, wd) - } else { - write!(f, "fetch '{}'", self.url) - } - } -} - -impl Display for Rule { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Rule::Write(rule) => write!(f, "{rule}"), - Rule::Read(rule) => write!(f, "{rule}"), - Rule::Execute(rule) => write!(f, "{rule}"), - Rule::Fetch(rule) => write!(f, "{rule}"), - } - } -} diff --git a/crates/forge_domain/src/transformer/drop_reasoning_details.rs b/crates/forge_domain/src/transformer/drop_reasoning_details.rs index 1efca1333c..4403f763ae 100644 --- a/crates/forge_domain/src/transformer/drop_reasoning_details.rs +++ b/crates/forge_domain/src/transformer/drop_reasoning_details.rs @@ -93,7 +93,7 @@ mod tests { #[test] fn test_drop_reasoning_details_removes_reasoning() { let fixture = create_context_with_reasoning_details(); - let mut transformer = DropReasoningDetails::default(); + let mut transformer = DropReasoningDetails; let actual = transformer.transform(fixture.clone()); let snapshot = TransformationSnapshot::new("DropReasoningDetails", fixture, actual); @@ -115,7 +115,7 @@ mod tests { reasoning_details: Some(reasoning_details), })); - let mut transformer = DropReasoningDetails::default(); + let mut transformer = DropReasoningDetails; let actual = transformer.transform(fixture.clone()); let snapshot = @@ -126,7 +126,7 @@ mod tests { #[test] fn test_drop_reasoning_details_mixed_message_types() { let fixture = create_context_with_mixed_messages(); - let mut transformer = DropReasoningDetails::default(); + let mut transformer = DropReasoningDetails; let actual = transformer.transform(fixture.clone()); let snapshot = @@ -141,7 +141,7 @@ mod tests { .add_message(ContextMessage::assistant("Assistant message", None, None)) .add_message(ContextMessage::system("System message")); - let mut transformer = DropReasoningDetails::default(); + let mut transformer = DropReasoningDetails; let actual = transformer.transform(fixture.clone()); let expected = fixture; @@ -172,7 +172,7 @@ mod tests { output: ToolOutput::text("Tool output".to_string()), }]); - let mut transformer = DropReasoningDetails::default(); + let mut transformer = DropReasoningDetails; let actual = transformer.transform(fixture.clone()); let snapshot = diff --git a/crates/forge_domain/src/transformer/reasoning_normalizer.rs b/crates/forge_domain/src/transformer/reasoning_normalizer.rs index 34bcd8d9a2..c1293a3911 100644 --- a/crates/forge_domain/src/transformer/reasoning_normalizer.rs +++ b/crates/forge_domain/src/transformer/reasoning_normalizer.rs @@ -131,7 +131,7 @@ mod tests { #[test] fn test_reasoning_normalizer_keeps_all_when_first_has_reasoning() { let fixture = create_context_first_assistant_has_reasoning(); - let mut transformer = ReasoningNormalizer::default(); + let mut transformer = ReasoningNormalizer; let actual = transformer.transform(fixture.clone()); // All reasoning details should be preserved since first assistant has reasoning @@ -143,7 +143,7 @@ mod tests { #[test] fn test_reasoning_normalizer_removes_all_when_first_assistant_message_has_no_reasoning() { let context = create_context_first_assistant_no_reasoning(); - let mut transformer = ReasoningNormalizer::default(); + let mut transformer = ReasoningNormalizer; let actual = transformer.transform(context.clone()); // All reasoning details should be removed since first assistant has no @@ -159,7 +159,7 @@ mod tests { .reasoning(ReasoningConfig::default().enabled(true)) .add_message(ContextMessage::system("System message")) .add_message(ContextMessage::user("User message", None)); - let mut transformer = ReasoningNormalizer::default(); + let mut transformer = ReasoningNormalizer; let actual = transformer.transform(context.clone()); // All reasoning details should be removed since first assistant has no diff --git a/crates/forge_infra/src/env.rs b/crates/forge_infra/src/env.rs index 0abaabd101..a670560350 100644 --- a/crates/forge_infra/src/env.rs +++ b/crates/forge_infra/src/env.rs @@ -384,7 +384,7 @@ mod tests { assert_eq!(actual.backoff_factor, 3); assert_eq!(actual.max_retry_attempts, 5); assert_eq!(actual.retry_status_codes, vec![429, 500, 502]); - assert_eq!(actual.suppress_retry_errors, true); + assert!(actual.suppress_retry_errors); clean_retry_env_vars(); } @@ -441,11 +441,11 @@ mod tests { let actual = resolve_http_config(); assert_eq!(actual.connect_timeout, 30); - assert_eq!(actual.hickory, true); + assert!(actual.hickory); assert_eq!(actual.tls_backend, TlsBackend::Rustls); assert_eq!(actual.min_tls_version, Some(TlsVersion::V1_2)); assert_eq!(actual.keep_alive_interval, Some(30)); - assert_eq!(actual.accept_invalid_certs, true); + assert!(actual.accept_invalid_certs); assert_eq!( actual.root_cert_paths, Some(vec![ @@ -525,7 +525,7 @@ mod tests { env::remove_var("FORGE_DUMP_AUTO_OPEN"); } let env = infra.get_environment(); - assert_eq!(env.auto_open_dump, false); + assert!(!env.auto_open_dump); } // Test enabled with "true" @@ -534,7 +534,7 @@ mod tests { env::set_var("FORGE_DUMP_AUTO_OPEN", "true"); } let env = infra.get_environment(); - assert_eq!(env.auto_open_dump, true); + assert!(env.auto_open_dump); unsafe { env::remove_var("FORGE_DUMP_AUTO_OPEN"); } @@ -546,7 +546,7 @@ mod tests { env::set_var("FORGE_DUMP_AUTO_OPEN", "1"); } let env = infra.get_environment(); - assert_eq!(env.auto_open_dump, true); + assert!(env.auto_open_dump); unsafe { env::remove_var("FORGE_DUMP_AUTO_OPEN"); } @@ -558,7 +558,7 @@ mod tests { env::set_var("FORGE_DUMP_AUTO_OPEN", "TRUE"); } let env = infra.get_environment(); - assert_eq!(env.auto_open_dump, true); + assert!(env.auto_open_dump); unsafe { env::remove_var("FORGE_DUMP_AUTO_OPEN"); } @@ -570,7 +570,7 @@ mod tests { env::set_var("FORGE_DUMP_AUTO_OPEN", "false"); } let env = infra.get_environment(); - assert_eq!(env.auto_open_dump, false); + assert!(!env.auto_open_dump); unsafe { env::remove_var("FORGE_DUMP_AUTO_OPEN"); } @@ -582,7 +582,7 @@ mod tests { env::set_var("FORGE_DUMP_AUTO_OPEN", "0"); } let env = infra.get_environment(); - assert_eq!(env.auto_open_dump, false); + assert!(!env.auto_open_dump); unsafe { env::remove_var("FORGE_DUMP_AUTO_OPEN"); } @@ -594,7 +594,7 @@ mod tests { env::set_var("FORGE_DUMP_AUTO_OPEN", "invalid"); } let env = infra.get_environment(); - assert_eq!(env.auto_open_dump, false); + assert!(!env.auto_open_dump); unsafe { env::remove_var("FORGE_DUMP_AUTO_OPEN"); } diff --git a/crates/forge_main/src/completer/input_completer.rs b/crates/forge_main/src/completer/input_completer.rs index 065a604fde..910923da6b 100644 --- a/crates/forge_main/src/completer/input_completer.rs +++ b/crates/forge_main/src/completer/input_completer.rs @@ -143,7 +143,7 @@ mod tests { let actual = completer.complete("@cfg", 4); // Should find config.rs and another_config.toml - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let config_match = actual.iter().find(|s| s.value.contains("config.rs")); assert!( config_match.is_some(), @@ -175,7 +175,7 @@ mod tests { // Test that literal matching still works for exact substrings let actual = completer.complete("@main", 5); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let main_match = actual.iter().find(|s| s.value.contains("main.rs")); assert!( main_match.is_some(), @@ -190,7 +190,7 @@ mod tests { // Test dollar '$' at the end let actual = completer.complete("@main$", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("main$")); assert!( match_found.is_some(), @@ -205,7 +205,7 @@ mod tests { // Test dollar '$' at the start let actual = completer.complete("@$main", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("$main")); assert!( match_found.is_some(), @@ -220,7 +220,7 @@ mod tests { // Test dollar '$' in the middle let actual = completer.complete("@ma$in", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("ma$in")); assert!( match_found.is_some(), @@ -235,7 +235,7 @@ mod tests { // Test caret '^' at the start let actual = completer.complete("@^main", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("^main")); assert!( match_found.is_some(), @@ -250,7 +250,7 @@ mod tests { // Test caret '^' at the end let actual = completer.complete("@main^", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("main^")); assert!( match_found.is_some(), @@ -265,7 +265,7 @@ mod tests { // Test caret '^' in the middle let actual = completer.complete("@ma^in", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("ma^in")); assert!( match_found.is_some(), @@ -280,7 +280,7 @@ mod tests { // Test exclamation '!' at the start let actual = completer.complete("@!test", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("!test")); assert!( match_found.is_some(), @@ -295,7 +295,7 @@ mod tests { // Test exclamation '!' at the end let actual = completer.complete("@test!", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("test!")); assert!( match_found.is_some(), @@ -310,7 +310,7 @@ mod tests { // Test exclamation '!' in the middle let actual = completer.complete("@te!st", 6); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("te!st")); assert!( match_found.is_some(), @@ -325,7 +325,7 @@ mod tests { // Test single quote '\'' at the start let actual = completer.complete("@'lib", 5); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("'lib")); assert!( match_found.is_some(), @@ -340,7 +340,7 @@ mod tests { // Test single quote '\'' at the end let actual = completer.complete("@lib'", 5); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("lib'")); assert!( match_found.is_some(), @@ -355,7 +355,7 @@ mod tests { // Test single quote '\'' in the middle let actual = completer.complete("@li'b", 5); - assert!(actual.len() >= 1); + assert!(!actual.is_empty()); let match_found = actual.iter().find(|s| s.value.contains("li'b")); assert!( match_found.is_some(), diff --git a/crates/forge_main/src/config/handler.rs b/crates/forge_main/src/config/handler.rs index f10dd0a43f..e4ebee5e8d 100644 --- a/crates/forge_main/src/config/handler.rs +++ b/crates/forge_main/src/config/handler.rs @@ -201,7 +201,7 @@ mod tests { #[test] fn test_get_valid_provider_names() { let fixture = get_valid_provider_names(); - let actual = fixture.len() > 0; + let actual = !fixture.is_empty(); let expected = true; assert_eq!(actual, expected); } diff --git a/crates/forge_main/src/conversation_selector.rs b/crates/forge_main/src/conversation_selector.rs index bb62ae4591..c32eb30929 100644 --- a/crates/forge_main/src/conversation_selector.rs +++ b/crates/forge_main/src/conversation_selector.rs @@ -114,7 +114,7 @@ mod tests { #[test] fn test_select_conversation_with_titles() { - let conversations = vec![ + let conversations = [ create_test_conversation( "550e8400-e29b-41d4-a716-446655440000", Some("First Conversation"), @@ -132,7 +132,7 @@ mod tests { #[test] fn test_select_conversation_without_titles() { - let conversations = vec![ + let conversations = [ create_test_conversation("550e8400-e29b-41d4-a716-446655440002", None), create_test_conversation("550e8400-e29b-41d4-a716-446655440003", None), ]; diff --git a/crates/forge_main/src/info.rs b/crates/forge_main/src/info.rs index 5ea3b42650..8635a47a35 100644 --- a/crates/forge_main/src/info.rs +++ b/crates/forge_main/src/info.rs @@ -563,11 +563,7 @@ mod tests { let path = PathBuf::from("C:\\Users\\User\\project"); let actual = super::format_path_for_display(&fixture, &path); - let expected = if cfg!(windows) { - "C:\\Users\\User\\project" - } else { - "C:\\Users\\User\\project" - }; + let expected = "C:\\Users\\User\\project"; assert_eq!(actual, expected); } @@ -577,11 +573,7 @@ mod tests { let path = PathBuf::from("C:\\Users\\User Name\\project"); let actual = super::format_path_for_display(&fixture, &path); - let expected = if cfg!(windows) { - "\"C:\\Users\\User Name\\project\"" - } else { - "\"C:\\Users\\User Name\\project\"" - }; + let expected = "\"C:\\Users\\User Name\\project\""; assert_eq!(actual, expected); } diff --git a/crates/forge_select/src/select.rs b/crates/forge_select/src/select.rs index 6b61710f9f..c5f44acf7c 100644 --- a/crates/forge_select/src/select.rs +++ b/crates/forge_select/src/select.rs @@ -391,7 +391,7 @@ mod tests { #[test] fn test_ansi_stripping() { - let options = vec!["\x1b[1mBold\x1b[0m", "\x1b[31mRed\x1b[0m"]; + let options = ["\x1b[1mBold\x1b[0m", "\x1b[31mRed\x1b[0m"]; let display: Vec = options .iter() .map(|s| strip_ansi_codes(s).to_string()) diff --git a/crates/forge_services/src/attachment.rs b/crates/forge_services/src/attachment.rs index fc017733ee..a3dbbb9b2e 100644 --- a/crates/forge_services/src/attachment.rs +++ b/crates/forge_services/src/attachment.rs @@ -808,7 +808,7 @@ pub mod tests { // Test reading line 2 only let url = "@[/test/multiline.txt:2:2]"; - let attachments = chat_request.attachments(&url).await.unwrap(); + let attachments = chat_request.attachments(url).await.unwrap(); assert_eq!(attachments.len(), 1); assert_eq!( @@ -836,7 +836,7 @@ pub mod tests { // Test reading lines 2-4 let url = "@[/test/range_test.txt:2:4]"; - let attachments = chat_request.attachments(&url).await.unwrap(); + let attachments = chat_request.attachments(url).await.unwrap(); assert_eq!(attachments.len(), 1); assert_eq!(attachments.len(), 1); @@ -864,7 +864,7 @@ pub mod tests { // Test reading from start to line 2 let url = "@[/test/start_range.txt:1:2]"; - let attachments = chat_request.attachments(&url).await.unwrap(); + let attachments = chat_request.attachments(url).await.unwrap(); assert_eq!( attachments[0].content, AttachmentContent::FileContent { @@ -889,7 +889,7 @@ pub mod tests { // Test reading from line 3 to end let url = "@[/test/end_range.txt:3:5]"; - let attachments = chat_request.attachments(&url).await.unwrap(); + let attachments = chat_request.attachments(url).await.unwrap(); assert_eq!( attachments[0].content, AttachmentContent::FileContent { @@ -914,7 +914,7 @@ pub mod tests { // Test reading beyond file length let url = "@[/test/edge_case.txt:1:10]"; - let attachments = chat_request.attachments(&url).await.unwrap(); + let attachments = chat_request.attachments(url).await.unwrap(); assert_eq!( attachments[0].content, AttachmentContent::FileContent { @@ -940,7 +940,7 @@ pub mod tests { // Test multiple files with different ranges let url = "Check @[/test/file_a.txt:1:2] and @[/test/file_b.txt:3:4]"; - let attachments = chat_request.attachments(&url).await.unwrap(); + let attachments = chat_request.attachments(url).await.unwrap(); assert_eq!(attachments.len(), 2); assert_eq!( @@ -976,7 +976,7 @@ pub mod tests { // Test that metadata is preserved correctly with ranges let url = "@[/test/metadata_test.txt:3:5]"; - let attachments = chat_request.attachments(&url).await.unwrap(); + let attachments = chat_request.attachments(url).await.unwrap(); assert_eq!(attachments.len(), 1); assert_eq!(attachments[0].path, "/test/metadata_test.txt"); @@ -1007,9 +1007,9 @@ pub mod tests { let url_range = "@[/test/comparison.txt:2:4]"; let url_range_start = "@[/test/comparison.txt:2]"; - let attachments_full = chat_request.attachments(&url_full).await.unwrap(); - let attachments_range = chat_request.attachments(&url_range).await.unwrap(); - let attachments_range_start = chat_request.attachments(&url_range_start).await.unwrap(); + let attachments_full = chat_request.attachments(url_full).await.unwrap(); + let attachments_range = chat_request.attachments(url_range).await.unwrap(); + let attachments_range_start = chat_request.attachments(url_range_start).await.unwrap(); assert_eq!(attachments_full.len(), 1); assert_eq!( diff --git a/crates/forge_services/src/provider/openai.rs b/crates/forge_services/src/provider/openai.rs index a0c9bcd991..fb003ed5c9 100644 --- a/crates/forge_services/src/provider/openai.rs +++ b/crates/forge_services/src/provider/openai.rs @@ -431,8 +431,10 @@ mod tests { let openai_provider = OpenAIProvider::new(provider, http_client); // Create a request with session_id - let mut request = Request::default(); - request.session_id = Some("test-conversation-id".to_string()); + let request = Request { + session_id: Some("test-conversation-id".to_string()), + ..Default::default() + }; let headers = openai_provider.get_headers_with_request(&request); @@ -458,8 +460,10 @@ mod tests { let openai_provider = OpenAIProvider::new(provider, http_client); // Create a request with session_id - let mut request = Request::default(); - request.session_id = Some("test-conversation-id".to_string()); + let request = Request { + session_id: Some("test-conversation-id".to_string()), + ..Default::default() + }; let headers = openai_provider.get_headers_with_request(&request); @@ -485,8 +489,10 @@ mod tests { let openai_provider = OpenAIProvider::new(provider, http_client); // Create a request with session_id - let mut request = Request::default(); - request.session_id = Some("test-conversation-id".to_string()); + let request = Request { + session_id: Some("test-conversation-id".to_string()), + ..Default::default() + }; let headers = openai_provider.get_headers_with_request(&request); @@ -530,8 +536,10 @@ mod tests { let openai_provider = OpenAIProvider::new(provider, http_client); // Create a request with session_id - let mut request = Request::default(); - request.session_id = Some("test-conversation-id".to_string()); + let request = Request { + session_id: Some("test-conversation-id".to_string()), + ..Default::default() + }; let headers = openai_provider.get_headers_with_request(&request);