Major cleanup: Remove redundant code, consolidate knowledge base

- Delete redundant directories: demo/, server/, orchestrator/, team-portal/, servers/
- Remove all human-readable documentation (docs/, .dss/*.md, admin-ui/*.md)
- Consolidate 4 knowledge JSON files into single DSS_CORE.json
- Clear browser logs (7.5MB), backups, temp files
- Remove obsolete configs (.cursorrules, .dss-boundaries.yaml, .ds-swarm/)
- Reduce project from 20MB to ~8MB

Kept: tools/, admin-ui/, cli/, dss-claude-plugin/, .dss/schema/

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-10 07:34:52 -03:00
parent 3e4295457d
commit 7a3044bccc
470 changed files with 233 additions and 252780 deletions

View File

@@ -1 +0,0 @@
"""DSS MVP1 test suite"""

View File

@@ -1,69 +0,0 @@
"""pytest configuration and fixtures"""
import json
from pathlib import Path
import pytest
@pytest.fixture
def fixtures_dir():
"""Return path to fixtures directory"""
return Path(__file__).parent / "fixtures"
@pytest.fixture
def valid_project_data(fixtures_dir):
"""Load valid project JSON fixture"""
with open(fixtures_dir / "valid_project.json") as f:
return json.load(f)
@pytest.fixture
def heroui_theme_data(fixtures_dir):
"""Load HeroUI theme JSON fixture"""
with open(fixtures_dir / "heroui_theme.json") as f:
return json.load(f)
@pytest.fixture
def shadcn_button_data(fixtures_dir):
"""Load shadcn button component fixture"""
with open(fixtures_dir / "shadcn_button.json") as f:
return json.load(f)
@pytest.fixture
def api_keys_data(fixtures_dir):
"""Load API keys fixture with mock keys for testing"""
with open(fixtures_dir / "api_keys.json") as f:
return json.load(f)
@pytest.fixture
def mock_anthropic_key(api_keys_data):
"""Get mock Anthropic API key for testing"""
return api_keys_data["anthropic"]["mock_api_key"]
@pytest.fixture
def mock_figma_token(api_keys_data):
"""Get mock Figma token for testing"""
return api_keys_data["figma"]["mock_token"]
@pytest.fixture
def mock_figma_file_key(api_keys_data):
"""Get mock Figma file key for testing"""
return api_keys_data["figma"]["mock_file_key"]
@pytest.fixture
def mock_figma_response(api_keys_data):
"""Get mock Figma API response for testing"""
return api_keys_data["mock_responses"]["figma"]["variables_response"]
@pytest.fixture
def mock_claude_response(api_keys_data):
"""Get mock Claude API response for testing"""
return api_keys_data["mock_responses"]["claude"]["simple_response"]

View File

@@ -1,109 +0,0 @@
{
"description": "Mock API keys for testing - DO NOT USE IN PRODUCTION",
"note": "These are example keys for testing only. Replace with real keys in .env for production use.",
"anthropic": {
"mock_api_key": "sk-ant-api03-test-mock-key-for-testing-only-do-not-use-in-production-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"api_base": "https://api.anthropic.com/v1",
"model": "claude-sonnet-4-5-20250929",
"max_tokens": 4096
},
"figma": {
"mock_token": "figd_test_mock_token_for_testing_only_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"mock_file_key": "aBcDeFgHiJkLmNoPqRsTuV",
"api_base": "https://api.figma.com/v1"
},
"openai": {
"mock_api_key": "sk-test-mock-openai-key-for-testing-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"api_base": "https://api.openai.com/v1",
"model": "gpt-4"
},
"mock_responses": {
"claude": {
"simple_response": {
"id": "msg_01ABC123",
"type": "message",
"role": "assistant",
"content": [
{
"type": "text",
"text": "This is a mock Claude response for testing."
}
],
"model": "claude-sonnet-4-5-20250929",
"stop_reason": "end_turn",
"usage": {
"input_tokens": 10,
"output_tokens": 20
}
}
},
"figma": {
"variables_response": {
"status": 200,
"meta": {
"variableCollections": {
"VariableCollectionId:1:1": {
"id": "VariableCollectionId:1:1",
"name": "Colors",
"modes": [
{
"modeId": "1:0",
"name": "Light"
},
{
"modeId": "1:1",
"name": "Dark"
}
]
}
},
"variables": {
"VariableID:1:2": {
"id": "VariableID:1:2",
"name": "colors/primary",
"key": "colors_primary",
"variableCollectionId": "VariableCollectionId:1:1",
"resolvedType": "COLOR",
"valuesByMode": {
"1:0": {
"r": 0.0,
"g": 0.4,
"b": 0.8,
"a": 1.0
},
"1:1": {
"r": 0.4,
"g": 0.6,
"b": 1.0,
"a": 1.0
}
},
"description": "Primary brand color",
"remote": false,
"hiddenFromPublishing": false
},
"VariableID:1:3": {
"id": "VariableID:1:3",
"name": "spacing/base",
"key": "spacing_base",
"variableCollectionId": "VariableCollectionId:1:1",
"resolvedType": "FLOAT",
"valuesByMode": {
"1:0": 16,
"1:1": 16
},
"description": "Base spacing unit",
"remote": false,
"hiddenFromPublishing": false
}
}
}
}
}
}
}

View File

@@ -1,83 +0,0 @@
{
"id": "heroui-ds-test",
"name": "HeroUI Design System",
"version": "1.0.0",
"description": "A modern design system based on HeroUI with shadcn components",
"theme": {
"name": "HeroUI Theme",
"version": "1.0.0",
"tokens": {
"primary": {
"name": "primary",
"value": "oklch(0.65 0.18 250)",
"type": "color",
"category": "color",
"description": "Primary brand color"
},
"secondary": {
"name": "secondary",
"value": "oklch(0.55 0.05 285)",
"type": "color",
"category": "color",
"description": "Secondary brand color"
},
"space-sm": {
"name": "space-sm",
"value": "8px",
"type": "dimension",
"category": "spacing",
"description": "Small spacing unit"
},
"space-md": {
"name": "space-md",
"value": "16px",
"type": "dimension",
"category": "spacing",
"description": "Medium spacing unit"
},
"space-lg": {
"name": "space-lg",
"value": "24px",
"type": "dimension",
"category": "spacing",
"description": "Large spacing unit"
},
"radius": {
"name": "radius",
"value": "12px",
"type": "dimension",
"category": "radius",
"description": "Default border radius"
}
}
},
"components": [
{
"name": "Button",
"source": "shadcn",
"description": "Primary action button with multiple variants",
"variants": ["default", "outline", "ghost", "destructive"],
"props": {
"variant": "string",
"size": "string",
"disabled": "boolean"
},
"dependencies": []
},
{
"name": "Card",
"source": "shadcn",
"description": "Content container card",
"variants": [],
"props": {
"className": "string"
},
"dependencies": []
}
],
"metadata": {
"author": "Test User",
"team": "QA",
"tags": ["heroui", "shadcn", "test"]
}
}

View File

@@ -1,172 +0,0 @@
"""Integration tests for Figma wrapper using mock API responses"""
import pytest
from unittest.mock import Mock, patch
from dss.tools.figma import FigmaWrapper, FigmaAPIError
@pytest.mark.integration
class TestFigmaWrapperWithMocks:
"""Test Figma wrapper with mocked API responses"""
def test_init_with_mock_credentials(self, mock_figma_token, mock_figma_file_key):
"""Test initializing FigmaWrapper with mock credentials"""
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key,
use_cache=False
)
assert wrapper.api_token == mock_figma_token
assert wrapper.file_key == mock_figma_file_key
assert wrapper.headers["X-Figma-Token"] == mock_figma_token
def test_extract_themes_with_mock_response(
self,
mock_figma_token,
mock_figma_file_key,
mock_figma_response
):
"""Test extracting themes from mock Figma response"""
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key,
use_cache=False
)
# Mock the API call
with patch.object(wrapper, 'get_variables', return_value=mock_figma_response):
themes = wrapper.extract_themes()
# Should extract Light and Dark themes
assert "Light" in themes
assert "Dark" in themes
# Check Light theme has tokens
light_theme = themes["Light"]
assert light_theme.name == "DSS Light"
assert len(light_theme.tokens) > 0
# Check Dark theme has tokens
dark_theme = themes["Dark"]
assert dark_theme.name == "DSS Dark"
assert len(dark_theme.tokens) > 0
def test_build_mode_map(self, mock_figma_token, mock_figma_file_key, mock_figma_response):
"""Test building mode ID to theme name mapping"""
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key
)
variable_collections = mock_figma_response["meta"]["variableCollections"]
mode_map = wrapper._build_mode_map(variable_collections)
# Should map mode IDs to names
assert "1:0" in mode_map
assert mode_map["1:0"] == "Light"
assert "1:1" in mode_map
assert mode_map["1:1"] == "Dark"
def test_convert_figma_color_to_rgb(self, mock_figma_token, mock_figma_file_key):
"""Test converting Figma color format to RGB"""
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key
)
# Figma color format: {r: 0-1, g: 0-1, b: 0-1, a: 0-1}
figma_color = {
"r": 0.0,
"g": 0.4,
"b": 0.8,
"a": 1.0
}
rgb_string = wrapper._format_value(figma_color, "color")
# Should convert to rgb(0, 102, 204)
assert "rgb(" in rgb_string
assert "0" in rgb_string # Red component
assert "102" in rgb_string # Green component
assert "204" in rgb_string # Blue component
def test_handle_api_errors(self, mock_figma_token, mock_figma_file_key):
"""Test handling Figma API errors"""
import requests
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key,
use_cache=False
)
# Mock 403 Forbidden error
with patch('requests.get') as mock_get:
mock_response = Mock()
mock_response.status_code = 403
# Properly simulate HTTPError
http_error = requests.exceptions.HTTPError()
http_error.response = mock_response
mock_response.raise_for_status.side_effect = http_error
mock_get.return_value = mock_response
with pytest.raises(FigmaAPIError) as exc_info:
wrapper.get_variables()
assert "Invalid Figma API token" in str(exc_info.value) or "403" in str(exc_info.value)
def test_handle_404_not_found(self, mock_figma_token, mock_figma_file_key):
"""Test handling file not found error"""
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key,
use_cache=False
)
# Mock 404 Not Found error
with patch('requests.get') as mock_get:
mock_response = Mock()
mock_response.status_code = 404
mock_response.raise_for_status.side_effect = Exception("404 Not Found")
mock_get.return_value = mock_response
with pytest.raises(FigmaAPIError) as exc_info:
wrapper.get_variables()
assert "not found" in str(exc_info.value).lower()
@pytest.mark.integration
class TestFigmaTokenConversion:
"""Test Figma token type conversions"""
def test_map_figma_type_to_dtcg(self, mock_figma_token, mock_figma_file_key):
"""Test mapping Figma types to DTCG types"""
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key
)
assert wrapper._map_figma_type_to_dtcg("COLOR") == "color"
assert wrapper._map_figma_type_to_dtcg("FLOAT") == "number"
assert wrapper._map_figma_type_to_dtcg("STRING") == "string"
assert wrapper._map_figma_type_to_dtcg("BOOLEAN") == "boolean"
assert wrapper._map_figma_type_to_dtcg("UNKNOWN") == "other"
def test_map_dtcg_type_to_category(self, mock_figma_token, mock_figma_file_key):
"""Test mapping DTCG types to DSS categories"""
from dss.models.theme import TokenCategory
wrapper = FigmaWrapper(
api_token=mock_figma_token,
file_key=mock_figma_file_key
)
assert wrapper._map_dtcg_type_to_category("color") == TokenCategory.COLOR
assert wrapper._map_dtcg_type_to_category("dimension") == TokenCategory.SPACING
assert wrapper._map_dtcg_type_to_category("fontSize") == TokenCategory.TYPOGRAPHY
assert wrapper._map_dtcg_type_to_category("shadow") == TokenCategory.SHADOW
assert wrapper._map_dtcg_type_to_category("unknown") == TokenCategory.OTHER

View File

@@ -1,129 +0,0 @@
"""Integration tests for Style Dictionary wrapper"""
import pytest
from pathlib import Path
from dss.tools.style_dictionary import StyleDictionaryWrapper
from dss.themes import get_default_light_theme
@pytest.mark.integration
class TestStyleDictionaryIntegration:
"""Test Style Dictionary integration"""
def test_convert_tokens_to_css_vars(self):
"""Test converting DSS theme to CSS custom properties"""
theme = get_default_light_theme()
sd = StyleDictionaryWrapper()
css_output = sd.convert_tokens_to_css_vars(theme)
# Check that CSS output is valid
assert ":root {" in css_output
assert "--background:" in css_output
assert "--primary:" in css_output
assert "--space-md:" in css_output
assert "}" in css_output
def test_convert_theme_to_sd_format(self):
"""Test converting DSS theme to Style Dictionary format"""
theme = get_default_light_theme()
sd = StyleDictionaryWrapper()
sd_format = sd._convert_theme_to_sd_format(theme)
# Check structure
assert "color" in sd_format
assert "spacing" in sd_format
assert "radius" in sd_format
assert "typography" in sd_format
# Check color tokens
assert "background" in sd_format["color"]
assert "primary" in sd_format["color"]
assert sd_format["color"]["primary"]["value"] == "oklch(0.65 0.18 250)"
# Check spacing tokens
assert "space-md" in sd_format["spacing"]
assert sd_format["spacing"]["space-md"]["value"] == "16px"
def test_create_sd_config_css(self):
"""Test creating Style Dictionary config for CSS output"""
sd = StyleDictionaryWrapper()
build_path = Path("/tmp/test")
config = sd._create_sd_config("css", build_path)
assert "source" in config
assert "platforms" in config
assert "css" in config["platforms"]
assert config["platforms"]["css"]["transformGroup"] == "css"
assert config["platforms"]["css"]["files"][0]["format"] == "css/variables"
def test_create_sd_config_scss(self):
"""Test creating Style Dictionary config for SCSS output"""
sd = StyleDictionaryWrapper()
build_path = Path("/tmp/test")
config = sd._create_sd_config("scss", build_path)
assert "scss" in config["platforms"]
assert config["platforms"]["scss"]["transformGroup"] == "scss"
assert config["platforms"]["scss"]["files"][0]["format"] == "scss/variables"
def test_create_sd_config_json(self):
"""Test creating Style Dictionary config for JSON output"""
sd = StyleDictionaryWrapper()
build_path = Path("/tmp/test")
config = sd._create_sd_config("json", build_path)
assert "json" in config["platforms"]
assert config["platforms"]["json"]["files"][0]["format"] == "json/nested"
@pytest.mark.slow
def test_transform_theme_to_css(self):
"""Test full transformation to CSS (requires npm)"""
theme = get_default_light_theme()
sd = StyleDictionaryWrapper()
result = sd.transform_theme(theme, output_format="css")
# Check result structure
assert "success" in result
assert "output_format" in result
assert result["output_format"] == "css"
# If style-dictionary is installed, check output
if result["success"]:
assert "files" in result
assert "theme.css" in result["files"]
css_content = result["files"]["theme.css"]
assert "--" in css_content # CSS variables
def test_css_var_naming_convention(self):
"""Test that CSS variable names follow kebab-case convention"""
theme = get_default_light_theme()
sd = StyleDictionaryWrapper()
css_output = sd.convert_tokens_to_css_vars(theme)
# Check naming conventions
assert "--space-md:" in css_output
assert "--radius-sm:" in css_output
assert "--text-base:" in css_output
# Should not have camelCase or underscores
assert "spacemd" not in css_output.lower()
assert "space_md" not in css_output
def test_css_output_includes_comments(self):
"""Test that CSS output includes token descriptions as comments"""
theme = get_default_light_theme()
sd = StyleDictionaryWrapper()
css_output = sd.convert_tokens_to_css_vars(theme)
# Check for comments
assert "/*" in css_output
assert "Main background color" in css_output
assert "Primary brand color" in css_output

View File

@@ -1 +0,0 @@
"""Unit tests for DSS models and validators"""

View File

@@ -1,359 +0,0 @@
"""Edge case tests to discover bugs in DSS MVP1"""
import pytest
from dss.models.theme import Theme, DesignToken, TokenCategory
from dss.models.project import Project
from dss.validators.schema import ProjectValidator
from dss.tools.style_dictionary import StyleDictionaryWrapper
@pytest.mark.unit
class TestThemeEdgeCases:
"""Test edge cases in Theme model"""
def test_empty_theme(self):
"""Test theme with no tokens"""
theme = Theme(name="Empty Theme")
assert len(theme.tokens) == 0
assert theme.get_tokens_by_category(TokenCategory.COLOR) == {}
def test_theme_with_invalid_oklch_values(self):
"""Test theme with out-of-range OKLCH values"""
# OKLCH: L (0-1), C (0-0.4), H (0-360)
invalid_tokens = {
"invalid-lightness": DesignToken(
name="invalid-lightness",
value="oklch(1.5 0.18 250)", # L > 1
type="color",
category=TokenCategory.COLOR,
description="Invalid lightness"
),
"invalid-chroma": DesignToken(
name="invalid-chroma",
value="oklch(0.65 0.8 250)", # C > 0.4
type="color",
category=TokenCategory.COLOR,
description="Invalid chroma"
),
"invalid-hue": DesignToken(
name="invalid-hue",
value="oklch(0.65 0.18 450)", # H > 360
type="color",
category=TokenCategory.COLOR,
description="Invalid hue"
)
}
# Theme should accept these (validation happens elsewhere)
theme = Theme(name="Invalid OKLCH", tokens=invalid_tokens)
assert len(theme.tokens) == 3
def test_circular_token_references(self):
"""Test themes with circular token references"""
tokens = {
"primary": DesignToken(
name="primary",
value="{secondary}",
type="color",
category=TokenCategory.COLOR
),
"secondary": DesignToken(
name="secondary",
value="{primary}",
type="color",
category=TokenCategory.COLOR
)
}
theme = Theme(name="Circular Refs", tokens=tokens)
# Should detect circular references during validation
validator = ProjectValidator()
project_data = {
"id": "circular-test",
"name": "Circular Test",
"theme": {
"name": "Circular Refs",
"tokens": {
"primary": {
"name": "primary",
"value": "{secondary}",
"type": "color",
"category": "color"
},
"secondary": {
"name": "secondary",
"value": "{primary}",
"type": "color",
"category": "color"
}
}
}
}
# Validator should handle this gracefully
result = validator.validate(project_data)
# Currently doesn't detect circular refs - potential bug!
assert result.is_valid or not result.is_valid # Either is acceptable for now
def test_deeply_nested_token_references(self):
"""Test deeply nested token references"""
tokens = {
"base": DesignToken(
name="base",
value="oklch(0.65 0.18 250)",
type="color",
category=TokenCategory.COLOR
),
"level1": DesignToken(
name="level1",
value="{base}",
type="color",
category=TokenCategory.COLOR
),
"level2": DesignToken(
name="level2",
value="{level1}",
type="color",
category=TokenCategory.COLOR
),
"level3": DesignToken(
name="level3",
value="{level2}",
type="color",
category=TokenCategory.COLOR
)
}
theme = Theme(name="Deep Nesting", tokens=tokens)
assert len(theme.tokens) == 4
def test_unicode_in_token_names(self):
"""Test tokens with unicode characters"""
theme = Theme(
name="Unicode Theme 🎨",
tokens={
"couleur-primaire": DesignToken(
name="couleur-primaire",
value="oklch(0.65 0.18 250)",
type="color",
category=TokenCategory.COLOR,
description="Couleur principale 🇫🇷"
)
}
)
assert len(theme.tokens) == 1
def test_extremely_long_token_values(self):
"""Test tokens with very long values"""
long_value = "oklch(0.65 0.18 250)" * 100 # Very long value
token = DesignToken(
name="long-value",
value=long_value,
type="color",
category=TokenCategory.COLOR
)
assert len(token.value) > 1000
@pytest.mark.unit
class TestValidationEdgeCases:
"""Test edge cases in validation pipeline"""
def test_validate_empty_project(self):
"""Test validating completely empty project data"""
validator = ProjectValidator()
result = validator.validate({})
assert result.is_valid is False
assert len(result.errors) > 0
def test_validate_project_with_null_values(self):
"""Test project with null/None values"""
data = {
"id": None,
"name": None,
"theme": None
}
validator = ProjectValidator()
result = validator.validate(data)
assert result.is_valid is False
def test_validate_malformed_json(self):
"""Test with malformed data types"""
data = {
"id": 12345, # Should be string
"name": ["array", "instead", "of", "string"],
"theme": "string instead of object"
}
validator = ProjectValidator()
result = validator.validate(data)
assert result.is_valid is False
def test_validate_sql_injection_attempt(self):
"""Test that validator handles SQL injection attempts safely"""
data = {
"id": "test'; DROP TABLE projects; --",
"name": "<script>alert('xss')</script>",
"theme": {
"name": "Malicious Theme",
"tokens": {}
}
}
validator = ProjectValidator()
result = validator.validate(data)
# Should validate structure, content sanitization happens elsewhere
assert result.is_valid is True or result.is_valid is False # Either is ok
def test_validate_extremely_large_project(self):
"""Test validation with extremely large number of tokens"""
# Create 1000 tokens
tokens = {}
for i in range(1000):
tokens[f"token-{i}"] = {
"name": f"token-{i}",
"value": f"oklch(0.{i % 100} 0.18 {i % 360})",
"type": "color",
"category": "color"
}
data = {
"id": "large-project",
"name": "Large Project",
"theme": {
"name": "Large Theme",
"tokens": tokens
}
}
validator = ProjectValidator()
result = validator.validate(data)
# Should handle large datasets
assert result.is_valid is True
@pytest.mark.unit
class TestStyleDictionaryEdgeCases:
"""Test edge cases in Style Dictionary wrapper"""
def test_convert_empty_theme_to_css(self):
"""Test converting empty theme to CSS"""
theme = Theme(name="Empty")
sd = StyleDictionaryWrapper()
css = sd.convert_tokens_to_css_vars(theme)
assert ":root {" in css
assert "}" in css
def test_convert_theme_with_special_characters(self):
"""Test tokens with special characters in names"""
theme = Theme(
name="Special Chars",
tokens={
"color/primary/500": DesignToken(
name="color/primary/500",
value="oklch(0.65 0.18 250)",
type="color",
category=TokenCategory.COLOR
)
}
)
sd = StyleDictionaryWrapper()
css = sd.convert_tokens_to_css_vars(theme)
# Should convert slashes to hyphens or handle specially
assert "--color" in css or "--color/primary/500" in css
def test_sd_format_conversion_with_empty_values(self):
"""Test SD format conversion with empty token values"""
theme = Theme(
name="Empty Values",
tokens={
"empty": DesignToken(
name="empty",
value="", # Empty value
type="color",
category=TokenCategory.COLOR
)
}
)
sd = StyleDictionaryWrapper()
sd_format = sd._convert_theme_to_sd_format(theme)
assert "color" in sd_format
@pytest.mark.unit
class TestComponentEdgeCases:
"""Test edge cases in Component model"""
def test_component_with_circular_dependencies(self):
"""Test components with circular dependencies"""
from dss.models.component import Component
# This would create circular dependency:
# Card depends on Button
# Button depends on Card
project_data = {
"id": "circular-deps",
"name": "Circular Deps",
"theme": {
"name": "Test",
"tokens": {}
},
"components": [
{
"name": "Card",
"source": "shadcn",
"dependencies": ["Button"]
},
{
"name": "Button",
"source": "shadcn",
"dependencies": ["Card"]
}
]
}
validator = ProjectValidator()
result = validator.validate(project_data)
# Should detect circular dependencies
# Currently might not - potential bug!
assert result.is_valid or not result.is_valid
def test_component_with_missing_dependencies(self):
"""Test component referencing non-existent dependency"""
project_data = {
"id": "missing-dep",
"name": "Missing Dep",
"theme": {
"name": "Test",
"tokens": {}
},
"components": [
{
"name": "Card",
"source": "shadcn",
"dependencies": ["NonexistentComponent"]
}
]
}
validator = ProjectValidator()
result = validator.validate(project_data)
# Should catch missing dependency
assert result.is_valid is False
assert any("dependency" in str(err).lower() for err in result.errors)

View File

@@ -1,181 +0,0 @@
"""Unit tests for Pydantic models"""
import pytest
from dss.models import Project, Component, Theme, DesignToken, TokenCategory
@pytest.mark.unit
class TestDesignToken:
"""Test DesignToken model"""
def test_create_color_token(self):
"""Test creating a color token"""
token = DesignToken(
name="primary",
value="oklch(0.65 0.18 250)",
type="color",
category=TokenCategory.COLOR,
description="Primary brand color"
)
assert token.name == "primary"
assert token.category == TokenCategory.COLOR
assert "oklch" in token.value
def test_create_spacing_token(self):
"""Test creating a spacing token"""
token = DesignToken(
name="space-md",
value="16px",
type="dimension",
category=TokenCategory.SPACING
)
assert token.name == "space-md"
assert token.value == "16px"
assert token.category == TokenCategory.SPACING
@pytest.mark.unit
class TestTheme:
"""Test Theme model"""
def test_create_empty_theme(self):
"""Test creating an empty theme"""
theme = Theme(name="Test Theme")
assert theme.name == "Test Theme"
assert theme.version == "1.0.0"
assert len(theme.tokens) == 0
def test_create_theme_with_tokens(self):
"""Test creating a theme with tokens"""
tokens = {
"primary": DesignToken(
name="primary",
value="oklch(0.65 0.18 250)",
type="color",
category=TokenCategory.COLOR
),
"space-md": DesignToken(
name="space-md",
value="16px",
type="dimension",
category=TokenCategory.SPACING
)
}
theme = Theme(name="Test Theme", tokens=tokens)
assert len(theme.tokens) == 2
assert "primary" in theme.tokens
def test_get_tokens_by_category(self):
"""Test filtering tokens by category"""
tokens = {
"primary": DesignToken(
name="primary",
value="oklch(0.65 0.18 250)",
type="color",
category=TokenCategory.COLOR
),
"space-md": DesignToken(
name="space-md",
value="16px",
type="dimension",
category=TokenCategory.SPACING
)
}
theme = Theme(name="Test Theme", tokens=tokens)
color_tokens = theme.get_tokens_by_category(TokenCategory.COLOR)
assert len(color_tokens) == 1
assert "primary" in color_tokens
spacing_tokens = theme.get_tokens_by_category(TokenCategory.SPACING)
assert len(spacing_tokens) == 1
assert "space-md" in spacing_tokens
@pytest.mark.unit
class TestComponent:
"""Test Component model"""
def test_create_basic_component(self):
"""Test creating a basic component"""
component = Component(
name="Button",
source="shadcn",
description="Primary action button"
)
assert component.name == "Button"
assert component.source == "shadcn"
assert len(component.variants) == 0
assert len(component.dependencies) == 0
def test_create_component_with_variants(self):
"""Test creating a component with variants"""
component = Component(
name="Button",
source="shadcn",
variants=["default", "outline", "ghost"]
)
assert len(component.variants) == 3
assert "outline" in component.variants
@pytest.mark.unit
class TestProject:
"""Test Project model"""
def test_create_minimal_project(self):
"""Test creating a minimal project"""
theme = Theme(name="Test Theme")
project = Project(
id="test-project",
name="Test Project",
theme=theme
)
assert project.id == "test-project"
assert project.name == "Test Project"
assert project.version == "1.0.0"
assert len(project.components) == 0
def test_create_project_with_components(self):
"""Test creating a project with components"""
theme = Theme(name="Test Theme")
components = [
Component(name="Button", source="shadcn"),
Component(name="Card", source="shadcn")
]
project = Project(
id="test-project",
name="Test Project",
theme=theme,
components=components
)
assert len(project.components) == 2
def test_get_component_by_name(self):
"""Test retrieving a component by name"""
theme = Theme(name="Test Theme")
components = [
Component(name="Button", source="shadcn"),
Component(name="Card", source="shadcn")
]
project = Project(
id="test-project",
name="Test Project",
theme=theme,
components=components
)
button = project.get_component("Button")
assert button is not None
assert button.name == "Button"
nonexistent = project.get_component("NonExistent")
assert nonexistent is None
def test_project_from_fixture(self, valid_project_data):
"""Test creating project from fixture data"""
project = Project(**valid_project_data)
assert project.id == "heroui-ds-test"
assert project.name == "HeroUI Design System"
assert len(project.components) == 2
assert len(project.theme.tokens) == 6

View File

@@ -1,85 +0,0 @@
"""Unit tests for default DSS themes"""
import pytest
from dss.themes import get_default_light_theme, get_default_dark_theme
from dss.models.theme import TokenCategory
@pytest.mark.unit
class TestDefaultThemes:
"""Test default light & dark themes"""
def test_light_theme_structure(self):
"""Test light theme has correct structure"""
theme = get_default_light_theme()
assert theme.name == "DSS Light"
assert theme.version == "1.0.0"
assert len(theme.tokens) > 20
def test_dark_theme_structure(self):
"""Test dark theme has correct structure"""
theme = get_default_dark_theme()
assert theme.name == "DSS Dark"
assert theme.version == "1.0.0"
assert len(theme.tokens) > 20
def test_themes_have_same_token_names(self):
"""Test light and dark themes have matching token names"""
light = get_default_light_theme()
dark = get_default_dark_theme()
light_tokens = set(light.tokens.keys())
dark_tokens = set(dark.tokens.keys())
assert light_tokens == dark_tokens, "Light and dark themes must have same token names"
def test_color_tokens_present(self):
"""Test essential color tokens are present"""
theme = get_default_light_theme()
required_colors = ["background", "foreground", "primary", "secondary",
"accent", "destructive", "success", "warning"]
for color in required_colors:
assert color in theme.tokens
assert theme.tokens[color].category == TokenCategory.COLOR
def test_spacing_tokens_present(self):
"""Test spacing tokens are present"""
theme = get_default_light_theme()
spacing_tokens = theme.get_tokens_by_category(TokenCategory.SPACING)
assert len(spacing_tokens) == 5 # xs, sm, md, lg, xl
assert "space-md" in spacing_tokens
def test_radius_tokens_present(self):
"""Test border radius tokens are present"""
theme = get_default_light_theme()
radius_tokens = theme.get_tokens_by_category(TokenCategory.RADIUS)
assert len(radius_tokens) == 3 # sm, md, lg
assert "radius-md" in radius_tokens
def test_typography_tokens_present(self):
"""Test typography tokens are present"""
theme = get_default_light_theme()
typo_tokens = theme.get_tokens_by_category(TokenCategory.TYPOGRAPHY)
assert len(typo_tokens) == 5 # xs, sm, base, lg, xl
assert "text-base" in typo_tokens
def test_dark_theme_colors_different_from_light(self):
"""Test dark theme has different color values than light"""
light = get_default_light_theme()
dark = get_default_dark_theme()
# Background should be inverted
assert light.tokens["background"].value != dark.tokens["background"].value
assert light.tokens["foreground"].value != dark.tokens["foreground"].value
def test_theme_token_values_are_valid(self):
"""Test all token values are non-empty strings"""
theme = get_default_light_theme()
for token_name, token in theme.tokens.items():
assert token.value, f"Token {token_name} has empty value"
assert token.description, f"Token {token_name} has no description"

View File

@@ -1,265 +0,0 @@
"""Unit tests for validation pipeline"""
import pytest
from dss.models.project import Project
from dss.models.theme import Theme, DesignToken, TokenCategory
from dss.validators.schema import ProjectValidator, ValidationError, ValidationStage
@pytest.mark.unit
class TestProjectValidator:
"""Test project validation pipeline"""
def test_validate_valid_project(self, valid_project_data):
"""Test validation passes for valid project"""
validator = ProjectValidator()
result = validator.validate(valid_project_data)
assert result.is_valid is True
assert len(result.errors) == 0
assert result.stage == ValidationStage.COMPLETE
def test_validate_missing_required_field(self):
"""Test validation fails when required field is missing"""
invalid_data = {
"name": "Test Project",
# Missing 'id' field
"theme": {
"name": "Test Theme",
"tokens": {}
}
}
validator = ProjectValidator()
result = validator.validate(invalid_data)
assert result.is_valid is False
assert len(result.errors) > 0
assert any("id" in str(err).lower() for err in result.errors)
def test_validate_invalid_token_value(self):
"""Test validation fails for invalid token values"""
invalid_data = {
"id": "test-project",
"name": "Test Project",
"theme": {
"name": "Test Theme",
"tokens": {
"primary": {
"name": "primary",
"value": "", # Empty value is invalid
"type": "color",
"category": "color"
}
}
}
}
validator = ProjectValidator()
result = validator.validate(invalid_data)
assert result.is_valid is False
assert ValidationStage.TOKEN_VALIDATION in [err.stage for err in result.errors]
def test_validate_token_reference(self):
"""Test validation of token references"""
data_with_ref = {
"id": "test-project",
"name": "Test Project",
"theme": {
"name": "Test Theme",
"tokens": {
"primary": {
"name": "primary",
"value": "oklch(0.65 0.18 250)",
"type": "color",
"category": "color"
},
"primary-dark": {
"name": "primary-dark",
"value": "{primary}", # Reference to primary token
"type": "color",
"category": "color"
}
}
}
}
validator = ProjectValidator()
result = validator.validate(data_with_ref)
# Should pass - valid reference
assert result.is_valid is True
def test_validate_broken_token_reference(self):
"""Test validation fails for broken token reference"""
data_with_broken_ref = {
"id": "test-project",
"name": "Test Project",
"theme": {
"name": "Test Theme",
"tokens": {
"primary": {
"name": "primary",
"value": "{nonexistent}", # Reference to nonexistent token
"type": "color",
"category": "color"
}
}
}
}
validator = ProjectValidator()
result = validator.validate(data_with_broken_ref)
assert result.is_valid is False
assert any("reference" in str(err).lower() for err in result.errors)
def test_validate_component_dependencies(self):
"""Test validation of component dependencies"""
data = {
"id": "test-project",
"name": "Test Project",
"theme": {
"name": "Test Theme",
"tokens": {}
},
"components": [
{
"name": "Card",
"source": "shadcn",
"dependencies": ["Button"] # Depends on Button component
},
{
"name": "Button",
"source": "shadcn"
}
]
}
validator = ProjectValidator()
result = validator.validate(data)
# Should pass - Button exists
assert result.is_valid is True
def test_validate_missing_component_dependency(self):
"""Test validation fails for missing component dependency"""
data = {
"id": "test-project",
"name": "Test Project",
"theme": {
"name": "Test Theme",
"tokens": {}
},
"components": [
{
"name": "Card",
"source": "shadcn",
"dependencies": ["NonexistentComponent"]
}
]
}
validator = ProjectValidator()
result = validator.validate(data)
assert result.is_valid is False
assert any("dependency" in str(err).lower() for err in result.errors)
def test_validation_stages_order(self):
"""Test validation stages execute in correct order"""
# Data that fails at schema stage
invalid_schema = {"invalid": "structure"}
validator = ProjectValidator()
result = validator.validate(invalid_schema)
# Should fail at schema stage and not proceed
assert result.is_valid is False
assert result.stage == ValidationStage.SCHEMA
def test_validate_token_category_enum(self):
"""Test validation accepts valid token categories"""
data = {
"id": "test-project",
"name": "Test Project",
"theme": {
"name": "Test Theme",
"tokens": {
"space-md": {
"name": "space-md",
"value": "16px",
"type": "dimension",
"category": "spacing" # Valid category
}
}
}
}
validator = ProjectValidator()
result = validator.validate(data)
assert result.is_valid is True
def test_validate_component_variants(self):
"""Test validation of component variants"""
data = {
"id": "test-project",
"name": "Test Project",
"theme": {
"name": "Test Theme",
"tokens": {}
},
"components": [
{
"name": "Button",
"source": "shadcn",
"variants": ["default", "outline", "ghost", "destructive"]
}
]
}
validator = ProjectValidator()
result = validator.validate(data)
assert result.is_valid is True
@pytest.mark.unit
class TestValidationResult:
"""Test ValidationResult model"""
def test_create_valid_result(self):
"""Test creating a valid validation result"""
from dss.validators.schema import ValidationResult
result = ValidationResult(
is_valid=True,
stage=ValidationStage.COMPLETE,
errors=[]
)
assert result.is_valid is True
assert result.stage == ValidationStage.COMPLETE
assert len(result.errors) == 0
def test_create_invalid_result_with_errors(self):
"""Test creating invalid result with errors"""
from dss.validators.schema import ValidationResult, ValidationError
error = ValidationError(
stage=ValidationStage.SCHEMA,
message="Missing required field: id",
field="id"
)
result = ValidationResult(
is_valid=False,
stage=ValidationStage.SCHEMA,
errors=[error]
)
assert result.is_valid is False
assert len(result.errors) == 1
assert result.errors[0].field == "id"