using Kompas.Mcp.Core.Documents; using Kompas.Mcp.Core.Drawings; using Kompas.Mcp.Core.Modeling; namespace Kompas.Mcp.Tests.Integration; /// Интеграция: линейный размер на виде чертежа (API7 ISymbols2DContainer.LineDimensions). [Trait("Category", "Integration")] [Collection(KompasCollection.Name)] public sealed class DrawingDimensionTests : IntegrationTestBase { private readonly DocumentService _docs; private readonly PartModeler _modeler; private readonly DrawingService _drawing; public DrawingDimensionTests(KompasFixture fx) : base(fx) { _docs = new DocumentService(fx.Session, fx.Dispatcher); _modeler = new PartModeler(fx.Session, fx.Dispatcher); _drawing = new DrawingService(fx.Session, fx.Dispatcher); } private async Task BuildAndSaveBoxAsync() { var path = TestPaths.NewFile(".m3d"); await _docs.CreateAsync(KompasDocumentType.Part); try { var s = await _modeler.OpenSketchAsync(BasePlane.XOY); await _modeler.AddRectangleAsync(s, 0, 0, 40, 30); await _modeler.CloseSketchAsync(s); await _modeler.ExtrudeAsync(s, depth: 20); await _modeler.RebuildAsync(); await _docs.SaveAsAsync(path); } finally { await _docs.CloseAsync(save: false); } return path; } [Fact] public async Task Horizontal_dimension_auto_measures_distance() { var partFile = await BuildAndSaveBoxAsync(); await _docs.CreateAsync(KompasDocumentType.Drawing); try { var views = await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150); Assert.Equal(3, views.ViewNumbers.Count); var r = await _drawing.AddLinearDimensionAsync( viewNumber: 0, x1: 0, y1: 0, x2: 40, y2: 0, x3: 20, y3: -10, DimensionOrientation.Horizontal); Assert.InRange(r.Value, 39.9, 40.1); // авто-значение = |X2-X1| Assert.Contains(r.ViewNumber, views.ViewNumbers); // размер попал в один из видов } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task Vertical_dimension_measures_y_span() { var partFile = await BuildAndSaveBoxAsync(); await _docs.CreateAsync(KompasDocumentType.Drawing); try { await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150); var r = await _drawing.AddLinearDimensionAsync( viewNumber: 0, x1: 0, y1: 0, x2: 0, y2: 20, x3: -10, y3: 10, DimensionOrientation.Vertical); Assert.InRange(r.Value, 19.9, 20.1); } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task Targets_specific_view_by_number_and_increments_its_object_count() { var partFile = await BuildAndSaveBoxAsync(); await _docs.CreateAsync(KompasDocumentType.Drawing); try { var views = await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150); var targetNumber = views.ViewNumbers[1]; // второй созданный вид (напр. сверху) // Размеры живут в ISymbols2DContainer вида — считаем именно их у ЦЕЛЕВОГО вида. var before = await _drawing.GetViewLineDimensionCountAsync(targetNumber); var r = await _drawing.AddLinearDimensionAsync( viewNumber: targetNumber, x1: 0, y1: 0, x2: 40, y2: 0, x3: 20, y3: -10, DimensionOrientation.Horizontal); var after = await _drawing.GetViewLineDimensionCountAsync(targetNumber); Assert.Equal(targetNumber, r.ViewNumber); Assert.Equal(before + 1, after); // размер попал именно в целевой вид } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task Parallel_dimension_measures_true_length() { var partFile = await BuildAndSaveBoxAsync(); await _docs.CreateAsync(KompasDocumentType.Drawing); try { await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150); // Параллельный размер (0,0)-(30,40): реальная длина = 50 (3-4-5). var r = await _drawing.AddLinearDimensionAsync( viewNumber: 0, x1: 0, y1: 0, x2: 30, y2: 40, x3: 25, y3: 5, DimensionOrientation.Parallel); Assert.InRange(r.Value, 49.5, 50.5); } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task Zero_projection_orientation_throws_and_rolls_back() { var partFile = await BuildAndSaveBoxAsync(); await _docs.CreateAsync(KompasDocumentType.Drawing); try { await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150); var before = await _drawing.GetViewLineDimensionCountAsync(0); // Горизонтальный размер для точек на одной вертикали → |X2-X1|=0 → ошибка + откат. await Assert.ThrowsAsync(() => _drawing.AddLinearDimensionAsync( viewNumber: 0, x1: 10, y1: 0, x2: 10, y2: 30, x3: 0, y3: 15, DimensionOrientation.Horizontal)); // Откат: число размеров не изменилось (вырожденный размер удалён). var after = await _drawing.GetViewLineDimensionCountAsync(0); Assert.Equal(before, after); } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task Coincident_points_throw() { var partFile = await BuildAndSaveBoxAsync(); await _docs.CreateAsync(KompasDocumentType.Drawing); try { await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150); await Assert.ThrowsAsync(() => _drawing.AddLinearDimensionAsync( viewNumber: 0, x1: 10, y1: 10, x2: 10, y2: 10, x3: 0, y3: 0, DimensionOrientation.Horizontal)); } finally { await _docs.CloseAsync(save: false); } } [Fact] public async Task No_views_throws() { // Чертёж без ассоциативных видов: только системный вид → понятная ошибка. await _docs.CreateAsync(KompasDocumentType.Drawing); try { await Assert.ThrowsAsync(() => _drawing.AddLinearDimensionAsync( viewNumber: 0, x1: 0, y1: 0, x2: 40, y2: 0, x3: 20, y3: -10, DimensionOrientation.Horizontal)); } finally { await _docs.CloseAsync(save: false); } } }