|
- using EnvelopeRenderer.Desktop.Core.Design;
-
- namespace EnvelopeRenderer.Desktop.Tests;
-
- public class CanvasElementEditorTests
- {
- // Fixed 20x10-point bounding box for every element, regardless of content — keeps hit-test
- // math deterministic without depending on real GDI text measurement.
- private static (double Width, double Height) FixedSize(TextElementLayout _) => (20.0, 10.0);
-
- private static CanvasElementEditor CreateEditor(out TemplateLayoutDocument document)
- {
- document = TemplateLayoutDocument.CreateDefault();
- return new CanvasElementEditor(document, FixedSize);
- }
-
- [Fact]
- public void AddStaticText_AddsToDocumentAndSelectsIt()
- {
- var editor = CreateEditor(out var document);
-
- var element = editor.AddStaticText(10, 20, "Hello");
-
- Assert.Single(document.Elements);
- Assert.Same(element, document.Elements[0]);
- Assert.Same(element, editor.Selected);
- Assert.Equal("Hello", element.StaticText);
- Assert.False(element.IsDynamic);
- }
-
- [Fact]
- public void AddDynamicPlaceholder_AddsToDocumentAndSelectsIt()
- {
- var editor = CreateEditor(out var document);
-
- var element = editor.AddDynamicPlaceholder(10, 20, "Full Name");
-
- Assert.Single(document.Elements);
- Assert.True(element.IsDynamic);
- Assert.Equal("Full Name", element.ColumnName);
- Assert.Same(element, editor.Selected);
- }
-
- [Fact]
- public void AddMultipleElements_AssignsIncreasingZOrder()
- {
- var editor = CreateEditor(out _);
-
- var first = editor.AddStaticText(0, 0, "A");
- var second = editor.AddDynamicPlaceholder(0, 0, "B");
- var third = editor.AddStaticText(0, 0, "C");
-
- Assert.Equal(0, first.ZOrder);
- Assert.Equal(1, second.ZOrder);
- Assert.Equal(2, third.ZOrder);
- }
-
- [Fact]
- public void HitTest_PointInsideElementBounds_ReturnsElement()
- {
- var editor = CreateEditor(out _);
- var element = editor.AddStaticText(100, 100, "Hello");
-
- var hit = editor.HitTest(105, 105); // inside [100,120] x [100,110]
-
- Assert.Same(element, hit);
- }
-
- [Fact]
- public void HitTest_PointOutsideElementBounds_ReturnsNull()
- {
- var editor = CreateEditor(out _);
- editor.AddStaticText(100, 100, "Hello");
-
- var hit = editor.HitTest(0, 0);
-
- Assert.Null(hit);
- }
-
- [Fact]
- public void HitTest_OverlappingElements_ReturnsTopmostZOrder()
- {
- var editor = CreateEditor(out _);
- var bottom = editor.AddStaticText(100, 100, "Bottom");
- var top = editor.AddStaticText(100, 100, "Top"); // same bounds, added later -> higher z-order
-
- var hit = editor.HitTest(105, 105);
-
- Assert.Same(top, hit);
- Assert.NotSame(bottom, hit);
- }
-
- [Fact]
- public void TrySelectAt_Hit_SelectsAndReturnsTrue()
- {
- var editor = CreateEditor(out _);
- var element = editor.AddStaticText(100, 100, "Hello");
- editor.Select(null);
-
- var result = editor.TrySelectAt(105, 105);
-
- Assert.True(result);
- Assert.Same(element, editor.Selected);
- }
-
- [Fact]
- public void TrySelectAt_Miss_ClearsSelectionAndReturnsFalse()
- {
- var editor = CreateEditor(out _);
- editor.AddStaticText(100, 100, "Hello");
-
- var result = editor.TrySelectAt(0, 0);
-
- Assert.False(result);
- Assert.Null(editor.Selected);
- }
-
- [Fact]
- public void DragTo_MovesSelectedElementPreservingGrabOffset()
- {
- var editor = CreateEditor(out _);
- var element = editor.AddStaticText(100, 100, "Hello");
- editor.TrySelectAt(105, 105); // grab 5pt into the element from its origin
-
- editor.BeginDrag(105, 105);
- editor.DragTo(205, 155); // moved 100 right, 50 up
-
- Assert.Equal(200.0, element.X, precision: 6);
- Assert.Equal(150.0, element.Y, precision: 6);
- Assert.True(editor.IsDragging);
- }
-
- [Fact]
- public void EndDrag_StopsFurtherMovementFromDragTo()
- {
- var editor = CreateEditor(out _);
- var element = editor.AddStaticText(100, 100, "Hello");
- editor.TrySelectAt(105, 105);
- editor.BeginDrag(105, 105);
- editor.EndDrag();
-
- editor.DragTo(500, 500);
-
- Assert.Equal(100.0, element.X, precision: 6);
- Assert.Equal(100.0, element.Y, precision: 6);
- Assert.False(editor.IsDragging);
- }
-
- [Fact]
- public void DragTo_WithoutSelection_IsNoOp()
- {
- var editor = CreateEditor(out _);
-
- editor.DragTo(50, 50); // nothing selected, nothing dragging — should not throw
-
- Assert.Null(editor.Selected);
- }
-
- [Fact]
- public void Move_UpdatesTemplateLayoutDocumentInPlace_SoCanvasAndStoredStateAgree()
- {
- var editor = CreateEditor(out var document);
- var element = editor.AddStaticText(0, 0, "Hello");
-
- editor.TrySelectAt(10, 5);
- editor.BeginDrag(10, 5);
- editor.DragTo(60, 45);
-
- // The document's element list holds the same instance that was moved — no separate
- // "committed" copy step, so the canvas (reading from `document.Elements`) and this
- // editor's own state can never disagree.
- Assert.Same(element, document.Elements[0]);
- Assert.Equal(50.0, document.Elements[0].X, precision: 6);
- Assert.Equal(40.0, document.Elements[0].Y, precision: 6);
- }
- }
|