60cf26f739
- 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>
74 lines
2.7 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|