Skip to content

Commit

Permalink
[MouseJump] cleaning up Tests / NativeMethods (microsoft#27511)
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeclayton committed Oct 18, 2023
1 parent 1b333df commit b8ecf53
Show file tree
Hide file tree
Showing 19 changed files with 134 additions and 98 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ public TestCase(PointInfo previewLocation, SizeInfo previewSize, RectangleInfo
this.ExpectedResult = expectedResult;
}

public PointInfo PreviewLocation { get; set; }
public PointInfo PreviewLocation { get; }

public SizeInfo PreviewSize { get; set; }
public SizeInfo PreviewSize { get; }

public RectangleInfo DesktopBounds { get; set; }
public RectangleInfo DesktopBounds { get; }

public PointInfo ExpectedResult { get; set; }
public PointInfo ExpectedResult { get; }
}

public static IEnumerable<object[]> GetTestCases()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,30 +23,30 @@ public TestCase(RectangleInfo rectangle, PointInfo point, RectangleInfo expected
this.ExpectedResult = expectedResult;
}

public RectangleInfo Rectangle { get; set; }
public RectangleInfo Rectangle { get; }

public PointInfo Point { get; set; }
public PointInfo Point { get; }

public RectangleInfo ExpectedResult { get; set; }
public RectangleInfo ExpectedResult { get; }
}

public static IEnumerable<object[]> GetTestCases()
{
// zero-sized
yield return new[] { new TestCase(new(0, 0, 0, 0), new(0, 0), new(0, 0, 0, 0)), };
yield return new object[] { new TestCase(new(0, 0, 0, 0), new(0, 0), new(0, 0, 0, 0)), };

// zero-origin
yield return new[] { new TestCase(new(0, 0, 200, 200), new(100, 100), new(0, 0, 200, 200)), };
yield return new[] { new TestCase(new(0, 0, 200, 200), new(500, 500), new(400, 400, 200, 200)), };
yield return new[] { new TestCase(new(0, 0, 800, 600), new(1000, 1000), new(600, 700, 800, 600)), };
yield return new object[] { new TestCase(new(0, 0, 200, 200), new(100, 100), new(0, 0, 200, 200)), };
yield return new object[] { new TestCase(new(0, 0, 200, 200), new(500, 500), new(400, 400, 200, 200)), };
yield return new object[] { new TestCase(new(0, 0, 800, 600), new(1000, 1000), new(600, 700, 800, 600)), };

// non-zero origin
yield return new[] { new TestCase(new(1000, 2000, 200, 200), new(100, 100), new(0, 0, 200, 200)), };
yield return new[] { new TestCase(new(1000, 2000, 200, 200), new(500, 500), new(400, 400, 200, 200)), };
yield return new[] { new TestCase(new(1000, 2000, 800, 600), new(1000, 1000), new(600, 700, 800, 600)), };
yield return new object[] { new TestCase(new(1000, 2000, 200, 200), new(100, 100), new(0, 0, 200, 200)), };
yield return new object[] { new TestCase(new(1000, 2000, 200, 200), new(500, 500), new(400, 400, 200, 200)), };
yield return new object[] { new TestCase(new(1000, 2000, 800, 600), new(1000, 1000), new(600, 700, 800, 600)), };

// negative result
yield return new[] { new TestCase(new(0, 0, 1000, 1200), new(300, 300), new(-200, -300, 1000, 1200)), };
yield return new object[] { new TestCase(new(0, 0, 1000, 1200), new(300, 300), new(-200, -300, 1000, 1200)), };
}

[TestMethod]
Expand Down Expand Up @@ -74,53 +74,53 @@ public TestCase(RectangleInfo inner, RectangleInfo outer, RectangleInfo expected
this.ExpectedResult = expectedResult;
}

public RectangleInfo Inner { get; set; }
public RectangleInfo Inner { get; }

public RectangleInfo Outer { get; set; }
public RectangleInfo Outer { get; }

public RectangleInfo ExpectedResult { get; set; }
public RectangleInfo ExpectedResult { get; }
}

public static IEnumerable<object[]> GetTestCases()
{
// already inside - obj fills bounds exactly
yield return new[]
yield return new object[]
{
new TestCase(new(0, 0, 100, 100), new(0, 0, 100, 100), new(0, 0, 100, 100)),
};

// already inside - obj exactly in each corner
yield return new[]
yield return new object[]
{
new TestCase(new(0, 0, 100, 100), new(0, 0, 200, 200), new(0, 0, 100, 100)),
};
yield return new[]
yield return new object[]
{
new TestCase(new(100, 0, 100, 100), new(0, 0, 200, 200), new(100, 0, 100, 100)),
};
yield return new[]
yield return new object[]
{
new TestCase(new(0, 100, 100, 100), new(0, 0, 200, 200), new(0, 100, 100, 100)),
};
yield return new[]
yield return new object[]
{
new TestCase(new(100, 100, 100, 100), new(0, 0, 200, 200), new(100, 100, 100, 100)),
};

// move inside - obj outside each corner
yield return new[]
yield return new object[]
{
new TestCase(new(-50, -50, 100, 100), new(0, 0, 200, 200), new(0, 0, 100, 100)),
};
yield return new[]
yield return new object[]
{
new TestCase(new(250, -50, 100, 100), new(0, 0, 200, 200), new(100, 0, 100, 100)),
};
yield return new[]
yield return new object[]
{
new TestCase(new(-50, 250, 100, 100), new(0, 0, 200, 200), new(0, 100, 100, 100)),
};
yield return new[]
yield return new object[]
{
new TestCase(new(150, 150, 100, 100), new(0, 0, 200, 200), new(100, 100, 100, 100)),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@ public TestCase(SizeInfo obj, SizeInfo bounds, SizeInfo expectedResult)
this.ExpectedResult = expectedResult;
}

public SizeInfo Obj { get; set; }
public SizeInfo Obj { get; }

public SizeInfo Bounds { get; set; }
public SizeInfo Bounds { get; }

public SizeInfo ExpectedResult { get; set; }
public SizeInfo ExpectedResult { get; }
}

public static IEnumerable<object[]> GetTestCases()
{
// identity tests
yield return new[] { new TestCase(new(512, 384), new(512, 384), new(512, 384)), };
yield return new[] { new TestCase(new(1024, 768), new(1024, 768), new(1024, 768)), };
yield return new object[] { new TestCase(new(512, 384), new(512, 384), new(512, 384)), };
yield return new object[] { new TestCase(new(1024, 768), new(1024, 768), new(1024, 768)), };

// general tests
yield return new[] { new TestCase(new(512, 384), new(2048, 1536), new(2048, 1536)), };
yield return new[] { new TestCase(new(2048, 1536), new(1024, 768), new(1024, 768)), };
yield return new object[] { new TestCase(new(512, 384), new(2048, 1536), new(2048, 1536)), };
yield return new object[] { new TestCase(new(2048, 1536), new(1024, 768), new(1024, 768)), };

// scale to fit width
yield return new[] { new TestCase(new(512, 384), new(2048, 3072), new(2048, 1536)), };
yield return new object[] { new TestCase(new(512, 384), new(2048, 3072), new(2048, 1536)), };

// scale to fit height
yield return new[] { new TestCase(new(512, 384), new(4096, 1536), new(2048, 1536)), };
yield return new object[] { new TestCase(new(512, 384), new(4096, 1536), new(2048, 1536)), };
}

[TestMethod]
Expand All @@ -70,28 +70,28 @@ public TestCase(SizeInfo obj, SizeInfo bounds, decimal expectedResult)
this.ExpectedResult = expectedResult;
}

public SizeInfo Obj { get; set; }
public SizeInfo Obj { get; }

public SizeInfo Bounds { get; set; }
public SizeInfo Bounds { get; }

public decimal ExpectedResult { get; set; }
public decimal ExpectedResult { get; }
}

public static IEnumerable<object[]> GetTestCases()
{
// identity tests
yield return new[] { new TestCase(new(512, 384), new(512, 384), 1), };
yield return new[] { new TestCase(new(1024, 768), new(1024, 768), 1), };
yield return new object[] { new TestCase(new(512, 384), new(512, 384), 1), };
yield return new object[] { new TestCase(new(1024, 768), new(1024, 768), 1), };

// general tests
yield return new[] { new TestCase(new(512, 384), new(2048, 1536), 4), };
yield return new[] { new TestCase(new(2048, 1536), new(1024, 768), 0.5M), };
yield return new object[] { new TestCase(new(512, 384), new(2048, 1536), 4), };
yield return new object[] { new TestCase(new(2048, 1536), new(1024, 768), 0.5M), };

// scale to fit width
yield return new[] { new TestCase(new(512, 384), new(2048, 3072), 4), };
yield return new object[] { new TestCase(new(512, 384), new(2048, 3072), 4), };

// scale to fit height
yield return new[] { new TestCase(new(512, 384), new(4096, 1536), 4), };
yield return new object[] { new TestCase(new(512, 384), new(4096, 1536), 4), };
}

[TestMethod]
Expand Down
12 changes: 9 additions & 3 deletions src/modules/MouseUtils/MouseJumpUI/Helpers/MouseHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,21 @@ public static void SetCursorPosition(PointInfo location)
//
// setting the position a second time seems to fix this and moves the
// cursor to the expected location (b)
var point = location.ToPoint();
var target = location.ToPoint();
for (var i = 0; i < 2; i++)
{
var result = User32.SetCursorPos(point.X, point.Y);
var result = User32.SetCursorPos(target.X, target.Y);
if (!result)
{
throw new Win32Exception(
Marshal.GetLastWin32Error());
}

var current = MouseHelper.GetCursorPosition();
if ((current.X == target.X) && (current.Y == target.Y))
{
break;
}
}

// temporary workaround for issue #1273
Expand Down Expand Up @@ -128,7 +134,7 @@ private static decimal CalculateAbsoluteCoordinateX(decimal x)
return (x * 65535) / User32.GetSystemMetrics(User32.SYSTEM_METRICS_INDEX.SM_CXSCREEN);
}

internal static decimal CalculateAbsoluteCoordinateY(decimal y)
private static decimal CalculateAbsoluteCoordinateY(decimal y)
{
// If MOUSEEVENTF_ABSOLUTE value is specified, dx and dy contain normalized absolute coordinates between 0 and 65,535.
// see https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput
Expand Down
10 changes: 5 additions & 5 deletions src/modules/MouseUtils/MouseJumpUI/Models/Drawing/PointInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,17 @@ public decimal Y
get;
}

public SizeInfo ToSize()
{
return new((int)this.X, (int)this.Y);
}

public PointInfo Scale(decimal scalingFactor) => new(this.X * scalingFactor, this.Y * scalingFactor);

public PointInfo Offset(PointInfo amount) => new(this.X + amount.X, this.Y + amount.Y);

public Point ToPoint() => new((int)this.X, (int)this.Y);

public SizeInfo ToSize()
{
return new((int)this.X, (int)this.Y);
}

public override string ToString()
{
return "{" +
Expand Down
64 changes: 35 additions & 29 deletions src/modules/MouseUtils/MouseJumpUI/Models/Drawing/RectangleInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace MouseJumpUI.Models.Drawing;
/// </summary>
public sealed class RectangleInfo
{
public static readonly RectangleInfo Empty = new(0, 0, 0, 0);

public RectangleInfo(decimal x, decimal y, decimal width, decimal height)
{
this.X = x;
Expand Down Expand Up @@ -63,46 +65,25 @@ public decimal Height

public decimal Bottom => this.Y + this.Height;

public SizeInfo Size => new(this.Width, this.Height);

public PointInfo Location => new(this.X, this.Y);

public decimal Area => this.Width * this.Height;

/// <remarks>
/// Adapted from https://github.com/dotnet/runtime
/// See https://github.com/dotnet/runtime/blob/dfd618dc648ba9b11dd0f8034f78113d69f223cd/src/libraries/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs
/// </remarks>
public bool Contains(RectangleInfo rect) =>
(this.X <= rect.X) && (rect.X + rect.Width <= this.X + this.Width) &&
(this.Y <= rect.Y) && (rect.Y + rect.Height <= this.Y + this.Height);

public RectangleInfo Enlarge(PaddingInfo padding) => new(
this.X + padding.Left,
this.Y + padding.Top,
this.Width + padding.Horizontal,
this.Height + padding.Vertical);

public RectangleInfo Offset(SizeInfo amount) => this.Offset(amount.Width, amount.Height);
public PointInfo Location => new(this.X, this.Y);

public RectangleInfo Offset(decimal dx, decimal dy) => new(this.X + dx, this.Y + dy, this.Width, this.Height);
public PointInfo Midpoint => new(
x: this.X + (this.Width / 2),
y: this.Y + (this.Height / 2));

public RectangleInfo Scale(decimal scalingFactor) => new(
this.X * scalingFactor,
this.Y * scalingFactor,
this.Width * scalingFactor,
this.Height * scalingFactor);
public SizeInfo Size => new(this.Width, this.Height);

public RectangleInfo Center(PointInfo point) => new(
x: point.X - (this.Width / 2),
y: point.Y - (this.Height / 2),
width: this.Width,
height: this.Height);

public PointInfo Midpoint => new(
x: this.X + (this.Width / 2),
y: this.Y + (this.Height / 2));

/// <summary>
/// Moves this RectangleInfo inside the specified RectangleInfo.
/// </summary>
public RectangleInfo Clamp(RectangleInfo outer)
{
if ((this.Width > outer.Width) || (this.Height > outer.Height))
Expand All @@ -117,6 +98,31 @@ public RectangleInfo Clamp(RectangleInfo outer)
height: this.Height);
}

/// <remarks>
/// Adapted from https://github.com/dotnet/runtime
/// See https://github.com/dotnet/runtime/blob/dfd618dc648ba9b11dd0f8034f78113d69f223cd/src/libraries/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs
/// </remarks>
public bool Contains(RectangleInfo rect) =>
(this.X <= rect.X) && (rect.X + rect.Width <= this.X + this.Width) &&
(this.Y <= rect.Y) && (rect.Y + rect.Height <= this.Y + this.Height);

public RectangleInfo Enlarge(PaddingInfo padding) =>
new(
this.X + padding.Left,
this.Y + padding.Top,
this.Width + padding.Horizontal,
this.Height + padding.Vertical);

public RectangleInfo Offset(SizeInfo amount) => this.Offset(amount.Width, amount.Height);

public RectangleInfo Offset(decimal dx, decimal dy) => new(this.X + dx, this.Y + dy, this.Width, this.Height);

public RectangleInfo Scale(decimal scalingFactor) => new(
this.X * scalingFactor,
this.Y * scalingFactor,
this.Width * scalingFactor,
this.Height * scalingFactor);

public Rectangle ToRectangle() => new((int)this.X, (int)this.Y, (int)this.Width, (int)this.Height);

public override string ToString()
Expand Down
13 changes: 8 additions & 5 deletions src/modules/MouseUtils/MouseJumpUI/Models/Drawing/SizeInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ public decimal Height
get;
}

public SizeInfo Negate() => new(-this.Width, -this.Height);
public SizeInfo Intersect(SizeInfo size) =>
new(
Math.Min(this.Width, size.Width),
Math.Min(this.Height, size.Height));

public SizeInfo Shrink(PaddingInfo padding) => new(this.Width - padding.Horizontal, this.Height - padding.Vertical);
public SizeInfo Negate() =>
new(-this.Width, -this.Height);

public SizeInfo Intersect(SizeInfo size) => new(
Math.Min(this.Width, size.Width),
Math.Min(this.Height, size.Height));
public SizeInfo Shrink(PaddingInfo padding) =>
new(this.Width - padding.Horizontal, this.Height - padding.Vertical);

public RectangleInfo PlaceAt(decimal x, decimal y) => new(x, y, this.Width, this.Height);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Runtime.InteropServices;

namespace MouseJumpUI.NativeMethods;

internal static partial class Core
Expand All @@ -23,6 +25,9 @@ public DWORD(uint value)
this.Value = value;
}

public static int Size =>
Marshal.SizeOf(typeof(DWORD));

public static implicit operator uint(DWORD value) => value.Value;

public static implicit operator DWORD(uint value) => new(value);
Expand Down
Loading

0 comments on commit b8ecf53

Please sign in to comment.