Files
2026-07-31 23:45:25 +08:00

191 lines
5.6 KiB
C#

using System.Reactive.Disposables;
using AtomUI.Controls.Primitives;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Threading;
using Avalonia.VisualTree;
using Shouldly;
using Xunit;
using AvaloniaWindow = Avalonia.Controls.Window;
using AtomUISizeType = AtomUI.SizeType;
namespace AtomUI.Desktop.Controls.Tests.Card;
public class CardBehaviorTests
{
static CardBehaviorTests()
{
AvaloniaTestApp.EnsureInitialized();
}
[Fact]
public void CardGridContent_ColumnDefinitions_Wrapper_Uses_Avalonia_Property()
{
var gridContent = new Desktop.Controls.CardGridContent();
var columns = new ColumnDefinitions("*,2*");
gridContent.SetValue(Desktop.Controls.CardGridContent.ColumnDefinitionsProperty, columns);
gridContent.ColumnDefinitions.ShouldBeSameAs(columns);
}
[Fact]
public void CardGridContent_RowDefinitions_Wrapper_Uses_Avalonia_Property()
{
var gridContent = new Desktop.Controls.CardGridContent();
var rows = new RowDefinitions("Auto,*");
gridContent.RowDefinitions = rows;
gridContent.GetValue(Desktop.Controls.CardGridContent.RowDefinitionsProperty).ShouldBeSameAs(rows);
}
[Fact]
public void Card_Content_Returns_To_Default_Layout_When_Grid_Content_Is_Replaced()
{
var card = new Desktop.Controls.Card
{
Width = 320,
Header = "Title",
Content = new Desktop.Controls.CardGridContent()
};
ShowInWindow(card, () =>
{
var body = FindCardContentBorder(card);
body.Padding.ShouldBe(new Thickness(0));
card.Content = new TextBlock { Text = "Plain content" };
Dispatcher.UIThread.RunJobs();
body.Padding.ShouldNotBe(new Thickness(0));
});
}
[Fact]
public void Card_Header_Frame_Keeps_Themed_Bottom_Separator()
{
var card = new Desktop.Controls.Card
{
Width = 320,
Header = "Title",
Content = new TextBlock { Text = "Plain content" }
};
ShowInWindow(card, () =>
{
var headerFrame = FindTemplatePixelAlignedBorder(card, "HeaderFrame");
headerFrame.BorderBrush.ShouldNotBeNull();
headerFrame.BorderThickness.Bottom.ShouldBeGreaterThan(0);
headerFrame.MinHeight.ShouldBeGreaterThan(0);
headerFrame.Padding.Left.ShouldBeGreaterThan(0);
});
}
[Fact]
public void Card_Releases_SizeType_Binding_From_Replaced_Special_Content()
{
var oldGridContent = new Desktop.Controls.CardGridContent();
var card = new Desktop.Controls.Card
{
SizeType = AtomUISizeType.Small,
Content = oldGridContent
};
ShowInWindow(card, () =>
{
oldGridContent.SizeType.ShouldBe(AtomUISizeType.Small);
card.Content = new TextBlock { Text = "Plain content" };
Dispatcher.UIThread.RunJobs();
card.SizeType = AtomUISizeType.Large;
Dispatcher.UIThread.RunJobs();
oldGridContent.SizeType.ShouldBe(AtomUISizeType.Middle);
});
}
[Fact]
public void CardGridContent_Disposes_Prepared_Container_State_When_Item_Is_Removed()
{
var disposeCount = 0;
var gridContent = new DisposableCardGridContent(() => disposeCount++);
var gridItem = new Desktop.Controls.CardGridItem();
gridContent.PrepareForTest(gridItem, "first", 0);
gridContent.ClearForTest(gridItem);
disposeCount.ShouldBe(1);
}
private static Border FindCardContentBorder(Desktop.Controls.Card card)
{
return FindTemplateBorder(card, "CardContent");
}
private static Border FindTemplateBorder(Desktop.Controls.Card card, string name)
{
return card.GetVisualDescendants()
.OfType<Border>()
.Single(border => border.Name == name);
}
private static PixelAlignedBorder FindTemplatePixelAlignedBorder(Desktop.Controls.Card card, string name)
{
return card.GetVisualDescendants()
.OfType<PixelAlignedBorder>()
.Single(border => border.Name == name);
}
private static void ShowInWindow(Control content, Action assertion)
{
var window = new AvaloniaWindow
{
Width = 480,
Height = 320,
Content = content
};
try
{
window.Show();
Dispatcher.UIThread.RunJobs();
assertion();
}
finally
{
window.Close();
}
}
private sealed class DisposableCardGridContent : Desktop.Controls.CardGridContent
{
private readonly Action _onDispose;
public DisposableCardGridContent(Action onDispose)
{
_onDispose = onDispose;
}
protected override void PrepareCardGridItem(Desktop.Controls.CardGridItem cardGridItem,
object? item,
int index,
CompositeDisposable compositeDisposable)
{
compositeDisposable.Add(Disposable.Create(_onDispose));
}
public void PrepareForTest(Control container, object? item, int index)
{
PrepareContainerForItemOverride(container, item, index);
}
public void ClearForTest(Control container)
{
ClearContainerForItemOverride(container);
}
}
}