We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jddunn/tenets'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
"""Tests for viz package initialization and factory functions."""
import json
from pathlib import Path
from unittest.mock import mock_open, patch
import pytest
from tenets.viz import (
ChartConfig,
ChartType,
ComplexityVisualizer,
ContributorVisualizer,
CouplingVisualizer,
DisplayConfig,
TerminalDisplay,
combine_visualizations,
create_chart,
create_terminal_display,
create_visualizer,
detect_visualization_type,
export_visualization,
)
class TestFactoryFunctions:
"""Test suite for factory functions."""
def test_create_visualizer_complexity(self):
"""Test creating complexity visualizer."""
viz = create_visualizer("complexity")
assert isinstance(viz, ComplexityVisualizer)
def test_create_visualizer_contributors(self):
"""Test creating contributor visualizer."""
viz = create_visualizer("contributors")
assert isinstance(viz, ContributorVisualizer)
def test_create_visualizer_coupling(self):
"""Test creating coupling visualizer."""
viz = create_visualizer("coupling")
assert isinstance(viz, CouplingVisualizer)
def test_create_visualizer_with_configs(self):
"""Test creating visualizer with custom configs."""
chart_config = ChartConfig(type=ChartType.LINE, title="Test")
display_config = DisplayConfig(use_colors=False)
viz = create_visualizer("complexity", chart_config, display_config)
assert isinstance(viz, ComplexityVisualizer)
assert viz.chart_config == chart_config
assert viz.display_config == display_config
def test_create_visualizer_invalid_type(self):
"""Test creating visualizer with invalid type."""
with pytest.raises(ValueError, match="Unknown visualizer type"):
create_visualizer("invalid")
def test_create_chart_bar(self):
"""Test creating bar chart."""
chart = create_chart("bar", {"labels": ["A", "B"], "values": [1, 2]}, title="Test Chart")
assert chart["type"] == "bar"
assert chart["options"]["plugins"]["title"]["text"] == "Test Chart"
assert chart["data"]["labels"] == ["A", "B"]
def test_create_chart_with_enum(self):
"""Test creating chart with ChartType enum."""
chart = create_chart(
ChartType.LINE, {"labels": ["Jan", "Feb"], "datasets": []}, title="Line Chart"
)
assert chart["type"] == "line"
assert chart["options"]["plugins"]["title"]["text"] == "Line Chart"
def test_create_chart_invalid_type(self):
"""Test creating chart with invalid type."""
with pytest.raises(ValueError, match="Unknown chart type"):
create_chart("invalid", {})
def test_create_terminal_display(self):
"""Test creating terminal display."""
display = create_terminal_display()
assert isinstance(display, TerminalDisplay)
def test_create_terminal_display_with_config(self):
"""Test creating terminal display with config."""
config = DisplayConfig(use_colors=False, max_width=80)
display = create_terminal_display(config)
assert isinstance(display, TerminalDisplay)
# Config would be used internally
class TestDetectVisualizationType:
"""Test suite for visualization type detection."""
def test_detect_complexity(self):
"""Test detecting complexity visualization."""
data = {"complexity": 10, "avg_complexity": 8.5, "complex_functions": []}
assert detect_visualization_type(data) == "complexity"
def test_detect_contributors(self):
"""Test detecting contributor visualization."""
data = {"contributors": [], "total_contributors": 10, "bus_factor": 3}
assert detect_visualization_type(data) == "contributors"
def test_detect_hotspots(self):
"""Test detecting hotspot visualization."""
data = {"hotspots": [], "risk_score": 45.5, "critical_count": 5}
assert detect_visualization_type(data) == "hotspots"
def test_detect_momentum(self):
"""Test detecting momentum visualization."""
data = {"velocity": 25, "sprint": "Sprint 5", "velocity_trend": []}
assert detect_visualization_type(data) == "momentum"
def test_detect_dependencies(self):
"""Test detecting dependency visualization."""
data = {"dependencies": [], "circular_dependencies": [], "dependency_graph": {}}
assert detect_visualization_type(data) == "dependencies"
def test_detect_coupling(self):
"""Test detecting coupling visualization."""
data = {"coupling": 5, "afferent_coupling": 3, "instability": 0.5}
assert detect_visualization_type(data) == "coupling"
def test_detect_from_list(self):
"""Test detecting from list data."""
data = [{"complexity": 10, "cyclomatic": 15}, {"complexity": 8, "cyclomatic": 12}]
assert detect_visualization_type(data) == "complexity"
data = [{"author": "Alice", "commits": 100}, {"contributor": "Bob", "commits": 50}]
assert detect_visualization_type(data) == "contributors"
def test_detect_custom(self):
"""Test detecting custom/unknown visualization."""
data = {"unknown": "data", "random": 123}
assert detect_visualization_type(data) == "custom"
data = []
assert detect_visualization_type(data) == "custom"
data = "string data"
assert detect_visualization_type(data) == "custom"
class TestExportVisualization:
"""Test suite for visualization export."""
@patch("builtins.open", new_callable=mock_open)
def test_export_json(self, mock_file):
"""Test exporting as JSON."""
visualization = {"type": "bar", "data": {"labels": ["A"], "values": [1]}}
export_visualization(visualization, "chart.json", format="json")
mock_file.assert_called_once_with(Path("chart.json"), "w")
handle = mock_file()
written_content = "".join(call.args[0] for call in handle.write.call_args_list)
# Verify JSON structure
parsed = json.loads(written_content)
assert parsed["type"] == "bar"
@patch("builtins.open", new_callable=mock_open)
def test_export_html(self, mock_file):
"""Test exporting as HTML."""
visualization = {"type": "bar", "data": {}}
config = ChartConfig(type=ChartType.BAR, title="Test Chart")
export_visualization(visualization, "chart.html", format="html", config=config)
mock_file.assert_called_once_with(Path("chart.html"), "w")
handle = mock_file()
written_content = "".join(call.args[0] for call in handle.write.call_args_list)
# Verify HTML structure
assert "<!DOCTYPE html>" in written_content
assert "Chart.js" in written_content
assert "Test Chart" in written_content
def test_export_unsupported_format(self):
"""Test exporting with unsupported format."""
visualization = {"type": "bar"}
with pytest.raises(NotImplementedError, match="SVG export requires"):
export_visualization(visualization, "chart.svg", format="svg")
with pytest.raises(ValueError, match="Unsupported export format"):
export_visualization(visualization, "chart.xyz", format="xyz")
class TestCombineVisualizations:
"""Test suite for combining visualizations."""
def test_combine_grid_layout(self):
"""Test combining with grid layout."""
viz1 = {"type": "bar", "data": {}}
viz2 = {"type": "line", "data": {}}
dashboard = combine_visualizations([viz1, viz2], layout="grid", title="Dashboard")
assert dashboard["type"] == "dashboard"
assert dashboard["title"] == "Dashboard"
assert dashboard["layout"] == "grid"
assert len(dashboard["visualizations"]) == 2
assert dashboard["options"]["responsive"] == True
def test_combine_vertical_layout(self):
"""Test combining with vertical layout."""
visualizations = [
{"type": "bar", "data": {}},
{"type": "pie", "data": {}},
{"type": "line", "data": {}},
]
dashboard = combine_visualizations(visualizations, layout="vertical")
assert dashboard["layout"] == "vertical"
assert len(dashboard["visualizations"]) == 3
def test_combine_default_title(self):
"""Test combining with default title."""
dashboard = combine_visualizations([{"type": "bar"}])
assert dashboard["title"] == "Dashboard"
class TestPrivateFunctions:
"""Test suite for private helper functions."""
def test_generate_html_visualization(self):
"""Test HTML generation for single visualization."""
from tenets.viz import _generate_html_visualization
visualization = {"type": "bar", "data": {"labels": ["A"], "values": [1]}}
config = ChartConfig(type=ChartType.BAR, title="Test", width=1000, height=600)
html = _generate_html_visualization(visualization, config)
assert "<!DOCTYPE html>" in html
assert "Test" in html
assert "1060px" in html # width + padding
assert "600px" in html
assert json.dumps(visualization) in html
def test_generate_dashboard_html(self):
"""Test HTML generation for dashboard."""
from tenets.viz import _generate_dashboard_html
dashboard = {
"type": "dashboard",
"title": "My Dashboard",
"layout": "grid",
"visualizations": [{"type": "bar", "data": {}}, {"type": "line", "data": {}}],
}
config = ChartConfig(type=ChartType.BAR)
html = _generate_dashboard_html(dashboard, config)
assert "<!DOCTYPE html>" in html
assert "My Dashboard" in html
assert "charts-grid" in html
assert "chart0" in html
assert "chart1" in html
assert "Chart(ctx0" in html
assert "Chart(ctx1" in html
class TestModuleImports:
"""Test module imports and public API."""
def test_all_exports(self):
"""Test __all__ exports are available."""
from tenets import viz
expected_exports = [
"BaseVisualizer",
"ChartConfig",
"ChartType",
"ColorPalette",
"DisplayConfig",
"DisplayFormat",
"ComplexityVisualizer",
"ContributorVisualizer",
"CouplingVisualizer",
"TerminalDisplay",
"ProgressDisplay",
"create_visualizer",
"create_chart",
"create_terminal_display",
"detect_visualization_type",
"export_visualization",
"combine_visualizations",
]
for export in expected_exports:
assert hasattr(viz, export)
def test_version(self):
"""Test version is defined."""
from tenets import viz
assert hasattr(viz, "__version__")
assert isinstance(viz.__version__, str)