diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/DataTemplateSelector.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/DataTemplateSelector.cs new file mode 100644 index 0000000..e317664 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/DataTemplateSelector.cs @@ -0,0 +1,22 @@ +using Avalonia.Controls; +using Avalonia.Controls.Templates; +using Avalonia.Metadata; + +namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation; + +internal class DataTemplateSelector : IDataTemplate +{ + [Content] public Dictionary Templates { get; } = new(); + + public Control? Build(object? param) + { + if (param is null) return null; + var type = param.GetType(); + return Templates.TryGetValue(type, out var template) ? template?.Build(param) : null; + } + + public bool Match(object? data) + { + return data is IFromItemViewModel; + } +} \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/Test.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/Test.cs new file mode 100644 index 0000000..ed0266e --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/Test.cs @@ -0,0 +1,124 @@ +using System.Collections.ObjectModel; +using Avalonia.Controls; +using Avalonia.Headless.XUnit; +using Avalonia.LogicalTree; +using Ursa.Controls; + +namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation; + +public class Test +{ + [AvaloniaFact] + public void FormItem_Generation() + { + // Arrange + var viewModel = new TestViewModel(); + viewModel.Items = new ObservableCollection + { + new FormTextViewModel { Label = "First Name" }, + new FormTextViewModel { Label = "Last Name" }, + new FormAgeViewModel { Label = "Age" }, + new FormDateRangeViewModel { Label = "Date of Birth" } + }; + var window = new TestWindow { DataContext = viewModel }; + + // Act + window.Show(); + + var form = window.FindControl
("Form"); + var logicalChildren = form.GetLogicalChildren().ToList(); + Assert.True(logicalChildren.All(a=>a is FormItem)); + Assert.IsType(logicalChildren[0].LogicalChildren[0]); + Assert.IsType(logicalChildren[1].LogicalChildren[0]); + Assert.IsType(logicalChildren[2].LogicalChildren[0]); + Assert.IsType(logicalChildren[3].LogicalChildren[0]); + Assert.Equal("First Name", FormItem.GetLabel((Control)logicalChildren[0])); + Assert.Equal("Last Name", FormItem.GetLabel((Control)logicalChildren[1])); + Assert.Equal("Age", FormItem.GetLabel((Control)logicalChildren[2])); + Assert.Equal("Date of Birth", FormItem.GetLabel((Control)logicalChildren[3])); + + window.Close(); + } + + [AvaloniaFact] + public void FormGroup_Generation() + { + // Arrange + var viewModel = new TestViewModel(); + viewModel.Items = new ObservableCollection + { + new FormGroupViewModel + { + Title = "Basic Information", + Items = new ObservableCollection + { + new FormTextViewModel { Label = "First Name" }, + new FormTextViewModel { Label = "Last Name" }, + new FormAgeViewModel { Label = "Age" }, + new FormDateRangeViewModel { Label = "Date of Birth" } + } + } + }; + var window = new TestWindow { DataContext = viewModel }; + + // Act + window.Show(); + + var form = window.FindControl("Form"); + var logicalChildren = form.GetLogicalChildren().ToList(); + Assert.True(logicalChildren.All(a=>a is FormGroup)); + var formGroup = (FormGroup)logicalChildren[0]; + Assert.Equal("Basic Information", formGroup.Header); + var formItems = formGroup.GetLogicalChildren().ToList(); + Assert.True(formItems.All(a=>a is FormItem)); + Assert.IsType(formItems[0].LogicalChildren[0]); + Assert.IsType(formItems[1].LogicalChildren[0]); + Assert.IsType(formItems[2].LogicalChildren[0]); + Assert.IsType(formItems[3].LogicalChildren[0]); + Assert.Equal("First Name", FormItem.GetLabel((Control)formItems[0])); + Assert.Equal("Last Name", FormItem.GetLabel((Control)formItems[1])); + Assert.Equal("Age", FormItem.GetLabel((Control)formItems[2])); + Assert.Equal("Date of Birth", FormItem.GetLabel((Control)formItems[3])); + + window.Close(); + } + + [AvaloniaFact] + public void Mixture_Generation() + { + // Arrange + var viewModel = new TestViewModel(); + viewModel.Items = new ObservableCollection + { + new FormTextViewModel { Label = "First Name" }, + new FormGroupViewModel + { + Title = "Basic Information", + Items = new ObservableCollection + { + new FormTextViewModel { Label = "Last Name" }, + new FormAgeViewModel { Label = "Age" }, + new FormDateRangeViewModel { Label = "Date of Birth" } + } + } + }; + var window = new TestWindow { DataContext = viewModel }; + + // Act + window.Show(); + + var form = window.FindControl("Form"); + var logicalChildren = form.GetLogicalChildren().ToList(); + Assert.True(logicalChildren.All(a=>a is FormItem || a is FormGroup)); + Assert.IsType(logicalChildren[0].LogicalChildren[0]); + var formGroup = (FormGroup)logicalChildren[1]; + Assert.Equal("Basic Information", formGroup.Header); + var formItems = formGroup.GetLogicalChildren().ToList(); + Assert.True(formItems.All(a=>a is FormItem)); + Assert.IsType(formItems[0].LogicalChildren[0]); + Assert.IsType(formItems[1].LogicalChildren[0]); + Assert.IsType(formItems[2].LogicalChildren[0]); + + window.Close(); + } +} \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestViewModel.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestViewModel.cs new file mode 100644 index 0000000..5e15349 --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestViewModel.cs @@ -0,0 +1,51 @@ +using System.Collections.ObjectModel; +using CommunityToolkit.Mvvm.ComponentModel; +using Irihi.Avalonia.Shared.Contracts; + +namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation; + +public class TestViewModel +{ + public ObservableCollection Items { get; set; } = []; +} + +public interface IFormElement +{ + +} + +public interface IFormGroupViewModel : IFormGroup, IFormElement +{ + public string? Title { get; set; } + public ObservableCollection Items { get; set; } +} + +public interface IFromItemViewModel: IFormElement +{ + public string? Label { get; set; } +} + +public partial class FormGroupViewModel : ObservableObject, IFormGroupViewModel +{ + [ObservableProperty] private string? _title; + public ObservableCollection Items { get; set; } = []; +} + +public partial class FormTextViewModel : ObservableObject, IFromItemViewModel +{ + [ObservableProperty] private string? _label; + [ObservableProperty] private string? _value; +} + +public partial class FormAgeViewModel : ObservableObject, IFromItemViewModel +{ + [ObservableProperty] private uint? _age; + [ObservableProperty] private string? _label; +} + +public partial class FormDateRangeViewModel : ObservableObject, IFromItemViewModel +{ + [ObservableProperty] private DateTime? _end; + [ObservableProperty] private string? _label; + [ObservableProperty] private DateTime? _start; +} \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestWindow.axaml b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestWindow.axaml new file mode 100644 index 0000000..c65b85e --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestWindow.axaml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestWindow.axaml.cs b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestWindow.axaml.cs new file mode 100644 index 0000000..f85d2fa --- /dev/null +++ b/tests/HeadlessTest.Ursa/Controls/FormTests/Dynamic_Item_Generation/TestWindow.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace HeadlessTest.Ursa.Controls.FormTests.Dynamic_Item_Generation; + +public partial class TestWindow : Window +{ + public TestWindow() + { + InitializeComponent(); + } +} \ No newline at end of file