mirror of
https://github.com/AtomUI/AtomUI.git
synced 2026-10-18 14:37:19 +08:00
225 lines
7.5 KiB
C#
225 lines
7.5 KiB
C#
using System.Reflection;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Threading;
|
|
using Avalonia.VisualTree;
|
|
using Shouldly;
|
|
using Xunit;
|
|
using AvaloniaWindow = Avalonia.Controls.Window;
|
|
|
|
namespace AtomUI.Desktop.Controls.Tests.Input;
|
|
|
|
public class SearchEditBehaviorTests
|
|
{
|
|
static SearchEditBehaviorTests()
|
|
{
|
|
AvaloniaTestApp.EnsureInitialized();
|
|
}
|
|
|
|
[Fact]
|
|
public void Search_On_Enter_Is_Enabled_By_Default()
|
|
{
|
|
var searchEdit = new SearchEdit();
|
|
|
|
searchEdit.IsSearchOnEnterEnabled.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Enter_Raises_SearchRequested_With_Query_And_Trigger()
|
|
{
|
|
var searchEdit = new SearchEdit { Text = "AtomUI" };
|
|
SearchRequestedEventArgs? receivedArgs = null;
|
|
searchEdit.SearchRequested += (_, args) => receivedArgs = args;
|
|
|
|
var keyEventArgs = RaiseKeyUp(searchEdit, Key.Enter);
|
|
|
|
receivedArgs.ShouldNotBeNull();
|
|
receivedArgs.Query.ShouldBe("AtomUI");
|
|
receivedArgs.Trigger.ShouldBe(SearchTriggerSource.EnterKey);
|
|
keyEventArgs.Handled.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Enter_Does_Not_Request_Search_When_Enter_Search_Is_Disabled()
|
|
{
|
|
var searchEdit = new SearchEdit { IsSearchOnEnterEnabled = false };
|
|
var requestCount = 0;
|
|
searchEdit.SearchRequested += (_, _) => requestCount++;
|
|
|
|
var keyEventArgs = RaiseKeyUp(searchEdit, Key.Enter);
|
|
|
|
requestCount.ShouldBe(0);
|
|
keyEventArgs.Handled.ShouldBeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void Handled_Enter_Does_Not_Request_Search()
|
|
{
|
|
var searchEdit = new SearchEdit();
|
|
var requestCount = 0;
|
|
searchEdit.SearchRequested += (_, _) => requestCount++;
|
|
|
|
var keyEventArgs = RaiseKeyUp(searchEdit, Key.Enter, isHandled: true);
|
|
|
|
requestCount.ShouldBe(0);
|
|
keyEventArgs.Handled.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void Non_Enter_Key_Does_Not_Request_Search()
|
|
{
|
|
var searchEdit = new SearchEdit();
|
|
var requestCount = 0;
|
|
searchEdit.SearchRequested += (_, _) => requestCount++;
|
|
|
|
var keyEventArgs = RaiseKeyUp(searchEdit, Key.A);
|
|
|
|
requestCount.ShouldBe(0);
|
|
keyEventArgs.Handled.ShouldBeFalse();
|
|
}
|
|
|
|
[Fact]
|
|
public void Search_Button_Raises_SearchRequested_With_Button_Trigger()
|
|
{
|
|
var searchEdit = new SearchEdit { Text = "Button query" };
|
|
SearchRequestedEventArgs? receivedArgs = null;
|
|
searchEdit.SearchRequested += (_, args) => receivedArgs = args;
|
|
|
|
ShowInWindow(searchEdit, () =>
|
|
{
|
|
var searchButton = searchEdit.GetVisualDescendants()
|
|
.OfType<Button>()
|
|
.Single(button => button.Name == "PART_RightAddOn");
|
|
|
|
searchButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, searchButton));
|
|
});
|
|
|
|
receivedArgs.ShouldNotBeNull();
|
|
receivedArgs.Query.ShouldBe("Button query");
|
|
receivedArgs.Trigger.ShouldBe(SearchTriggerSource.Button);
|
|
}
|
|
|
|
[Fact]
|
|
public void Operating_State_Suppresses_Search_Requests()
|
|
{
|
|
var searchEdit = new SearchEdit
|
|
{
|
|
IsOperating = true,
|
|
Text = "Ignored query"
|
|
};
|
|
var requestCount = 0;
|
|
searchEdit.SearchRequested += (_, _) => requestCount++;
|
|
|
|
var keyEventArgs = RaiseKeyUp(searchEdit, Key.Enter);
|
|
|
|
ShowInWindow(searchEdit, () =>
|
|
{
|
|
var searchButton = searchEdit.GetVisualDescendants()
|
|
.OfType<Button>()
|
|
.Single(button => button.Name == "PART_RightAddOn");
|
|
|
|
searchButton.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, searchButton));
|
|
});
|
|
|
|
requestCount.ShouldBe(0);
|
|
keyEventArgs.Handled.ShouldBeTrue();
|
|
}
|
|
|
|
[Fact]
|
|
public void AutoCompleteSearchEdit_Forwards_Search_Properties_And_Request()
|
|
{
|
|
var autoComplete = new AutoCompleteSearchEdit
|
|
{
|
|
Width = 240,
|
|
Value = "AutoComplete query",
|
|
IsOperating = true,
|
|
IsSearchOnEnterEnabled = false
|
|
};
|
|
SearchRequestedEventArgs? receivedArgs = null;
|
|
autoComplete.SearchRequested += (_, args) => receivedArgs = args;
|
|
|
|
ShowInWindow(autoComplete, () =>
|
|
{
|
|
var searchEdit = autoComplete.GetVisualDescendants()
|
|
.OfType<SearchEdit>()
|
|
.Single();
|
|
|
|
searchEdit.IsOperating.ShouldBeTrue();
|
|
searchEdit.IsSearchOnEnterEnabled.ShouldBeFalse();
|
|
|
|
autoComplete.IsOperating = false;
|
|
autoComplete.IsSearchOnEnterEnabled = true;
|
|
Dispatcher.UIThread.RunJobs();
|
|
|
|
searchEdit.IsOperating.ShouldBeFalse();
|
|
searchEdit.IsSearchOnEnterEnabled.ShouldBeTrue();
|
|
|
|
RaiseKeyUp(searchEdit, Key.Enter);
|
|
|
|
receivedArgs.ShouldNotBeNull();
|
|
receivedArgs.Query.ShouldBe("AutoComplete query");
|
|
receivedArgs.Trigger.ShouldBe(SearchTriggerSource.EnterKey);
|
|
receivedArgs.Source.ShouldBeSameAs(searchEdit);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public void Search_Status_Api_Preserves_IsOperating()
|
|
{
|
|
const BindingFlags publicStatic = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
|
|
|
|
typeof(SearchEdit).GetProperty("HandleEnterAsSearch").ShouldBeNull();
|
|
typeof(SearchEdit).GetField("HandleEnterAsSearchProperty", publicStatic).ShouldBeNull();
|
|
typeof(SearchEdit).GetProperty("IsOperating").ShouldNotBeNull();
|
|
typeof(SearchEdit).GetField("IsOperatingProperty", publicStatic).ShouldNotBeNull();
|
|
typeof(SearchEdit).GetProperty("IsSearching").ShouldBeNull();
|
|
typeof(SearchEdit).GetField("IsSearchingProperty", publicStatic).ShouldBeNull();
|
|
typeof(SearchEdit).GetEvent("SearchButtonClick").ShouldBeNull();
|
|
typeof(SearchEdit).GetField("SearchButtonClickEvent", publicStatic).ShouldBeNull();
|
|
|
|
typeof(AutoCompleteSearchEdit).GetProperty("IsOperating").ShouldNotBeNull();
|
|
typeof(AutoCompleteSearchEdit).GetField("IsOperatingProperty", publicStatic).ShouldNotBeNull();
|
|
typeof(AutoCompleteSearchEdit).GetProperty("IsSearching").ShouldBeNull();
|
|
typeof(AutoCompleteSearchEdit).GetField("IsSearchingProperty", publicStatic).ShouldBeNull();
|
|
typeof(AutoCompleteSearchEdit).GetEvent("SearchButtonClick").ShouldBeNull();
|
|
}
|
|
|
|
private static KeyEventArgs RaiseKeyUp(InputElement target, Key key, bool isHandled = false)
|
|
{
|
|
var eventArgs = new KeyEventArgs
|
|
{
|
|
RoutedEvent = InputElement.KeyUpEvent,
|
|
Source = target,
|
|
Key = key,
|
|
PhysicalKey = key == Key.Enter ? PhysicalKey.Enter : PhysicalKey.None,
|
|
KeyModifiers = KeyModifiers.None,
|
|
Handled = isHandled
|
|
};
|
|
|
|
target.RaiseEvent(eventArgs);
|
|
return eventArgs;
|
|
}
|
|
|
|
private static void ShowInWindow(Control content, Action assertion)
|
|
{
|
|
var window = new AvaloniaWindow
|
|
{
|
|
Width = 480,
|
|
Height = 160,
|
|
Content = content
|
|
};
|
|
|
|
try
|
|
{
|
|
window.Show();
|
|
Dispatcher.UIThread.RunJobs();
|
|
assertion();
|
|
}
|
|
finally
|
|
{
|
|
window.Close();
|
|
}
|
|
}
|
|
}
|