68 lines
2.8 KiB
Python
68 lines
2.8 KiB
Python
"""
|
|
Tests for SKILL.md validation.
|
|
Task 1: Test SKILL.md file exists.
|
|
Task 2: Test SKILL.md has valid YAML frontmatter.
|
|
Task 3: Test SKILL.md has name field.
|
|
Task 4: Test SKILL.md has description field.
|
|
Task 5: Test description contains /gsd: pattern for triggering.
|
|
"""
|
|
import pytest
|
|
from pathlib import Path
|
|
import yaml
|
|
|
|
|
|
class TestSkillMd:
|
|
"""Tests for SKILL.md structure and trigger patterns."""
|
|
|
|
@property
|
|
def skill_path(self) -> Path:
|
|
"""Get path to SKILL.md."""
|
|
return Path(__file__).parent.parent / "skill" / "SKILL.md"
|
|
|
|
def test_skill_md_exists(self):
|
|
"""SKILL.md file exists at skill/SKILL.md."""
|
|
assert self.skill_path.exists(), f"SKILL.md not found at {self.skill_path}"
|
|
|
|
def test_skill_md_has_valid_frontmatter(self):
|
|
"""SKILL.md has valid YAML frontmatter between --- delimiters."""
|
|
content = self.skill_path.read_text(encoding="utf-8")
|
|
|
|
# Check file starts with ---
|
|
assert content.startswith("---\n"), "SKILL.md must start with '---' frontmatter delimiter"
|
|
|
|
# Find closing delimiter
|
|
parts = content.split("---\n", 2)
|
|
assert len(parts) >= 3, "SKILL.md must have opening and closing '---' delimiters"
|
|
|
|
# Parse frontmatter as YAML
|
|
frontmatter_text = parts[1].strip()
|
|
frontmatter = yaml.safe_load(frontmatter_text)
|
|
assert isinstance(frontmatter, dict), "Frontmatter must be valid YAML"
|
|
|
|
def test_skill_md_has_name_field(self):
|
|
"""SKILL.md frontmatter contains 'name' field."""
|
|
frontmatter = self._parse_frontmatter()
|
|
assert "name" in frontmatter, "Frontmatter must contain 'name' field"
|
|
assert isinstance(frontmatter["name"], str), "'name' must be a string"
|
|
assert len(frontmatter["name"]) > 0, "'name' must not be empty"
|
|
|
|
def test_skill_md_has_description_field(self):
|
|
"""SKILL.md frontmatter contains 'description' field."""
|
|
frontmatter = self._parse_frontmatter()
|
|
assert "description" in frontmatter, "Frontmatter must contain 'description' field"
|
|
assert isinstance(frontmatter["description"], str), "'description' must be a string"
|
|
assert len(frontmatter["description"]) > 0, "'description' must not be empty"
|
|
|
|
def test_skill_md_description_contains_gsd_pattern(self):
|
|
"""SKILL.md description contains /gsd: pattern for trigger matching."""
|
|
frontmatter = self._parse_frontmatter()
|
|
description = frontmatter.get("description", "")
|
|
assert "/gsd:" in description, "Description must contain '/gsd:' pattern for OpenClaw trigger matching"
|
|
|
|
def _parse_frontmatter(self) -> dict:
|
|
"""Parse and return frontmatter from SKILL.md."""
|
|
content = self.skill_path.read_text(encoding="utf-8")
|
|
parts = content.split("---\n", 2)
|
|
frontmatter_text = parts[1].strip()
|
|
return yaml.safe_load(frontmatter_text)
|