fix: resolve all clippy --all-targets warnings across 15 files
- gateway/mod.rs: move send_json before test module (items_after_test_module) - memory/vector.rs: fix float_cmp, cast_precision_loss, approx_constant - memory/chunker.rs: fix format_collect, format_push_string, write_with_newline - memory/sqlite.rs: fix useless_vec - heartbeat/engine.rs: fix format_collect, write_with_newline - config/schema.rs: fix needless_raw_string_hashes - tools/composio.rs: fix needless_raw_string_hashes - integrations/registry.rs: fix uninlined_format_args, unused import - tunnel/mod.rs: fix doc_markdown - skills/mod.rs: allow similar_names in test module - channels/cli.rs: fix unreadable_literal - observability/mod.rs: fix manual_string_new - runtime/mod.rs: fix manual_string_new - examples/custom_memory.rs: add Default impl (new_without_default) - examples/custom_channel.rs: fix needless_borrows_for_generic_args
This commit is contained in:
parent
18582fe9c8
commit
1fd51f1984
15 changed files with 82 additions and 49 deletions
|
|
@ -54,7 +54,7 @@ impl Channel for TelegramChannel {
|
|||
|
||||
async fn send(&self, message: &str, chat_id: &str) -> Result<()> {
|
||||
self.client
|
||||
.post(&self.api_url("sendMessage"))
|
||||
.post(self.api_url("sendMessage"))
|
||||
.json(&serde_json::json!({
|
||||
"chat_id": chat_id,
|
||||
"text": message,
|
||||
|
|
@ -71,7 +71,7 @@ impl Channel for TelegramChannel {
|
|||
loop {
|
||||
let resp = self
|
||||
.client
|
||||
.get(&self.api_url("getUpdates"))
|
||||
.get(self.api_url("getUpdates"))
|
||||
.query(&[("offset", offset.to_string()), ("timeout", "30".into())])
|
||||
.send()
|
||||
.await?
|
||||
|
|
@ -110,7 +110,7 @@ impl Channel for TelegramChannel {
|
|||
|
||||
async fn health_check(&self) -> bool {
|
||||
self.client
|
||||
.get(&self.api_url("getMe"))
|
||||
.get(self.api_url("getMe"))
|
||||
.send()
|
||||
.await
|
||||
.map(|r| r.status().is_success())
|
||||
|
|
|
|||
|
|
@ -48,14 +48,20 @@ pub struct InMemoryBackend {
|
|||
store: Mutex<HashMap<String, MemoryEntry>>,
|
||||
}
|
||||
|
||||
impl InMemoryBackend {
|
||||
pub fn new() -> Self {
|
||||
impl Default for InMemoryBackend {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
store: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InMemoryBackend {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Memory for InMemoryBackend {
|
||||
fn name(&self) -> &str {
|
||||
|
|
|
|||
|
|
@ -92,13 +92,13 @@ mod tests {
|
|||
sender: "user".into(),
|
||||
content: "hello".into(),
|
||||
channel: "cli".into(),
|
||||
timestamp: 1234567890,
|
||||
timestamp: 1_234_567_890,
|
||||
};
|
||||
assert_eq!(msg.id, "test-id");
|
||||
assert_eq!(msg.sender, "user");
|
||||
assert_eq!(msg.content, "hello");
|
||||
assert_eq!(msg.channel, "cli");
|
||||
assert_eq!(msg.timestamp, 1234567890);
|
||||
assert_eq!(msg.timestamp, 1_234_567_890);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
|
|
@ -1013,9 +1013,9 @@ default_temperature = 0.7
|
|||
|
||||
#[test]
|
||||
fn composio_config_partial_toml() {
|
||||
let toml_str = r#"
|
||||
let toml_str = r"
|
||||
enabled = true
|
||||
"#;
|
||||
";
|
||||
let parsed: ComposioConfig = toml::from_str(toml_str).unwrap();
|
||||
assert!(parsed.enabled);
|
||||
assert!(parsed.api_key.is_none());
|
||||
|
|
|
|||
|
|
@ -326,6 +326,26 @@ async fn send_response(
|
|||
stream.write_all(response.as_bytes()).await
|
||||
}
|
||||
|
||||
async fn send_json(
|
||||
stream: &mut tokio::net::TcpStream,
|
||||
status: u16,
|
||||
body: &serde_json::Value,
|
||||
) -> std::io::Result<()> {
|
||||
let reason = match status {
|
||||
200 => "OK",
|
||||
400 => "Bad Request",
|
||||
404 => "Not Found",
|
||||
500 => "Internal Server Error",
|
||||
_ => "Unknown",
|
||||
};
|
||||
let json = serde_json::to_string(body).unwrap_or_default();
|
||||
let response = format!(
|
||||
"HTTP/1.1 {status} {reason}\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{json}",
|
||||
json.len()
|
||||
);
|
||||
stream.write_all(response.as_bytes()).await
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
@ -502,23 +522,3 @@ mod tests {
|
|||
assert_eq!(extract_header("\r\n\r\n", "X-Webhook-Secret"), None);
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_json(
|
||||
stream: &mut tokio::net::TcpStream,
|
||||
status: u16,
|
||||
body: &serde_json::Value,
|
||||
) -> std::io::Result<()> {
|
||||
let reason = match status {
|
||||
200 => "OK",
|
||||
400 => "Bad Request",
|
||||
404 => "Not Found",
|
||||
500 => "Internal Server Error",
|
||||
_ => "Unknown",
|
||||
};
|
||||
let json = serde_json::to_string(body).unwrap_or_default();
|
||||
let response = format!(
|
||||
"HTTP/1.1 {status} {reason}\r\nContent-Type: application/json\r\nContent-Length: {}\r\nConnection: close\r\n\r\n{json}",
|
||||
json.len()
|
||||
);
|
||||
stream.write_all(response.as_bytes()).await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -193,7 +193,11 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn parse_tasks_many_tasks() {
|
||||
let content: String = (0..100).map(|i| format!("- Task {i}\n")).collect();
|
||||
let content: String = (0..100).fold(String::new(), |mut s, i| {
|
||||
use std::fmt::Write;
|
||||
let _ = writeln!(s, "- Task {i}");
|
||||
s
|
||||
});
|
||||
let tasks = HeartbeatEngine::parse_tasks(&content);
|
||||
assert_eq!(tasks.len(), 100);
|
||||
assert_eq!(tasks[99], "Task 99");
|
||||
|
|
|
|||
|
|
@ -667,7 +667,7 @@ pub fn all_integrations() -> Vec<IntegrationEntry> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::config::schema::{ChannelsConfig, IMessageConfig, MatrixConfig, TelegramConfig};
|
||||
use crate::config::schema::{IMessageConfig, MatrixConfig, TelegramConfig};
|
||||
use crate::config::Config;
|
||||
|
||||
#[test]
|
||||
|
|
@ -685,7 +685,7 @@ mod tests {
|
|||
let entries = all_integrations();
|
||||
for cat in IntegrationCategory::all() {
|
||||
let count = entries.iter().filter(|e| e.category == *cat).count();
|
||||
assert!(count > 0, "Category {:?} has no entries", cat);
|
||||
assert!(count > 0, "Category {cat:?} has no entries");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -206,9 +206,14 @@ mod tests {
|
|||
#[test]
|
||||
fn respects_max_tokens() {
|
||||
// Build multi-line text (one sentence per line) to exercise line-level splitting
|
||||
let long_text: String = (0..200)
|
||||
.map(|i| format!("This is sentence number {i} with some extra words to fill it up.\n"))
|
||||
.collect();
|
||||
let long_text: String = (0..200).fold(String::new(), |mut s, i| {
|
||||
use std::fmt::Write;
|
||||
let _ = writeln!(
|
||||
s,
|
||||
"This is sentence number {i} with some extra words to fill it up."
|
||||
);
|
||||
s
|
||||
});
|
||||
let chunks = chunk_markdown(&long_text, 50); // 50 tokens ≈ 200 chars
|
||||
assert!(
|
||||
chunks.len() > 1,
|
||||
|
|
@ -229,7 +234,8 @@ mod tests {
|
|||
fn preserves_heading_in_split_sections() {
|
||||
let mut text = String::from("## Big Section\n");
|
||||
for i in 0..100 {
|
||||
text.push_str(&format!("Line {i} with some content here.\n\n"));
|
||||
use std::fmt::Write;
|
||||
let _ = write!(text, "Line {i} with some content here.\n\n");
|
||||
}
|
||||
let chunks = chunk_markdown(&text, 50);
|
||||
assert!(chunks.len() > 1);
|
||||
|
|
@ -355,7 +361,11 @@ mod tests {
|
|||
fn no_content_loss() {
|
||||
let text = "# A\nContent A line 1\nContent A line 2\n\n## B\nContent B\n\n## C\nContent C";
|
||||
let chunks = chunk_markdown(text, 512);
|
||||
let reassembled: String = chunks.iter().map(|c| format!("{}\n", c.content)).collect();
|
||||
let reassembled: String = chunks.iter().fold(String::new(), |mut s, c| {
|
||||
use std::fmt::Write;
|
||||
let _ = writeln!(s, "{}", c.content);
|
||||
s
|
||||
});
|
||||
// All original content words should appear
|
||||
for word in ["Content", "line", "1", "2"] {
|
||||
assert!(
|
||||
|
|
|
|||
|
|
@ -763,7 +763,7 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn sqlite_category_roundtrip() {
|
||||
let (_tmp, mem) = temp_sqlite();
|
||||
let categories = vec![
|
||||
let categories = [
|
||||
MemoryCategory::Core,
|
||||
MemoryCategory::Daily,
|
||||
MemoryCategory::Conversation,
|
||||
|
|
|
|||
|
|
@ -132,6 +132,12 @@ pub fn hybrid_merge(
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(
|
||||
clippy::float_cmp,
|
||||
clippy::approx_constant,
|
||||
clippy::cast_precision_loss,
|
||||
clippy::cast_possible_truncation
|
||||
)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
|
|
@ -271,13 +277,15 @@ mod tests {
|
|||
let b = vec![-1.0, 0.0];
|
||||
// Cosine = -1.0, clamped to 0.0
|
||||
let sim = cosine_similarity(&a, &b);
|
||||
assert_eq!(sim, 0.0);
|
||||
assert!(sim.abs() < f32::EPSILON);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cosine_high_dimensional() {
|
||||
let a: Vec<f32> = (0..1536).map(|i| (i as f32) * 0.001).collect();
|
||||
let b: Vec<f32> = (0..1536).map(|i| (i as f32) * 0.001 + 0.0001).collect();
|
||||
let a: Vec<f32> = (0..1536).map(|i| (f64::from(i) * 0.001) as f32).collect();
|
||||
let b: Vec<f32> = (0..1536)
|
||||
.map(|i| (f64::from(i) * 0.001 + 0.0001) as f32)
|
||||
.collect();
|
||||
let sim = cosine_similarity(&a, &b);
|
||||
assert!(
|
||||
sim > 0.99,
|
||||
|
|
@ -288,14 +296,14 @@ mod tests {
|
|||
#[test]
|
||||
fn cosine_single_element() {
|
||||
assert!((cosine_similarity(&[5.0], &[5.0]) - 1.0).abs() < 0.001);
|
||||
assert_eq!(cosine_similarity(&[5.0], &[-5.0]), 0.0);
|
||||
assert!(cosine_similarity(&[5.0], &[-5.0]).abs() < f32::EPSILON);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cosine_both_zero_vectors() {
|
||||
let a = vec![0.0, 0.0];
|
||||
let b = vec![0.0, 0.0];
|
||||
assert_eq!(cosine_similarity(&a, &b), 0.0);
|
||||
assert!(cosine_similarity(&a, &b).abs() < f32::EPSILON);
|
||||
}
|
||||
|
||||
// ── Edge cases: vec↔bytes serialization ──────────────────────
|
||||
|
|
@ -306,7 +314,7 @@ mod tests {
|
|||
let bytes = vec![0u8, 0, 0, 0, 0xFF];
|
||||
let result = bytes_to_vec(&bytes);
|
||||
assert_eq!(result.len(), 1);
|
||||
assert_eq!(result[0], 0.0);
|
||||
assert!(result[0].abs() < f32::EPSILON);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -351,7 +359,7 @@ mod tests {
|
|||
let merged = hybrid_merge(&vec_results, &kw_results, 0.0, 0.0, 10);
|
||||
// All final scores should be 0.0
|
||||
for r in &merged {
|
||||
assert_eq!(r.final_score, 0.0);
|
||||
assert!(r.final_score.abs() < f32::EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn factory_empty_string_falls_back_to_noop() {
|
||||
let cfg = ObservabilityConfig { backend: "".into() };
|
||||
let cfg = ObservabilityConfig {
|
||||
backend: String::new(),
|
||||
};
|
||||
assert_eq!(create_observer(&cfg).name(), "noop");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn factory_empty_falls_back() {
|
||||
let cfg = RuntimeConfig { kind: "".into() };
|
||||
let cfg = RuntimeConfig {
|
||||
kind: String::new(),
|
||||
};
|
||||
let rt = create_runtime(&cfg);
|
||||
assert_eq!(rt.name(), "native");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ pub fn handle_command(command: super::SkillCommands, workspace_dir: &Path) -> Re
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(clippy::similar_names)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::fs;
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn composio_actions_response_missing_items_defaults() {
|
||||
let json_str = r#"{}"#;
|
||||
let json_str = r"{}";
|
||||
let resp: ComposioActionsResponse = serde_json::from_str(json_str).unwrap();
|
||||
assert!(resp.items.is_empty());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ mod tests {
|
|||
CloudflareTunnelConfig, CustomTunnelConfig, NgrokTunnelConfig, TunnelConfig,
|
||||
};
|
||||
|
||||
/// Helper: assert create_tunnel returns an error containing `needle`.
|
||||
/// Helper: assert `create_tunnel` returns an error containing `needle`.
|
||||
fn assert_tunnel_err(cfg: &TunnelConfig, needle: &str) {
|
||||
match create_tunnel(cfg) {
|
||||
Err(e) => assert!(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue