107 lines
3.7 KiB
C#
107 lines
3.7 KiB
C#
using CursorLang.Core.Interop;
|
|
using CursorLang.Tests.Shared;
|
|
|
|
namespace CursorLang.Core.Tests.Interop;
|
|
|
|
/// <summary>
|
|
/// Vetting the caret position. Some applications report it in their own
|
|
/// coordinate system, and such answers have to be sifted out by the bounds
|
|
/// of the input window.
|
|
/// </summary>
|
|
public sealed class CaretNativeTests
|
|
{
|
|
private static readonly PopupWindowNative.Rect Window = new()
|
|
{
|
|
Left = 100,
|
|
Top = 100,
|
|
Right = 900,
|
|
Bottom = 700,
|
|
};
|
|
|
|
[Fact]
|
|
public void A_caret_inside_the_window_is_taken_as_is()
|
|
{
|
|
var caret = new PopupWindowNative.Rect { Left = 200, Top = 300, Right = 202, Bottom = 320 };
|
|
|
|
Assert.Equal(caret, CaretNative.Validate(caret, Window, scale: 1.5));
|
|
}
|
|
|
|
// The application reported the coordinates without the screen scale: on
|
|
// their own they sit above and to the left of the input window, and after
|
|
// being brought to the scale they land inside it
|
|
[Fact]
|
|
public void An_unscaled_caret_is_brought_to_the_screen_scale()
|
|
{
|
|
var caret = new PopupWindowNative.Rect { Left = 80, Top = 80, Right = 81, Bottom = 90 };
|
|
|
|
PopupWindowNative.Rect? validated = CaretNative.Validate(caret, Window, scale: 1.5);
|
|
|
|
Assert.NotNull(validated);
|
|
Assert.Equal(120, validated.Value.Left);
|
|
Assert.Equal(120, validated.Value.Top);
|
|
Assert.Equal(121, validated.Value.Right);
|
|
Assert.Equal(135, validated.Value.Bottom);
|
|
}
|
|
|
|
[Fact]
|
|
public void A_caret_far_from_the_window_is_discarded()
|
|
{
|
|
var caret = new PopupWindowNative.Rect { Left = 5000, Top = 5000, Right = 5002, Bottom = 5020 };
|
|
|
|
Assert.Null(CaretNative.Validate(caret, Window, scale: 1.5));
|
|
}
|
|
|
|
// At the ordinary scale there is nothing to fix: wrong coordinates stay wrong
|
|
[Fact]
|
|
public void At_scale_one_a_caret_outside_the_window_is_discarded()
|
|
{
|
|
var caret = new PopupWindowNative.Rect { Left = 10, Top = 10, Right = 12, Bottom = 30 };
|
|
|
|
Assert.Null(CaretNative.Validate(caret, Window, scale: 1.0));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(100, 100, 900, 700, true)]
|
|
[InlineData(99, 100, 900, 700, false)]
|
|
[InlineData(100, 99, 900, 700, false)]
|
|
[InlineData(100, 100, 901, 700, false)]
|
|
[InlineData(100, 100, 900, 701, false)]
|
|
[InlineData(400, 400, 402, 420, true)]
|
|
public void Inside_the_window_means_entirely_inside(
|
|
int left, int top, int right, int bottom, bool expected)
|
|
{
|
|
var caret = new PopupWindowNative.Rect { Left = left, Top = top, Right = right, Bottom = bottom };
|
|
|
|
Assert.Equal(expected, CaretNative.IsInside(caret, Window));
|
|
}
|
|
|
|
// When there is no caret, its rectangle comes back with zero height. Zero
|
|
// coordinates, on the other hand, are the ordinary start of an empty field
|
|
[Theory]
|
|
[InlineData(0, 0, 0, 0, true)]
|
|
[InlineData(0, 0, 2, 0, true)]
|
|
[InlineData(0, 10, 2, 5, true)]
|
|
[InlineData(0, 0, 0, 1, false)]
|
|
[InlineData(0, 0, 0, 20, false)]
|
|
public void A_caret_without_height_counts_as_empty(
|
|
int left, int top, int right, int bottom, bool expected)
|
|
{
|
|
var rect = new PopupWindowNative.Rect { Left = left, Top = top, Right = right, Bottom = bottom };
|
|
|
|
Assert.Equal(expected, CaretNative.IsEmpty(rect));
|
|
}
|
|
|
|
// The answer depends on what is on screen right now, but it has no right to
|
|
// throw: the tooltip is shown whatever the answer
|
|
[Fact]
|
|
public void Asking_the_system_for_the_caret_goes_without_errors()
|
|
{
|
|
PopupWindowNative.Rect? caret = Pump.Run(CaretNative.TryGetCaretRect);
|
|
|
|
if (caret is not null)
|
|
{
|
|
Assert.True(caret.Value.Bottom > caret.Value.Top);
|
|
}
|
|
}
|
|
}
|