Files
kompas3d-mcp/tests/Kompas.Mcp.Tests/TextAlignsTests.cs
T
mikhail e127cebb49 Итерация 1: удаление операции, выравнивание надписи, отбор рёбер
По протоколу регресс-прогона (46 вызовов против 90 в прошлом):

feature_delete — ksDocument3D.DeleteObject + RebuildDocument, зависимые уходят каскадом.
Неудачная проба больше не требует пересобирать документ (у субагента таких кругов было три).

align/vAlign у примитива text: сервер строит, замеряет и сдвигает надпись сам. Ловушка,
стоившая двух заходов: ksMoveObj и ksDeleteObj по ссылке от ksConvertTextToCurve возвращают
успех и не делают ничего — двигать надо по ссылке ТЕКСТА, а габарит после сдвига считать
арифметикой (по текстовой ссылке рамка идёт по ячейке). Поймано тестом, который сверяет
заявленный габарит с выдавленной геометрией.

list_edges: отбор по типу и координатному окну + концы рёбер в списке. Так адресуется
нижний контур под фаску, который иначе не выбрать: индексов не отфильтровать, точек не угадать.

Навык: wf меряет пропорцию крупно (1.0→1.25 = +29 %), но квантован ступенями — точную ширину
набирают height; прирост каймы указан НА СТОРОНУ и зависит от начертания, а не от шрифта;
добавлено предупреждение, что primitive(subtract) режет наехавшие буквы.
2026-07-31 17:11:53 +03:00

72 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Kompas.Mcp.Core.Modeling;
namespace Kompas.Mcp.Tests;
/// <summary>
/// Выравнивание надписи. КОМПАС кладёт строку только вправо-вверх от точки вставки, поэтому
/// «по центру» — это пересчёт по фактическому габариту глифов; раньше его делал агент отдельным
/// кругом «вставил → замерил → пересобрал».
/// </summary>
[Trait("Category", "Unit")]
public sealed class TextAlignsTests
{
[Theory]
[InlineData(null, TextAlign.Left)]
[InlineData("", TextAlign.Left)]
[InlineData("left", TextAlign.Left)]
[InlineData("CENTER", TextAlign.Center)]
[InlineData(" centre ", TextAlign.Center)]
[InlineData("right", TextAlign.Right)]
public void Horizontal_alignment_is_parsed(string? value, TextAlign expected)
=> Assert.Equal(expected, TextAligns.Parse(value));
[Theory]
[InlineData(null, TextVAlign.Baseline)]
[InlineData("bottom", TextVAlign.Bottom)]
[InlineData("middle", TextVAlign.Middle)]
[InlineData("top", TextVAlign.Top)]
public void Vertical_alignment_is_parsed(string? value, TextVAlign expected)
=> Assert.Equal(expected, TextAligns.ParseVertical(value));
[Fact]
public void Unknown_alignment_lists_the_allowed_values()
{
var ex = Assert.Throws<ArgumentException>(() => TextAligns.Parse("justify"));
Assert.Contains("left", ex.Message, StringComparison.Ordinal);
Assert.Contains("center", ex.Message, StringComparison.Ordinal);
}
[Fact]
public void Centering_moves_the_box_middle_onto_the_anchor()
{
// Глифы легли на 10…30 (середина 20), якорь — 0: сдвиг −20.
var (dx, dy) = TextAligns.Offset((10, 0, 30, 12), (0, 0), TextAlign.Center, TextVAlign.Baseline);
Assert.Equal(-20, dx, 9);
Assert.Equal(0, dy, 9);
}
[Fact]
public void Right_alignment_puts_the_box_end_onto_the_anchor()
{
var (dx, _) = TextAligns.Offset((10, 0, 30, 12), (90, 0), TextAlign.Right, TextVAlign.Baseline);
Assert.Equal(60, dx, 9); // 90 30
}
[Fact]
public void Vertical_middle_uses_the_glyph_box_not_the_baseline()
{
// Выносные ушли ниже базовой линии: габарит −3…12, середина 4.5.
var (_, dy) = TextAligns.Offset((0, -3, 20, 12), (0, 0), TextAlign.Left, TextVAlign.Middle);
Assert.Equal(-4.5, dy, 9);
}
[Fact]
public void Left_baseline_is_a_no_op()
{
var (dx, dy) = TextAligns.Offset((10, -3, 30, 12), (5, 7), TextAlign.Left, TextVAlign.Baseline);
Assert.Equal(0, dx, 9);
Assert.Equal(0, dy, 9);
}
}