Files
kompas3d-mcp/tests/Kompas.Mcp.Tests/Integration/VariableTests.cs
T
mikhail bc52b5d920 feat: параметрика — переменные модели (create/set/delete_variable) через API5
- VariableService: CreateVariableAsync/SetVariableAsync/DeleteVariableAsync/GetVariableValueAsync
- создание ТОЛЬКО на ksFeature.VariableCollection (ksPart — только внешние); RebuildModel + re-fetch
- Expression — ведущее поле (константа/формула со ссылками); value пересчитывается
- list_variables (ModelInspectionService) исправлен: читает feature-коллекцию (все переменные)
- инструменты create_variable/set_variable/delete_variable (VariableTools) + DI
- интеграционный тест CRUD round-trip (создание, формула width*2, удаление по зависимостям)
- ОГРАНИЧЕНИЕ: переменные драйвят геометрию лишь в параметрической модели (эскизы на литералах — нет)
- 116 тестов; спек docs/superpowers/specs/2026-05-27-parametrics-design.md
2026-05-27 11:14:28 +03:00

65 lines
2.9 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
{
private readonly DocumentService _docs;
private readonly PartModeler _modeler;
private readonly VariableService _vars;
private readonly ModelInspectionService _inspect;
public VariableTests(KompasFixture 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 _vars.CreateVariableAsync("height", 5);
var doubled = await _vars.SetVariableAsync("height", "width * 2");
Assert.Equal(40, doubled, 3); // width=20 → 40
// 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); }
}
}