Skip to content

Commit 1b526cb

Browse files
committed
test: update tests for repo cleanup
- Rewrite test_claude_md.py → test AGENTS.md structure and CLAUDE.md symlink - Remove TestCommandFiles and TestSettingsJson from test_marketplace.py (commands/ and .claude/ directories removed) - Fix UTF-8 encoding in test_skill_structure.py read_text() calls
1 parent 19df269 commit 1b526cb

3 files changed

Lines changed: 56 additions & 118 deletions

File tree

tests/unit/test_claude_md.py

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,56 @@
1-
"""Tests for CLAUDE.md structure and content."""
1+
"""Tests for AGENTS.md (and CLAUDE.md symlink) structure and content."""
22

33
import pytest
44

55

6-
class TestClaudeMdStructure:
7-
"""Test that CLAUDE.md has required structure."""
6+
class TestAgentsMdStructure:
7+
"""Test that AGENTS.md has required structure."""
88

99
@pytest.fixture
10-
def claude_md(self, skill_root):
11-
"""Load CLAUDE.md content."""
10+
def agents_md(self, skill_root):
11+
"""Load AGENTS.md content."""
12+
agents_path = skill_root / "AGENTS.md"
13+
assert agents_path.exists(), "AGENTS.md must exist at project root"
14+
return agents_path.read_text()
15+
16+
def test_agents_md_exists(self, skill_root):
17+
"""AGENTS.md must exist at project root."""
18+
assert (skill_root / "AGENTS.md").exists()
19+
20+
def test_claude_md_symlink_exists(self, skill_root):
21+
"""CLAUDE.md should exist as a symlink to AGENTS.md."""
1222
claude_path = skill_root / "CLAUDE.md"
1323
assert claude_path.exists(), "CLAUDE.md must exist at project root"
14-
return claude_path.read_text()
15-
16-
def test_claude_md_exists(self, skill_root):
17-
"""CLAUDE.md must exist at project root."""
18-
assert (skill_root / "CLAUDE.md").exists()
19-
20-
def test_has_tdd_rule(self, claude_md):
21-
"""CLAUDE.md must mention TDD-first development."""
22-
assert "TDD" in claude_md
23-
assert "test" in claude_md.lower()
24-
25-
def test_references_test_file(self, claude_md):
26-
"""CLAUDE.md should reference test examples."""
27-
assert "test_skill_structure.py" in claude_md
28-
29-
def test_has_project_structure(self, claude_md):
30-
"""CLAUDE.md should document project structure."""
31-
assert "rhdh/" in claude_md
32-
assert "skills/" in claude_md
33-
assert "tests/" in claude_md
34-
35-
def test_has_cli_section(self, claude_md):
36-
"""CLAUDE.md should document CLI usage."""
37-
assert "rhdh" in claude_md
38-
assert "uv run" in claude_md
39-
40-
def test_documents_output_format(self, claude_md):
41-
"""CLAUDE.md should explain JSON/human output detection."""
42-
assert "JSON" in claude_md
43-
assert "TTY" in claude_md or "human" in claude_md.lower()
24+
25+
def test_has_think_before_coding_rule(self, agents_md):
26+
"""AGENTS.md must mention think before coding."""
27+
assert "Think Before Coding" in agents_md
28+
29+
def test_has_simplicity_rule(self, agents_md):
30+
"""AGENTS.md must mention simplicity first."""
31+
assert "Simplicity First" in agents_md
32+
33+
def test_has_surgical_changes_rule(self, agents_md):
34+
"""AGENTS.md must mention surgical changes."""
35+
assert "Surgical Changes" in agents_md
36+
37+
def test_has_goal_driven_rule(self, agents_md):
38+
"""AGENTS.md must mention goal-driven execution."""
39+
assert "Goal-Driven Execution" in agents_md
40+
41+
def test_has_verification_command(self, agents_md):
42+
"""AGENTS.md should reference test verification."""
43+
assert "uv run pytest" in agents_md
44+
45+
def test_has_versioning_section(self, agents_md):
46+
"""AGENTS.md should document versioning."""
47+
assert "pyproject.toml" in agents_md
48+
assert "plugin.json" in agents_md
49+
assert "marketplace.json" in agents_md
50+
51+
def test_has_agent_skills_section(self, agents_md):
52+
"""AGENTS.md should have agent skills config section."""
53+
assert "## Agent skills" in agents_md
54+
assert "issue-tracker.md" in agents_md
55+
assert "triage-labels.md" in agents_md
56+
assert "domain.md" in agents_md

tests/unit/test_marketplace.py

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
"""Tests for marketplace configuration files."""
22

33
import json
4-
import re
54

65
import pytest
7-
import yaml
86

97

108
class TestPluginJson:
@@ -81,76 +79,3 @@ def test_plugin_entry_has_required_fields(self, marketplace_json):
8179
assert "name" in plugin
8280
assert "source" in plugin
8381
assert "version" in plugin
84-
85-
86-
class TestCommandFiles:
87-
"""Test command files have proper structure."""
88-
89-
@pytest.fixture
90-
def command_files(self, skill_root):
91-
"""Get all command files."""
92-
commands_dir = skill_root / "commands"
93-
return list(commands_dir.glob("*.md"))
94-
95-
def test_commands_exist(self, command_files):
96-
"""At least one command should exist."""
97-
assert len(command_files) >= 1
98-
99-
def test_command_has_frontmatter(self, command_files):
100-
"""Each command should have YAML frontmatter."""
101-
for cmd in command_files:
102-
content = cmd.read_text()
103-
match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
104-
assert match, f"{cmd.name} missing YAML frontmatter"
105-
106-
frontmatter = yaml.safe_load(match.group(1))
107-
assert "description" in frontmatter, f"{cmd.name} missing description"
108-
109-
def test_command_has_allowed_tools(self, command_files):
110-
"""Each command should specify allowed-tools."""
111-
for cmd in command_files:
112-
content = cmd.read_text()
113-
match = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
114-
assert match, f"{cmd.name} missing YAML frontmatter"
115-
frontmatter = yaml.safe_load(match.group(1))
116-
117-
assert "allowed-tools" in frontmatter, f"{cmd.name} missing allowed-tools"
118-
# Should reference the skill
119-
assert "Skill" in frontmatter["allowed-tools"], (
120-
f"{cmd.name} allowed-tools should reference Skill"
121-
)
122-
123-
124-
class TestSettingsJson:
125-
"""Test .claude/settings.json structure."""
126-
127-
@pytest.fixture
128-
def settings_json(self, skill_root):
129-
"""Load settings.json content."""
130-
path = skill_root / ".claude" / "settings.json"
131-
return json.loads(path.read_text())
132-
133-
def test_has_commands(self, settings_json):
134-
"""settings.json should have commands section."""
135-
assert "commands" in settings_json
136-
assert len(settings_json["commands"]) >= 1
137-
138-
def test_has_skills(self, settings_json):
139-
"""settings.json should have skills section."""
140-
assert "skills" in settings_json
141-
assert "rhdh" in settings_json["skills"]
142-
143-
def test_skill_has_path(self, settings_json):
144-
"""Skill entry should have path."""
145-
skill = settings_json["skills"]["rhdh"]
146-
assert "path" in skill
147-
148-
def test_command_paths_are_valid(self, settings_json, skill_root):
149-
"""Command paths should resolve to existing files."""
150-
claude_dir = skill_root / ".claude"
151-
152-
for name, cmd in settings_json["commands"].items():
153-
if "path" in cmd:
154-
# Resolve relative path from .claude/
155-
cmd_path = (claude_dir / cmd["path"]).resolve()
156-
assert cmd_path.exists(), f"Command {name} path does not exist: {cmd_path}"

tests/unit/test_skill_structure.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class TestOrchestratorSkillMd:
1313
def skill_md(self, skills_dir):
1414
"""Load orchestrator SKILL.md content."""
1515
skill_path = skills_dir / "SKILL.md"
16-
return skill_path.read_text()
16+
return skill_path.read_text(encoding="utf-8")
1717

1818
@pytest.fixture
1919
def skill_frontmatter(self, skill_md):
@@ -81,7 +81,7 @@ class TestOverlaySkillMd:
8181
def skill_md(self, overlay_skill_dir):
8282
"""Load overlay SKILL.md content."""
8383
skill_path = overlay_skill_dir / "SKILL.md"
84-
return skill_path.read_text()
84+
return skill_path.read_text(encoding="utf-8")
8585

8686
@pytest.fixture
8787
def skill_frontmatter(self, skill_md):
@@ -181,22 +181,22 @@ def test_workflows_exist(self, workflow_files):
181181
def test_workflow_has_required_reading(self, workflow_files):
182182
"""Each workflow should have <required_reading> section."""
183183
for workflow in workflow_files:
184-
content = workflow.read_text()
184+
content = workflow.read_text(encoding="utf-8")
185185
assert "<required_reading>" in content or "<prerequisites>" in content, (
186186
f"{workflow.name} missing required_reading or prerequisites"
187187
)
188188

189189
def test_workflow_has_process(self, workflow_files):
190190
"""Each workflow should have <process> section."""
191191
for workflow in workflow_files:
192-
content = workflow.read_text()
192+
content = workflow.read_text(encoding="utf-8")
193193
assert "<process>" in content, f"{workflow.name} missing <process> section"
194194
assert "</process>" in content, f"{workflow.name} missing </process> closing tag"
195195

196196
def test_workflow_has_success_criteria(self, workflow_files):
197197
"""Each workflow should have <success_criteria> section."""
198198
for workflow in workflow_files:
199-
content = workflow.read_text()
199+
content = workflow.read_text(encoding="utf-8")
200200
assert "<success_criteria>" in content, (
201201
f"{workflow.name} missing <success_criteria> section"
202202
)
@@ -210,7 +210,7 @@ def rhdh_repos(self, skills_dir):
210210
"""Load rhdh-repos.md content."""
211211
path = skills_dir / "references" / "rhdh-repos.md"
212212
assert path.exists(), "rhdh-repos.md must exist in skills/rhdh/references/"
213-
return path.read_text()
213+
return path.read_text(encoding="utf-8")
214214

215215
def test_rhdh_repos_exists(self, skills_dir):
216216
"""rhdh-repos.md must exist."""
@@ -268,7 +268,7 @@ def test_reference_has_xml_sections(self, reference_files):
268268
for ref in reference_files:
269269
if ref.name in xml_optional:
270270
continue
271-
content = ref.read_text()
271+
content = ref.read_text(encoding="utf-8")
272272
# Should have at least one XML tag
273273
has_xml = bool(re.search(r"<\w+>", content))
274274
assert has_xml, f"{ref.name} should use XML tags for structure"
@@ -290,5 +290,5 @@ def test_templates_exist(self, template_files):
290290
def test_template_has_code_blocks(self, template_files):
291291
"""Templates should contain code block examples."""
292292
for template in template_files:
293-
content = template.read_text()
293+
content = template.read_text(encoding="utf-8")
294294
assert "```" in content, f"{template.name} should have code block examples"

0 commit comments

Comments
 (0)