using SheetMe.Core.Layout;
namespace SheetMe.Core.Tests;
///
/// 정렬 산술 고정 — 특히 반올림 방향.
///
/// 반올림은 눈에 안 띄는 채로 틀린다. 폭 75 짜리를 폭 720 용지 가운데 두면 목표가 정확히 322.5 인데,
/// .NET 기본 반올림(ToEven)은 322 로 내리고 323.5 는 324 로 올린다 — 폭이 제각각인 라벨 다섯 개를
/// 가운데 맞춤하면 어떤 건 322, 어떤 건 323 에 앉아 한 픽셀씩 어긋난다.
///
[TestClass]
public sealed class AlignSolverTests
{
#region Member Fields
private static readonly SnapRect Page = new(0, 0, 720, 856);
/// 둘째 장 — 월드 원점이 0 이 아닌 기준
private static readonly SnapRect SecondPage = new(0, 884, 720, 856);
#endregion
#region Methods
[TestMethod]
public void 좌우_모서리에_맞춘다()
{
var item = new SnapRect(10, 10, 50, 20);
Assert.AreEqual(0, AlignSolver.Apply(item, Page, AlignMode.Left).X, 1e-9);
Assert.AreEqual(670, AlignSolver.Apply(item, Page, AlignMode.Right).X, 1e-9);
Assert.AreEqual(335, AlignSolver.Apply(item, Page, AlignMode.CenterH).X, 1e-9);
}
[TestMethod]
public void 위아래_모서리에_맞춘다()
{
var item = new SnapRect(10, 10, 50, 20);
Assert.AreEqual(0, AlignSolver.Apply(item, Page, AlignMode.Top).Y, 1e-9);
Assert.AreEqual(836, AlignSolver.Apply(item, Page, AlignMode.Bottom).Y, 1e-9);
Assert.AreEqual(418, AlignSolver.Apply(item, Page, AlignMode.CenterV).Y, 1e-9);
}
[TestMethod]
public void 반정수_중심은_바깥쪽으로_올린다()
{
// (720 − 75) / 2 = 322.5 — 기본 반올림(ToEven)이면 322 가 나온다
var odd = new SnapRect(0, 0, 75, 20);
Assert.AreEqual(323, AlignSolver.Apply(odd, Page, AlignMode.CenterH).X, 1e-9);
// (100 − 51) / 2 = 24.5 — ToEven 이면 24
var narrow = new SnapRect(0, 0, 51, 20);
Assert.AreEqual(25, AlignSolver.Apply(narrow, new SnapRect(0, 0, 100, 100), AlignMode.CenterH).X, 1e-9);
}
[TestMethod]
public void 두_번_맞춰도_같은_자리다()
{
var item = new SnapRect(13, 7, 75, 20);
var once = AlignSolver.Apply(item, Page, AlignMode.CenterH);
var twice = AlignSolver.Apply(once, Page, AlignMode.CenterH);
Assert.AreEqual(once.X, twice.X, 1e-9, "기준이 고정이면 두 번째 호출이 자리를 바꿀 이유가 없다");
}
[TestMethod]
public void 기준보다_넓으면_음수가_나오고_그게_맞다()
{
var wide = new SnapRect(0, 0, 800, 20);
Assert.AreEqual(-40, AlignSolver.Apply(wide, Page, AlignMode.CenterH).X, 1e-9,
"가운데에 두려면 그래야 한다 — 여기서 잘라 붙이면 가운데가 아니게 된다");
}
[TestMethod]
public void 크기가_0_이어도_터지지_않는다()
{
var empty = new SnapRect(300, 300, 0, 0);
Assert.AreEqual(0, AlignSolver.Apply(empty, Page, AlignMode.Left).X, 1e-9);
Assert.AreEqual(720, AlignSolver.Apply(empty, Page, AlignMode.Right).X, 1e-9);
}
[TestMethod]
public void 둘째_장에서도_그_장의_좌표로_맞춘다()
{
var item = new SnapRect(10, 1000, 50, 20);
Assert.AreEqual(884, AlignSolver.Apply(item, SecondPage, AlignMode.Top).Y, 1e-9);
Assert.AreEqual(1720, AlignSolver.Apply(item, SecondPage, AlignMode.Bottom).Y, 1e-9);
}
[TestMethod]
public void 맞추지_않는_축은_건드리지_않는다()
{
var item = new SnapRect(13, 77, 50, 20);
var moved = AlignSolver.Apply(item, Page, AlignMode.Left);
Assert.AreEqual(77, moved.Y, 1e-9);
Assert.AreEqual(50, moved.W, 1e-9);
Assert.AreEqual(20, moved.H, 1e-9);
}
[TestMethod]
public void 명령_문자열을_방향으로_읽는다()
{
Assert.AreEqual(AlignMode.Left, AlignSolver.Parse("Left"));
Assert.AreEqual(AlignMode.CenterV, AlignSolver.Parse("CenterV"));
Assert.IsNull(AlignSolver.Parse("Sideways"), "모르는 값은 null — 호출부가 아무 일도 하지 않는다");
Assert.IsNull(AlignSolver.Parse(string.Empty));
}
[TestMethod]
public void 세로_축을_가려낸다()
{
// 여러 페이지에 걸친 선택에서 거부해야 할 것들 — 다른 종이의 '위 맞춤'에는 뜻이 없다
Assert.IsTrue(AlignSolver.IsVertical(AlignMode.Top));
Assert.IsTrue(AlignSolver.IsVertical(AlignMode.CenterV));
Assert.IsTrue(AlignSolver.IsVertical(AlignMode.Bottom));
Assert.IsFalse(AlignSolver.IsVertical(AlignMode.Left));
Assert.IsFalse(AlignSolver.IsVertical(AlignMode.CenterH));
Assert.IsFalse(AlignSolver.IsVertical(AlignMode.Right));
}
#endregion
}