#!/usr/bin/env python3 """ Tests for cli/quality_checker.py functionality """ import tempfile import unittest from pathlib import Path from skill_seekers.cli.quality_checker import QualityReport, SkillQualityChecker class TestQualityChecker(unittest.TestCase): """Test quality checker functionality""" def create_test_skill(self, tmpdir, skill_md_content, create_references=True): """Helper to create a test skill directory""" skill_dir = Path(tmpdir) / "test-skill" skill_dir.mkdir() # Create SKILL.md skill_md = skill_dir / "SKILL.md" skill_md.write_text(skill_md_content, encoding="utf-8") # Create references directory if create_references: refs_dir = skill_dir / "references" refs_dir.mkdir() (refs_dir / "index.md").write_text("# Index\n\nTest reference.", encoding="utf-8") (refs_dir / "getting_started.md").write_text( "# Getting Started\n\nHow to start.", encoding="utf-8" ) return skill_dir def test_checker_detects_missing_skill_md(self): """Test that checker detects missing SKILL.md""" with tempfile.TemporaryDirectory() as tmpdir: skill_dir = Path(tmpdir) / "test-skill" skill_dir.mkdir() checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have error about missing SKILL.md self.assertTrue(report.has_errors) self.assertTrue(any("SKILL.md" in issue.message for issue in report.errors)) def test_checker_detects_missing_references(self): """Test that checker warns about missing references""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test --- # Test Skill This is a test. """ skill_dir = self.create_test_skill(tmpdir, skill_md, create_references=False) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have warning about missing references self.assertTrue(report.has_warnings) self.assertTrue(any("references" in issue.message.lower() for issue in report.warnings)) def test_checker_detects_invalid_frontmatter(self): """Test that checker detects invalid YAML frontmatter""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """# Test Skill No frontmatter here! """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have error about missing frontmatter self.assertTrue(report.has_errors) self.assertTrue(any("frontmatter" in issue.message.lower() for issue in report.errors)) def test_checker_detects_missing_name_field(self): """Test that checker detects missing name field in frontmatter""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- description: test --- # Test Skill """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have error about missing name field self.assertTrue(report.has_errors) self.assertTrue(any("name" in issue.message.lower() for issue in report.errors)) def test_checker_detects_code_without_language(self): """Test that checker warns about code blocks without language tags""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test --- # Test Skill Here's some code: ``` print("hello") ``` """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have warning about code without language self.assertTrue(report.has_warnings) self.assertTrue(any("language" in issue.message.lower() for issue in report.warnings)) def test_checker_approves_good_skill(self): """Test that checker gives high score to well-formed skill""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test description: A test skill --- # Test Skill ## When to Use This Skill Use this when you need to test. ## Quick Reference Here are some examples: ```python def hello(): print("hello") ``` ```javascript console.log("hello"); ``` ## Example: Basic Usage This shows how to use it. ## Reference Files See the references directory for more: - [Getting Started](references/getting_started.md) - [Index](references/index.md) """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have no errors self.assertFalse(report.has_errors) # Quality score should be high self.assertGreaterEqual(report.quality_score, 80.0) def test_checker_detects_broken_links(self): """Test that checker detects broken internal links""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test --- # Test Skill See [this file](nonexistent.md) for more info. """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have warning about broken link self.assertTrue(report.has_warnings) self.assertTrue( any("broken link" in issue.message.lower() for issue in report.warnings) ) def test_quality_score_calculation(self): """Test that quality score is calculated correctly""" with tempfile.TemporaryDirectory() as tmpdir: report = QualityReport("test", Path(tmpdir)) # Perfect score to start self.assertEqual(report.quality_score, 100.0) # Add an error (should deduct 15 points) report.add_error("test", "Test error") self.assertEqual(report.quality_score, 85.0) # Add a warning (should deduct 5 points) report.add_warning("test", "Test warning") self.assertEqual(report.quality_score, 80.0) # Add more errors report.add_error("test", "Another error") report.add_error("test", "Yet another error") self.assertEqual(report.quality_score, 50.0) def test_quality_grade_calculation(self): """Test that quality grades are assigned correctly""" with tempfile.TemporaryDirectory() as tmpdir: report = QualityReport("test", Path(tmpdir)) # Grade A (90-100) self.assertEqual(report.quality_grade, "A") # Grade B (80-89) report.add_error("test", "Error 1") self.assertEqual(report.quality_grade, "B") # Grade C (70-79) report.add_warning("test", "Warning 1") report.add_warning("test", "Warning 2") self.assertEqual(report.quality_grade, "C") # Grade D (60-69) report.add_warning("test", "Warning 3") report.add_warning("test", "Warning 4") self.assertEqual(report.quality_grade, "D") # Grade F (below 60) report.add_error("test", "Error 2") report.add_error("test", "Error 3") self.assertEqual(report.quality_grade, "F") def test_is_excellent_property(self): """Test is_excellent property""" with tempfile.TemporaryDirectory() as tmpdir: report = QualityReport("test", Path(tmpdir)) # Should be excellent with no issues self.assertTrue(report.is_excellent) # Adding an error should make it not excellent report.add_error("test", "Test error") self.assertFalse(report.is_excellent) # Clean report report2 = QualityReport("test", Path(tmpdir)) # Adding a warning should also make it not excellent report2.add_warning("test", "Test warning") self.assertFalse(report2.is_excellent) class TestCompletenessChecks(unittest.TestCase): """Test completeness check functionality""" def create_test_skill(self, tmpdir, skill_md_content): """Helper to create a test skill directory""" skill_dir = Path(tmpdir) / "test-skill" skill_dir.mkdir() # Create SKILL.md skill_md = skill_dir / "SKILL.md" skill_md.write_text(skill_md_content, encoding="utf-8") # Create references directory refs_dir = skill_dir / "references" refs_dir.mkdir() (refs_dir / "index.md").write_text("# Index\n", encoding="utf-8") return skill_dir def test_checker_detects_prerequisites_section(self): """Test that checker detects prerequisites section""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test --- # Test Skill ## Prerequisites Make sure you have: - Python 3.10+ - pip installed ## Usage Run the command. """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have info about found prerequisites completeness_infos = [i for i in report.info if i.category == "completeness"] self.assertTrue( any( "prerequisites" in i.message.lower() or "verification" in i.message.lower() for i in completeness_infos ) ) def test_checker_detects_troubleshooting_section(self): """Test that checker detects troubleshooting section""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test --- # Test Skill ## Usage Run the command. ## Troubleshooting ### Common Issues If the command fails, check your permissions. """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have info about found troubleshooting completeness_infos = [i for i in report.info if i.category == "completeness"] self.assertTrue( any( "troubleshoot" in i.message.lower() or "error handling" in i.message.lower() for i in completeness_infos ) ) def test_checker_detects_workflow_steps(self): """Test that checker detects workflow steps""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test --- # Test Skill ## Getting Started First, install the dependencies. Then, configure your environment. Next, run the setup script. Finally, verify the installation. """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have info about found workflow steps completeness_infos = [i for i in report.info if i.category == "completeness"] self.assertTrue( any( "workflow" in i.message.lower() or "step" in i.message.lower() for i in completeness_infos ) ) def test_checker_suggests_adding_prerequisites(self): """Test that checker suggests adding prerequisites when missing""" with tempfile.TemporaryDirectory() as tmpdir: skill_md = """--- name: test --- # Test Skill ## Usage Just run the command. """ skill_dir = self.create_test_skill(tmpdir, skill_md) checker = SkillQualityChecker(skill_dir) report = checker.check_all() # Should have info suggesting prerequisites completeness_infos = [i for i in report.info if i.category == "completeness"] self.assertTrue( any( "consider" in i.message.lower() and "prerequisites" in i.message.lower() for i in completeness_infos ) ) class TestQualityCheckerCLI(unittest.TestCase): """Test quality checker CLI""" def test_cli_help_output(self): """Test that CLI help works""" import subprocess try: result = subprocess.run( ["python3", "-m", "skill_seekers.cli.quality_checker", "--help"], capture_output=True, text=True, timeout=5, ) # Should include usage info output = result.stdout + result.stderr self.assertTrue("usage:" in output.lower() or "quality" in output.lower()) except FileNotFoundError: self.skipTest("Module not installed") def test_cli_with_nonexistent_directory(self): """Test CLI behavior with nonexistent directory""" import subprocess result = subprocess.run( ["python3", "-m", "skill_seekers.cli.quality_checker", "/nonexistent/path"], capture_output=True, text=True, ) # Should fail self.assertNotEqual(result.returncode, 0) if __name__ == "__main__": unittest.main()