소스 검색

Added View.Mouse tests

Tig 10 달 전
부모
커밋
58d0781a98
4개의 변경된 파일389개의 추가작업 그리고 28개의 파일을 삭제
  1. 24 26
      Terminal.Gui/View/View.Mouse.cs
  2. 1 1
      UnitTests/View/Mouse/GetViewsUnderMouseTests.cs
  3. 361 0
      UnitTests/View/Mouse/MouseEnterLeaveTests.cs
  4. 3 1
      UnitTests/View/Mouse/MouseTests.cs

+ 24 - 26
Terminal.Gui/View/View.Mouse.cs

@@ -157,10 +157,7 @@ public partial class View // Mouse APIs
     /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
     protected internal virtual bool? OnMouseEnter (MouseEvent mouseEvent)
     {
-        var args = new MouseEventEventArgs (mouseEvent);
-        MouseEnter?.Invoke (this, args);
-
-        return args.Handled;
+        return false;
     }
 
     /// <summary>Called when a mouse event occurs within the view's <see cref="Viewport"/>.</summary>
@@ -196,20 +193,7 @@ public partial class View // Mouse APIs
     /// <returns><see langword="true"/>, if the event was handled, <see langword="false"/> otherwise.</returns>
     protected internal virtual bool OnMouseLeave (MouseEvent mouseEvent)
     {
-        if (!Enabled)
-        {
-            return true;
-        }
-
-        if (!CanBeVisible (this))
-        {
-            return false;
-        }
-
-        var args = new MouseEventEventArgs (mouseEvent);
-        MouseLeave?.Invoke (this, args);
-
-        return args.Handled;
+        return false;
     }
 
     /// <summary>
@@ -333,9 +317,9 @@ public partial class View // Mouse APIs
     }
 
     /// <summary>
-    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse enters <see cref="Viewport"/>. <see cref="MouseLeave"/> will
-    ///     be raised when the mouse is no longer over the <see cref="Viewport"/>. If another View occludes the current one, the
-    ///     that View will also receive a MouseEnter event.
+    ///     INTERNAL Called by <see cref="Application.OnMouseEvent"/> when the mouse moves over the View's <see cref="Frame"/>. <see cref="MouseLeave"/> will
+    ///     be raised when the mouse is no longer over the <see cref="Frame"/>. If another View occludes this View, the
+    ///     that View will also receive MouseEnter/Leave events.
     /// </summary>
     /// <remarks>
     ///     <para>
@@ -345,17 +329,20 @@ public partial class View // Mouse APIs
     ///         This method calls <see cref="OnMouseEnter"/> to raise the <see cref="MouseEnter"/> event.
     ///     </para>
     ///     <para>
+    ///         Adornments receive MouseEnter/Leave events when the mouse is over the Adornment's <see cref="Thickness"/>.
+    ///     </para>
+    ///     <para>
     ///         See <see cref="SetHighlight"/> for more information.
     ///     </para>
     /// </remarks>
     /// <param name="mouseEvent"></param>
     /// <returns><see langword="true"/> if the event was handled, <see langword="false"/> otherwise. Handling the event
-    /// prevents Views higher in the visible hierarchy from recieving Enter/Leave events.</returns>
+    /// prevents Views higher in the visible hierarchy from receiving Enter/Leave events.</returns>
     internal bool? NewMouseEnterEvent (MouseEvent mouseEvent)
     {
         if (!Enabled)
         {
-            return true;
+            return false;
         }
 
         if (!CanBeVisible (this))
@@ -368,6 +355,9 @@ public partial class View // Mouse APIs
             return true;
         }
 
+        var args = new MouseEventEventArgs (mouseEvent);
+        MouseEnter?.Invoke (this, args);
+
 #if HOVER
         if (HighlightStyle.HasFlag(HighlightStyle.Hover))
         {
@@ -377,11 +367,12 @@ public partial class View // Mouse APIs
             }
         }
 #endif
-        return false;
+
+        return args.Handled;
     }
 
     /// <summary>
-    ///     Called by <see cref="Application.OnMouseEvent"/> when the mouse leaves <see cref="Viewport"/>.
+    ///     INTERNAL Called by <see cref="Application.OnMouseEvent"/> when the mouse leaves <see cref="Frame"/>.
     /// </summary>
     /// <remarks>
     ///     <para>
@@ -391,6 +382,9 @@ public partial class View // Mouse APIs
     ///         This method calls <see cref="OnMouseLeave"/> to raise the <see cref="MouseLeave"/> event.
     ///     </para>
     ///     <para>
+    ///         Adornments receive MouseEnter/Leave events when the mouse is over the Adornment's <see cref="Thickness"/>.
+    ///     </para>
+    ///     <para>
     ///         See <see cref="SetHighlight"/> for more information.
     ///     </para>
     /// </remarks>
@@ -407,6 +401,10 @@ public partial class View // Mouse APIs
         {
             return true;
         }
+
+        var args = new MouseEventEventArgs (mouseEvent);
+        MouseLeave?.Invoke (this, args);
+
 #if HOVER
         if (HighlightStyle.HasFlag (HighlightStyle.Hover))
         {
@@ -414,7 +412,7 @@ public partial class View // Mouse APIs
         }
 #endif
 
-        return false;
+        return args.Handled;
     }
 
     /// <summary>

+ 1 - 1
UnitTests/View/GetViewsUnderMouseTests.cs → UnitTests/View/Mouse/GetViewsUnderMouseTests.cs

@@ -1,6 +1,6 @@
 #nullable enable
 
-namespace Terminal.Gui.ViewTests;
+namespace Terminal.Gui.ViewMouseTests;
 
 public class GetViewsUnderMouseTests
 {

+ 361 - 0
UnitTests/View/Mouse/MouseEnterLeaveTests.cs

@@ -0,0 +1,361 @@
+namespace Terminal.Gui.ViewMouseTests;
+
+[Trait ("Category", "Input")]
+public class MouseEnterLeaveTests
+{
+    private class TestView : View
+    {
+        public TestView ()
+        {
+            MouseEnter += OnMouseEnterHandler;
+            MouseLeave += OnMouseLeaveHandler;
+        }
+
+        public bool HandleOnEnter { get; init; }
+        public bool HandleOnLeave { get; }
+
+        public bool HandleEnterEvent { get; init; }
+        public bool HandleLeaveEvent { get; }
+
+        public bool OnMouseEnterCalled { get; private set; }
+        public bool OnMouseLeaveCalled { get; private set; }
+
+        protected internal override bool? OnMouseEnter (MouseEvent mouseEvent)
+        {
+            OnMouseEnterCalled = true;
+            mouseEvent.Handled = HandleOnEnter;
+
+            base.OnMouseEnter (mouseEvent);
+
+            return mouseEvent.Handled;
+        }
+
+        protected internal override bool OnMouseLeave (MouseEvent mouseEvent)
+        {
+            OnMouseLeaveCalled = true;
+            mouseEvent.Handled = HandleOnLeave;
+
+            base.OnMouseLeave (mouseEvent);
+
+            return mouseEvent.Handled;
+        }
+
+        public bool MouseEnterRaised { get; private set; }
+        public bool MouseLeaveRaised { get; private set; }
+
+        private void OnMouseEnterHandler (object s, MouseEventEventArgs e)
+        {
+            MouseEnterRaised = true;
+
+            if (HandleEnterEvent)
+            {
+                e.Handled = true;
+            }
+        }
+
+        private void OnMouseLeaveHandler (object s, MouseEventEventArgs e)
+        {
+            MouseLeaveRaised = true;
+
+            if (HandleLeaveEvent)
+            {
+                e.Handled = true;
+            }
+        }
+    }
+
+    [Fact]
+    public void NewMouseEnterEvent_ViewIsEnabledAndVisible_CallsOnMouseEnter ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.True (view.OnMouseEnterCalled);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseEnterEvent_ViewIsDisabled_DoesNotCallOnMouseEnter ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = false,
+            Visible = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.False (view.OnMouseEnterCalled);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseEnterEvent_ViewIsNotVisible_DoesNotCallOnMouseEnter ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = false
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.False (view.OnMouseEnterCalled);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseLeaveEvent_ViewIsVisible_CallsOnMouseLeave ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true, Visible = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseLeaveEvent (mouseEvent);
+
+        // Assert
+        Assert.True (view.OnMouseLeaveCalled);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseLeaveEvent_ViewIsNotVisible_DoesNotCallOnMouseLeave ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = false
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseLeaveEvent (mouseEvent);
+
+        // Assert
+        Assert.False (view.OnMouseLeaveCalled);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    // Events
+
+    [Fact]
+    public void NewMouseEnterEvent_ViewIsEnabledAndVisible_RaisesMouseEnter ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.True (view.MouseEnterRaised);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseEnterEvent_ViewIsDisabled_DoesNotRaiseMouseEnter ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = false,
+            Visible = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.False (view.MouseEnterRaised);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseEnterEvent_ViewIsNotVisible_DoesNotRaiseMouseEnter ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = false
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.False (view.MouseEnterRaised);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseLeaveEvent_ViewIsVisible_RaisesMouseLeave ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true, Visible = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseLeaveEvent (mouseEvent);
+
+        // Assert
+        Assert.True (view.MouseLeaveRaised);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseLeaveEvent_ViewIsNotVisible_DoesNotRaiseMouseLeave ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = false
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseLeaveEvent (mouseEvent);
+
+        // Assert
+        Assert.False (view.MouseLeaveRaised);
+        Assert.False (handled);
+        Assert.False (mouseEvent.Handled);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    // Handled tests
+    [Fact]
+    public void NewMouseEnterEvent_HandleOnMouseEnter_Event_Not_Raised ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = true,
+            HandleOnEnter = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.True (view.OnMouseEnterCalled);
+        Assert.True (handled);
+        Assert.True (mouseEvent.Handled);
+
+        Assert.False (view.MouseEnterRaised);
+
+        // Cleanup
+        view.Dispose ();
+    }
+
+    [Fact]
+    public void NewMouseEnterEvent_HandleMouseEnterEvent ()
+    {
+        // Arrange
+        var view = new TestView
+        {
+            Enabled = true,
+            Visible = true,
+            HandleEnterEvent = true
+        };
+
+        var mouseEvent = new MouseEvent ();
+
+        // Act
+        bool? handled = view.NewMouseEnterEvent (mouseEvent);
+
+        // Assert
+        Assert.True (view.OnMouseEnterCalled);
+        Assert.True (handled);
+        Assert.True (mouseEvent.Handled);
+
+        Assert.True (view.MouseEnterRaised);
+
+        // Cleanup
+        view.Dispose ();
+    }
+}

+ 3 - 1
UnitTests/View/MouseTests.cs → UnitTests/View/Mouse/MouseTests.cs

@@ -1,6 +1,6 @@
 using Xunit.Abstractions;
 
-namespace Terminal.Gui.ViewTests;
+namespace Terminal.Gui.ViewMouseTests;
 
 [Trait ("Category", "Input")]
 
@@ -465,4 +465,6 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews
             }
         }
     }
+
+
 }