2cab53bc94
Docker Publish / Build and Push Docker Images (map[description:Skill Seekers CLI - Convert documentation to AI skills dockerfile:Dockerfile name:skill-seekers]) (push) Waiting to run
Docker Publish / Build and Push Docker Images (map[description:Skill Seekers MCP Server - 25 tools for AI assistants dockerfile:Dockerfile.mcp name:skill-seekers-mcp]) (push) Waiting to run
Docker Publish / Test Docker Images (push) Blocked by required conditions
Test Vector Database Adaptors / Test chroma Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test faiss Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test qdrant Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test weaviate Adaptor (push) Waiting to run
Test Vector Database Adaptors / Test MCP Vector DB Tools (push) Waiting to run
Tests / Code Quality (Ruff & Mypy) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (macos-latest, 3.11) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (macos-latest, 3.12) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.10) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.11) (push) Waiting to run
Tests / Fast Unit Tests (parallel) (ubuntu-latest, 3.12) (push) Waiting to run
Tests / Tests (push) Blocked by required conditions
Tests / Serial / Integration / E2E Tests (push) Blocked by required conditions
Tests / MCP Server Tests (push) Blocked by required conditions
151 lines
5.5 KiB
Python
151 lines
5.5 KiB
Python
"""
|
|
Tests for framework detection fix (Issue #239).
|
|
|
|
Verifies that framework detection works correctly by detecting imports
|
|
from Python files, even if those files have no classes or functions.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import shutil
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
|
|
class TestFrameworkDetection(unittest.TestCase):
|
|
"""Tests for Issue #239 - Framework detection with import-only files"""
|
|
|
|
def setUp(self):
|
|
"""Create temporary directory for testing."""
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.test_project = Path(self.temp_dir) / "test_project"
|
|
self.test_project.mkdir()
|
|
self.output_dir = Path(self.temp_dir) / "output"
|
|
|
|
def tearDown(self):
|
|
"""Clean up temporary directory."""
|
|
if os.path.exists(self.temp_dir):
|
|
shutil.rmtree(self.temp_dir)
|
|
|
|
def test_flask_framework_detection_from_imports(self):
|
|
"""Test that Flask is detected from import statements (Issue #239)."""
|
|
# Create simple Flask project with import-only __init__.py
|
|
app_dir = self.test_project / "app"
|
|
app_dir.mkdir()
|
|
|
|
# File with only imports (no classes/functions)
|
|
(app_dir / "__init__.py").write_text("from flask import Flask\napp = Flask(__name__)")
|
|
|
|
# File with Flask routes
|
|
(app_dir / "routes.py").write_text(
|
|
"from flask import render_template\n"
|
|
"from app import app\n\n"
|
|
"@app.route('/')\n"
|
|
"def index():\n"
|
|
" return render_template('index.html')\n"
|
|
)
|
|
|
|
# Run codebase analyzer directly
|
|
from skill_seekers.cli.codebase_scraper import analyze_codebase
|
|
|
|
analyze_codebase(
|
|
directory=self.test_project,
|
|
output_dir=self.output_dir,
|
|
depth="deep",
|
|
enhance_level=0,
|
|
detect_patterns=False,
|
|
extract_test_examples=False,
|
|
build_how_to_guides=False,
|
|
extract_config_patterns=False,
|
|
extract_docs=False,
|
|
)
|
|
|
|
# Verify Flask was detected
|
|
arch_file = self.output_dir / "references" / "architecture" / "architectural_patterns.json"
|
|
self.assertTrue(arch_file.exists(), "Architecture file should be created")
|
|
|
|
with open(arch_file) as f:
|
|
arch_data = json.load(f)
|
|
|
|
self.assertIn("frameworks_detected", arch_data)
|
|
self.assertIn(
|
|
"Flask", arch_data["frameworks_detected"], "Flask should be detected from imports"
|
|
)
|
|
|
|
def test_files_with_imports_are_included(self):
|
|
"""Test that files with only imports are included in analysis (Issue #239)."""
|
|
# Create file with only imports
|
|
(self.test_project / "imports_only.py").write_text(
|
|
"import django\nfrom flask import Flask\nimport requests"
|
|
)
|
|
|
|
# Run codebase analyzer directly
|
|
from skill_seekers.cli.codebase_scraper import analyze_codebase
|
|
|
|
analyze_codebase(
|
|
directory=self.test_project,
|
|
output_dir=self.output_dir,
|
|
depth="deep",
|
|
enhance_level=0,
|
|
)
|
|
|
|
# Verify file was analyzed
|
|
code_analysis = self.output_dir / "code_analysis.json"
|
|
self.assertTrue(code_analysis.exists(), "Code analysis file should exist")
|
|
|
|
with open(code_analysis) as f:
|
|
analysis_data = json.load(f)
|
|
|
|
# File should be included
|
|
self.assertGreater(len(analysis_data["files"]), 0, "Files with imports should be included")
|
|
|
|
# Find our import-only file
|
|
import_file = next(
|
|
(f for f in analysis_data["files"] if "imports_only.py" in f["file"]), None
|
|
)
|
|
self.assertIsNotNone(import_file, "Import-only file should be in analysis")
|
|
|
|
# Verify imports were extracted
|
|
self.assertIn("imports", import_file, "Imports should be extracted")
|
|
self.assertGreater(len(import_file["imports"]), 0, "Should have captured imports")
|
|
self.assertIn("django", import_file["imports"], "Django import should be captured")
|
|
self.assertIn("flask", import_file["imports"], "Flask import should be captured")
|
|
|
|
def test_no_false_positive_frameworks(self):
|
|
"""Test that framework detection doesn't produce false positives (Issue #239)."""
|
|
# Create project with "app" directory but no Flask
|
|
app_dir = self.test_project / "app"
|
|
app_dir.mkdir()
|
|
|
|
# File with no framework imports
|
|
(app_dir / "utils.py").write_text("def my_function():\n return 'hello'\n")
|
|
|
|
# Run codebase analyzer directly
|
|
from skill_seekers.cli.codebase_scraper import analyze_codebase
|
|
|
|
analyze_codebase(
|
|
directory=self.test_project,
|
|
output_dir=self.output_dir,
|
|
depth="deep",
|
|
enhance_level=0,
|
|
)
|
|
|
|
# Check frameworks detected
|
|
arch_file = self.output_dir / "references" / "architecture" / "architectural_patterns.json"
|
|
|
|
if arch_file.exists():
|
|
with open(arch_file) as f:
|
|
arch_data = json.load(f)
|
|
|
|
frameworks = arch_data.get("frameworks_detected", [])
|
|
# Should not detect Flask just from "app" directory name
|
|
self.assertNotIn("Flask", frameworks, "Should not detect Flask without imports")
|
|
# Should not detect other frameworks with "app" in markers
|
|
for fw in ["ASP.NET", "Rails", "Laravel"]:
|
|
self.assertNotIn(fw, frameworks, f"Should not detect {fw} without real evidence")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|