Update: 将子项目从 submodule 转为完整内容
- 移除 GovAI, nomifun-tauri, 算力盒子 的 submodule 引用 - 添加所有子项目的完整源代码 - 保留原始 .git 为 .git.bak 备份
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use nomifun_cron::skill_file::{
|
||||
ParsedSkillContent, build_skill_content, content_hash, cron_skill_dir, cron_skill_file_path, parse_skill_content,
|
||||
read_skill_content, validate_skill_content, write_raw_skill_file, write_skill_file,
|
||||
};
|
||||
|
||||
fn unique_temp_dir(label: &str) -> std::path::PathBuf {
|
||||
let nanos = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_nanos();
|
||||
std::env::temp_dir().join(format!("nomifun-cron-{label}-{}-{nanos}", std::process::id()))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn build_skill_content_matches_frontend_shape() {
|
||||
let content = build_skill_content(
|
||||
"Daily Report",
|
||||
"Line 1\nLine 2\r\nLine 3",
|
||||
"Run report",
|
||||
Some("Every day at 9am"),
|
||||
);
|
||||
|
||||
assert!(content.contains("name: Daily Report"));
|
||||
assert!(content.contains("description: Line 1 Line 2 Line 3"));
|
||||
assert!(content.contains("This is a scheduled task: **Daily Report**"));
|
||||
assert!(content.contains("Schedule: Every day at 9am"));
|
||||
assert!(content.contains("## Instructions"));
|
||||
assert!(content.ends_with("Run report"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_skill_content_roundtrips_built_files() {
|
||||
let built = build_skill_content("My Job", "My Description", "First\n\nSecond", None);
|
||||
let parsed = parse_skill_content(&built).unwrap();
|
||||
assert_eq!(
|
||||
parsed,
|
||||
ParsedSkillContent {
|
||||
name: "My Job".into(),
|
||||
description: "My Description".into(),
|
||||
body: "First\n\nSecond".into(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_skill_content_skips_blank_lines_after_frontmatter() {
|
||||
let parsed = parse_skill_content("---\nname: Test\ndescription: Desc\n---\n\n\nPrompt").unwrap();
|
||||
assert_eq!(parsed.body, "Prompt");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_skill_content_handles_empty_body() {
|
||||
let parsed = parse_skill_content("---\nname: Test\ndescription: Desc\n---\n\n").unwrap();
|
||||
assert_eq!(parsed.body, "");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_skill_content_rejects_placeholders() {
|
||||
let err =
|
||||
validate_skill_content("---\nname: skill-name\ndescription: Real description\n---\n\nReal body").unwrap_err();
|
||||
assert!(err.to_string().contains("template placeholder"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn content_hash_normalizes_line_endings_and_edges() {
|
||||
let a = content_hash("---\nname: Test\ndescription: Desc\n---\n\nBody\n");
|
||||
let b = content_hash("---\r\nname: Test\r\ndescription: Desc\r\n---\r\n\r\nBody");
|
||||
let c = content_hash(" ---\nname: Test\ndescription: Desc\n---\n\nBody ");
|
||||
assert_eq!(a, b);
|
||||
assert_eq!(a, c);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_read_and_resolve_skill_file_paths() {
|
||||
let base = unique_temp_dir("write-read");
|
||||
std::fs::create_dir_all(&base).unwrap();
|
||||
|
||||
let file_path = write_skill_file(
|
||||
&base,
|
||||
"job-123",
|
||||
"Daily Report",
|
||||
"Generate daily report",
|
||||
"Run report",
|
||||
Some("Every day at 9am"),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(
|
||||
cron_skill_dir(&base, "job-123").unwrap(),
|
||||
base.join("cron").join("skills").join("cron-job-123")
|
||||
);
|
||||
assert_eq!(file_path, cron_skill_file_path(&base, "job-123").unwrap());
|
||||
|
||||
let raw = read_skill_content(&base, "job-123").await.unwrap().unwrap();
|
||||
let parsed = parse_skill_content(&raw).unwrap();
|
||||
assert_eq!(parsed.name, "Daily Report");
|
||||
assert_eq!(parsed.description, "Generate daily report");
|
||||
assert_eq!(parsed.body, "Run report");
|
||||
|
||||
std::fs::remove_dir_all(&base).unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_raw_skill_file_validates_before_writing() {
|
||||
let base = unique_temp_dir("write-raw");
|
||||
std::fs::create_dir_all(&base).unwrap();
|
||||
|
||||
let err = write_raw_skill_file(&base, "job-456", "not valid").await.unwrap_err();
|
||||
assert!(err.to_string().contains("skill file must start with YAML frontmatter"));
|
||||
assert!(read_skill_content(&base, "job-456").await.unwrap().is_none());
|
||||
|
||||
std::fs::remove_dir_all(&base).unwrap();
|
||||
}
|
||||
Reference in New Issue
Block a user