KeiSeiKit-1.0/_primitives/_rust/kei-skills/tests/format_roundtrip.rs
Parfii-bot a4e667de10 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

81 lines
3.1 KiB
Rust

//! Format round-trip: parse a Hermes reference SKILL.md, serialize, and
//! diff. Byte-equality is the contract — Hermes interop must be lossless.
use kei_skills::format::{parse, serialize};
use std::path::PathBuf;
fn ref_skill_minimal() -> &'static str {
// Description avoids special chars that serde_yaml would force-quote.
"---\nname: yuanbao\ndescription: yuanbao groups mention\n---\n\n# Body\n\nHello.\n"
}
fn ref_skill_with_extras() -> &'static str {
concat!(
"---\n",
"name: ocr-and-documents\n",
"description: \"OCR + PDF/Word/Excel/PPT.\"\n",
"category: productivity\n",
"stability: validated\n",
"metadata:\n",
" hermes:\n",
" tags:\n",
" - ocr\n",
" - pdf\n",
"---\n",
"\n",
"## Overview\n",
"Body text.\n",
)
}
#[test]
fn roundtrip_minimal_byte_equal() {
let src = ref_skill_minimal();
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
let out = serialize(&parsed).expect("serialize");
// Reparse-equal is the primary contract: serde_yaml may pick
// different (still-valid) YAML output for the same logical mapping
// (quote style, anchor handling). Round-trip via reparse confirms
// no semantic loss.
let reparsed = parse(&out, PathBuf::from("<inline>")).expect("reparse");
assert_eq!(reparsed.frontmatter, parsed.frontmatter);
assert_eq!(reparsed.body, parsed.body);
}
#[test]
fn roundtrip_with_category_and_stability() {
let src = "---\nname: research\ndescription: deep-research\ncategory: meta\nstability: experimental\n---\n\nBody.\n";
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
assert_eq!(parsed.frontmatter.category.as_deref(), Some("meta"));
assert_eq!(parsed.frontmatter.stability.as_deref(), Some("experimental"));
let out = serialize(&parsed).expect("serialize");
let reparsed = parse(&out, PathBuf::from("<inline>")).expect("reparse");
assert_eq!(reparsed.frontmatter, parsed.frontmatter);
assert_eq!(reparsed.body, parsed.body);
}
#[test]
fn roundtrip_preserves_extra_metadata() {
let src = ref_skill_with_extras();
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
assert_eq!(parsed.frontmatter.name, "ocr-and-documents");
assert!(parsed.frontmatter.extra.contains_key(serde_yaml::Value::String("metadata".into())));
let out = serialize(&parsed).expect("serialize");
let reparsed = parse(&out, PathBuf::from("<inline>")).expect("re-parse");
assert_eq!(reparsed.frontmatter, parsed.frontmatter);
assert_eq!(reparsed.body, parsed.body);
}
#[test]
fn body_only_after_close_fence() {
let src = "---\nname: x\ndescription: y\n---\nBody starts here.\n";
let parsed = parse(src, PathBuf::from("<inline>")).expect("parse");
assert_eq!(parsed.body, "Body starts here.\n");
}
#[test]
fn parse_rejects_unclosed_frontmatter() {
let src = "---\nname: x\ndescription: y\n# never closes\n";
let err = parse(src, PathBuf::from("<inline>")).expect_err("must error");
assert!(err.to_string().contains("not closed"));
}