refactor: Major project cleanup and reorganization
## Removed Duplicate Directories - Deleted old `dashboard/` (replaced by atomizer-dashboard) - Deleted old `mcp_server/` Python tools (moved model_discovery to optimization_engine) - Deleted `tests/mcp_server/` (obsolete tests) - Deleted `launch_dashboard.bat` (old launcher) ## Consolidated Code - Moved `mcp_server/tools/model_discovery.py` to `optimization_engine/model_discovery/` - Updated import in `optimization_config_builder.py` - Deleted stub `extract_mass.py` (use extract_mass_from_bdf instead) - Deleted unused `intelligent_setup.py` and `hybrid_study_creator.py` - Archived `result_extractors/` to `archive/deprecated/` ## Documentation Cleanup - Deleted deprecated `docs/06_PROTOCOLS_DETAILED/` (14 files) - Archived dated dev docs to `docs/08_ARCHIVE/sessions/` - Archived old plans to `docs/08_ARCHIVE/plans/` - Updated `docs/protocols/README.md` with SYS_15 ## Skills Consolidation - Archived redundant study creation skills to `.claude/skills/archive/` - Kept `core/study-creation-core.md` as canonical ## Housekeeping - Updated `.gitignore` to prevent `nul` and `_dat_run*.dat` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,211 +0,0 @@
|
||||
"""
|
||||
Unit tests for MCP Model Discovery Tool
|
||||
|
||||
Tests the .sim file parser and FEA model discovery functionality.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
import sys
|
||||
|
||||
# Add project root to path
|
||||
project_root = Path(__file__).parent.parent.parent.parent
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from mcp_server.tools.model_discovery import (
|
||||
discover_fea_model,
|
||||
format_discovery_result_for_llm,
|
||||
SimFileParser
|
||||
)
|
||||
|
||||
|
||||
class TestSimFileParser:
|
||||
"""Test the SimFileParser class"""
|
||||
|
||||
@pytest.fixture
|
||||
def example_sim_path(self):
|
||||
"""Path to example .sim file"""
|
||||
return project_root / "examples" / "test_bracket.sim"
|
||||
|
||||
def test_parser_initialization(self, example_sim_path):
|
||||
"""Test that parser initializes correctly"""
|
||||
parser = SimFileParser(example_sim_path)
|
||||
assert parser.sim_path.exists()
|
||||
assert parser.tree is not None
|
||||
assert parser.root is not None
|
||||
|
||||
def test_parser_file_not_found(self):
|
||||
"""Test error handling for missing file"""
|
||||
with pytest.raises(FileNotFoundError):
|
||||
SimFileParser("/nonexistent/path/file.sim")
|
||||
|
||||
def test_parser_invalid_extension(self):
|
||||
"""Test error handling for non-.sim file"""
|
||||
with pytest.raises(ValueError):
|
||||
SimFileParser(project_root / "README.md")
|
||||
|
||||
def test_extract_solutions(self, example_sim_path):
|
||||
"""Test solution extraction"""
|
||||
parser = SimFileParser(example_sim_path)
|
||||
solutions = parser.extract_solutions()
|
||||
|
||||
assert len(solutions) > 0
|
||||
assert solutions[0]['name'] == 'Structural Analysis 1'
|
||||
assert solutions[0]['type'] == 'Static Structural'
|
||||
assert solutions[0]['solver'] == 'NX Nastran'
|
||||
|
||||
def test_extract_expressions(self, example_sim_path):
|
||||
"""Test expression extraction"""
|
||||
parser = SimFileParser(example_sim_path)
|
||||
expressions = parser.extract_expressions()
|
||||
|
||||
assert len(expressions) > 0
|
||||
|
||||
# Check for expected expressions
|
||||
expr_names = [e['name'] for e in expressions]
|
||||
assert 'wall_thickness' in expr_names
|
||||
assert 'hole_diameter' in expr_names
|
||||
assert 'rib_spacing' in expr_names
|
||||
|
||||
# Check expression values
|
||||
wall_thickness = next(e for e in expressions if e['name'] == 'wall_thickness')
|
||||
assert wall_thickness['value'] == '5.0'
|
||||
assert wall_thickness['units'] == 'mm'
|
||||
|
||||
def test_extract_fem_info(self, example_sim_path):
|
||||
"""Test FEM information extraction"""
|
||||
parser = SimFileParser(example_sim_path)
|
||||
fem_info = parser.extract_fem_info()
|
||||
|
||||
# Check mesh info
|
||||
assert 'mesh' in fem_info
|
||||
assert fem_info['mesh']['name'] == 'Bracket Mesh'
|
||||
assert fem_info['mesh']['node_count'] == '8234'
|
||||
assert fem_info['mesh']['element_count'] == '4521'
|
||||
|
||||
# Check materials
|
||||
assert len(fem_info['materials']) > 0
|
||||
assert fem_info['materials'][0]['name'] == 'Aluminum 6061-T6'
|
||||
|
||||
# Check loads
|
||||
assert len(fem_info['loads']) > 0
|
||||
assert fem_info['loads'][0]['name'] == 'Applied Force'
|
||||
|
||||
# Check constraints
|
||||
assert len(fem_info['constraints']) > 0
|
||||
assert fem_info['constraints'][0]['name'] == 'Fixed Support'
|
||||
|
||||
|
||||
class TestDiscoverFEAModel:
|
||||
"""Test the main discover_fea_model function"""
|
||||
|
||||
@pytest.fixture
|
||||
def example_sim_path(self):
|
||||
"""Path to example .sim file"""
|
||||
return str(project_root / "examples" / "test_bracket.sim")
|
||||
|
||||
def test_successful_discovery(self, example_sim_path):
|
||||
"""Test successful model discovery"""
|
||||
result = discover_fea_model(example_sim_path)
|
||||
|
||||
assert result['status'] == 'success'
|
||||
assert result['file_exists'] is True
|
||||
assert 'solutions' in result
|
||||
assert 'expressions' in result
|
||||
assert 'fem_info' in result
|
||||
assert 'summary' in result
|
||||
|
||||
# Check summary statistics
|
||||
assert result['summary']['solution_count'] >= 1
|
||||
assert result['summary']['expression_count'] >= 3
|
||||
|
||||
def test_file_not_found_error(self):
|
||||
"""Test error handling for missing file"""
|
||||
result = discover_fea_model("/nonexistent/file.sim")
|
||||
|
||||
assert result['status'] == 'error'
|
||||
assert result['error_type'] == 'file_not_found'
|
||||
assert 'message' in result
|
||||
assert 'suggestion' in result
|
||||
|
||||
def test_result_structure(self, example_sim_path):
|
||||
"""Test that result has expected structure"""
|
||||
result = discover_fea_model(example_sim_path)
|
||||
|
||||
# Check top-level keys
|
||||
expected_keys = ['status', 'sim_file', 'file_exists', 'solutions',
|
||||
'expressions', 'fem_info', 'linked_files', 'metadata', 'summary']
|
||||
|
||||
for key in expected_keys:
|
||||
assert key in result, f"Missing key: {key}"
|
||||
|
||||
# Check summary keys
|
||||
expected_summary_keys = ['solution_count', 'expression_count',
|
||||
'material_count', 'load_count', 'constraint_count']
|
||||
|
||||
for key in expected_summary_keys:
|
||||
assert key in result['summary'], f"Missing summary key: {key}"
|
||||
|
||||
|
||||
class TestFormatDiscoveryResult:
|
||||
"""Test the Markdown formatting function"""
|
||||
|
||||
@pytest.fixture
|
||||
def example_sim_path(self):
|
||||
"""Path to example .sim file"""
|
||||
return str(project_root / "examples" / "test_bracket.sim")
|
||||
|
||||
def test_format_success_result(self, example_sim_path):
|
||||
"""Test formatting of successful discovery"""
|
||||
result = discover_fea_model(example_sim_path)
|
||||
formatted = format_discovery_result_for_llm(result)
|
||||
|
||||
assert isinstance(formatted, str)
|
||||
assert '# FEA Model Analysis' in formatted
|
||||
assert 'Solutions' in formatted
|
||||
assert 'Expressions' in formatted
|
||||
assert 'wall_thickness' in formatted
|
||||
|
||||
def test_format_error_result(self):
|
||||
"""Test formatting of error result"""
|
||||
result = discover_fea_model("/nonexistent/file.sim")
|
||||
formatted = format_discovery_result_for_llm(result)
|
||||
|
||||
assert isinstance(formatted, str)
|
||||
assert '❌' in formatted or 'Error' in formatted
|
||||
assert result['message'] in formatted
|
||||
|
||||
|
||||
# Integration test
|
||||
def test_end_to_end_workflow():
|
||||
"""
|
||||
Test the complete workflow:
|
||||
1. Discover model
|
||||
2. Format for LLM
|
||||
3. Verify output is useful
|
||||
"""
|
||||
example_sim = str(project_root / "examples" / "test_bracket.sim")
|
||||
|
||||
# Step 1: Discover
|
||||
result = discover_fea_model(example_sim)
|
||||
assert result['status'] == 'success'
|
||||
|
||||
# Step 2: Format
|
||||
formatted = format_discovery_result_for_llm(result)
|
||||
assert len(formatted) > 100 # Should be substantial output
|
||||
|
||||
# Step 3: Verify key information is present
|
||||
assert 'wall_thickness' in formatted
|
||||
assert 'Aluminum' in formatted
|
||||
assert 'Static Structural' in formatted
|
||||
|
||||
print("\n" + "="*60)
|
||||
print("INTEGRATION TEST OUTPUT:")
|
||||
print("="*60)
|
||||
print(formatted)
|
||||
print("="*60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Run tests with pytest
|
||||
pytest.main([__file__, "-v", "-s"])
|
||||
Reference in New Issue
Block a user