Files
kompas3d-mcp/tests/Kompas.Mcp.Tests/Integration/ModelingTests.cs
T
mikhail 60cf26f739 refactor(core): правки по код-ревью (COM-утечки, безопасный shutdown, типобезопасность)
- PartModeler: ResetAsync/Dispose освобождают RCW и чистят реестр эскизов/операций;
  Editor освобождается после EndEdit (C1)
- DocumentTools: сброс реестра при create/open/close — нет устаревших id (C2)
- DocumentService: освобождение транзитных IDocuments/IKompasDocument (m9)
- KompasSession.Dispose: ограниченное ожидание 5с вместо вечного блока (M3)
- PartModeler.ExtrudeAsync: убран dynamic -> конкретные definition-типы;
  throughAll только для cut (M4)
- FeatureTools.extrude_cut: дефолт throughAll=false, без подмены depth (m7)
- tests: регрессия на сброс реестра (старый id недействителен)
- docs/OPEN_QUESTIONS.md: итоги ревью (исправлено/отложено)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 09:18:52 +03:00

74 lines
2.7 KiB
C#

using Kompas.Mcp.Core.Documents;
using Kompas.Mcp.Core.Modeling;
using Kompas.Mcp.Core.Vision;
namespace Kompas.Mcp.Tests.Integration;
/// <summary>Интеграция: построение 3D (эскиз → выдавливание) и снимок.</summary>
[Trait("Category", "Integration")]
[Collection(KompasCollection.Name)]
public sealed class ModelingTests
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly SnapshotService _snap;
public ModelingTests(KompasFixture fx)
{
_docs = new DocumentService(fx.Session, fx.Dispatcher);
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
_snap = new SnapshotService(fx.Session, fx.Dispatcher);
}
[Fact]
public async Task Build_cylinder_then_cut_hole_and_snapshot()
{
await _docs.CreateAsync(KompasDocumentType.Part);
try
{
// Эскиз 1: окружность R20 на XOY → выдавить boss на 40 (цилиндр).
var s1 = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddCircleAsync(s1, 0, 0, 20);
await _modeler.CloseSketchAsync(s1);
var boss = await _modeler.ExtrudeAsync(s1, depth: 40);
Assert.True(boss > 0);
// Эскиз 2: окружность R8 на XOY → вырезать насквозь (отверстие).
var s2 = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.AddCircleAsync(s2, 0, 0, 8);
await _modeler.CloseSketchAsync(s2);
var cut = await _modeler.ExtrudeAsync(s2, depth: 40, cut: true, throughAll: true);
Assert.True(cut > 0);
await _modeler.RebuildAsync();
var path = TestPaths.NewFile(".png");
var snap = await _snap.CaptureActiveModelAsync(saveToFile: path);
Assert.True(snap.Bytes.Length > 1000, "Снимок цилиндра подозрительно мал.");
Assert.True(File.Exists(path));
}
finally
{
await _docs.CloseAsync(save: false);
}
}
[Fact]
public async Task Reset_invalidates_sketch_ids()
{
await _docs.CreateAsync(KompasDocumentType.Part);
try
{
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
await _modeler.ResetAsync();
// После сброса реестра старый id недействителен.
await Assert.ThrowsAsync<KeyNotFoundException>(
() => _modeler.AddCircleAsync(s, 0, 0, 5));
}
finally
{
await _docs.CloseAsync(save: false);
}
}
}