From d09431a9f51e353cf8f4deffc8cb40ac8b1ed02c Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Tue, 31 Dec 2024 18:49:07 +0800 Subject: [PATCH 1/2] test: AutoCompleteBox tests. --- .../AutoCompleteBox/AutoCompleteBox.cs | 15 +-- .../Controls/AutoCompleteBoxTests/Tests.cs | 100 ++++++++++++++++++ tests/Test.Ursa/AutoCompleteBoxTests/Tests.cs | 20 ++++ 3 files changed, 125 insertions(+), 10 deletions(-) create mode 100644 tests/HeadlessTest.Ursa/Controls/AutoCompleteBoxTests/Tests.cs create mode 100644 tests/Test.Ursa/AutoCompleteBoxTests/Tests.cs diff --git a/src/Ursa/Controls/AutoCompleteBox/AutoCompleteBox.cs b/src/Ursa/Controls/AutoCompleteBox/AutoCompleteBox.cs index 0f496a2..423c840 100644 --- a/src/Ursa/Controls/AutoCompleteBox/AutoCompleteBox.cs +++ b/src/Ursa/Controls/AutoCompleteBox/AutoCompleteBox.cs @@ -1,3 +1,5 @@ +using System.Diagnostics; +using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; using Avalonia.Input; @@ -8,8 +10,6 @@ namespace Ursa.Controls; public class AutoCompleteBox: Avalonia.Controls.AutoCompleteBox, IClearControl { - // protected override Type StyleKeyOverride { get; } = typeof(Avalonia.Controls.AutoCompleteBox); - private TextBox? _text; static AutoCompleteBox() { MinimumPrefixLengthProperty.OverrideDefaultValue(0); @@ -17,15 +17,9 @@ public class AutoCompleteBox: Avalonia.Controls.AutoCompleteBox, IClearControl public AutoCompleteBox() { - this.AddHandler(PointerPressedEvent, OnBoxPointerPressed, RoutingStrategies.Tunnel); + AddHandler(PointerPressedEvent, OnBoxPointerPressed, RoutingStrategies.Tunnel); } - - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - _text = e.NameScope.Get("PART_TextBox"); - } - + private void OnBoxPointerPressed(object? sender, PointerPressedEventArgs e) { if (Equals(sender, this) && e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) @@ -37,6 +31,7 @@ public class AutoCompleteBox: Avalonia.Controls.AutoCompleteBox, IClearControl protected override void OnGotFocus(GotFocusEventArgs e) { base.OnGotFocus(e); + if (IsDropDownOpen) return; SetCurrentValue(IsDropDownOpenProperty, true); } diff --git a/tests/HeadlessTest.Ursa/Controls/AutoCompleteBoxTests/Tests.cs b/tests/HeadlessTest.Ursa/Controls/AutoCompleteBoxTests/Tests.cs new file mode 100644 index 0000000..aacf2d4 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/AutoCompleteBoxTests/Tests.cs @@ -0,0 +1,100 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Headless; +using Avalonia.Headless.XUnit; +using Avalonia.Input; +using Avalonia.Layout; +using UrsaControl = Ursa.Controls; + +namespace HeadlessTest.Ursa.Controls.AutoCompleteBoxTests; + +public class Tests +{ + [AvaloniaFact] + // Ideally Should not open popup when there is no items, but sub class have no access to this status. + public void AutoCompleteBox_Focus_And_LostFocus() + { + var window = new Window(); + var autoCompleteBox = new UrsaControl.AutoCompleteBox() + { + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + Width = 100, + Height = 100, + }; + var textBox = new TextBox() + { + Width = 100, Height = 100, + }; + window.Content = new StackPanel() + { + Children = { autoCompleteBox, textBox } + }; + window.Show(); + + Assert.False(autoCompleteBox.IsDropDownOpen); + autoCompleteBox.Focus(); + Assert.True(autoCompleteBox.IsDropDownOpen); + textBox.Focus(); + Assert.False(autoCompleteBox.IsDropDownOpen); + } + + [AvaloniaFact] + public void Click_AutoCompleteBox_With_Mouse_Should_Open_Dropdown() + { + var window = new Window(); + var autoCompleteBox = new UrsaControl.AutoCompleteBox() + { + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + Width = 100, + Height = 100, + ItemsSource = new List {"Hello", "World"} + }; + window.Content = autoCompleteBox; + window.Show(); + + Assert.False(autoCompleteBox.IsDropDownOpen); + window.MouseDown(new Point(10, 10), MouseButton.Left); + Assert.True(autoCompleteBox.IsDropDownOpen); + } + + [AvaloniaFact] + public void Click_AutoCompleteBox_With_Mouse_Should_NotOpen_Dropdown_When_Empty() + { + var window = new Window(); + var autoCompleteBox = new UrsaControl.AutoCompleteBox() + { + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + Width = 100, + Height = 100, + }; + window.Content = autoCompleteBox; + window.Show(); + + Assert.False(autoCompleteBox.IsDropDownOpen); + window.MouseDown(new Point(10, 10), MouseButton.Left); + Assert.False(autoCompleteBox.IsDropDownOpen); + } + + [AvaloniaFact] + public void Right_Click_AutoCompleteBox_With_Mouse_Should_NotOpen_Dropdown() + { + var window = new Window(); + var autoCompleteBox = new UrsaControl.AutoCompleteBox() + { + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top, + Width = 100, + Height = 100, + ItemsSource = new List {"Hello", "World"}, + }; + window.Content = autoCompleteBox; + window.Show(); + + Assert.False(autoCompleteBox.IsDropDownOpen); + window.MouseDown(new Point(10, 10), MouseButton.Right); + Assert.False(autoCompleteBox.IsDropDownOpen); + } +} \ No newline at end of file diff --git a/tests/Test.Ursa/AutoCompleteBoxTests/Tests.cs b/tests/Test.Ursa/AutoCompleteBoxTests/Tests.cs new file mode 100644 index 0000000..1dbacc4 --- /dev/null +++ b/tests/Test.Ursa/AutoCompleteBoxTests/Tests.cs @@ -0,0 +1,20 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Input; +using Avalonia.Remote.Protocol.Input; +using AutoCompleteBox = Ursa.Controls.AutoCompleteBox; + +namespace Test.Ursa.AutoCompleteBoxTests; + +public class Tests +{ + [Fact] + public void Clear_SetsSelectedItemToNull() + { + var autoCompleteBox = new AutoCompleteBox(); + autoCompleteBox.SelectedItem = "TestItem"; + autoCompleteBox.Clear(); + Assert.Null(autoCompleteBox.SelectedItem); + } +} \ No newline at end of file From c61d37e9e801e48be75441f83a6aaae40fa19649 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Fri, 3 Jan 2025 20:04:13 +0800 Subject: [PATCH 2/2] test: add banner test. --- demo/Ursa.Demo/Pages/BannerDemo.axaml | 5 ++ src/Ursa/Controls/Avatar/Avatar.cs | 5 +- src/Ursa/Controls/Banner/Banner.cs | 10 ++- .../Controls/BannerTests/Tests.cs | 87 +++++++++++++++++++ .../HeadlessTest.Ursa.csproj | 5 +- tests/HeadlessTest.Ursa/TestAppBuilder.cs | 16 +++- 6 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 tests/HeadlessTest.Ursa/Controls/BannerTests/Tests.cs diff --git a/demo/Ursa.Demo/Pages/BannerDemo.axaml b/demo/Ursa.Demo/Pages/BannerDemo.axaml index 91c8f89..eefcdca 100644 --- a/demo/Ursa.Demo/Pages/BannerDemo.axaml +++ b/demo/Ursa.Demo/Pages/BannerDemo.axaml @@ -19,6 +19,11 @@ Classes.Bordered="{Binding Bordered}" Content="This is the Demo of Ursa Banner. " Header="Welcome to Ursa" + Width="300" + Height="100" + HorizontalAlignment="Left" + VerticalAlignment="Top" + CanClose="True" Type="{Binding SelectedType}" /> diff --git a/src/Ursa/Controls/Avatar/Avatar.cs b/src/Ursa/Controls/Avatar/Avatar.cs index a3d134c..43aaf71 100644 --- a/src/Ursa/Controls/Avatar/Avatar.cs +++ b/src/Ursa/Controls/Avatar/Avatar.cs @@ -1,4 +1,5 @@ -using Avalonia; +using System.Diagnostics.CodeAnalysis; +using Avalonia; using Avalonia.Controls; using Avalonia.Media; @@ -12,12 +13,14 @@ public class Avatar : Button public static readonly StyledProperty HoverMaskProperty = AvaloniaProperty.Register( nameof(HoverMask)); + [ExcludeFromCodeCoverage] public IImage? Source { get => GetValue(SourceProperty); set => SetValue(SourceProperty, value); } + [ExcludeFromCodeCoverage] public object? HoverMask { get => GetValue(HoverMaskProperty); diff --git a/src/Ursa/Controls/Banner/Banner.cs b/src/Ursa/Controls/Banner/Banner.cs index f852701..8b3fd1b 100644 --- a/src/Ursa/Controls/Banner/Banner.cs +++ b/src/Ursa/Controls/Banner/Banner.cs @@ -1,8 +1,10 @@ +using System.Diagnostics.CodeAnalysis; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Notifications; using Avalonia.Controls.Primitives; +using Avalonia.Input; using Avalonia.Interactivity; using Irihi.Avalonia.Shared.Helpers; @@ -20,15 +22,17 @@ public class Banner: HeaderedContentControl public static readonly StyledProperty CanCloseProperty = AvaloniaProperty.Register( nameof(CanClose)); + [ExcludeFromCodeCoverage] public bool CanClose { get => GetValue(CanCloseProperty); set => SetValue(CanCloseProperty, value); } - + public static readonly StyledProperty ShowIconProperty = AvaloniaProperty.Register( nameof(ShowIcon), true); + [ExcludeFromCodeCoverage] public bool ShowIcon { get => GetValue(ShowIconProperty); @@ -38,6 +42,7 @@ public class Banner: HeaderedContentControl public static readonly StyledProperty IconProperty = AvaloniaProperty.Register( nameof(Icon)); + [ExcludeFromCodeCoverage] public object? Icon { get => GetValue(IconProperty); @@ -47,6 +52,7 @@ public class Banner: HeaderedContentControl public static readonly StyledProperty TypeProperty = AvaloniaProperty.Register( nameof(Type)); + [ExcludeFromCodeCoverage] public NotificationType Type { get => GetValue(TypeProperty); @@ -63,6 +69,6 @@ public class Banner: HeaderedContentControl private void OnCloseClick(object? sender, RoutedEventArgs args) { - IsVisible = false; + SetCurrentValue(IsVisibleProperty, false); } } \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/BannerTests/Tests.cs b/tests/HeadlessTest.Ursa/Controls/BannerTests/Tests.cs new file mode 100644 index 0000000..6ac7fb7 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/BannerTests/Tests.cs @@ -0,0 +1,87 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Shapes; +using Avalonia.Controls.Templates; +using Avalonia.Headless; +using Avalonia.Headless.XUnit; +using Avalonia.Input; +using Avalonia.Media; +using Avalonia.VisualTree; +using UrsaControls = Ursa.Controls; + +namespace HeadlessTest.Ursa.Controls.BannerTests; + +public class Tests +{ + [AvaloniaFact] + public void Click_On_Banner_Close_Button_Should_Hide_Banner() + { + // Arrange + var window = new Window(); + var banner = new UrsaControls.Banner() + { + HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left, + VerticalAlignment = Avalonia.Layout.VerticalAlignment.Top, + Width = 300, + Height = 100, + CanClose = true + }; + window.Content = banner; + window.Show(); + + Assert.True(banner.IsVisible); + + var closeButton = banner.GetTemplateChildren().OfType