8afad88241
Базовый класс IntegrationTestBase (IAsyncLifetime) закрывает все открытые документы КОМПАС после КАЖДОГО теста (DocumentService.CloseAllAsync) — чтобы не копились вкладки-пустышки и упавший Assert не оставлял открытый документ. Все интеграционные тест-классы переведены на него (: base(fx)); индивидуальные finally CloseAsync сохранены как первичная очистка. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
75 lines
3.6 KiB
C#
75 lines
3.6 KiB
C#
using Kompas.Mcp.Core.Documents;
|
|
using Kompas.Mcp.Core.Modeling;
|
|
using Kompas.Mcp.Core.Query;
|
|
|
|
namespace Kompas.Mcp.Tests.Integration;
|
|
|
|
/// <summary>Интеграция: переменные модели (параметрика, API5 ksVariable).</summary>
|
|
[Trait("Category", "Integration")]
|
|
[Collection(KompasCollection.Name)]
|
|
public sealed class VariableTests : IntegrationTestBase
|
|
{
|
|
private readonly DocumentService _docs;
|
|
private readonly PartModeler _modeler;
|
|
private readonly VariableService _vars;
|
|
private readonly ModelInspectionService _inspect;
|
|
|
|
public VariableTests(KompasFixture fx) : base(fx)
|
|
{
|
|
_docs = new DocumentService(fx.Session, fx.Dispatcher);
|
|
_modeler = new PartModeler(fx.Session, fx.Dispatcher);
|
|
_vars = new VariableService(fx.Session, fx.Dispatcher);
|
|
_inspect = new ModelInspectionService(fx.Session, fx.Dispatcher);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Variable_crud_roundtrip()
|
|
{
|
|
await _docs.CreateAsync(KompasDocumentType.Part);
|
|
try
|
|
{
|
|
// Небольшая геометрия, чтобы было дерево построения.
|
|
var s = await _modeler.OpenSketchAsync(BasePlane.XOY);
|
|
await _modeler.AddRectangleAsync(s, 0, 0, 20, 20);
|
|
await _modeler.CloseSketchAsync(s);
|
|
await _modeler.ExtrudeAsync(s, depth: 10);
|
|
|
|
// create
|
|
var created = await _vars.CreateVariableAsync("width", 40, "ширина");
|
|
Assert.Equal(40, created, 3);
|
|
Assert.Equal(40, await _vars.GetVariableValueAsync("width"), 3);
|
|
|
|
// видна в list_variables (пользовательское чтение)
|
|
var list = await _inspect.ListVariablesAsync();
|
|
Assert.Contains(list, v => v.Name == "width");
|
|
|
|
// set expression (формула → вычисленное значение)
|
|
var computed = await _vars.SetVariableAsync("width", "12+8");
|
|
Assert.Equal(20, computed, 3);
|
|
Assert.Equal(20, await _vars.GetVariableValueAsync("width"), 3);
|
|
|
|
// дубликат имени отвергается
|
|
await Assert.ThrowsAsync<InvalidOperationException>(() => _vars.CreateVariableAsync("width", 1));
|
|
|
|
// вторая переменная, ссылающаяся на первую (формула с именем переменной)
|
|
await _vars.CreateVariableAsync("height", 5);
|
|
var doubled = await _vars.SetVariableAsync("height", "width * 2");
|
|
Assert.Equal(40, doubled, 3); // width=20 → 40
|
|
|
|
// десятичный разделитель — точка; зависимая переменная пересчитывается
|
|
Assert.Equal(3.5, await _vars.SetVariableAsync("width", "3.5"), 3);
|
|
Assert.Equal(7, await _vars.GetVariableValueAsync("height"), 3); // 3.5*2
|
|
|
|
// нельзя удалить переменную, на которую ссылаются (height = width*2)
|
|
await Assert.ThrowsAsync<InvalidOperationException>(() => _vars.DeleteVariableAsync("width"));
|
|
|
|
// delete (в порядке зависимостей: сначала зависимая height, затем width)
|
|
await _vars.DeleteVariableAsync("height");
|
|
await _vars.DeleteVariableAsync("width");
|
|
await Assert.ThrowsAsync<KeyNotFoundException>(() => _vars.GetVariableValueAsync("width"));
|
|
await Assert.ThrowsAsync<KeyNotFoundException>(() => _vars.GetVariableValueAsync("height"));
|
|
}
|
|
finally { await _docs.CloseAsync(save: false); }
|
|
}
|
|
}
|