Files
zclaw_openfang/crates/zclaw-skills/tests/runner_tests.rs
iven a43806ccc2
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
fix(growth,kernel,runtime): 穷尽审计后 7 项修复 — body 持久化 + embedding 死路径 + 安全加固
CRITICAL 修复:
- body_markdown 数据丢失: SkillManifest.body 字段 + serialize_skill_md 使用 body 替代默认内容
- embedding 检索死路径: rerank_entries 使用异步 index_entry_with_embedding + score_similarity_with_embedding (70/30 混合)
- try_write 静默丢失: pending_embedding 字段 + apply_pending_embedding() 延迟应用

IMPORTANT 修复:
- auto_mode 内存泄漏: add_pending 容量限制 100 + 溢出时丢弃最旧
- name_to_slug 空 ID: uuid fallback for empty/whitespace-only names
- compaction embedding 缺失: compaction GrowthIntegration 也接收 embedding
- kernel 未初始化警告: viking_configure_embedding warn log

验证: 934+ tests PASS, 0 failures
2026-04-21 17:27:37 +08:00

80 lines
2.5 KiB
Rust

//! Tests for PromptOnlySkill runner
use zclaw_skills::*;
use zclaw_types::SkillId;
/// Helper to create a minimal manifest
fn test_manifest(mode: SkillMode) -> SkillManifest {
SkillManifest {
id: SkillId::new("test-prompt-skill"),
name: "Test Prompt Skill".to_string(),
description: "A test prompt skill".to_string(),
version: "1.0.0".to_string(),
author: None,
mode,
capabilities: vec![],
input_schema: None,
output_schema: None,
tags: vec![],
category: None,
triggers: vec![],
tools: vec![],
enabled: true,
body: None,
}
}
#[tokio::test]
async fn prompt_only_skill_returns_formatted_prompt() {
let manifest = test_manifest(SkillMode::PromptOnly);
let template = "Hello {{input}}, welcome!".to_string();
let skill = PromptOnlySkill::new(manifest, template);
let ctx = SkillContext::default();
let skill_ref: &dyn Skill = &skill;
let result = skill_ref.execute(&ctx, serde_json::json!("World")).await.unwrap();
assert!(result.success);
let output = result.output.as_str().unwrap();
assert_eq!(output, "Hello World, welcome!");
}
#[tokio::test]
async fn prompt_only_skill_json_input() {
let manifest = test_manifest(SkillMode::PromptOnly);
let template = "Input: {{input}}".to_string();
let skill = PromptOnlySkill::new(manifest, template);
let ctx = SkillContext::default();
let input = serde_json::json!({"key": "value"});
let skill_ref: &dyn Skill = &skill;
let result = skill_ref.execute(&ctx, input).await.unwrap();
assert!(result.success);
let output = result.output.as_str().unwrap();
assert!(output.contains("key"));
assert!(output.contains("value"));
}
#[tokio::test]
async fn prompt_only_skill_no_placeholder() {
let manifest = test_manifest(SkillMode::PromptOnly);
let template = "Static prompt content".to_string();
let skill = PromptOnlySkill::new(manifest, template);
let ctx = SkillContext::default();
let skill_ref: &dyn Skill = &skill;
let result = skill_ref.execute(&ctx, serde_json::json!("ignored")).await.unwrap();
assert!(result.success);
assert_eq!(result.output.as_str().unwrap(), "Static prompt content");
}
#[tokio::test]
async fn prompt_only_skill_manifest() {
let manifest = test_manifest(SkillMode::PromptOnly);
let skill = PromptOnlySkill::new(manifest.clone(), "prompt".to_string());
assert_eq!(skill.manifest().id.as_str(), "test-prompt-skill");
assert_eq!(skill.manifest().name, "Test Prompt Skill");
}