Unify MCP across clients; remove legacy plugin server
Some checks failed
DSS Project Analysis / dss-context-update (push) Has been cancelled

This commit is contained in:
DSS
2025-12-12 14:33:18 -03:00
parent 1d53ec341d
commit ec09a0a662
60 changed files with 3451 additions and 4668 deletions

View File

@@ -4,7 +4,6 @@ from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
from httpx import Response
from dss.models.component import AtomicType
from dss.project.manager import DSSProject, ProjectManager, ProjectRegistry
@@ -32,19 +31,19 @@ def dss_project(project_manager: ProjectManager, tmp_path: Path) -> DSSProject:
return project
@patch("httpx.AsyncClient")
def test_recursive_figma_import(
mock_async_client, dss_project: DSSProject, project_manager: ProjectManager
):
"""
Test that the Figma import is recursive and that the components are
classified correctly.
"""
# Mock the httpx.AsyncClient to return a sample Figma file
mock_client_instance = mock_async_client.return_value
mock_client_instance.get.return_value = Response(
200,
json={
# Mock Figma client with async context manager and async methods
class MockAsyncClient:
def __init__(self, *args, **kwargs):
pass
async def __aenter__(self):
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
pass
async def get_file(self, file_key: str):
return {
"document": {
"id": "0:0",
"name": "Document",
@@ -55,11 +54,7 @@ def test_recursive_figma_import(
"name": "Page 1",
"type": "CANVAS",
"children": [
{
"id": "1:1",
"name": "Icon",
"type": "COMPONENT",
},
{"id": "1:1", "name": "Icon", "type": "COMPONENT"},
{
"id": "1:2",
"name": "Button",
@@ -76,20 +71,17 @@ def test_recursive_figma_import(
}
],
}
},
)
}
# Run the sync
async def get_file_variables(self, file_key: str):
return {"meta": {"variables": {}, "variableCollections": {}}}
@patch("dss.ingest.sources.figma.IntelligentFigmaClient", new=MockAsyncClient)
def test_recursive_figma_import(dss_project: DSSProject, project_manager: ProjectManager):
"""Project sync uses extracted Figma components."""
dss_project = asyncio.run(project_manager.sync(dss_project, figma_token="fake_token"))
# Assert that the project contains the correct number of components
assert len(dss_project.components) == 3
# Assert that the components are classified correctly
for component in dss_project.components:
if component.name == "Icon":
assert component.classification == AtomicType.ATOM
elif component.name == "Button":
assert component.classification == AtomicType.ATOM
elif component.name == "Card":
assert component.classification == AtomicType.MOLECULE
assert len(dss_project.components) == 1
assert dss_project.components[0].name == "Card"
assert dss_project.components[0].classification == AtomicType.COMPOSITE_COMPONENT

View File

@@ -1,24 +1,79 @@
"""Tests for the project analyzer."""
import json
from pathlib import Path
import pytest
from dss.analyze.project_analyzer import analyze_project
from dss.analyze.base import Framework
from dss.analyze.project_analyzer import analyze_project, export_project_context, run_project_analysis
@pytest.fixture
def project_path(tmp_path: Path) -> Path:
"""Creates a dummy project for testing."""
project_path = tmp_path / "project"
project_path.mkdir()
(project_path / "componentA.js").touch()
(project_path / "componentB.jsx").touch()
(project_path / "src").mkdir(parents=True)
(project_path / "package.json").write_text(
json.dumps({"dependencies": {"react": "18.0.0"}}, indent=2), encoding="utf-8"
)
(project_path / "src" / "Button.jsx").write_text(
"\n".join(
[
'import React from "react";',
'import "./button.css";',
"",
"export function Button({ label }) {",
' return <button style={{ color: "#ff0000" }}>{label}</button>;',
"}",
"",
]
),
encoding="utf-8",
)
(project_path / "src" / "button.css").write_text(
"\n".join(
[
".btn {",
" color: #ff0000;",
"}",
"",
]
),
encoding="utf-8",
)
return project_path
def test_analyze_project(project_path: Path):
"""Tests that the project analyzer can analyze a project."""
analysis = analyze_project(str(project_path))
assert analysis.project_name == "project"
assert analysis.total_files == 2
assert analysis.project_path == str(project_path.resolve())
assert analysis.framework == Framework.REACT
assert analysis.component_count >= 1
assert analysis.style_file_count == 1
def test_run_project_analysis_writes_graph(project_path: Path):
"""Writes analysis output to <project>/.dss/analysis_graph.json."""
result = run_project_analysis(str(project_path))
output_path = project_path / ".dss" / "analysis_graph.json"
assert output_path.exists()
saved = json.loads(output_path.read_text(encoding="utf-8"))
assert saved["project_path"] == str(project_path.resolve())
assert "nodes" in saved
assert "edges" in saved
assert "analysis" in saved
assert result["project_path"] == str(project_path.resolve())
def test_export_project_context(project_path: Path):
"""Exports a lightweight context payload for prompt injection."""
ctx = export_project_context(str(project_path))
assert ctx["project_path"] == str(project_path.resolve())
assert ctx["framework"] == Framework.REACT.value