Files
AtomUI/tests/AtomUI.Desktop.Controls.Tests/NavMenu/NavMenuThemeContractTests.cs
T

181 lines
11 KiB
C#

using System.IO;
using Shouldly;
using Xunit;
namespace AtomUI.Desktop.Controls.Tests.NavMenu;
public class NavMenuThemeContractTests
{
[Fact]
public void NavMenu_Root_Background_Uses_Component_ItemBg_Token_Without_Right_Divider()
{
var source = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuTheme.axaml");
source.ShouldContain("<Setter Property=\"Background\" Value=\"{atom:NavMenuTokenResource ItemBg}\" />");
source.ShouldContain("<Setter Property=\"Background\" Value=\"{atom:NavMenuTokenResource DarkMenuBg}\" />");
source.ShouldContain("<Setter Property=\"BorderThickness\" Value=\"0\" />");
source.ShouldContain("<Setter Property=\"IsVisible\" Value=\"False\" />");
source.ShouldNotContain("<Setter Property=\"BorderThickness\" Value=\"0,0,1,0\" />");
source.ShouldNotContain("<Setter Property=\"Background\" Value=\"Transparent\" />");
source.ShouldNotContain("<Setter Property=\"Background\" Value=\"{atom:SharedTokenResource ColorBgContainer}\" />");
source.ShouldNotContain("<Setter Property=\"Background\" Value=\"{atom:NavMenuTokenResource DarkMenuPopupBg}\" />");
}
[Fact]
public void Inline_Submenu_Container_Uses_Submenu_Background_Tokens()
{
var source = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuItemTheme.axaml");
source.ShouldContain("Name=\"PART_ChildItemsFrame\"");
source.ShouldContain("Value=\"{atom:NavMenuTokenResource SubMenuItemBg}\"");
source.ShouldContain("Value=\"{atom:NavMenuTokenResource DarkSubMenuItemBg}\"");
}
[Fact]
public void Item_Background_Control_Is_Public_And_Forwarded_To_Internal_Menu_Parts()
{
var navMenuSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/NavMenu.cs");
var navMenuItemSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/NavMenuItem.cs");
var headerSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Header/BaseNavMenuItemHeader.cs");
var navMenuThemeSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuItemTheme.axaml");
navMenuSource.ShouldContain("public static readonly StyledProperty<bool> IsItemBackgroundEnabledProperty");
navMenuSource.ShouldContain("AvaloniaProperty.Register<NavMenu, bool>(nameof(IsItemBackgroundEnabled), true)");
navMenuSource.ShouldContain("public bool IsItemBackgroundEnabled");
navMenuSource.ShouldContain("menuItem[!NavMenuItem.IsItemBackgroundEnabledProperty] = this[!IsItemBackgroundEnabledProperty];");
navMenuItemSource.ShouldContain("internal static readonly StyledProperty<bool> IsItemBackgroundEnabledProperty");
navMenuItemSource.ShouldContain("menuItem[!NavMenuItem.IsItemBackgroundEnabledProperty] = this[!IsItemBackgroundEnabledProperty];");
headerSource.ShouldContain("internal static readonly StyledProperty<bool> IsItemBackgroundEnabledProperty");
navMenuThemeSource.ShouldContain("IsItemBackgroundEnabled=\"{TemplateBinding IsItemBackgroundEnabled}\"");
}
[Fact]
public void Disabled_Item_Background_Mode_Gates_Item_Background_Without_Gating_Header_Backgrounds()
{
var headerThemeSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/BaseNavMenuItemHeaderTheme.axaml");
var horizontalThemeSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/HorizontalNavMenuItemHeaderTheme.axaml");
var navMenuItemThemeSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuItemTheme.axaml");
headerThemeSource.ShouldNotContain("Selector=\"^[IsItemBackgroundEnabled=True]\"");
headerThemeSource.ShouldNotContain("Selector=\"^[IsItemBackgroundEnabled=False]\"");
horizontalThemeSource.ShouldNotContain("Selector=\"^[IsItemBackgroundEnabled=True]\"");
horizontalThemeSource.ShouldNotContain("Selector=\"^[IsItemBackgroundEnabled=False]\"");
navMenuItemThemeSource.ShouldContain("Selector=\"^[IsItemBackgroundEnabled=True]\"");
navMenuItemThemeSource.ShouldContain("Selector=\"^[IsItemBackgroundEnabled=False]\"");
navMenuItemThemeSource.ShouldContain("Selector=\"^ /template/ Border#PART_ChildItemsFrame\"");
navMenuItemThemeSource.ShouldContain("<Setter Property=\"Background\" Value=\"Transparent\" />");
}
[Fact]
public void Block_And_Popup_Item_Header_Backgrounds_Use_Content_Margin()
{
var inlineHeaderSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/InlineNavMenuItemHeaderTheme.axaml");
var verticalHeaderSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/VerticalNavMenuItemHeaderTheme.axaml");
var horizontalHeaderSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/HorizontalNavMenuItemHeaderTheme.axaml");
inlineHeaderSource.ShouldContain("<Setter Property=\"Margin\" Value=\"{atom:NavMenuTokenResource ItemContentMargin}\" />");
verticalHeaderSource.ShouldContain("<Setter Property=\"Margin\" Value=\"{atom:NavMenuTokenResource ItemContentMargin}\" />");
horizontalHeaderSource.ShouldContain("Selector=\"^[IsTopLevel=False]\"");
horizontalHeaderSource.ShouldContain("<Setter Property=\"Margin\" Value=\"{atom:NavMenuTokenResource ItemContentMargin}\" />");
}
[Fact]
public void Popup_Frame_Uses_Component_Popup_Background_Token()
{
var source = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuItemTheme.axaml");
source.ShouldContain("Value=\"{atom:NavMenuTokenResource MenuPopupBg}\"");
source.ShouldNotContain("Value=\"{atom:SharedTokenResource ColorBgElevated}\"");
}
[Fact]
public void Inline_And_Vertical_Pressed_State_Does_Not_Style_Header_From_Ancestor_NavMenuItem()
{
var source = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuItemTheme.axaml");
source.ShouldNotContain(":pressed:not(:selected):not(^[IsDarkStyle=True])");
source.ShouldNotContain("Value=\"{atom:NavMenuTokenResource ItemActiveBg}\"");
}
[Fact]
public void Keyboard_Active_Visual_Is_Header_State_And_Does_Not_ReUse_Selected_State()
{
var headerSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/BaseNavMenuItemHeaderTheme.axaml");
var navMenuItemSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuItemTheme.axaml");
navMenuItemSource.ShouldContain("IsKeyboardActive=\"{TemplateBinding IsKeyboardActive}\"");
headerSource.ShouldContain("Selector=\"^[IsKeyboardActive=True]:not(^[IsSelected=True])\"");
headerSource.ShouldNotContain("Selector=\"^[IsKeyboardActive=True]:not(^[IsSelected=True]):not(^[IsInSelectedPath=True])\"");
headerSource.ShouldContain("Value=\"{atom:NavMenuTokenResource ItemActiveBg}\"");
headerSource.ShouldContain("Value=\"{atom:NavMenuTokenResource DarkItemHoverBg}\"");
}
[Fact]
public void Submenu_Title_Hover_Uses_Foreground_And_Background_Tokens()
{
var source = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/BaseNavMenuItemHeaderTheme.axaml");
source.ShouldContain("Value=\"{atom:NavMenuTokenResource ItemHoverColor}\"");
source.ShouldContain("Value=\"{atom:NavMenuTokenResource ItemHoverBg}\"");
source.ShouldContain("Value=\"{atom:NavMenuTokenResource DarkItemHoverColor}\"");
source.ShouldContain("Value=\"{atom:NavMenuTokenResource DarkItemHoverBg}\"");
}
[Fact]
public void NavMenu_Tokens_Keep_Root_And_Header_Background_Semantics_Separate()
{
var tokenSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/NavMenuToken.cs");
var headerSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/BaseNavMenuItemHeaderTheme.axaml");
tokenSource.ShouldContain("ItemBg = SharedToken.ColorBgContainer;");
headerSource.ShouldContain("<Setter Property=\"Background\" Value=\"Transparent\" />");
}
[Fact]
public void Inline_Collapsed_Uses_Effective_Mode_And_Axaml_Visual_State()
{
var navMenuSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/NavMenu.cs");
var navMenuThemeSource = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuTheme.axaml");
var navMenuItemTheme = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/NavMenuItemTheme.axaml");
var verticalHeaderTheme = ReadRepoFile("src/AtomUI.Desktop.Controls/NavMenu/Themes/VerticalNavMenuItemHeaderTheme.axaml");
navMenuSource.ShouldContain("public static readonly StyledProperty<bool> IsInlineCollapsedProperty");
navMenuSource.ShouldContain("public static readonly StyledProperty<double> InlineCollapsedWidthProperty");
navMenuSource.ShouldContain("internal static readonly StyledProperty<double> InlineCollapsedLayoutWidthProperty");
navMenuSource.ShouldContain("menuItem[!NavMenuItem.ModeProperty] = this[!EffectiveModeProperty];");
navMenuSource.ShouldContain("menuItem[!NavMenuItem.IsInlineCollapsedProperty] = this[!IsEffectiveInlineCollapsedProperty];");
navMenuSource.ShouldNotContain("Layoutable.MaxWidthProperty");
navMenuSource.ShouldNotContain("Layoutable.WidthProperty,\n BindingMode.OneWay,\n BindingPriority.Animation");
navMenuSource.ShouldContain("WidthProperty.OverrideMetadata<NavMenu>");
navMenuSource.ShouldContain("RunInlineCollapsedWidthMotionAsync");
navMenuThemeSource.ShouldContain("<Setter Property=\"InlineCollapsedWidth\" Value=\"{atom:NavMenuTokenResource InlineCollapsedWidth}\" />");
navMenuThemeSource.ShouldNotContain("<DoubleTransition Property=\"Width\"");
navMenuThemeSource.ShouldNotContain("{Binding InlineCollapsedWidth");
navMenuItemTheme.ShouldContain("IsInlineCollapsed=\"{TemplateBinding IsInlineCollapsed}\"");
verticalHeaderTheme.ShouldContain("Selector=\"^[IsInlineCollapsed=True]\"");
verticalHeaderTheme.ShouldContain("Value=\"{atom:NavMenuTokenResource CollapsedIconSize}\"");
verticalHeaderTheme.ShouldContain("FirstCharacterConverter");
}
private static string ReadRepoFile(string relativePath)
{
var directory = new DirectoryInfo(AppContext.BaseDirectory);
while (directory is not null)
{
var candidate = Path.Combine(directory.FullName, relativePath);
if (File.Exists(candidate))
{
return File.ReadAllText(candidate);
}
directory = directory.Parent;
}
throw new FileNotFoundException($"Could not find repository file: {relativePath}");
}
}