#!/usr/bin/env python3 """ Tests for CLI Parser System Tests the modular parser registration system. """ import argparse import pytest from skill_seekers.cli.parsers import ( PARSERS, SubcommandParser, get_parser_names, register_parsers, ) from skill_seekers.cli.parsers.scrape_parser import ScrapeParser from skill_seekers.cli.parsers.github_parser import GitHubParser from skill_seekers.cli.parsers.package_parser import PackageParser class TestParserRegistry: """Test parser registry functionality.""" def test_all_parsers_registered(self): """Test that all parsers are registered.""" assert len(PARSERS) == 36, f"Expected 36 parsers, got {len(PARSERS)}" def test_get_parser_names(self): """Test getting list of parser names.""" names = get_parser_names() assert len(names) == 36 assert "scrape" in names assert "github" in names assert "package" in names assert "upload" in names assert "analyze" in names assert "config" in names assert "workflows" in names assert "video" in names def test_all_parsers_are_subcommand_parsers(self): """Test that all parsers inherit from SubcommandParser.""" for parser in PARSERS: assert isinstance(parser, SubcommandParser) def test_all_parsers_have_required_properties(self): """Test that all parsers have name, help, description.""" for parser in PARSERS: assert hasattr(parser, "name") assert hasattr(parser, "help") assert hasattr(parser, "description") assert isinstance(parser.name, str) assert isinstance(parser.help, str) assert isinstance(parser.description, str) assert len(parser.name) > 0 assert len(parser.help) > 0 def test_all_parsers_have_add_arguments_method(self): """Test that all parsers implement add_arguments.""" for parser in PARSERS: assert hasattr(parser, "add_arguments") assert callable(parser.add_arguments) def test_no_duplicate_parser_names(self): """Test that all parser names are unique.""" names = [p.name for p in PARSERS] assert len(names) == len(set(names)), "Duplicate parser names found!" class TestParserCreation: """Test parser creation functionality.""" def test_scrape_parser_creates_subparser(self): """Test that ScrapeParser creates valid subparser.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers() scrape_parser = ScrapeParser() subparser = scrape_parser.create_parser(subparsers) assert subparser is not None assert scrape_parser.name == "scrape" assert scrape_parser.help == "Scrape documentation website" def test_github_parser_creates_subparser(self): """Test that GitHubParser creates valid subparser.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers() github_parser = GitHubParser() subparser = github_parser.create_parser(subparsers) assert subparser is not None assert github_parser.name == "github" def test_package_parser_creates_subparser(self): """Test that PackageParser creates valid subparser.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers() package_parser = PackageParser() subparser = package_parser.create_parser(subparsers) assert subparser is not None assert package_parser.name == "package" def test_register_parsers_creates_all_subcommands(self): """Test that register_parsers creates all 19 subcommands.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers(dest="command") # Register all parsers register_parsers(subparsers) # Test that all commands can be parsed test_commands = [ "config --show", "scrape --config test.json", "github --repo owner/repo", "package output/test/", "upload test.zip", "analyze --directory .", "enhance output/test/", "estimate test.json", ] for cmd in test_commands: args = main_parser.parse_args(cmd.split()) assert args.command is not None class TestSpecificParsers: """Test specific parser implementations.""" def test_scrape_parser_arguments(self): """Test ScrapeParser has correct arguments.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers(dest="command") scrape_parser = ScrapeParser() scrape_parser.create_parser(subparsers) # Test various argument combinations args = main_parser.parse_args(["scrape", "--config", "test.json"]) assert args.command == "scrape" assert args.config == "test.json" args = main_parser.parse_args(["scrape", "--config", "test.json", "--max-pages", "100"]) assert args.max_pages == 100 args = main_parser.parse_args(["scrape", "--enhance-level", "2"]) assert args.enhance_level == 2 def test_github_parser_arguments(self): """Test GitHubParser has correct arguments.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers(dest="command") github_parser = GitHubParser() github_parser.create_parser(subparsers) args = main_parser.parse_args(["github", "--repo", "owner/repo"]) assert args.command == "github" assert args.repo == "owner/repo" args = main_parser.parse_args(["github", "--repo", "owner/repo", "--non-interactive"]) assert args.non_interactive is True def test_package_parser_arguments(self): """Test PackageParser has correct arguments.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers(dest="command") package_parser = PackageParser() package_parser.create_parser(subparsers) args = main_parser.parse_args(["package", "output/test/"]) assert args.command == "package" assert args.skill_directory == "output/test/" args = main_parser.parse_args(["package", "output/test/", "--target", "gemini"]) assert args.target == "gemini" args = main_parser.parse_args(["package", "output/test/", "--no-open"]) assert args.no_open is True def test_analyze_parser_arguments(self): """Test AnalyzeParser has correct arguments.""" main_parser = argparse.ArgumentParser() subparsers = main_parser.add_subparsers(dest="command") from skill_seekers.cli.parsers.analyze_parser import AnalyzeParser analyze_parser = AnalyzeParser() analyze_parser.create_parser(subparsers) args = main_parser.parse_args(["analyze", "--directory", "."]) assert args.command == "analyze" assert args.directory == "." args = main_parser.parse_args(["analyze", "--directory", ".", "--quick"]) assert args.quick is True args = main_parser.parse_args(["analyze", "--directory", ".", "--comprehensive"]) assert args.comprehensive is True args = main_parser.parse_args(["analyze", "--directory", ".", "--skip-patterns"]) assert args.skip_patterns is True class TestBackwardCompatibility: """Test backward compatibility with old CLI.""" def test_all_original_commands_still_work(self): """Test that all original commands are still registered.""" names = get_parser_names() # Original commands from old main.py original_commands = [ "config", "scrape", "github", "pdf", "unified", "enhance", "enhance-status", "package", "upload", "estimate", "extract-test-examples", "install-agent", "analyze", "install", "resume", "stream", "update", "multilang", "quality", ] for cmd in original_commands: assert cmd in names, f"Command '{cmd}' not found in parser registry!" def test_command_count_matches(self): """Test that we have exactly 35 commands (25 original + 10 new source types).""" assert len(PARSERS) == 36 assert len(get_parser_names()) == 36 if __name__ == "__main__": pytest.main([__file__, "-v"])