using Kompas.Mcp.Core.Documents; using Kompas.Mcp.Core.Modeling; using Kompas.Mcp.Core.Query; namespace Kompas.Mcp.Tests.Integration; /// Интеграция: структурное «зрение» — дерево, топология, drill-down, измерения. [Trait("Category", "Integration")] [Collection(KompasCollection.Name)] public sealed class InspectionTests : IntegrationTestBase { private readonly DocumentService _docs; private readonly PartModeler _modeler; private readonly ModelInspectionService _inspect; public InspectionTests(KompasFixture fx) : base(fx) { _docs = new DocumentService(fx.Session, fx.Dispatcher); _modeler = new PartModeler(fx.Session, fx.Dispatcher); _inspect = new ModelInspectionService(fx.Session, fx.Dispatcher); } /// Построить эталон: прямоугольник 40×20 → выдавить 15 мм → скругление R3 первого ребра. private async Task BuildDemoPartAsync() { var s = await _modeler.OpenSketchAsync(BasePlane.XOY); await _modeler.AddRectangleAsync(s, -20, -10, 20, 10); await _modeler.CloseSketchAsync(s); await _modeler.ExtrudeAsync(s, depth: 15); await _modeler.FilletEdgeIndexAsync(0, 3); await _modeler.RebuildAsync(); } [Fact] public async Task Describe_model_shows_tree_topology_and_bodies() { await _docs.CreateAsync(KompasDocumentType.Part); try { await BuildDemoPartAsync(); var d = await _inspect.DescribeModelAsync(); Assert.False(d.IsEmpty); Assert.False(d.Imported); // родная параметрическая деталь Assert.Single(d.Bodies); // одно тело Assert.True(d.Bodies[0].IsSolid); // Габарит исходного бруска 40×20×15 (скругление R3 не меняет общий габарит). Assert.NotNull(d.Box); Assert.InRange(d.Box!.SizeX, 39.9, 40.1); Assert.InRange(d.Box!.SizeZ, 14.9, 15.1); // Топология: есть плоскости и цилиндр от скругления. Assert.Contains("plane", d.FaceTypes); Assert.Contains("cylinder", d.FaceTypes); // Дерево: выдавливание с глубиной и скругление. Assert.Contains(d.Features, f => f.Kind == "extrusion" && (f.Detail ?? "").Contains("15")); Assert.Contains(d.Features, f => f.Kind == "fillet"); } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task List_features_reports_extrusion_depth() { await _docs.CreateAsync(KompasDocumentType.Part); try { await BuildDemoPartAsync(); var fs = await _inspect.ListFeaturesAsync(); var extrusion = Assert.Single(fs, f => f.Kind == "extrusion"); Assert.Contains("15", extrusion.Detail ?? ""); Assert.Contains(fs, f => f.Kind == "fillet"); } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task Describe_face_returns_area_and_edges() { await _docs.CreateAsync(KompasDocumentType.Part); try { await BuildDemoPartAsync(); var face = await _inspect.DescribeFaceAsync(0); Assert.True(face.Area > 0); Assert.True(face.EdgeCount > 0); Assert.NotNull(face.Normal); } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task Measure_between_two_faces_succeeds() { await _docs.CreateAsync(KompasDocumentType.Part); try { await BuildDemoPartAsync(); var m = await _inspect.MeasureAsync("face", 0, "face", 1); Assert.True(m.MinDistance >= 0); // путь измерения работает Assert.True(double.IsFinite(m.Distance)); } finally { await _docs.CloseAsync(save: false); } } }