diff --git a/crates/acp-utils/tests/client_session.rs b/crates/acp-utils/tests/client_session.rs index d4c51c748..a67f304fc 100644 --- a/crates/acp-utils/tests/client_session.rs +++ b/crates/acp-utils/tests/client_session.rs @@ -265,7 +265,7 @@ async fn v2_initialization_accessors_expose_agent_metadata() -> Result<(), TestE assert_eq!(client.agent_name(), "Display Name"); assert!(client.prompt_capabilities().is_some()); assert!(client.session_capabilities().is_some()); - assert!(client.auth_methods().is_empty()); + assert_eq!(client.auth_methods(), []); client.handle.disconnect().await; Ok(()) }) diff --git a/crates/acp-utils/tests/client_turns.rs b/crates/acp-utils/tests/client_turns.rs index 2d577ecfa..bf034ee2a 100644 --- a/crates/acp-utils/tests/client_turns.rs +++ b/crates/acp-utils/tests/client_turns.rs @@ -32,10 +32,10 @@ async fn prompts_and_resumes_do_not_gate_requests() { let first = fake.submit("one").await; let second = fake.submit("one").await; fake.client.handle.request(CloseSessionRequest::new("saved")).await.unwrap(); - assert!(fake.client.handle.request(ListSessionsRequest::new()).await.unwrap().sessions.is_empty()); + assert_eq!(fake.client.handle.request(ListSessionsRequest::new()).await.unwrap().sessions.len(), 0); let resume = fake.resume("two", true); let (_, responder) = fake.resumes.recv().await.unwrap(); - assert!(fake.client.handle.request(ListSessionsRequest::new()).await.unwrap().sessions.is_empty()); + assert_eq!(fake.client.handle.request(ListSessionsRequest::new()).await.unwrap().sessions.len(), 0); for replay in [false, true] { let other = fake.resume("other", replay); let (_, responder) = fake.resumes.recv().await.unwrap(); diff --git a/crates/acp-utils/tests/conversation.rs b/crates/acp-utils/tests/conversation.rs index c52c4fa66..a55efae0f 100644 --- a/crates/acp-utils/tests/conversation.rs +++ b/crates/acp-utils/tests/conversation.rs @@ -76,7 +76,7 @@ fn remote_user_resources_render_as_references_but_keep_their_blocks() { fn user_messages_appear_once_the_agent_inserts_them_and_are_keyed_by_message_id() { let mut conversation = Conversation::new(); conversation.apply_event(&running()); - assert!(conversation.items().is_empty()); + assert_eq!(conversation.items(), []); conversation.apply_event(&user_message("user", "prompt")); conversation.apply_event(&user_message("user", "prompt")); @@ -117,8 +117,8 @@ fn first_tool_update_creates_and_later_patches_replace_or_clear() { acp::ToolCallUpdate::new("tool").title(MaybeUndefined::Null).raw_input(MaybeUndefined::Null), )); assert_eq!(conversation.items().len(), 1); - assert!(tool(&conversation, 0).title().is_empty()); - assert!(tool(&conversation, 0).raw_input().is_empty()); + assert_eq!(tool(&conversation, 0).title(), ""); + assert_eq!(tool(&conversation, 0).raw_input(), ""); } #[test] @@ -133,7 +133,7 @@ fn tool_content_chunks_append_but_updates_replace() { assert_eq!(tool(&conversation, 0).content().len(), 1); conversation.apply_event(&tool_update(acp::ToolCallUpdate::new("tool").content(MaybeUndefined::Null))); - assert!(tool(&conversation, 0).content().is_empty()); + assert_eq!(tool(&conversation, 0).content(), []); } #[test] @@ -337,7 +337,7 @@ fn activity_after_the_turn_ends_is_ignored_until_the_next_turn() { conversation.apply_event(&compaction(acp::CompactionStatus::InProgress)); assert_eq!(conversation.activity(), Activity::Idle); - assert!(tool(&conversation, 0).sub_agents.is_empty()); + assert_eq!(tool(&conversation, 0).sub_agents, []); assert!(!conversation.is_compacting()); conversation.apply_event(&running()); @@ -390,7 +390,7 @@ fn clear_replaces_identity_and_resets_everything() { conversation.clear(); assert_ne!(conversation.id(), previous_id); - assert!(conversation.items().is_empty()); + assert_eq!(conversation.items(), []); assert!(conversation.turn().is_idle(), "a running turn ends with the conversation"); assert!(conversation.plan().is_none()); assert!(conversation.context_usage().is_none()); diff --git a/crates/aether-cli/src/acp/session/actor.rs b/crates/aether-cli/src/acp/session/actor.rs index 48ce89615..61ffda899 100644 --- a/crates/aether-cli/src/acp/session/actor.rs +++ b/crates/aether-cli/src/acp/session/actor.rs @@ -970,7 +970,7 @@ mod tests { dispatch_event(&cx, McpClientEvent::ServerStatusesChanged(vec![])); let McpNotification::ServerStatus { servers } = peer.next_mcp_notification().await; - assert!(servers.is_empty()); + assert_eq!(servers.len(), 0); }) .await; } diff --git a/crates/aether-cli/src/sandbox.rs b/crates/aether-cli/src/sandbox.rs index 980a08b9e..2f9a83fa9 100644 --- a/crates/aether-cli/src/sandbox.rs +++ b/crates/aether-cli/src/sandbox.rs @@ -351,7 +351,7 @@ mod tests { fn select_forwarded_vars_excludes_unknown() { let vars = vec![("HOME".to_string(), "/root".to_string()), ("EDITOR".to_string(), "vim".to_string())]; let forwarded = select_forwarded_vars(vars.into_iter()); - assert!(forwarded.is_empty()); + assert_eq!(forwarded.len(), 0); } #[test] diff --git a/crates/aether-cli/src/workspace/git.rs b/crates/aether-cli/src/workspace/git.rs index a796f5f22..fcd2689b2 100644 --- a/crates/aether-cli/src/workspace/git.rs +++ b/crates/aether-cli/src/workspace/git.rs @@ -165,7 +165,7 @@ mod tests { git(&clone, &["commit", "-m", "diverge"]); let original = root_commit_hash(&repo).unwrap(); - assert!(!original.is_empty()); + assert_ne!(original, ""); assert_eq!(root_commit_hash(&clone).unwrap(), original); } diff --git a/crates/aether-cli/src/workspace/registry.rs b/crates/aether-cli/src/workspace/registry.rs index 3d08532c0..c0bf5429c 100644 --- a/crates/aether-cli/src/workspace/registry.rs +++ b/crates/aether-cli/src/workspace/registry.rs @@ -144,7 +144,7 @@ mod tests { registry.register("old", &a).unwrap(); registry.register("new", &a).unwrap(); - assert!(registry.workspaces_for("old").unwrap().is_empty()); + assert_eq!(registry.workspaces_for("old").unwrap().len(), 0); assert_eq!(registry.workspaces_for("new").unwrap().len(), 1); } @@ -169,6 +169,6 @@ mod tests { #[test] fn missing_registry_file_lists_empty() { let (_dir, registry) = temp_registry(); - assert!(registry.workspaces_for("repo1").unwrap().is_empty()); + assert_eq!(registry.workspaces_for("repo1").unwrap().len(), 0); } } diff --git a/crates/aether-cli/tests/integration/acp_git_diff.rs b/crates/aether-cli/tests/integration/acp_git_diff.rs index 7972b94fa..fa6c8c231 100644 --- a/crates/aether-cli/tests/integration/acp_git_diff.rs +++ b/crates/aether-cli/tests/integration/acp_git_diff.rs @@ -60,7 +60,7 @@ async fn git_diff_refresh_tracks_scope_and_reports_status_ref() { .block_task() .await .expect("status succeeds"); - assert!(!status.display_dir.is_empty()); + assert_ne!(status.display_dir, ""); }) .await; } diff --git a/crates/aether-cli/tests/integration/acp_prompt_search.rs b/crates/aether-cli/tests/integration/acp_prompt_search.rs index e66f1f13b..320d92579 100644 --- a/crates/aether-cli/tests/integration/acp_prompt_search.rs +++ b/crates/aether-cli/tests/integration/acp_prompt_search.rs @@ -35,8 +35,8 @@ async fn prompt_search_request_searches_user_text_only() { vec![llm::ContentBlock::text("first block"), llm::ContentBlock::text("second block")], ); - assert!(search(&harness, "agent").await.results.is_empty()); - assert!(search(&harness, "aW1n").await.results.is_empty()); + assert_eq!(search(&harness, "agent").await.results.len(), 0); + assert_eq!(search(&harness, "aW1n").await.results.len(), 0); let multi = search(&harness, "second").await; assert_eq!(multi.results.len(), 1); @@ -66,7 +66,7 @@ async fn prompt_search_request_uses_literal_smart_case_unicode_matching() { assert!(lower.results.iter().any(|hit| hit.prompt == "HELLO world")); let upper = search(&harness, "Hello").await; - assert!(upper.results.is_empty()); + assert_eq!(upper.results.len(), 0); let unicode = search(&harness, "fé").await; assert_eq!(unicode.results.len(), 1); @@ -102,7 +102,7 @@ async fn prompt_search_request_with_empty_query_returns_no_results() { harness.append_stored_prompt("s1", "cached alpha"); let response = search(&harness, "").await; - assert!(response.results.is_empty()); + assert_eq!(response.results.len(), 0); assert!(!response.truncated); }) .await; diff --git a/crates/aether-cli/tests/integration/acp_remote/client.rs b/crates/aether-cli/tests/integration/acp_remote/client.rs index 54c9c8e80..3ae073e07 100644 --- a/crates/aether-cli/tests/integration/acp_remote/client.rs +++ b/crates/aether-cli/tests/integration/acp_remote/client.rs @@ -16,7 +16,7 @@ fn remote_client_parser_defaults_and_overrides() { let args = ClientCli::try_parse_from(["client"]).unwrap().args; assert_eq!(args.url, "ws://127.0.0.1:8765"); assert!(args.session.is_none()); - assert!(args.headers.is_empty()); + assert_eq!(args.headers.len(), 0); assert!(args.log_dir.is_none()); let args = ClientCli::try_parse_from([ "client", diff --git a/crates/aether-cli/tests/integration/acp_remote/websocket.rs b/crates/aether-cli/tests/integration/acp_remote/websocket.rs index 802fe8525..7b442f68c 100644 --- a/crates/aether-cli/tests/integration/acp_remote/websocket.rs +++ b/crates/aether-cli/tests/integration/acp_remote/websocket.rs @@ -217,7 +217,7 @@ async fn occupied_server_drops_non_websocket_request_without_detaching_owner() { invalid.write_all(b"GET / HTTP/1.1\r\nHost: localhost\r\n\r\n").await.unwrap(); let mut response = Vec::new(); invalid.read_to_end(&mut response).await.unwrap(); - assert!(response.is_empty()); + assert_eq!(response.len(), 0); assert_occupied(&server).await; drop(owner); server.shutdown().await; diff --git a/crates/aether-cli/tests/integration/acp_session_lifecycle.rs b/crates/aether-cli/tests/integration/acp_session_lifecycle.rs index 6808a2103..ddfbed9dd 100644 --- a/crates/aether-cli/tests/integration/acp_session_lifecycle.rs +++ b/crates/aether-cli/tests/integration/acp_session_lifecycle.rs @@ -69,7 +69,7 @@ async fn terminal_list_cursor_returns_an_empty_page() { .to_string(), ); let response = list(&harness, ListSessionsRequest::new().cursor(cursor)).await; - assert!(response.sessions.is_empty()); + assert_eq!(response.sessions.len(), 0); assert!(response.next_cursor.is_none()); }) .await; diff --git a/crates/aether-cli/tests/integration/run_init.rs b/crates/aether-cli/tests/integration/run_init.rs index ffe35c6ab..b321bced9 100644 --- a/crates/aether-cli/tests/integration/run_init.rs +++ b/crates/aether-cli/tests/integration/run_init.rs @@ -352,7 +352,7 @@ fn assert_plan_tools(agent: &aether_project::AgentConfig) { ToolMatcher::name("review__review_artifact"), ] ); - assert!(agent.tools.deny.is_empty()); + assert_eq!(agent.tools.deny.len(), 0); } fn assert_read_only_coding_tools(agent: &aether_project::AgentConfig) { @@ -365,7 +365,7 @@ fn assert_read_only_coding_tools(agent: &aether_project::AgentConfig) { ToolMatcher::name("tasks__*"), ] ); - assert!(agent.tools.deny.is_empty()); + assert_eq!(agent.tools.deny.len(), 0); } fn assert_minimal_mcp_and_tools(agent: &aether_project::AgentConfig) { @@ -373,7 +373,7 @@ fn assert_minimal_mcp_and_tools(agent: &aether_project::AgentConfig) { let names: Vec<&str> = servers.keys().map(String::as_str).collect(); assert_eq!(names, vec!["coding", "skills"]); assert_eq!(agent.tools.allow, vec![ToolMatcher::name("coding__bash"), ToolMatcher::name("skills__*")]); - assert!(agent.tools.deny.is_empty()); + assert_eq!(agent.tools.deny.len(), 0); } fn assert_contains_all(args: &[String], expected: &[&str], context: &str) { diff --git a/crates/aether-core/src/agent_spec.rs b/crates/aether-core/src/agent_spec.rs index 441c6eabe..dae2eb85d 100644 --- a/crates/aether-core/src/agent_spec.rs +++ b/crates/aether-core/src/agent_spec.rs @@ -277,7 +277,7 @@ mod tests { deny: vec![], }; let tools = vec![make_annotated_tool("read", ToolAnnotations::read_only())]; - assert!(filter.apply(tools).is_empty()); + assert_eq!(filter.apply(tools).len(), 0); } #[test] @@ -288,7 +288,7 @@ mod tests { "coding__read_file", ToolAnnotations { read_only_hint: Some(true), ..ToolAnnotations::default() }, )]; - assert!(filter.apply(tools).is_empty()); + assert_eq!(filter.apply(tools).len(), 0); } #[test] @@ -314,7 +314,7 @@ mod tests { "coding__grep", ToolAnnotations { read_only_hint: Some(true), ..ToolAnnotations::default() }, )]; - assert!(filter.apply(tools).is_empty()); + assert_eq!(filter.apply(tools).len(), 0); } #[test] diff --git a/crates/aether-core/src/mcp/mcp_builder.rs b/crates/aether-core/src/mcp/mcp_builder.rs index c374e2198..8dcbd087b 100644 --- a/crates/aether-core/src/mcp/mcp_builder.rs +++ b/crates/aether-core/src/mcp/mcp_builder.rs @@ -477,7 +477,7 @@ mod tests { updates.changed().await.expect("connection publishes a snapshot"); let observed = updates.borrow().clone(); - assert!(old.tool_definitions().is_empty()); + assert_eq!(old.tool_definitions().len(), 0); assert_eq!(ready.tool_definitions()[0].name, "test__add_numbers"); assert_eq!(observed.tool_definitions(), ready.tool_definitions()); assert!(!Arc::ptr_eq(&old, &ready)); diff --git a/crates/aether-core/tests/mcp/oauth_tests.rs b/crates/aether-core/tests/mcp/oauth_tests.rs index 3200ee540..154fb09de 100644 --- a/crates/aether-core/tests/mcp/oauth_tests.rs +++ b/crates/aether-core/tests/mcp/oauth_tests.rs @@ -162,7 +162,7 @@ async fn builder_with_oauth_handler_factory_spawns_successfully() { .unwrap(); let snapshot = spawn.block_until_ready().await.expect("bootstrap completes"); - assert!(snapshot.tool_definitions().is_empty()); + assert_eq!(snapshot.tool_definitions().len(), 0); assert!(snapshot.model_instructions().is_empty()); } @@ -221,7 +221,7 @@ async fn add_mcps_continues_on_oauth_failure() { .await .is_ok() ); - assert!(manager.tool_definitions().is_empty()); + assert_eq!(manager.tool_definitions().len(), 0); } #[tokio::test] @@ -269,7 +269,7 @@ async fn deferred_server_with_failing_http_surfaces_failure() { let local_status = statuses.iter().find(|s| s.name == "local").expect("Expected status entry for 'local'"); assert!(matches!(local_status.status, McpServerStatus::Connected { .. })); assert!(local_status.deferred_tools); - assert!(manager.tool_definitions().is_empty()); + assert_eq!(manager.tool_definitions().len(), 0); } #[tokio::test] @@ -304,7 +304,7 @@ async fn deferred_tools_partial_connection_works() { let _ = manager.add_mcps(servers).await; - assert!(manager.tool_definitions().is_empty()); + assert_eq!(manager.tool_definitions().len(), 0); let statuses = manager.server_statuses(); assert!(matches!( statuses.iter().find(|status| status.name == "working").unwrap().status, diff --git a/crates/aether-core/tests/mcp/task_tests.rs b/crates/aether-core/tests/mcp/task_tests.rs index 7cd988ead..98ec2f66b 100644 --- a/crates/aether-core/tests/mcp/task_tests.rs +++ b/crates/aether-core/tests/mcp/task_tests.rs @@ -198,7 +198,7 @@ async fn expired_task_terminates_before_polling() { assert_eq!(notification.status, "failed"); assert!(notification.body.contains("expired before completion")); - assert!(state.task_get_ids().is_empty()); + assert_eq!(state.task_get_ids().len(), 0); } #[tokio::test] diff --git a/crates/aether-lspd/src/diagnostics_store.rs b/crates/aether-lspd/src/diagnostics_store.rs index aa5487ede..77f3ba9f3 100644 --- a/crates/aether-lspd/src/diagnostics_store.rs +++ b/crates/aether-lspd/src/diagnostics_store.rs @@ -170,6 +170,6 @@ mod tests { let uri: Uri = "file:///test.rs".parse().unwrap(); store.publish(diagnostics(uri.as_str(), "error")); store.forget_uri(&uri); - assert!(store.get(Some(&uri)).is_empty()); + assert_eq!(store.get(Some(&uri)).len(), 0); } } diff --git a/crates/aether-lspd/src/document_lifecycle.rs b/crates/aether-lspd/src/document_lifecycle.rs index 38227c9f6..17db03202 100644 --- a/crates/aether-lspd/src/document_lifecycle.rs +++ b/crates/aether-lspd/src/document_lifecycle.rs @@ -229,7 +229,7 @@ mod tests { let filtered = lifecycle .filter_watcher_changes(vec![FileEvent { uri: uri.clone(), typ: lsp_types::FileChangeType::CHANGED }]); - assert!(filtered.is_empty()); + assert_eq!(filtered.len(), 0); assert!(matches!(lifecycle.release(&uri), ReleaseAction::CloseAndRefresh)); } @@ -246,7 +246,7 @@ mod tests { let filtered = lifecycle .filter_watcher_changes(vec![FileEvent { uri: uri.clone(), typ: lsp_types::FileChangeType::CHANGED }]); - assert!(filtered.is_empty()); + assert_eq!(filtered.len(), 0); assert!(matches!(lifecycle.release(&uri), ReleaseAction::Unchanged)); assert!(matches!(lifecycle.release(&uri), ReleaseAction::CloseAndRefresh)); } diff --git a/crates/aether-lspd/src/file_watcher.rs b/crates/aether-lspd/src/file_watcher.rs index 1e365ad20..16b2679a7 100644 --- a/crates/aether-lspd/src/file_watcher.rs +++ b/crates/aether-lspd/src/file_watcher.rs @@ -515,7 +515,7 @@ mod tests { actor.accumulate_event(¬ify_event(MODIFY_CONTENT, vec!["/tmp/project/src/main.rs"])); actor.flush_pending().await; let batch = event_rx.recv().await.expect("expected file watcher batch"); - assert!(batch.forwarded_changes.is_empty()); + assert_eq!(batch.forwarded_changes.len(), 0); assert_eq!(batch.discovered_uris.len(), 1); } diff --git a/crates/aether-lspd/tests/e2e/e2e_lifecycle.rs b/crates/aether-lspd/tests/e2e/e2e_lifecycle.rs index a39fa625c..19e22665f 100644 --- a/crates/aether-lspd/tests/e2e/e2e_lifecycle.rs +++ b/crates/aether-lspd/tests/e2e/e2e_lifecycle.rs @@ -34,7 +34,7 @@ async fn multiple_clients_share_fake_server_session() { let hover1 = hover_text(client1.hover(uri.clone(), 0, 0).await.expect("Hover failed")); let hover2 = hover_text(client2.hover(uri.clone(), 0, 0).await.expect("Hover failed")); - assert!(!hover1.is_empty()); + assert_ne!(hover1, ""); assert_eq!(hover1, hover2); harness.kill().await.expect("Failed to kill daemon"); diff --git a/crates/aether-lspd/tests/e2e_smoke_real.rs b/crates/aether-lspd/tests/e2e_smoke_real.rs index 6879ee7fa..e40e933eb 100644 --- a/crates/aether-lspd/tests/e2e_smoke_real.rs +++ b/crates/aether-lspd/tests/e2e_smoke_real.rs @@ -15,7 +15,7 @@ async fn rust_analyzer_smoke_hover() { let uri = project.file_uri("src/main.rs"); let hover = hover_text(client.hover(uri, 0, 0).await.expect("Hover failed")); - assert!(!hover.is_empty()); + assert_ne!(hover, ""); harness.kill().await.expect("Failed to kill daemon"); } diff --git a/crates/aether-project/src/aether_settings.rs b/crates/aether-project/src/aether_settings.rs index d0b51929b..64acebc8f 100644 --- a/crates/aether-project/src/aether_settings.rs +++ b/crates/aether-project/src/aether_settings.rs @@ -972,8 +972,8 @@ mod tests { settings.inline_resources(project.root()).unwrap(); - assert!(settings.prompts.is_empty()); - assert!(settings.mcps.is_empty()); + assert_eq!(settings.prompts.len(), 0); + assert_eq!(settings.mcps.len(), 0); } #[test] diff --git a/crates/aether-project/src/prompt_file.rs b/crates/aether-project/src/prompt_file.rs index 79fed4976..fceff0163 100644 --- a/crates/aether-project/src/prompt_file.rs +++ b/crates/aether-project/src/prompt_file.rs @@ -282,7 +282,7 @@ mod tests { let parsed = PromptFile::parse(&dir.root().join("old-skill").join(SKILL_FILENAME)).unwrap(); assert_eq!(parsed.description, "An old skill"); - assert!(parsed.tags.is_empty()); + assert_eq!(parsed.tags.len(), 0); assert!(!parsed.agent_authored); assert_eq!(parsed.helpful, 0); assert_eq!(parsed.harmful, 0); diff --git a/crates/aether-sessions/tests/store.rs b/crates/aether-sessions/tests/store.rs index ca52e0b6c..051c14728 100644 --- a/crates/aether-sessions/tests/store.rs +++ b/crates/aether-sessions/tests/store.rs @@ -94,12 +94,12 @@ fn prompt_search_is_smart_case_unicode_safe_and_retains_recent_entries() { store.append("session-1", &user_message("café")); let old = store.store().search_prompts("prompt 0", None).expect("search succeeds"); - assert!(old.results.is_empty()); + assert_eq!(old.results.len(), 0); let lower = store.store().search_prompts("hello", None).expect("search succeeds"); assert_eq!(lower.results.len(), 1); let upper = store.store().search_prompts("Hello", None).expect("search succeeds"); - assert!(upper.results.is_empty()); + assert_eq!(upper.results.len(), 0); let unicode = store.store().search_prompts("fé", None).expect("search succeeds"); let hit = &unicode.results[0]; assert_eq!(&hit.prompt[hit.match_start..hit.match_end], "fé"); @@ -210,18 +210,18 @@ fn blank_runs_and_oversized_lines_consume_preview_budget() { let preview = store.store().preview("session-1").expect("preview succeeds"); assert!(preview.truncated); - assert!(preview.transcript.is_empty()); + assert_eq!(preview.transcript.len(), 0); } #[test] fn empty_and_missing_stores_have_no_sessions_or_prompts() { let store = TestStore::new(); - assert!(store.store().list().is_empty()); + assert_eq!(store.store().list().len(), 0); let missing_session = store.store().load("missing").unwrap_err(); assert!(matches!(missing_session, SessionStoreError::Io(error) if error.kind() == std::io::ErrorKind::NotFound)); let empty = store.store().search_prompts(" ", None).expect("search succeeds"); - assert!(empty.results.is_empty()); + assert_eq!(empty.results.len(), 0); let missing = SessionStore::from_path(store.path().join("missing")); - assert!(missing.list().is_empty()); + assert_eq!(missing.list().len(), 0); } diff --git a/crates/aether-telemetry/tests/otlp_collector_tests.rs b/crates/aether-telemetry/tests/otlp_collector_tests.rs index 955c5fc96..cecb1fbbc 100644 --- a/crates/aether-telemetry/tests/otlp_collector_tests.rs +++ b/crates/aether-telemetry/tests/otlp_collector_tests.rs @@ -36,7 +36,7 @@ async fn runtime_exports_metrics_to_a_signal_specific_endpoint() { runtime.shutdown().expect("runtime flushes metrics"); let exports = collector.exports(); - assert!(exports.traces.is_empty()); + assert_eq!(exports.traces.len(), 0); assert_eq!(exports.metrics.len(), 1); } @@ -57,7 +57,7 @@ async fn runtime_exports_traces_to_a_signal_specific_endpoint() { let exports = collector.exports(); assert_eq!(exports.traces.len(), 1); - assert!(exports.metrics.is_empty()); + assert_eq!(exports.metrics.len(), 0); } #[tokio::test(flavor = "multi_thread")] @@ -87,7 +87,7 @@ async fn runtime_parents_every_turn_to_the_supplied_trace_context() { let spans = trace_spans(&exports); assert_propagated_hierarchy(&spans, &expected_trace_id, &expected_parent_span_id); - assert!(!exports.metrics.is_empty()); + assert_ne!(exports.metrics.len(), 0); } #[tokio::test(flavor = "multi_thread")] diff --git a/crates/llm/src/catalog/mod.rs b/crates/llm/src/catalog/mod.rs index 96734d350..64aaa8884 100644 --- a/crates/llm/src/catalog/mod.rs +++ b/crates/llm/src/catalog/mod.rs @@ -229,7 +229,7 @@ mod tests { #[test] fn dynamic_provider_models_have_no_reasoning_levels() { - assert!(LlmModel::Ollama("llama3.2".into()).reasoning_levels().is_empty()); + assert_eq!(LlmModel::Ollama("llama3.2".into()).reasoning_levels(), []); assert!(!LlmModel::Ollama("llama3.2".into()).supports_reasoning()); } @@ -310,7 +310,7 @@ mod tests { fn bedrock_profile_fallback_parses_arbitrary_id() { let profile: LlmModel = "bedrock:us.anthropic.future-model-v99:0".parse().unwrap(); assert_eq!(profile.context_window(), None); - assert!(profile.reasoning_levels().is_empty()); + assert_eq!(profile.reasoning_levels(), []); assert!(!profile.supports_prompt_caching()); } } diff --git a/crates/llm/src/providers/bedrock/mappers.rs b/crates/llm/src/providers/bedrock/mappers.rs index 713d3f880..0136eb046 100644 --- a/crates/llm/src/providers/bedrock/mappers.rs +++ b/crates/llm/src/providers/bedrock/mappers.rs @@ -274,7 +274,7 @@ mod tests { let messages = vec![ChatMessage::user("Hello")]; let (system, mapped) = map_messages(&messages, None).unwrap(); - assert!(system.is_empty()); + assert_eq!(system.len(), 0); assert_eq!(mapped.len(), 1); assert_eq!(mapped[0].role(), &ConversationRole::User); assert_eq!(mapped[0].content().len(), 1); @@ -474,7 +474,7 @@ mod tests { let (system, _mapped) = map_messages(&messages, Some(&cache_point)).unwrap(); - assert!(system.is_empty()); + assert_eq!(system.len(), 0); } #[test] diff --git a/crates/llm/src/providers/codex/oauth.rs b/crates/llm/src/providers/codex/oauth.rs index d99976da8..6fb1fe97e 100644 --- a/crates/llm/src/providers/codex/oauth.rs +++ b/crates/llm/src/providers/codex/oauth.rs @@ -287,7 +287,7 @@ mod tests { #[test] fn generate_random_state_is_valid_uuid() { let state = generate_random_state(); - assert!(!state.is_empty()); + assert_ne!(state, ""); assert!(uuid::Uuid::parse_str(&state).is_ok()); } diff --git a/crates/llm/src/providers/openrouter/provider.rs b/crates/llm/src/providers/openrouter/provider.rs index 67bf59e35..d05c8a3fb 100644 --- a/crates/llm/src/providers/openrouter/provider.rs +++ b/crates/llm/src/providers/openrouter/provider.rs @@ -136,7 +136,7 @@ mod tests { assert_eq!(responses.len(), 1); assert!(matches!(&responses[0], Err(LlmError::ReasoningValidation(_)))); assert!(!responses[0].as_ref().unwrap_err().is_retryable()); - assert!(request_bodies(&service).is_empty()); + assert_eq!(request_bodies(&service).len(), 0); } #[tokio::test] diff --git a/crates/mcp-servers/src/skills/server.rs b/crates/mcp-servers/src/skills/server.rs index 3527761c6..15c3ce168 100644 --- a/crates/mcp-servers/src/skills/server.rs +++ b/crates/mcp-servers/src/skills/server.rs @@ -609,7 +609,7 @@ mod tests { assert_eq!(result.path, "rust-rules.md"); let content = result.content.expect("flat prompt content should exist"); assert!(content.contains("Use Rust conventions.")); - assert!(result.available_files.is_empty()); + assert_eq!(result.available_files.len(), 0); assert!(result.error.is_none()); } @@ -626,7 +626,7 @@ mod tests { let result = load(&server, "rust-rules", Some("details.md")).await; assert!(result.content.is_none()); - assert!(result.available_files.is_empty()); + assert_eq!(result.available_files.len(), 0); assert!(result.error.as_deref().unwrap().contains("does not support relative paths")); } @@ -645,7 +645,7 @@ mod tests { assert_eq!(result.path, "traits.md"); assert_eq!(result.content.unwrap(), "# Traits content"); - assert!(result.available_files.is_empty()); + assert_eq!(result.available_files.len(), 0); } #[tokio::test] @@ -784,7 +784,7 @@ mod tests { assert_eq!(files[1].name, "rust"); assert_eq!(files[1].path, "traits.md"); assert_eq!(files[1].content.as_deref(), Some("# Traits")); - assert!(files[1].available_files.is_empty()); + assert_eq!(files[1].available_files.len(), 0); assert_eq!(files[2].name, "python"); assert_eq!(files[2].path, "SKILL.md"); diff --git a/crates/mcp-servers/src/subagents/tools/spawn_subagent/mod.rs b/crates/mcp-servers/src/subagents/tools/spawn_subagent/mod.rs index 035441c42..c873ba713 100644 --- a/crates/mcp-servers/src/subagents/tools/spawn_subagent/mod.rs +++ b/crates/mcp-servers/src/subagents/tools/spawn_subagent/mod.rs @@ -403,8 +403,8 @@ Hope this helps!"#; assert_eq!(result.summary, "Agent did not return structured output"); assert!(result.artifacts.is_empty()); - assert!(result.decisions.is_empty()); - assert!(result.next_steps.is_empty()); + assert_eq!(result.decisions.len(), 0); + assert_eq!(result.next_steps.len(), 0); assert_eq!(result.details, Some(plain_text.to_string())); } diff --git a/crates/mcp-servers/tests/integration/test_web_fetch.rs b/crates/mcp-servers/tests/integration/test_web_fetch.rs index bd4b4fbb3..d5fc5dc77 100644 --- a/crates/mcp-servers/tests/integration/test_web_fetch.rs +++ b/crates/mcp-servers/tests/integration/test_web_fetch.rs @@ -53,7 +53,7 @@ async fn test_fetch_real_page() { .unwrap(); assert_eq!(result.status_code, 200); - assert!(!result.content.is_empty()); + assert_ne!(result.content, ""); assert!(result.content.contains("Melville") || result.content.contains("Moby")); } @@ -128,7 +128,7 @@ async fn test_fetch_with_prompt() { .unwrap(); assert_eq!(result.status_code, 200); - assert!(!result.content.is_empty()); + assert_ne!(result.content, ""); } #[tokio::test] diff --git a/crates/mcp-utils/src/client/manager.rs b/crates/mcp-utils/src/client/manager.rs index 5193e8672..5ad502eff 100644 --- a/crates/mcp-utils/src/client/manager.rs +++ b/crates/mcp-utils/src/client/manager.rs @@ -967,7 +967,7 @@ mod tests { snapshots.changed().await.unwrap(); let removed = snapshots.borrow().clone(); - assert!(removed.tool_definitions().is_empty()); + assert_eq!(removed.tool_definitions().len(), 0); assert!( removed .resolve(ToolRoute::ModelVisible { namespaced_name: "test__echo".to_string() }, serde_json::Map::new(),) diff --git a/crates/mcp-utils/src/tool_gateway/transport.rs b/crates/mcp-utils/src/tool_gateway/transport.rs index 614d383eb..e94d9e0f6 100644 --- a/crates/mcp-utils/src/tool_gateway/transport.rs +++ b/crates/mcp-utils/src/tool_gateway/transport.rs @@ -244,7 +244,7 @@ mod tests { let _server = transport.spawn(TestServer { tool_router: TestServer::tool_router() }); let client = ().serve(connect(&socket).await.unwrap()).await.unwrap(); - assert!(client.list_all_tools().await.unwrap().is_empty()); + assert_eq!(client.list_all_tools().await.unwrap().len(), 0); } #[tokio::test] diff --git a/crates/mcp-utils/tests/tool_catalog.rs b/crates/mcp-utils/tests/tool_catalog.rs index 3685a1686..a5af6499f 100644 --- a/crates/mcp-utils/tests/tool_catalog.rs +++ b/crates/mcp-utils/tests/tool_catalog.rs @@ -116,9 +116,9 @@ fn disconnected_servers_retain_status_without_exposing_tools_or_instructions() { catalog.set_progressive_discovery_instructions(Some("not visible".to_string())); let tools = catalog.tools(); - assert!(tools.model_visible.is_empty()); - assert!(tools.deferred.is_empty()); - assert!(catalog.discoverable_deferred_servers().is_empty()); + assert_eq!(tools.model_visible.len(), 0); + assert_eq!(tools.deferred.len(), 0); + assert_eq!(catalog.discoverable_deferred_servers().len(), 0); assert!(catalog.model_instructions().is_empty()); assert!(!catalog.route_permitted(&ToolRoute::Deferred { server: "remote".into(), tool: "hidden".into() })); assert!(matches!(catalog.servers()[0].status(), McpServerStatus::NeedsOAuth)); diff --git a/crates/wisp/src/conversation/plan_tracker.rs b/crates/wisp/src/conversation/plan_tracker.rs index 912672956..d515dfa5d 100644 --- a/crates/wisp/src/conversation/plan_tracker.rs +++ b/crates/wisp/src/conversation/plan_tracker.rs @@ -137,7 +137,7 @@ mod tests { tracker.replace("plan".into(), vec![entry("Task A", PlanEntryStatus::Completed)], now); let visible = tracker.visible_entries(now + GRACE_PERIOD + Duration::from_millis(1)); - assert!(visible.is_empty()); + assert_eq!(visible.len(), 0); } #[test] @@ -260,7 +260,7 @@ mod tests { tracker.replace("plan".into(), vec![entry], now + Duration::from_secs(2)); assert_eq!(tracker.visible_entries(now + GRACE_PERIOD).len(), 1); - assert!(tracker.visible_entries(now + GRACE_PERIOD + Duration::from_millis(1)).is_empty()); + assert_eq!(tracker.visible_entries(now + GRACE_PERIOD + Duration::from_millis(1)).len(), 0); } #[test] @@ -335,7 +335,7 @@ mod tests { tracker.clear(); let visible = tracker.visible_entries(now); - assert!(visible.is_empty()); + assert_eq!(visible.len(), 0); assert!(!tracker.has_entries()); } diff --git a/crates/wisp/src/surfaces/modal/url.rs b/crates/wisp/src/surfaces/modal/url.rs index e5b303112..2d350bcaa 100644 --- a/crates/wisp/src/surfaces/modal/url.rs +++ b/crates/wisp/src/surfaces/modal/url.rs @@ -101,7 +101,7 @@ mod tests { fn url_modal_parses_host() { let url = UrlModal::new("github".into(), "Auth".into(), "https://github.com/login".into()); assert_eq!(url.host.as_deref(), Some("github.com")); - assert!(url.warnings.is_empty()); + assert_eq!(url.warnings.len(), 0); } #[test] @@ -114,13 +114,13 @@ mod tests { #[test] fn url_modal_does_not_warn_on_localhost() { let url = UrlModal::new("test".into(), "Local".into(), "http://localhost:3000/auth".into()); - assert!(url.warnings.is_empty()); + assert_eq!(url.warnings.len(), 0); } #[test] fn url_modal_allows_127_0_0_1_as_localhost() { let url = UrlModal::new("test".into(), "Local".into(), "http://127.0.0.1:8000/api".into()); - assert!(url.warnings.is_empty()); + assert_eq!(url.warnings.len(), 0); } #[test] diff --git a/crates/wisp/src/view/wrap.rs b/crates/wisp/src/view/wrap.rs index f6c42895b..9682b0a65 100644 --- a/crates/wisp/src/view/wrap.rs +++ b/crates/wisp/src/view/wrap.rs @@ -314,7 +314,7 @@ mod tests { fn truncate_spans_narrow_width_returns_empty() { let spans = vec![Span::raw("abc")]; let result = truncate_spans(&spans, 0, Style::new()); - assert!(result.is_empty()); + assert_eq!(result.len(), 0); } #[test] diff --git a/crates/wisp/tests/runtime_acp.rs b/crates/wisp/tests/runtime_acp.rs index 1a178f994..9ef190c88 100644 --- a/crates/wisp/tests/runtime_acp.rs +++ b/crates/wisp/tests/runtime_acp.rs @@ -374,7 +374,7 @@ async fn remote_startup_resumes_selected_session_and_preserves_queued_replay() { let (request, responder) = requests.resume.recv().await.unwrap(); assert_eq!(request.session_id, SessionId::new(selected)); assert_eq!(request.cwd.0, PathBuf::from(cwd)); - assert!(request.mcp_servers.is_empty()); + assert_eq!(request.mcp_servers.len(), 0); assert!(matches!(request.replay_from, Some(ReplayFrom::Start(_)))); let connection = requests.connection.recv().await.unwrap(); connection @@ -496,7 +496,7 @@ async fn connect(capabilities: Option) -> (Session, Peer) { let session = Session::connect_to(client_transport, PathBuf::from("/workspace")).await.unwrap(); let created = requests.new_session.recv().await.unwrap(); assert_eq!(created.cwd.0, PathBuf::from("/workspace")); - assert!(created.mcp_servers.is_empty()); + assert_eq!(created.mcp_servers.len(), 0); let connection = requests.connection.recv().await.unwrap(); ( session, diff --git a/crates/wisp/tests/tui/attachments.rs b/crates/wisp/tests/tui/attachments.rs index 8f17e7415..b31b94530 100644 --- a/crates/wisp/tests/tui/attachments.rs +++ b/crates/wisp/tests/tui/attachments.rs @@ -80,7 +80,7 @@ fn remote_paste_never_attaches_even_when_the_path_exists_locally() { let image = create_temp_file(&tmp, "photo.png", b"client-only contents"); let mut ui = TestUiBuilder::new().remote_workspace().build(); ui.paste(image.to_str().unwrap()); - assert!(ui.app().composer().pending_media().is_empty()); + assert_eq!(ui.app().composer().pending_media().len(), 0); assert_eq!(ui.app().composer().text(), image.to_str().unwrap()); ui.key(key(KeyCode::Enter)); assert!( @@ -99,7 +99,7 @@ fn paste_image_path_adds_pending_media() { assert_eq!(app.app().composer().pending_media().len(), 1); assert_eq!(app.app().composer().pending_media()[0].display_name, "photo.png"); - assert!(app.app().composer().text().is_empty()); + assert_eq!(app.app().composer().text(), ""); } #[test] @@ -120,7 +120,7 @@ fn paste_ordinary_text_inserts_as_text() { app.paste("hello world"); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); assert_eq!(app.app().composer().text(), "hello world"); } @@ -132,8 +132,8 @@ fn paste_non_media_file_falls_back_to_text() { app.paste(txt.to_str().unwrap()); - assert!(app.app().composer().pending_media().is_empty()); - assert!(!app.app().composer().text().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); + assert_ne!(app.app().composer().text(), ""); } #[test] @@ -145,7 +145,7 @@ fn paste_nonexistent_path_remains_as_text() { app.paste(input); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); assert_eq!(app.app().composer().text(), input); } @@ -158,7 +158,7 @@ fn paste_nonexistent_file_uri_remains_as_text() { app.paste(&uri); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); assert_eq!(app.app().composer().text(), uri); } @@ -173,7 +173,7 @@ fn paste_directory_path_remains_as_text() { app.paste(input); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); assert_eq!(app.app().composer().text(), input); } @@ -187,7 +187,7 @@ fn paste_multiple_nonexistent_paths_remain_as_text() { app.paste(&input); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); assert_eq!(app.app().composer().text(), input); } @@ -214,7 +214,7 @@ fn paste_mixed_valid_and_missing_media_keeps_text_and_adds_nothing() { app.paste(&input); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); assert_eq!(app.app().composer().text(), input); } @@ -229,7 +229,7 @@ fn paste_mixed_valid_media_and_directory_keeps_text_and_adds_nothing() { app.paste(&input); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); assert_eq!(app.app().composer().text(), input); } @@ -275,7 +275,7 @@ fn media_only_submit_sends_with_content_blocks() { AgentCommand::Prompt { text, content, .. } => { assert!(text.is_empty(), "media-only send should have empty text"); assert!(content.is_some(), "media-only send should have content blocks"); - assert!(!content.unwrap().is_empty()); + assert_ne!(content.unwrap().len(), 0); } other => panic!("expected Prompt command, got {other:?}"), } @@ -314,8 +314,8 @@ fn submit_clears_pending_media() { app.settle_tasks(); app.next_agent_command().unwrap(); - assert!(app.app().composer().pending_media().is_empty()); - assert!(app.app().composer().text().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); + assert_eq!(app.app().composer().text(), ""); } #[test] @@ -334,7 +334,7 @@ fn backspace_on_empty_composer_removes_last_dropped_media() { assert_eq!(app.app().composer().pending_media()[0].display_name, "a.png"); app.key(key(KeyCode::Backspace)); - assert!(app.app().composer().pending_media().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); } #[test] @@ -348,7 +348,7 @@ fn backspace_does_not_remove_media_when_text_present() { app.key(key(KeyCode::Backspace)); assert_eq!(app.app().composer().pending_media().len(), 1); - assert!(app.app().composer().text().is_empty()); + assert_eq!(app.app().composer().text(), ""); } #[test] @@ -532,8 +532,8 @@ fn clear_command_also_clears_pending_media() { app.key(key(KeyCode::Tab)); let _ = app.next_agent_command().unwrap(); - assert!(app.app().composer().pending_media().is_empty()); - assert!(app.app().composer().text().is_empty()); + assert_eq!(app.app().composer().pending_media().len(), 0); + assert_eq!(app.app().composer().text(), ""); } #[test] @@ -835,7 +835,7 @@ fn image_above_ten_mib_is_rejected() { let (_dir, path) = write_temp("photo.png", &vec![0u8; TEN_MIB + 1]); let outcome = build_attachments(&attach(path, "photo.png")); - assert!(outcome.blocks.is_empty()); + assert_eq!(outcome.blocks.len(), 0); assert_eq!(outcome.warnings.len(), 1); assert_eq!(outcome.warnings[0], "Skipped photo.png: file too large (max 10485760)"); } @@ -856,7 +856,7 @@ fn audio_above_ten_mib_is_rejected() { let (_dir, path) = write_temp("note.wav", &vec![0u8; TEN_MIB + 1]); let outcome = build_attachments(&attach(path, "note.wav")); - assert!(outcome.blocks.is_empty()); + assert_eq!(outcome.blocks.len(), 0); assert_eq!(outcome.warnings.len(), 1); assert_eq!(outcome.warnings[0], "Skipped note.wav: file too large (max 10485760)"); } @@ -978,7 +978,7 @@ fn non_utf8_file_is_skipped_with_warning() { let (_dir, path) = write_temp("data.bin", &[0xff, 0xfe, 0xfd]); let outcome = build_attachments(&attach(path, "data.bin")); - assert!(outcome.blocks.is_empty()); + assert_eq!(outcome.blocks.len(), 0); assert_eq!(outcome.warnings.len(), 1); assert_eq!(outcome.warnings[0], "Skipped binary or non-UTF8 file: data.bin"); } @@ -989,7 +989,7 @@ fn unsupported_extension_text_is_embedded_as_resource() { let outcome = build_attachments(&attach(path, "notes.xyz")); assert_eq!(outcome.blocks.len(), 1); - assert!(outcome.warnings.is_empty()); + assert_eq!(outcome.warnings.len(), 0); assert!(matches!(outcome.blocks[0], acp::ContentBlock::Resource(_))); assert_eq!(text_of(&outcome.blocks[0]), "hello world"); } diff --git a/crates/wisp/tests/tui/foundation.rs b/crates/wisp/tests/tui/foundation.rs index 77e880028..bc09ffd14 100644 --- a/crates/wisp/tests/tui/foundation.rs +++ b/crates/wisp/tests/tui/foundation.rs @@ -169,7 +169,7 @@ fn composer_history_restores_the_unsubmitted_draft() { composer.insert_str("first"); let submission = composer.take_submission(); assert_eq!(submission.text, "first"); - assert!(submission.attachments().is_empty()); + assert_eq!(submission.attachments().len(), 0); composer.insert_str("draft"); assert!(composer.recall_previous()); diff --git a/crates/wisp/tests/tui/queued_prompts.rs b/crates/wisp/tests/tui/queued_prompts.rs index 85ce74043..251e5f6ac 100644 --- a/crates/wisp/tests/tui/queued_prompts.rs +++ b/crates/wisp/tests/tui/queued_prompts.rs @@ -19,7 +19,7 @@ fn a_prompt_sent_during_a_turn_is_queued_until_the_agent_inserts_it() { ui.insert_queued_prompts(); - assert!(queued_texts(&ui).is_empty()); + assert_eq!(queued_texts(&ui).len(), 0); assert!(!ui.viewport_text().contains("queued ›")); assert_eq!(transcript(&ui), ["first", "first reply", "second"]); assert!(ui.app().waiting_for_response(), "the inserted prompt joins the running turn"); @@ -70,7 +70,7 @@ fn prompts_rejected_by_a_cancel_return_to_the_composer_in_order() { ui.complete_prompt(acp::StopReason::Cancelled); assert_eq!(ui.app().composer().text(), "second\nthird"); - assert!(queued_texts(&ui).is_empty()); + assert_eq!(queued_texts(&ui).len(), 0); assert!(!ui.app().waiting_for_response()); assert_eq!(transcript(&ui), ["first"], "cancelled prompts never join the conversation and need no notice"); } diff --git a/crates/wisp/tests/tui/settings.rs b/crates/wisp/tests/tui/settings.rs index be2df1ede..c2ce9fc65 100644 --- a/crates/wisp/tests/tui/settings.rs +++ b/crates/wisp/tests/tui/settings.rs @@ -744,7 +744,7 @@ fn settings_builtin_opens_overlay_and_clears_composer() { ui.key(key(KeyCode::Tab)); // Composer should be cleared - assert!(ui.app().composer().text().is_empty()); + assert_eq!(ui.app().composer().text(), ""); // Should not emit a Prompt assert_no_commands(&mut ui, "settings open should not emit an action command"); // Overlay should be open (has_modal returns true) diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 927414a01..6fec67ac4 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "1.98" +channel = "1.99" components = ["rustfmt", "clippy", "rust-analyzer"] targets = ["wasm32-unknown-unknown"] profile = "minimal"