feat: drawing_add_linear_dimension — упрочнение по ревью Codex реализации
#4: отклонение нулевого NominalValue после Update (ориентация несовместима с точками, напр. horizontal на вертикали |X2-X1|=0) — откат dim.Delete + ошибка. #3: Parallel протестирован — работает БЕЗ явного Angle (КОМПАС авто-вычисляет угол по точкам; (0,0)-(30,40)→50). #7: rollback-ветка покрыта тестом нулевой проекции. #8: контракт «первый несистемный вид» — осознанный (задокументирован). Тесты: DrawingDimensionTests 5→7 (+parallel, +нулевая проекция/откат). Итого 131 unit + 72 integration = 203. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,19 @@
|
|||||||
# Дизайн: линейный размер на виде чертежа (drawing_add_linear_dimension) через API7
|
# Дизайн: линейный размер на виде чертежа (drawing_add_linear_dimension) через API7
|
||||||
|
|
||||||
**Дата:** 2026-05-27
|
**Дата:** 2026-05-27
|
||||||
**Статус:** реализовано и проверено (5 интеграционных + unit, всего 201); ревью Codex спека учтено
|
**Статус:** реализовано и проверено (7 интеграционных + unit, всего 203); ревью Codex спека и реализации учтено
|
||||||
|
|
||||||
|
## Правки по ревью реализации Codex
|
||||||
|
|
||||||
|
- **#4 нулевое значение** (важно): после `Update`+`Valid` проверяем `|NominalValue| > 1e-6` — ловит
|
||||||
|
несовместимость ориентации с точками (horizontal для точек на одной вертикали: `|X2-X1|=0`), которую
|
||||||
|
`RequireDistinctPoints` не видит. При нуле — откат (`dim.Delete`) + ошибка. Тест добавлен.
|
||||||
|
- **#3 Parallel** (важно): добавлен интеграционный тест — параллельный (0,0)-(30,40) → 50 (3-4-5).
|
||||||
|
**Работает БЕЗ явного `Angle`** (КОМПАС авто-вычисляет угол по точкам) — Parallel оставлен.
|
||||||
|
- **#7 rollback** (важно): тест нулевой проекции проходит через ветку `dim.Delete()` (откат) —
|
||||||
|
проверяет, что число размеров вида не изменилось. (Update==false/Valid==false без fault injection.)
|
||||||
|
- **#8 ассоциативность вида** (минор): осознанный контракт «первый НЕсистемный вид» (задокументирован
|
||||||
|
в описании инструмента и ошибке FindView).
|
||||||
|
|
||||||
## Находка реализации: размеры НЕ в IView.ObjectCount
|
## Находка реализации: размеры НЕ в IView.ObjectCount
|
||||||
|
|
||||||
|
|||||||
@@ -118,6 +118,12 @@ public sealed class DrawingService
|
|||||||
|
|
||||||
// NominalValue читаем ТОЛЬКО после успешного Update и Valid.
|
// NominalValue читаем ТОЛЬКО после успешного Update и Valid.
|
||||||
var value = ((IDimensionText)dim).NominalValue;
|
var value = ((IDimensionText)dim).NominalValue;
|
||||||
|
// Нулевое значение — ориентация несовместима с точками (напр. horizontal для точек на одной
|
||||||
|
// вертикали: |X2-X1|=0). RequireDistinctPoints это не ловит — точки различны по Y.
|
||||||
|
if (Math.Abs(value) < 1e-6)
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"Размер измерил нулевое значение — выбранная ориентация несовместима с точками " +
|
||||||
|
"(например, horizontal для точек на одной вертикали; используйте vertical/parallel).");
|
||||||
return new DrawingDimensionResult { Value = value, ViewNumber = view.Number };
|
return new DrawingDimensionResult { Value = value, ViewNumber = view.Number };
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -93,6 +93,43 @@ public sealed class DrawingDimensionTests : IntegrationTestBase
|
|||||||
finally { await _docs.CloseAsync(save: false); }
|
finally { await _docs.CloseAsync(save: false); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Parallel_dimension_measures_true_length()
|
||||||
|
{
|
||||||
|
var partFile = await BuildAndSaveBoxAsync();
|
||||||
|
await _docs.CreateAsync(KompasDocumentType.Drawing);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150);
|
||||||
|
// Параллельный размер (0,0)-(30,40): реальная длина = 50 (3-4-5).
|
||||||
|
var r = await _drawing.AddLinearDimensionAsync(
|
||||||
|
viewNumber: 0, x1: 0, y1: 0, x2: 30, y2: 40, x3: 25, y3: 5, DimensionOrientation.Parallel);
|
||||||
|
Assert.InRange(r.Value, 49.5, 50.5);
|
||||||
|
}
|
||||||
|
finally { await _docs.CloseAsync(save: false); }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Zero_projection_orientation_throws_and_rolls_back()
|
||||||
|
{
|
||||||
|
var partFile = await BuildAndSaveBoxAsync();
|
||||||
|
await _docs.CreateAsync(KompasDocumentType.Drawing);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150);
|
||||||
|
var before = await _drawing.GetViewLineDimensionCountAsync(0);
|
||||||
|
|
||||||
|
// Горизонтальный размер для точек на одной вертикали → |X2-X1|=0 → ошибка + откат.
|
||||||
|
await Assert.ThrowsAsync<InvalidOperationException>(() => _drawing.AddLinearDimensionAsync(
|
||||||
|
viewNumber: 0, x1: 10, y1: 0, x2: 10, y2: 30, x3: 0, y3: 15, DimensionOrientation.Horizontal));
|
||||||
|
|
||||||
|
// Откат: число размеров не изменилось (вырожденный размер удалён).
|
||||||
|
var after = await _drawing.GetViewLineDimensionCountAsync(0);
|
||||||
|
Assert.Equal(before, after);
|
||||||
|
}
|
||||||
|
finally { await _docs.CloseAsync(save: false); }
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task Coincident_points_throw()
|
public async Task Coincident_points_throw()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user