153 lines
4.4 KiB
Rust
153 lines
4.4 KiB
Rust
use super::*;
|
|
use std::path::PathBuf;
|
|
|
|
fn temp_json(name: &str, contents: &str) -> String {
|
|
let path = std::env::temp_dir().join(format!(
|
|
"op-cli-conversion-{name}-{}.json",
|
|
std::process::id()
|
|
));
|
|
std::fs::write(&path, contents).expect("write temp json");
|
|
path.to_string_lossy().into_owned()
|
|
}
|
|
|
|
fn temp_out_dir(name: &str) -> PathBuf {
|
|
let path =
|
|
std::env::temp_dir().join(format!("op-cli-skill-export-{name}-{}", std::process::id()));
|
|
std::fs::remove_dir_all(&path).ok();
|
|
path
|
|
}
|
|
|
|
#[test]
|
|
fn design_upsert_vars_maps_to_tool_call() {
|
|
let vars = temp_json(
|
|
"vars",
|
|
r##"{"color/primary":{"type":"color","value":"#3366ff"}}"##,
|
|
);
|
|
let parsed = parse_args(&[
|
|
"design:upsert-vars".into(),
|
|
"--key".into(),
|
|
"tokens:theme.css".into(),
|
|
"--file".into(),
|
|
vars.clone(),
|
|
"--source".into(),
|
|
"src/theme.css".into(),
|
|
"--hash".into(),
|
|
"h1".into(),
|
|
])
|
|
.expect("parse design:upsert-vars");
|
|
std::fs::remove_file(vars).ok();
|
|
|
|
match parsed.command {
|
|
Command::ToolCall { tool, args } => {
|
|
assert_eq!(tool, "upsert_variables");
|
|
assert!(args.contains(&("key".into(), "tokens:theme.css".into())));
|
|
assert!(args
|
|
.iter()
|
|
.any(|(key, value)| key == "variables" && value.contains("color/primary")));
|
|
assert!(args.contains(&("sourcePath".into(), "src/theme.css".into())));
|
|
assert!(args.contains(&("sourceHash".into(), "h1".into())));
|
|
}
|
|
other => panic!("expected ToolCall, got {other:?}"),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn design_upsert_component_requires_name() {
|
|
let node = temp_json("component", r#"{"type":"frame","id":"button"}"#);
|
|
let parsed = parse_args(&[
|
|
"design:upsert-component".into(),
|
|
"--key".into(),
|
|
"src/Button.tsx#Button".into(),
|
|
"--file".into(),
|
|
node.clone(),
|
|
]);
|
|
std::fs::remove_file(node).ok();
|
|
|
|
assert!(parsed.is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn design_upsert_screen_maps_payload_file() {
|
|
let node = temp_json("screen", r#"{"type":"frame","id":"home"}"#);
|
|
let parsed = parse_args(&[
|
|
"design:upsert-screen".into(),
|
|
"--key".into(),
|
|
"route:/".into(),
|
|
"--file".into(),
|
|
node.clone(),
|
|
])
|
|
.expect("parse design:upsert-screen");
|
|
std::fs::remove_file(node).ok();
|
|
|
|
assert_eq!(
|
|
parsed.command,
|
|
Command::ToolCall {
|
|
tool: "upsert_screen".into(),
|
|
args: vec![
|
|
("key".into(), "route:/".into()),
|
|
("node_json".into(), r#"{"type":"frame","id":"home"}"#.into()),
|
|
],
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn design_status_and_lint_map_to_read_tools() {
|
|
let status = parse_args(&["design:status".into(), "--kind".into(), "component".into()])
|
|
.expect("parse design:status");
|
|
assert_eq!(
|
|
status.command,
|
|
Command::ToolCall {
|
|
tool: "conversion_status".into(),
|
|
args: vec![("kind".into(), "component".into())],
|
|
}
|
|
);
|
|
|
|
let lint = parse_args(&["design:lint".into(), "--node".into(), "n1".into()])
|
|
.expect("parse design:lint");
|
|
assert_eq!(
|
|
lint.command,
|
|
Command::ToolCall {
|
|
tool: "lint_document".into(),
|
|
args: vec![("nodeId".into(), "n1".into())],
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn skill_export_maps_to_cli_command() {
|
|
let parsed = parse_args(&[
|
|
"skill:export".into(),
|
|
"code-to-design".into(),
|
|
"--out".into(),
|
|
".tmp-skills".into(),
|
|
])
|
|
.expect("parse skill:export");
|
|
|
|
assert_eq!(
|
|
parsed.command,
|
|
Command::SkillExport {
|
|
name: "code-to-design".into(),
|
|
out_dir: Some(".tmp-skills".into()),
|
|
}
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn skill_export_writes_claude_skill_md() {
|
|
let out_dir = temp_out_dir("code-to-design");
|
|
let output = crate::skill_export_cli::run_export(
|
|
"code-to-design",
|
|
Some(out_dir.to_string_lossy().as_ref()),
|
|
)
|
|
.expect("export code-to-design skill");
|
|
let skill_path = out_dir.join("code-to-design").join("SKILL.md");
|
|
let contents = std::fs::read_to_string(&skill_path).expect("read exported skill");
|
|
std::fs::remove_dir_all(&out_dir).ok();
|
|
|
|
assert!(output.contains("SKILL.md"));
|
|
assert!(contents.starts_with("---\nname: code-to-design\n"));
|
|
assert!(contents.contains("Five-step"));
|
|
assert!(contents.contains("upsert_variables"));
|
|
}
|