Files
cursor-lang/CursorLang.Core.Tests/Services/PopupLayoutTests.cs
T
alex 55ac8e6556 lightweight variant (#1)
Reviewed-on: #1
Co-authored-by: Aleksandr Neychev <alexnejchev73@gmail.com>
2026-08-12 13:37:30 +00:00

230 lines
7.9 KiB
C#

using CursorLang.Core.Interop;
using CursorLang.Core.Models;
using CursorLang.Core.Services;
namespace CursorLang.Core.Tests.Services;
/// <summary>
/// The placement maths for the tooltip. This is the easiest place to get a sign
/// or half a size wrong, and on screen such a mistake is only visible by eye.
/// </summary>
public sealed class PopupLayoutTests
{
// The anchor: 100..140 horizontally, 200..220 vertically
private static readonly PopupWindowNative.Rect Anchor = new()
{
Left = 100,
Top = 200,
Right = 140,
Bottom = 220,
};
private const int Offset = 10;
private const int Width = 30;
private const int Height = 16;
[Fact]
public void Bottom_right_offsets_the_tooltip_from_the_bottom_right_corner()
{
PopupWindowNative.Point point = Near(AnchorSide.BottomRight);
Assert.Equal(140 + 10, point.X);
Assert.Equal(220 + 10, point.Y);
}
[Fact]
public void Bottom_left_fits_the_tooltip_to_the_left_of_the_anchor()
{
PopupWindowNative.Point point = Near(AnchorSide.BottomLeft);
Assert.Equal(100 - 10 - Width, point.X);
Assert.Equal(220 + 10, point.Y);
}
[Fact]
public void Top_right_fits_the_tooltip_above_the_anchor()
{
PopupWindowNative.Point point = Near(AnchorSide.TopRight);
Assert.Equal(140 + 10, point.X);
Assert.Equal(200 - 10 - Height, point.Y);
}
[Fact]
public void Top_left_fits_the_tooltip_both_left_of_and_above_the_anchor()
{
PopupWindowNative.Point point = Near(AnchorSide.TopLeft);
Assert.Equal(100 - 10 - Width, point.X);
Assert.Equal(200 - 10 - Height, point.Y);
}
// At the sides the tooltip lines up with the middle of the anchor
[Fact]
public void On_the_right_the_tooltip_lines_up_with_the_anchor()
{
PopupWindowNative.Point point = Near(AnchorSide.Right);
Assert.Equal(140 + 10, point.X);
Assert.Equal(200 + ((20 - Height) / 2), point.Y);
}
[Fact]
public void On_the_left_the_tooltip_lines_up_with_the_anchor()
{
PopupWindowNative.Point point = Near(AnchorSide.Left);
Assert.Equal(100 - 10 - Width, point.X);
Assert.Equal(200 + ((20 - Height) / 2), point.Y);
}
// A tooltip taller than the input field: the middle is measured from the
// anchor, not from zero
[Fact]
public void At_the_side_a_tooltip_taller_than_the_anchor_rises_above_it()
{
PopupWindowNative.Point point =
PopupLayout.NearAnchor(Anchor, AnchorSide.Right, Offset, Width, height: 40);
Assert.Equal(200 + ((20 - 40) / 2), point.Y);
Assert.True(point.Y < Anchor.Top);
}
[Fact]
public void The_cursor_anchors_as_a_rectangle_of_zero_size()
{
PopupWindowNative.Rect anchor = PopupLayout.AsAnchor(new PopupWindowNative.Point { X = 50, Y = 60 });
Assert.Equal(50, anchor.Left);
Assert.Equal(50, anchor.Right);
Assert.Equal(60, anchor.Top);
Assert.Equal(60, anchor.Bottom);
}
[Fact]
public void At_the_cursor_both_sides_are_measured_from_the_same_point()
{
PopupWindowNative.Rect cursor = PopupLayout.AsAnchor(new PopupWindowNative.Point { X = 50, Y = 60 });
PopupWindowNative.Point bottomRight =
PopupLayout.NearAnchor(cursor, AnchorSide.BottomRight, Offset, Width, Height);
PopupWindowNative.Point topLeft =
PopupLayout.NearAnchor(cursor, AnchorSide.TopLeft, Offset, Width, Height);
Assert.Equal(60, bottomRight.X);
Assert.Equal(70, bottomRight.Y);
Assert.Equal(50 - 10 - Width, topLeft.X);
Assert.Equal(60 - 10 - Height, topLeft.Y);
}
// A monitor to the left of the primary one gives negative coordinates — that is normal
[Fact]
public void Negative_coordinates_of_a_neighbouring_monitor_are_allowed()
{
var anchor = new PopupWindowNative.Rect { Left = -800, Top = -200, Right = -800, Bottom = -200 };
PopupWindowNative.Point point =
PopupLayout.NearAnchor(anchor, AnchorSide.BottomRight, Offset, Width, Height);
Assert.Equal(-790, point.X);
Assert.Equal(-190, point.Y);
}
[Fact]
public void A_zero_offset_puts_the_tooltip_flush_against_the_anchor()
{
PopupWindowNative.Point point =
PopupLayout.NearAnchor(Anchor, AnchorSide.BottomRight, offset: 0, Width, Height);
Assert.Equal(Anchor.Right, point.X);
Assert.Equal(Anchor.Bottom, point.Y);
}
[Theory]
[InlineData(AnchorSide.TopLeft)]
[InlineData(AnchorSide.TopRight)]
[InlineData(AnchorSide.Left)]
[InlineData(AnchorSide.Right)]
[InlineData(AnchorSide.BottomLeft)]
[InlineData(AnchorSide.BottomRight)]
public void No_side_is_left_behind(AnchorSide side)
{
// The sides are handled by a switch expression with a fallback branch:
// each of them has to get its own place, not the shared "bottom right"
PopupWindowNative.Point point = Near(side);
PopupWindowNative.Point bottomRight = Near(AnchorSide.BottomRight);
if (side != AnchorSide.BottomRight)
{
Assert.True(point.X != bottomRight.X || point.Y != bottomRight.Y);
}
}
public static TheoryData<ScreenPosition, int, int> ScreenCases() => new()
{
// A work area of 0..1000 horizontally and 0..800 vertically, margin 20
{ ScreenPosition.TopLeft, 20, 20 },
{ ScreenPosition.Top, (1000 - Width) / 2, 20 },
{ ScreenPosition.TopRight, 1000 - 20 - Width, 20 },
{ ScreenPosition.Center, (1000 - Width) / 2, (800 - Height) / 2 },
{ ScreenPosition.BottomLeft, 20, 800 - 20 - Height },
{ ScreenPosition.Bottom, (1000 - Width) / 2, 800 - 20 - Height },
{ ScreenPosition.BottomRight, 1000 - 20 - Width, 800 - 20 - Height },
};
[Theory]
[MemberData(nameof(ScreenCases))]
public void The_place_on_the_monitor_is_measured_from_the_work_area(
ScreenPosition position, int expectedX, int expectedY)
{
var work = new PopupWindowNative.Rect { Left = 0, Top = 0, Right = 1000, Bottom = 800 };
PopupWindowNative.Point point = PopupLayout.OnScreen(work, position, margin: 20, Width, Height);
Assert.Equal(expectedX, point.X);
Assert.Equal(expectedY, point.Y);
}
// The work area of a second monitor does not start at zero, and the taskbar
// takes its bottom away — the place is measured from those bounds
[Fact]
public void The_place_on_a_neighbouring_monitor_is_measured_from_its_own_bounds()
{
var work = new PopupWindowNative.Rect { Left = 1920, Top = 0, Right = 3520, Bottom = 860 };
PopupWindowNative.Point point =
PopupLayout.OnScreen(work, ScreenPosition.BottomRight, margin: 20, Width, Height);
Assert.Equal(3520 - 20 - Width, point.X);
Assert.Equal(860 - 20 - Height, point.Y);
}
[Fact]
public void In_the_centre_of_the_monitor_the_margin_is_ignored()
{
var work = new PopupWindowNative.Rect { Left = 0, Top = 0, Right = 1000, Bottom = 800 };
PopupWindowNative.Point withMargin = PopupLayout.OnScreen(work, ScreenPosition.Center, 20, Width, Height);
PopupWindowNative.Point withoutMargin = PopupLayout.OnScreen(work, ScreenPosition.Center, 0, Width, Height);
Assert.Equal(withoutMargin.X, withMargin.X);
Assert.Equal(withoutMargin.Y, withMargin.Y);
}
private static PopupWindowNative.Point Near(AnchorSide side) =>
PopupLayout.NearAnchor(Anchor, side, Offset, Width, Height);
[Theory]
[InlineData(16, 1.0, 16)]
[InlineData(16, 1.25, 20)]
[InlineData(16, 1.5, 24)]
[InlineData(16, 2.0, 32)]
[InlineData(0, 2.0, 0)]
[InlineData(20.4, 1.0, 20)]
[InlineData(20.6, 1.0, 21)]
public void WPF_units_turn_into_pixels_by_the_scale(double units, double scale, int expected)
{
Assert.Equal(expected, PopupLayout.ToPixels(units, scale));
}
}