using XFESystem.Core; using XFESystem.Desktop; using Xunit; namespace XFESystem.Core.Tests; public sealed class ChromeAnimationTests { private sealed class Canvas : IDesktopCanvas { public int Width => 1280; public int Height => 800; public bool SupportsSceneCache => true; public List Damage { get; } = []; public List Texts { get; } = []; public void Fill(uint rgb, int x, int y, int width, int height) { } public void Line(uint rgb, int x1, int y1, int x2, int y2) { } public void Text(string text, uint rgb, int x, int y) => Texts.Add(text); public void Present() { } public void SaveScene(DesktopBounds damage) => Damage.Add(damage); } [Fact] public void ReversibleAnimationPassesThroughMiddleAndStopsAtEndpoints() { var animation = new DesktopChromeAnimation(); animation.SetTargets(1000, true, true, true, true); Assert.True(animation.IsAnimating); Assert.Equal(0, animation.CloseProgress); var changed = animation.Advance(1090); Assert.Equal(DesktopChromeAnimationChanges.Minimize | DesktopChromeAnimationChanges.Close | DesktopChromeAnimationChanges.TitleHint | DesktopChromeAnimationChanges.Resize, changed); Assert.Equal(0.5, animation.CloseProgress, 5); Assert.Equal(0.5, animation.MinimizeProgress, 5); Assert.Equal(0.5, animation.TitleHintProgress, 5); Assert.Equal(0.5, animation.ResizeProgress, 5); animation.SetTargets(1090, false, false, false, false); Assert.Equal(0.5, animation.CloseProgress, 5); animation.Advance(1135); Assert.InRange(animation.CloseProgress, 0.1, 0.2); animation.Advance(1180); Assert.Equal(0, animation.CloseProgress); Assert.False(animation.IsAnimating); Assert.Equal(DesktopChromeAnimationChanges.None, animation.Advance(2000)); } [Fact] public void RepeatedTargetsAndBackwardsClockCannotRestartOrJumpAnimation() { var animation = new DesktopChromeAnimation(); animation.SetTargets(100, false, true, false, false); animation.Advance(145); double before = animation.CloseProgress; Assert.Equal(DesktopChromeAnimationChanges.None, animation.Advance(140)); Assert.Equal(before, animation.CloseProgress); animation.SetTargets(145, false, true, false, false); Assert.Equal(before, animation.CloseProgress); animation.Advance(280); Assert.Equal(1, animation.CloseProgress); Assert.False(animation.IsAnimating); Assert.Equal(DesktopChromeAnimationChanges.None, animation.Advance(281)); } [Fact] public void DesktopHasNoSystemTopbarAndSettingsIsFifthDesktopEntrance() { var canvas = new Canvas(); var desktop = new DesktopSession(canvas, new MemoryWorkspace()); Assert.Equal(new DesktopBounds(0, 0, 1280, 752), desktop.WorkArea); desktop.Render(); Assert.Contains("Settings", canvas.Texts); Assert.DoesNotContain("C# Native Desktop", canvas.Texts); desktop.Pointer(50, 492, true, timestampMs: 100); desktop.Pointer(50, 492, false, timestampMs: 101); Assert.Equal(DesktopApplication.Settings, desktop.ActiveWindow!.Application); } [Fact] public void CaptionHoverAnimatesOnlyCaptionDamageAndSettlesWithoutIdleFrames() { var canvas = new Canvas(); var desktop = new DesktopSession(canvas, new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); desktop.Render(); var b = window.Bounds; desktop.Pointer(b.X + b.Width - 16, b.Y + 16, false, timestampMs: 1000); desktop.Render(); desktop.AdvanceFeedback(1090); Assert.Equal(0.5, window.ChromeAnimation.CloseProgress, 5); desktop.Render(); Assert.True(canvas.Damage[^1].Width <= 34); Assert.True(canvas.Damage[^1].Height <= 34); desktop.AdvanceFeedback(1180); desktop.Render(); Assert.Equal(1, window.ChromeAnimation.CloseProgress); desktop.AdvanceFeedback(2000); Assert.False(desktop.NeedsRender); desktop.Pointer(b.X + 200, b.Y + 100, false, timestampMs: 2010); desktop.Render(); desktop.AdvanceFeedback(2100); Assert.InRange(window.ChromeAnimation.CloseProgress, 0.45, 0.55); desktop.AdvanceFeedback(2190); desktop.Render(); Assert.Equal(0, window.ChromeAnimation.CloseProgress); desktop.AdvanceFeedback(3000); Assert.False(desktop.NeedsRender); } [Fact] public void TitleAndResizeHintsRemainOnDuringCaptureEvenOutsideHoverTarget() { var canvas = new Canvas(); var desktop = new DesktopSession(canvas, new MemoryWorkspace()); var window = desktop.Open(DesktopApplication.Files); var b = window.Bounds; desktop.Pointer(b.X + 200, b.Y + 16, true, timestampMs: 1000); desktop.Pointer(1279, 10, true, timestampMs: 1050); desktop.AdvanceFeedback(1180); Assert.Equal(1, window.ChromeAnimation.TitleHintProgress); desktop.Pointer(1279, 10, false, timestampMs: 1190); desktop.AdvanceFeedback(1370); Assert.Equal(0, window.ChromeAnimation.TitleHintProgress); b = window.Bounds; desktop.Pointer(b.X + b.Width - 2, b.Y + b.Height - 2, true, timestampMs: 2000); desktop.Pointer(0, 0, true, timestampMs: 2050); desktop.AdvanceFeedback(2180); Assert.Equal(1, window.ChromeAnimation.ResizeProgress); desktop.Pointer(0, 0, false, timestampMs: 2190); desktop.AdvanceFeedback(2370); Assert.Equal(0, window.ChromeAnimation.ResizeProgress); } }