fix: правки параметрики по ревью Codex

- проверка возврата ksPart.RebuildModel() во всех операциях (не рапортовать успех при неудаче) — P2
- сообщение об удалении: намёк на зависимые переменные — P3
- дисклеймер про геометрию в описании set_variable + десятичный разделитель — P3
- тест дополнен: дубликат имени, удаление с зависимыми, десятичное выражение (3.5), пересчёт зависимой
- 116 тестов зелёных
This commit is contained in:
2026-05-27 11:20:38 +03:00
parent bc52b5d920
commit a30614d005
3 changed files with 20 additions and 5 deletions
@@ -38,7 +38,8 @@ public sealed class VariableService
var v = vc.AddNewVariable(name, value, note ?? "") as ksVariable
?? throw new InvalidOperationException("AddNewVariable вернул null (недопустимое имя?).");
if (external) v.external = true;
part.RebuildModel();
if (!part.RebuildModel())
throw new InvalidOperationException($"Не удалось применить создание переменной '{name}' (RebuildModel вернул FALSE).");
return ReadValueFresh(name); // значение перечитываем после перестроения
}, ct);
@@ -53,7 +54,9 @@ public sealed class VariableService
var (part, vc) = RootVariables();
var v = RequireVariable(vc, name);
v.Expression = expression;
part.RebuildModel();
if (!part.RebuildModel())
throw new InvalidOperationException(
$"Не удалось пересчитать модель с выражением «{expression}» для '{name}' (недопустимое выражение или ссылка на несуществующую переменную?).");
return ReadValueFresh(name); // переменную перечитываем после перестроения (value пересчитан)
}, ct);
@@ -65,8 +68,10 @@ public sealed class VariableService
var (part, vc) = RootVariables();
RequireVariable(vc, name); // понятная ошибка, если её нет
if (!vc.RemoveVariable(name))
throw new InvalidOperationException($"Не удалось удалить переменную '{name}'.");
part.RebuildModel();
throw new InvalidOperationException(
$"Не удалось удалить переменную '{name}' (возможно, на неё ссылаются другие переменные — удалите зависимые сначала).");
if (!part.RebuildModel())
throw new InvalidOperationException($"Не удалось применить удаление переменной '{name}' (RebuildModel вернул FALSE).");
}, ct);
/// <summary>Прочитать текущее (вычисленное) значение переменной.</summary>
+1 -1
View File
@@ -23,7 +23,7 @@ public sealed class VariableTools(KompasSession session, VariableService variabl
}
[McpServerTool(Name = "set_variable")]
[Description("Задать выражение существующей переменной: константа (например «30») или формула со ссылками на другие переменные (например «width*2+5»). Модель перестраивается, значение пересчитывается. Возвращает вычисленное значение.")]
[Description("Задать выражение существующей переменной: константа (например «30») или формула со ссылками на другие переменные (например «width*2+5»). Модель перестраивается, значение пересчитывается. Десятичный разделитель — точка. Примечание: изменит геометрию только в параметрической модели (где размеры эскизов связаны с именами переменных); для моделей с литеральными размерами значение пересчитается, но геометрия не изменится. Возвращает вычисленное значение.")]
public async Task<string> SetVariable(
string name,
[Description("Выражение: число или формула (width*2+5)")] string expression)
@@ -48,11 +48,21 @@ public sealed class VariableTests
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");