mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-29 04:26:20 +00:00
- Robust ID extraction in CentralityCalculator, CommunityDetector, and ConnectivityAnalyzer - Support for direct Entity objects and dictionaries as node identifiers - Improved Entity hashability in utils/types.py - Added integration test to verify fix and prevent regression
228 lines
9.7 KiB
Python
228 lines
9.7 KiB
Python
import unittest
|
|
from unittest.mock import MagicMock, patch
|
|
import sys
|
|
import numpy as np
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
# Mock heavy libraries before importing visualization modules
|
|
sys.modules['matplotlib'] = MagicMock()
|
|
sys.modules['matplotlib.pyplot'] = MagicMock()
|
|
sys.modules['matplotlib.colors'] = MagicMock()
|
|
sys.modules['matplotlib.patches'] = MagicMock()
|
|
sys.modules['plotly'] = MagicMock()
|
|
sys.modules['plotly.express'] = MagicMock()
|
|
sys.modules['plotly.graph_objects'] = MagicMock()
|
|
sys.modules['plotly.subplots'] = MagicMock()
|
|
sys.modules['seaborn'] = MagicMock()
|
|
sys.modules['umap'] = MagicMock()
|
|
sys.modules['sklearn'] = MagicMock()
|
|
sys.modules['sklearn.decomposition'] = MagicMock()
|
|
sys.modules['sklearn.manifold'] = MagicMock()
|
|
sys.modules['networkx'] = MagicMock()
|
|
sys.modules['graphviz'] = MagicMock()
|
|
|
|
# Import visualizers
|
|
from semantica.visualization.kg_visualizer import KGVisualizer
|
|
from semantica.visualization.ontology_visualizer import OntologyVisualizer
|
|
from semantica.visualization.embedding_visualizer import EmbeddingVisualizer
|
|
from semantica.visualization.semantic_network_visualizer import SemanticNetworkVisualizer
|
|
from semantica.visualization.analytics_visualizer import AnalyticsVisualizer
|
|
from semantica.visualization.temporal_visualizer import TemporalVisualizer
|
|
from semantica.visualization.utils.color_schemes import ColorScheme
|
|
|
|
pytestmark = pytest.mark.integration
|
|
class TestVisualizationComprehensive(unittest.TestCase):
|
|
|
|
def setUp(self):
|
|
self.mock_logger = MagicMock()
|
|
self.mock_tracker = MagicMock()
|
|
|
|
# Patch dependencies for all visualizers
|
|
self.patchers = [
|
|
patch('semantica.visualization.kg_visualizer.get_logger', return_value=self.mock_logger),
|
|
patch('semantica.visualization.kg_visualizer.get_progress_tracker', return_value=self.mock_tracker),
|
|
patch('semantica.visualization.ontology_visualizer.get_logger', return_value=self.mock_logger),
|
|
patch('semantica.visualization.ontology_visualizer.get_progress_tracker', return_value=self.mock_tracker),
|
|
patch('semantica.visualization.embedding_visualizer.get_logger', return_value=self.mock_logger),
|
|
patch('semantica.visualization.embedding_visualizer.get_progress_tracker', return_value=self.mock_tracker),
|
|
patch('semantica.visualization.semantic_network_visualizer.get_logger', return_value=self.mock_logger),
|
|
patch('semantica.visualization.semantic_network_visualizer.get_progress_tracker', return_value=self.mock_tracker),
|
|
patch('semantica.visualization.analytics_visualizer.get_logger', return_value=self.mock_logger),
|
|
patch('semantica.visualization.analytics_visualizer.get_progress_tracker', return_value=self.mock_tracker),
|
|
patch('semantica.visualization.temporal_visualizer.get_logger', return_value=self.mock_logger),
|
|
patch('semantica.visualization.temporal_visualizer.get_progress_tracker', return_value=self.mock_tracker),
|
|
# Mock Layouts
|
|
patch('semantica.visualization.kg_visualizer.ForceDirectedLayout', MagicMock()),
|
|
patch('semantica.visualization.kg_visualizer.HierarchicalLayout', MagicMock()),
|
|
patch('semantica.visualization.kg_visualizer.CircularLayout', MagicMock()),
|
|
patch('semantica.visualization.ontology_visualizer.HierarchicalLayout', MagicMock()),
|
|
patch('semantica.visualization.semantic_network_visualizer.ForceDirectedLayout', MagicMock()),
|
|
]
|
|
|
|
for p in self.patchers:
|
|
p.start()
|
|
|
|
# Reset plotly mocks
|
|
import plotly.graph_objects as go
|
|
import plotly.express as px
|
|
go.Figure.reset_mock()
|
|
px.bar.reset_mock()
|
|
px.scatter.reset_mock()
|
|
|
|
def tearDown(self):
|
|
for p in self.patchers:
|
|
p.stop()
|
|
|
|
# --- KGVisualizer Tests ---
|
|
def test_kg_visualizer(self):
|
|
viz = KGVisualizer()
|
|
graph = {
|
|
"entities": [{"id": "e1", "label": "E1", "type": "T1"}, {"id": "e2", "label": "E2", "type": "T2"}],
|
|
"relationships": [{"source": "e1", "target": "e2", "type": "R1"}]
|
|
}
|
|
|
|
# Test visualize_network
|
|
viz.visualize_network(graph)
|
|
|
|
# Test visualize_communities
|
|
communities = {"node_assignments": {"e1": 0, "e2": 1}, "num_communities": 2}
|
|
viz.visualize_communities(graph, communities)
|
|
|
|
# Test visualize_centrality
|
|
centrality = {"centrality": {"e1": 0.5, "e2": 0.3}}
|
|
viz.visualize_centrality(graph, centrality)
|
|
|
|
# Test visualize_entity_types
|
|
viz.visualize_entity_types(graph)
|
|
|
|
# Test visualize_relationship_matrix
|
|
viz.visualize_relationship_matrix(graph)
|
|
|
|
# --- OntologyVisualizer Tests ---
|
|
def test_ontology_visualizer(self):
|
|
viz = OntologyVisualizer()
|
|
ontology = {
|
|
"classes": [
|
|
{"name": "C1", "label": "Class 1", "parent": None},
|
|
{"name": "C2", "label": "Class 2", "parent": "C1"}
|
|
],
|
|
"properties": [
|
|
{"name": "P1", "label": "Prop 1", "domain": "C1", "range": "C2"}
|
|
]
|
|
}
|
|
|
|
# Test visualize_hierarchy
|
|
viz.visualize_hierarchy(ontology)
|
|
|
|
# Test visualize_properties
|
|
viz.visualize_properties(ontology)
|
|
|
|
# Test visualize_structure
|
|
viz.visualize_structure(ontology)
|
|
|
|
# Test visualize_class_property_matrix
|
|
viz.visualize_class_property_matrix(ontology)
|
|
|
|
# Test visualize_metrics
|
|
viz.visualize_metrics(ontology)
|
|
|
|
# Test visualize_semantic_model (mocking extract classes)
|
|
semantic_model = {"nodes": [{"id": "n1", "type": "T1"}], "edges": []}
|
|
viz.visualize_semantic_model(semantic_model)
|
|
|
|
# --- SemanticNetworkVisualizer Tests ---
|
|
def test_semantic_network_visualizer(self):
|
|
viz = SemanticNetworkVisualizer()
|
|
semantic_network = {
|
|
"nodes": [{"id": "n1", "label": "N1", "type": "T1"}],
|
|
"edges": [{"source": "n1", "target": "n1", "label": "R1"}]
|
|
}
|
|
|
|
# Test visualize_network
|
|
with patch('semantica.visualization.kg_visualizer.KGVisualizer') as MockKG:
|
|
viz.visualize_network(semantic_network)
|
|
MockKG.return_value.visualize_network.assert_called()
|
|
|
|
# Test visualize_node_types
|
|
viz.visualize_node_types(semantic_network)
|
|
|
|
# Test visualize_edge_types
|
|
viz.visualize_edge_types(semantic_network)
|
|
|
|
# --- AnalyticsVisualizer Tests ---
|
|
def test_analytics_visualizer(self):
|
|
viz = AnalyticsVisualizer()
|
|
graph = {"entities": [], "relationships": []}
|
|
|
|
# Test visualize_centrality_rankings
|
|
centrality = {"rankings": [{"node": "n1", "score": 0.9}]}
|
|
viz.visualize_centrality_rankings(centrality)
|
|
|
|
# Test visualize_community_structure
|
|
communities = {"node_assignments": {}}
|
|
with patch('semantica.visualization.kg_visualizer.KGVisualizer') as MockKG:
|
|
viz.visualize_community_structure(graph, communities)
|
|
|
|
# Test visualize_connectivity
|
|
connectivity = {"is_connected": True, "num_components": 1, "component_sizes": [10]}
|
|
viz.visualize_connectivity(connectivity)
|
|
|
|
# Test visualize_degree_distribution
|
|
viz.visualize_degree_distribution(graph)
|
|
|
|
# Test visualize_metrics_dashboard
|
|
metrics = {"num_nodes": 10, "num_edges": 20, "density": 0.1}
|
|
viz.visualize_metrics_dashboard(metrics)
|
|
|
|
# Test visualize_centrality_comparison
|
|
results = {"degree": {"rankings": [{"node": "n1", "score": 0.9}]}}
|
|
viz.visualize_centrality_comparison(results)
|
|
|
|
# --- TemporalVisualizer Tests ---
|
|
def test_temporal_visualizer(self):
|
|
viz = TemporalVisualizer()
|
|
|
|
# Test visualize_timeline
|
|
temporal_data = {"events": [{"timestamp": "2023-01-01", "type": "create", "label": "E1"}], "timestamps": ["2023-01-01"]}
|
|
viz.visualize_timeline(temporal_data)
|
|
|
|
# Test visualize_temporal_patterns
|
|
patterns = [{"pattern_type": "trend", "start_time": "2023", "end_time": "2024", "entities": ["e1"]}]
|
|
viz.visualize_temporal_patterns(patterns)
|
|
|
|
# Test visualize_snapshot_comparison
|
|
snapshots = {"2023": {"entities": ["e1"], "relationships": []}}
|
|
viz.visualize_snapshot_comparison(snapshots)
|
|
|
|
# Test visualize_version_history
|
|
history = [{"version": "v1", "date": "2023-01-01"}]
|
|
viz.visualize_version_history(history)
|
|
|
|
# Test visualize_metrics_evolution
|
|
metrics_history = {"nodes": [10, 20]}
|
|
timestamps = ["2023", "2024"]
|
|
viz.visualize_metrics_evolution(metrics_history, timestamps)
|
|
|
|
# --- EmbeddingVisualizer Tests ---
|
|
def test_embedding_visualizer(self):
|
|
viz = EmbeddingVisualizer()
|
|
embeddings = np.random.rand(10, 10)
|
|
|
|
# Test visualize_2d_projection (mock UMAP/PCA)
|
|
with patch('semantica.visualization.embedding_visualizer.umap.UMAP') as MockUMAP:
|
|
MockUMAP.return_value.fit_transform.return_value = np.random.rand(10, 2)
|
|
viz.visualize_2d_projection(embeddings)
|
|
|
|
# Test visualize_similarity_heatmap
|
|
viz.visualize_similarity_heatmap(embeddings[:5]) # smaller for heatmap
|
|
|
|
# Test visualize_clustering
|
|
clusters = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
|
|
with patch('semantica.visualization.embedding_visualizer.umap.UMAP') as MockUMAP:
|
|
MockUMAP.return_value.fit_transform.return_value = np.random.rand(10, 2)
|
|
viz.visualize_clustering(embeddings, clusters)
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|