Files
skill-seekers-reference/tests/test_cli_refactor_e2e.py
yusyus ba1670a220 feat: Unified create command + consolidated enhancement flags
This commit includes two major improvements:

## 1. Unified Create Command (v3.0.0 feature)
- Auto-detects source type (web, GitHub, local, PDF, config)
- Three-tier argument organization (universal, source-specific, advanced)
- Routes to existing scrapers (100% backward compatible)
- Progressive disclosure: 15 universal flags in default help

**New files:**
- src/skill_seekers/cli/source_detector.py - Auto-detection logic
- src/skill_seekers/cli/arguments/create.py - Argument definitions
- src/skill_seekers/cli/create_command.py - Main orchestrator
- src/skill_seekers/cli/parsers/create_parser.py - Parser integration

**Tests:**
- tests/test_source_detector.py (35 tests)
- tests/test_create_arguments.py (30 tests)
- tests/test_create_integration_basic.py (10 tests)

## 2. Enhanced Flag Consolidation (Phase 1)
- Consolidated 3 flags (--enhance, --enhance-local, --enhance-level) → 1 flag
- --enhance-level 0-3 with auto-detection of API vs LOCAL mode
- Default: --enhance-level 2 (balanced enhancement)

**Modified files:**
- arguments/{common,create,scrape,github,analyze}.py - Added enhance_level
- {doc_scraper,github_scraper,config_extractor,main}.py - Updated logic
- create_command.py - Uses consolidated flag

**Auto-detection:**
- If ANTHROPIC_API_KEY set → API mode
- Else → LOCAL mode (Claude Code)

## 3. PresetManager Bug Fix
- Fixed module naming conflict (presets.py vs presets/ directory)
- Moved presets.py → presets/manager.py
- Updated __init__.py exports

**Test Results:**
- All 160+ tests passing
- Zero regressions
- 100% backward compatible

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-15 14:29:19 +03:00

331 lines
12 KiB
Python

#!/usr/bin/env python3
"""
End-to-End Tests for CLI Refactor (Issues #285 and #268)
These tests verify that the unified CLI architecture works correctly:
1. Parser sync: All parsers use shared argument definitions
2. Preset system: Analyze command supports presets
3. Backward compatibility: Old flags still work with deprecation warnings
4. Integration: The complete flow from CLI to execution
"""
import pytest
import subprocess
import argparse
import sys
from pathlib import Path
class TestParserSync:
"""E2E tests for parser synchronization (Issue #285)."""
def test_scrape_interactive_flag_works(self):
"""Test that --interactive flag (previously missing) now works."""
result = subprocess.run(
["skill-seekers", "scrape", "--interactive", "--help"],
capture_output=True,
text=True
)
assert result.returncode == 0, "Command should execute successfully"
assert "--interactive" in result.stdout, "Help should show --interactive flag"
assert "-i" in result.stdout, "Help should show short form -i"
def test_scrape_chunk_for_rag_flag_works(self):
"""Test that --chunk-for-rag flag (previously missing) now works."""
result = subprocess.run(
["skill-seekers", "scrape", "--help"],
capture_output=True,
text=True
)
assert "--chunk-for-rag" in result.stdout, "Help should show --chunk-for-rag flag"
assert "--chunk-size" in result.stdout, "Help should show --chunk-size flag"
assert "--chunk-overlap" in result.stdout, "Help should show --chunk-overlap flag"
def test_scrape_verbose_flag_works(self):
"""Test that --verbose flag (previously missing) now works."""
result = subprocess.run(
["skill-seekers", "scrape", "--help"],
capture_output=True,
text=True
)
assert "--verbose" in result.stdout, "Help should show --verbose flag"
assert "-v" in result.stdout, "Help should show short form -v"
def test_scrape_url_flag_works(self):
"""Test that --url flag (previously missing) now works."""
result = subprocess.run(
["skill-seekers", "scrape", "--help"],
capture_output=True,
text=True
)
assert "--url URL" in result.stdout, "Help should show --url flag"
def test_github_all_flags_present(self):
"""Test that github command has all expected flags."""
result = subprocess.run(
["skill-seekers", "github", "--help"],
capture_output=True,
text=True
)
# Key github flags that should be present
expected_flags = [
"--repo",
"--output",
"--api-key",
"--profile",
"--non-interactive",
]
for flag in expected_flags:
assert flag in result.stdout, f"Help should show {flag} flag"
class TestPresetSystem:
"""E2E tests for preset system (Issue #268)."""
def test_analyze_preset_flag_exists(self):
"""Test that analyze command has --preset flag."""
result = subprocess.run(
["skill-seekers", "analyze", "--help"],
capture_output=True,
text=True
)
assert "--preset" in result.stdout, "Help should show --preset flag"
assert "quick" in result.stdout, "Help should mention 'quick' preset"
assert "standard" in result.stdout, "Help should mention 'standard' preset"
assert "comprehensive" in result.stdout, "Help should mention 'comprehensive' preset"
def test_analyze_preset_list_flag_exists(self):
"""Test that analyze command has --preset-list flag."""
result = subprocess.run(
["skill-seekers", "analyze", "--help"],
capture_output=True,
text=True
)
assert "--preset-list" in result.stdout, "Help should show --preset-list flag"
def test_preset_list_shows_presets(self):
"""Test that --preset-list shows all available presets."""
result = subprocess.run(
["skill-seekers", "analyze", "--preset-list"],
capture_output=True,
text=True
)
assert result.returncode == 0, "Command should execute successfully"
assert "Available presets" in result.stdout, "Should show preset list header"
assert "quick" in result.stdout, "Should show quick preset"
assert "standard" in result.stdout, "Should show standard preset"
assert "comprehensive" in result.stdout, "Should show comprehensive preset"
assert "1-2 minutes" in result.stdout, "Should show time estimates"
def test_deprecated_quick_flag_shows_warning(self):
"""Test that --quick flag shows deprecation warning."""
result = subprocess.run(
["skill-seekers", "analyze", "--directory", ".", "--quick", "--dry-run"],
capture_output=True,
text=True
)
# Note: Deprecation warnings go to stderr
output = result.stdout + result.stderr
assert "DEPRECATED" in output, "Should show deprecation warning"
assert "--preset quick" in output, "Should suggest alternative"
def test_deprecated_comprehensive_flag_shows_warning(self):
"""Test that --comprehensive flag shows deprecation warning."""
result = subprocess.run(
["skill-seekers", "analyze", "--directory", ".", "--comprehensive", "--dry-run"],
capture_output=True,
text=True
)
output = result.stdout + result.stderr
assert "DEPRECATED" in output, "Should show deprecation warning"
assert "--preset comprehensive" in output, "Should suggest alternative"
class TestBackwardCompatibility:
"""E2E tests for backward compatibility."""
def test_old_scrape_command_still_works(self):
"""Test that old scrape command invocations still work."""
result = subprocess.run(
["skill-seekers-scrape", "--help"],
capture_output=True,
text=True
)
assert result.returncode == 0, "Old command should still work"
assert "Scrape documentation" in result.stdout
def test_unified_cli_and_standalone_have_same_args(self):
"""Test that unified CLI and standalone have identical arguments."""
# Get help from unified CLI
unified_result = subprocess.run(
["skill-seekers", "scrape", "--help"],
capture_output=True,
text=True
)
# Get help from standalone
standalone_result = subprocess.run(
["skill-seekers-scrape", "--help"],
capture_output=True,
text=True
)
# Both should have the same key flags
key_flags = [
"--interactive",
"--url",
"--verbose",
"--chunk-for-rag",
"--config",
"--max-pages",
]
for flag in key_flags:
assert flag in unified_result.stdout, f"Unified should have {flag}"
assert flag in standalone_result.stdout, f"Standalone should have {flag}"
class TestProgrammaticAPI:
"""Test that the shared argument functions work programmatically."""
def test_import_shared_scrape_arguments(self):
"""Test that shared scrape arguments can be imported."""
from skill_seekers.cli.arguments.scrape import add_scrape_arguments
parser = argparse.ArgumentParser()
add_scrape_arguments(parser)
# Verify key arguments were added
args_dict = vars(parser.parse_args(["https://example.com"]))
assert "url" in args_dict
def test_import_shared_github_arguments(self):
"""Test that shared github arguments can be imported."""
from skill_seekers.cli.arguments.github import add_github_arguments
parser = argparse.ArgumentParser()
add_github_arguments(parser)
# Parse with --repo flag
args = parser.parse_args(["--repo", "owner/repo"])
assert args.repo == "owner/repo"
def test_import_analyze_presets(self):
"""Test that analyze presets can be imported."""
from skill_seekers.cli.presets.analyze_presets import ANALYZE_PRESETS, AnalysisPreset
assert "quick" in ANALYZE_PRESETS
assert "standard" in ANALYZE_PRESETS
assert "comprehensive" in ANALYZE_PRESETS
# Verify preset structure
quick = ANALYZE_PRESETS["quick"]
assert isinstance(quick, AnalysisPreset)
assert quick.name == "Quick"
assert quick.depth == "surface"
assert quick.enhance_level == 0
class TestIntegration:
"""Integration tests for the complete flow."""
def test_unified_cli_subcommands_registered(self):
"""Test that all subcommands are properly registered."""
result = subprocess.run(
["skill-seekers", "--help"],
capture_output=True,
text=True
)
# All major commands should be listed
expected_commands = [
"scrape",
"github",
"pdf",
"unified",
"analyze",
"enhance",
"package",
"upload",
]
for cmd in expected_commands:
assert cmd in result.stdout, f"Should list {cmd} command"
def test_scrape_help_detailed(self):
"""Test that scrape help shows all argument details."""
result = subprocess.run(
["skill-seekers", "scrape", "--help"],
capture_output=True,
text=True
)
# Check for argument categories
assert "url" in result.stdout.lower(), "Should show url argument"
assert "scraping options" in result.stdout.lower() or "options" in result.stdout.lower()
assert "enhancement" in result.stdout.lower(), "Should mention enhancement options"
def test_analyze_help_shows_presets(self):
"""Test that analyze help prominently shows preset information."""
result = subprocess.run(
["skill-seekers", "analyze", "--help"],
capture_output=True,
text=True
)
assert "--preset" in result.stdout, "Should show --preset flag"
assert "DEFAULT" in result.stdout or "default" in result.stdout, "Should indicate default preset"
class TestE2EWorkflow:
"""End-to-end workflow tests."""
@pytest.mark.slow
def test_dry_run_scrape_with_new_args(self, tmp_path):
"""Test scraping with previously missing arguments (dry run)."""
result = subprocess.run(
[
"skill-seekers", "scrape",
"--url", "https://example.com",
"--interactive", "false", # Would fail if arg didn't exist
"--verbose", # Would fail if arg didn't exist
"--dry-run",
"--output", str(tmp_path / "test_output")
],
capture_output=True,
text=True,
timeout=10
)
# Dry run should complete without errors
# (it may return non-zero if --interactive false isn't valid,
# but it shouldn't crash with "unrecognized arguments")
assert "unrecognized arguments" not in result.stderr.lower()
@pytest.mark.slow
def test_dry_run_analyze_with_preset(self, tmp_path):
"""Test analyze with preset (dry run)."""
# Create a dummy directory to analyze
test_dir = tmp_path / "test_code"
test_dir.mkdir()
(test_dir / "test.py").write_text("def hello(): pass")
result = subprocess.run(
[
"skill-seekers", "analyze",
"--directory", str(test_dir),
"--preset", "quick",
"--dry-run"
],
capture_output=True,
text=True,
timeout=30
)
# Should execute without errors
assert "unrecognized arguments" not in result.stderr.lower()
if __name__ == "__main__":
pytest.main([__file__, "-v", "-s"])