committed by
GitHub
6 changed files with 395 additions and 5 deletions
@ -0,0 +1,78 @@ |
|||
using System; |
|||
using System.Diagnostics.CodeAnalysis; |
|||
using Avalonia.Automation.Provider; |
|||
using Avalonia.Controls; |
|||
using Avalonia.Controls.Primitives; |
|||
|
|||
namespace Avalonia.Automation.Peers |
|||
{ |
|||
public class CalendarDayButtonAutomationPeer : ButtonAutomationPeer, ISelectionItemProvider |
|||
{ |
|||
public CalendarDayButtonAutomationPeer(CalendarDayButton owner) |
|||
: base(owner) |
|||
{ |
|||
} |
|||
|
|||
public new CalendarDayButton Owner => (CalendarDayButton)base.Owner; |
|||
|
|||
public bool IsSelected => Owner.IsSelected; |
|||
|
|||
public ISelectionProvider? SelectionContainer |
|||
=> Owner.Owner is { } calendar |
|||
? GetOrCreate(calendar).GetProvider<ISelectionProvider>() |
|||
: null; |
|||
|
|||
public void Select() |
|||
{ |
|||
EnsureEnabled(); |
|||
|
|||
if (TryGetSelectableDate(out var calendar, out var date)) |
|||
calendar.SelectedDate = date; |
|||
} |
|||
|
|||
void ISelectionItemProvider.AddToSelection() |
|||
{ |
|||
EnsureEnabled(); |
|||
|
|||
if (!TryGetSelectableDate(out var calendar, out var date) || |
|||
calendar.SelectedDates.Contains(date)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
if (calendar.SelectionMode == CalendarSelectionMode.SingleDate) |
|||
calendar.SelectedDate = date; |
|||
else |
|||
calendar.SelectedDates.Add(date); |
|||
} |
|||
|
|||
void ISelectionItemProvider.RemoveFromSelection() |
|||
{ |
|||
EnsureEnabled(); |
|||
|
|||
if (Owner.Owner is { SelectionMode: not CalendarSelectionMode.None } calendar && |
|||
Owner.DataContext is DateTime date) |
|||
{ |
|||
calendar.SelectedDates.Remove(date); |
|||
} |
|||
} |
|||
|
|||
private bool TryGetSelectableDate([NotNullWhen(true)] out Calendar? calendar, out DateTime date) |
|||
{ |
|||
if (Owner.Owner is { SelectionMode: not CalendarSelectionMode.None } owner && |
|||
Owner.DataContext is DateTime value && |
|||
!Owner.IsBlackout) |
|||
{ |
|||
calendar = owner; |
|||
date = value; |
|||
return true; |
|||
} |
|||
|
|||
calendar = null; |
|||
date = default; |
|||
return false; |
|||
} |
|||
|
|||
protected override string GetClassNameCore() => nameof(CalendarDayButton); |
|||
} |
|||
} |
|||
@ -0,0 +1,166 @@ |
|||
using System; |
|||
using Avalonia.Automation.Peers; |
|||
using Avalonia.Automation.Provider; |
|||
using Avalonia.Controls.Primitives; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Controls.UnitTests.Automation; |
|||
|
|||
public class CalendarDayButtonAutomationPeerTests : ScopedTestBase |
|||
{ |
|||
private static readonly DateTime Date1 = new(2026, 6, 5); |
|||
private static readonly DateTime Date2 = new(2026, 6, 10); |
|||
|
|||
private static (Calendar, CalendarDayButton, ISelectionItemProvider) CreateTarget( |
|||
CalendarSelectionMode mode, DateTime? date = null) |
|||
{ |
|||
var calendar = new Calendar { SelectionMode = mode }; |
|||
var dayButton = new CalendarDayButton { Owner = calendar, DataContext = date ?? Date1 }; |
|||
var peer = ControlAutomationPeer.CreatePeerForElement(dayButton); |
|||
return (calendar, dayButton, Assert.IsAssignableFrom<ISelectionItemProvider>(peer)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Creates_CalendarDayButtonAutomationPeer() |
|||
{ |
|||
var peer = ControlAutomationPeer.CreatePeerForElement(new CalendarDayButton()); |
|||
|
|||
Assert.IsType<CalendarDayButtonAutomationPeer>(peer); |
|||
Assert.IsAssignableFrom<ISelectionItemProvider>(peer); |
|||
Assert.IsAssignableFrom<IInvokeProvider>(peer); |
|||
} |
|||
|
|||
[Fact] |
|||
public void IsSelected_Reflects_Owner_State() |
|||
{ |
|||
var (_, dayButton, provider) = CreateTarget(CalendarSelectionMode.SingleDate); |
|||
|
|||
Assert.False(provider.IsSelected); |
|||
dayButton.IsSelected = true; |
|||
Assert.True(provider.IsSelected); |
|||
} |
|||
|
|||
[Fact] |
|||
public void SelectionContainer_Is_Calendar_Peer() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.SingleDate); |
|||
|
|||
var container = provider.SelectionContainer; |
|||
|
|||
Assert.NotNull(container); |
|||
Assert.Same(ControlAutomationPeer.CreatePeerForElement(calendar), container); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Select_Sets_SelectedDate() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.SingleDate); |
|||
|
|||
provider.Select(); |
|||
|
|||
Assert.Equal(Date1, calendar.SelectedDate); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Select_Replaces_Existing_Selection_In_SingleDate_Mode() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.SingleDate); |
|||
calendar.SelectedDate = Date2; |
|||
|
|||
provider.Select(); |
|||
|
|||
Assert.Equal(Date1, calendar.SelectedDate); |
|||
Assert.Equal(1, calendar.SelectedDates.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Select_Is_NoOp_When_SelectionMode_None() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.None); |
|||
|
|||
provider.Select(); |
|||
|
|||
Assert.Null(calendar.SelectedDate); |
|||
Assert.Empty(calendar.SelectedDates); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Select_Is_NoOp_For_Blackout_Day() |
|||
{ |
|||
var (calendar, dayButton, provider) = CreateTarget(CalendarSelectionMode.SingleDate); |
|||
dayButton.IsBlackout = true; |
|||
|
|||
provider.Select(); |
|||
|
|||
Assert.Null(calendar.SelectedDate); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AddToSelection_Replaces_Selection_In_SingleDate_Mode() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.SingleDate); |
|||
calendar.SelectedDate = Date2; |
|||
|
|||
provider.AddToSelection(); |
|||
|
|||
Assert.Equal(Date1, calendar.SelectedDate); |
|||
Assert.Equal(1, calendar.SelectedDates.Count); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AddToSelection_Appends_In_MultipleRange_Mode() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.MultipleRange); |
|||
calendar.SelectedDates.Add(Date2); |
|||
|
|||
provider.AddToSelection(); |
|||
|
|||
Assert.Equal(2, calendar.SelectedDates.Count); |
|||
Assert.Contains(Date1, calendar.SelectedDates); |
|||
Assert.Contains(Date2, calendar.SelectedDates); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AddToSelection_Is_NoOp_When_SelectionMode_None() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.None); |
|||
|
|||
provider.AddToSelection(); |
|||
|
|||
Assert.Empty(calendar.SelectedDates); |
|||
} |
|||
|
|||
[Fact] |
|||
public void AddToSelection_Is_NoOp_For_Blackout_Day() |
|||
{ |
|||
var (calendar, dayButton, provider) = CreateTarget(CalendarSelectionMode.MultipleRange); |
|||
dayButton.IsBlackout = true; |
|||
|
|||
provider.AddToSelection(); |
|||
|
|||
Assert.Empty(calendar.SelectedDates); |
|||
} |
|||
|
|||
[Fact] |
|||
public void RemoveFromSelection_Removes_Date() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.MultipleRange); |
|||
calendar.SelectedDates.Add(Date1); |
|||
calendar.SelectedDates.Add(Date2); |
|||
|
|||
provider.RemoveFromSelection(); |
|||
|
|||
Assert.Equal(Date2, Assert.Single(calendar.SelectedDates)); |
|||
} |
|||
|
|||
[Fact] |
|||
public void RemoveFromSelection_Is_NoOp_When_SelectionMode_None() |
|||
{ |
|||
var (calendar, _, provider) = CreateTarget(CalendarSelectionMode.None); |
|||
|
|||
provider.RemoveFromSelection(); |
|||
|
|||
Assert.Empty(calendar.SelectedDates); |
|||
} |
|||
} |
|||
@ -0,0 +1,95 @@ |
|||
using Avalonia.Automation; |
|||
using Avalonia.Automation.Peers; |
|||
using Avalonia.Automation.Provider; |
|||
using Avalonia.UnitTests; |
|||
using Xunit; |
|||
|
|||
namespace Avalonia.Controls.UnitTests.Automation; |
|||
|
|||
public class MenuItemAutomationPeerTests : ScopedTestBase |
|||
{ |
|||
private static IToggleProvider GetProvider(MenuItem menuItem) |
|||
{ |
|||
var provider = ControlAutomationPeer.CreatePeerForElement(menuItem).GetProvider<IToggleProvider>(); |
|||
Assert.NotNull(provider); |
|||
return provider; |
|||
} |
|||
|
|||
[Fact] |
|||
public void Toggle_Provider_Is_Not_Exposed_When_ToggleType_None() |
|||
{ |
|||
var peer = ControlAutomationPeer.CreatePeerForElement(new MenuItem()); |
|||
|
|||
Assert.Null(peer.GetProvider<IToggleProvider>()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(MenuItemToggleType.CheckBox)] |
|||
[InlineData(MenuItemToggleType.Radio)] |
|||
public void Toggle_Provider_Is_Exposed_For_Checkable_Items(MenuItemToggleType toggleType) |
|||
{ |
|||
var peer = ControlAutomationPeer.CreatePeerForElement(new MenuItem { ToggleType = toggleType }); |
|||
|
|||
Assert.NotNull(peer.GetProvider<IToggleProvider>()); |
|||
} |
|||
|
|||
[Fact] |
|||
public void ToggleState_Reflects_IsChecked() |
|||
{ |
|||
var menuItem = new MenuItem { ToggleType = MenuItemToggleType.CheckBox }; |
|||
var provider = GetProvider(menuItem); |
|||
|
|||
Assert.Equal(ToggleState.Off, provider.ToggleState); |
|||
menuItem.IsChecked = true; |
|||
Assert.Equal(ToggleState.On, provider.ToggleState); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Toggle_Flips_CheckBox_Item() |
|||
{ |
|||
var menuItem = new MenuItem { ToggleType = MenuItemToggleType.CheckBox }; |
|||
var provider = GetProvider(menuItem); |
|||
|
|||
provider.Toggle(); |
|||
Assert.True(menuItem.IsChecked); |
|||
|
|||
provider.Toggle(); |
|||
Assert.False(menuItem.IsChecked); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Toggle_Checks_But_Does_Not_Uncheck_Radio_Item() |
|||
{ |
|||
var menuItem = new MenuItem { ToggleType = MenuItemToggleType.Radio }; |
|||
var provider = GetProvider(menuItem); |
|||
|
|||
provider.Toggle(); |
|||
Assert.True(menuItem.IsChecked); |
|||
|
|||
provider.Toggle(); |
|||
Assert.True(menuItem.IsChecked); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Toggle_Raises_ToggleState_PropertyChanged() |
|||
{ |
|||
var menuItem = new MenuItem { ToggleType = MenuItemToggleType.CheckBox }; |
|||
var peer = ControlAutomationPeer.CreatePeerForElement(menuItem); |
|||
var provider = GetProvider(menuItem); |
|||
|
|||
var raised = 0; |
|||
peer.PropertyChanged += (_, e) => |
|||
{ |
|||
if (e.Property == TogglePatternIdentifiers.ToggleStateProperty) |
|||
{ |
|||
Assert.Equal(ToggleState.Off, e.OldValue); |
|||
Assert.Equal(ToggleState.On, e.NewValue); |
|||
raised++; |
|||
} |
|||
}; |
|||
|
|||
provider.Toggle(); |
|||
|
|||
Assert.Equal(1, raised); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue