// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Markup.Xaml.Data;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Markup.Xaml.Templates;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.UnitTests;
using System.Collections;
using System.ComponentModel;
using System.Linq;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{
public class BasicTests
{
[Fact]
public void Simple_Property_Is_Set()
{
var xaml = @" ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.NotNull(target);
Assert.Equal("Foo", target.Content);
}
[Fact]
public void Default_Content_Property_Is_Set()
{
var xaml = @"Foo ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.NotNull(target);
Assert.Equal("Foo", target.Content);
}
[Fact]
public void AvaloniaProperty_Without_Getter_And_Setter_Is_Set()
{
var xaml =
@" ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(55, target.GetValue(NonControl.FooProperty));
}
[Fact]
public void AvaloniaProperty_With_Getter_And_No_Setter_Is_Set()
{
var xaml =
@" ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal("bar", target.Bar);
}
[Fact]
public void Attached_Property_Is_Set()
{
var xaml =
@" ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.NotNull(target);
Assert.Equal(21.0, TextBlock.GetFontSize(target));
}
[Fact]
public void Attached_Property_Supports_Binding()
{
using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
{
var xaml =
@" ";
var target = AvaloniaXamlLoader.Parse(xaml);
target.DataContext = 21.0;
Assert.Equal(21.0, TextBlock.GetFontSize(target));
}
}
[Fact]
public void Attached_Property_In_Panel_Is_Set()
{
var xaml = @"
Foo
";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(0, target.Children.Count);
Assert.Equal("Foo", ToolTip.GetTip(target));
}
[Fact]
public void ContentControl_ContentTemplate_Is_Functional()
{
var xaml =
@"
";
var contentControl = AvaloniaXamlLoader.Parse(xaml);
var target = contentControl.ContentTemplate;
Assert.NotNull(target);
var txt = (TextBlock)target.Build(null);
Assert.Equal("Foo", txt.Text);
}
[Fact]
public void Named_Control_Is_Added_To_NameScope_Simple()
{
var xaml = @"
Foo
";
var control = AvaloniaXamlLoader.Parse(xaml);
var button = control.FindControl("button");
Assert.Equal("Foo", button.Content);
}
[Fact]
public void Direct_Content_In_ItemsControl_Is_Operational()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
Foo
Bar
";
var control = AvaloniaXamlLoader.Parse(xaml);
var itemsControl = control.FindControl("items");
Assert.NotNull(itemsControl);
var items = itemsControl.Items.Cast().ToArray();
Assert.Equal("Foo", items[0].Content);
Assert.Equal("Bar", items[1].Content);
}
}
[Fact]
public void Panel_Children_Are_Added()
{
var xaml = @"
";
var control = AvaloniaXamlLoader.Parse(xaml);
var panel = control.FindControl("panel");
Assert.Equal(2, panel.Children.Count);
var foo = control.FindControl("Foo");
var bar = control.FindControl("Bar");
Assert.Contains(foo, panel.Children);
Assert.Contains(bar, panel.Children);
}
[Fact]
public void Grid_Row_Col_Definitions_Are_Built()
{
var xaml = @"
";
var grid = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(4, grid.ColumnDefinitions.Count);
Assert.Equal(4, grid.RowDefinitions.Count);
var expected1 = new GridLength(100);
var expected2 = GridLength.Auto;
var expected3 = new GridLength(1, GridUnitType.Star);
var expected4 = new GridLength(100, GridUnitType.Star);
Assert.Equal(expected1, grid.ColumnDefinitions[0].Width);
Assert.Equal(expected2, grid.ColumnDefinitions[1].Width);
Assert.Equal(expected3, grid.ColumnDefinitions[2].Width);
Assert.Equal(expected4, grid.ColumnDefinitions[3].Width);
Assert.Equal(expected1, grid.RowDefinitions[0].Height);
Assert.Equal(expected2, grid.RowDefinitions[1].Height);
Assert.Equal(expected3, grid.RowDefinitions[2].Height);
Assert.Equal(expected4, grid.RowDefinitions[3].Height);
}
[Fact]
public void Grid_Row_Col_Definitions_Are_Parsed()
{
var xaml = @"
";
var grid = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(4, grid.ColumnDefinitions.Count);
Assert.Equal(4, grid.RowDefinitions.Count);
var expected1 = new GridLength(100);
var expected2 = GridLength.Auto;
var expected3 = new GridLength(1, GridUnitType.Star);
var expected4 = new GridLength(100, GridUnitType.Star);
Assert.Equal(expected1, grid.ColumnDefinitions[0].Width);
Assert.Equal(expected2, grid.ColumnDefinitions[1].Width);
Assert.Equal(expected3, grid.ColumnDefinitions[2].Width);
Assert.Equal(expected4, grid.ColumnDefinitions[3].Width);
Assert.Equal(expected1, grid.RowDefinitions[0].Height);
Assert.Equal(expected2, grid.RowDefinitions[1].Height);
Assert.Equal(expected3, grid.RowDefinitions[2].Height);
Assert.Equal(expected4, grid.RowDefinitions[3].Height);
}
[Fact]
public void ControlTemplate_With_Nested_Child_Is_Operational()
{
var xaml = @"
";
var template = AvaloniaXamlLoader.Parse(xaml);
var parent = (ContentControl)template.Build(new ContentControl());
Assert.Equal("parent", parent.Name);
var child = parent.Content as ContentControl;
Assert.NotNull(child);
Assert.Equal("child", child.Name);
}
[Fact]
public void ControlTemplate_With_Panel_Children_Are_Added()
{
var xaml = @"
";
var template = AvaloniaXamlLoader.Parse(xaml);
var panel = (Panel)template.Build(new ContentControl());
Assert.Equal(2, panel.Children.Count);
var foo = panel.Children[0];
var bar = panel.Children[1];
Assert.Equal("Foo", foo.Name);
Assert.Equal("Bar", bar.Name);
}
[Fact]
public void Named_x_Control_Is_Added_To_NameScope_Simple()
{
var xaml = @"
Foo
";
var control = AvaloniaXamlLoader.Parse(xaml);
var button = control.FindControl("button");
Assert.Equal("Foo", button.Content);
}
[Fact]
public void Standart_TypeConverter_Is_Used()
{
var xaml = @" ";
var control = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(200.5, control.Width);
}
[Fact]
public void Avalonia_TypeConverter_Is_Used()
{
var xaml = @" ";
var control = AvaloniaXamlLoader.Parse(xaml);
var bk = control.Background;
Assert.IsType(bk);
Assert.Equal(Colors.White, (bk as SolidColorBrush).Color);
}
[Fact]
public void Simple_Style_Is_Parsed()
{
var xaml = @"
";
var styles = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(1, styles.Count);
var style = (Style)styles[0];
var setters = style.Setters.Cast().ToArray();
Assert.Equal(2, setters.Length);
Assert.Equal(TextBlock.BackgroundProperty, setters[0].Property);
Assert.Equal(Brushes.White.Color, ((ISolidColorBrush)setters[0].Value).Color);
Assert.Equal(TextBlock.WidthProperty, setters[1].Property);
Assert.Equal(100.0, setters[1].Value);
}
[Fact]
public void Style_Setter_With_AttachedProperty_Is_Parsed()
{
var xaml = @"
";
var styles = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(1, styles.Count);
var style = (Style)styles[0];
var setters = style.Setters.Cast().ToArray();
Assert.Equal(1, setters.Length);
Assert.Equal(TextBlock.FontSizeProperty, setters[0].Property);
Assert.Equal(21.0, setters[0].Value);
}
[Fact]
public void Complex_Style_Is_Parsed()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var styles = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(1, styles.Count);
var style = (Style)styles[0];
var setters = style.Setters.Cast().ToArray();
Assert.Equal(3, setters.Length);
Assert.Equal(CheckBox.BorderBrushProperty, setters[0].Property);
Assert.Equal(CheckBox.BorderThicknessProperty, setters[1].Property);
Assert.Equal(CheckBox.TemplateProperty, setters[2].Property);
Assert.IsType(setters[0].Value);
Assert.IsType(setters[1].Value);
Assert.IsType(setters[2].Value);
}
}
[Fact]
public void Style_Resources_Are_Built()
{
var xaml = @"
";
var style = AvaloniaXamlLoader.Parse ";
var styles = AvaloniaXamlLoader.Parse(xaml);
Assert.True(styles.Count == 1);
var styleInclude = styles.First() as StyleInclude;
Assert.NotNull(styleInclude);
var style = styleInclude.Loaded;
Assert.NotNull(style);
}
}
[Fact]
public void Simple_Xaml_Binding_Is_Operational()
{
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper
.With(windowingPlatform: new MockWindowingPlatform())))
{
var xaml =
@" ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.Null(target.Content);
target.DataContext = "Foo";
Assert.Equal("Foo", target.Content);
}
}
[Fact]
public void Xaml_Binding_Is_Delayed()
{
using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
{
var xaml =
@" ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.Null(target.Content);
target.DataContext = "Foo";
Assert.Null(target.Content);
DelayedBinding.ApplyBindings(target);
Assert.Equal("Foo", target.Content);
}
}
[Fact]
public void Double_Xaml_Binding_Is_Operational()
{
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper
.With(windowingPlatform: new MockWindowingPlatform())))
{
var xaml =
@" ";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.Null(target.Content);
target.DataContext = 55.0;
Assert.Equal(55.0, target.Width);
}
}
[Fact]
public void Collection_Xaml_Binding_Is_Operational()
{
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper
.With(windowingPlatform: new MockWindowingPlatform())))
{
var xaml = @"
";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.NotNull(target.Content);
var itemsControl = target.FindControl("itemsControl");
var items = new string[] { "Foo", "Bar" };
//DelayedBinding.ApplyBindings(itemsControl);
target.DataContext = items;
Assert.Equal(items, itemsControl.Items);
}
}
[Fact]
public void Multi_Xaml_Binding_Is_Parsed()
{
var xaml =
@"
";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.Equal(2, target.Bindings.Count);
Assert.Equal(BoolConverters.And, target.Converter);
var bindings = target.Bindings.Cast().ToArray();
Assert.Equal("Foo", bindings[0].Path);
Assert.Equal("Bar", bindings[1].Path);
}
[Fact]
public void Control_Template_Is_Operational()
{
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper
.With(windowingPlatform: new MockWindowingPlatform())))
{
var xaml = @"
";
var target = AvaloniaXamlLoader.Parse(xaml);
Assert.NotNull(target.Template);
Assert.Null(target.Presenter);
target.ApplyTemplate();
Assert.NotNull(target.Presenter);
target.Content = "Foo";
Assert.Equal("Foo", target.Presenter.Content);
}
}
[Fact]
public void Style_ControlTemplate_Is_Built()
{
var xaml = @"
";
var style = AvaloniaXamlLoader.Parse
";
var window = AvaloniaXamlLoader.Parse(xaml);
var tracker = (InitializationOrderTracker)window.Content;
//ensure binding is set and operational first
Assert.Equal(100.0, tracker.Tag);
Assert.Equal("EndInit 0", tracker.Order.Last());
}
}
[Fact]
public void BeginInit_Matches_EndInit()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var window = AvaloniaXamlLoader.Parse(xaml);
var tracker = (InitializationOrderTracker)window.Content;
Assert.Equal(0, tracker.InitState);
}
}
[Fact]
public void DeferedXamlLoader_Should_Preserve_NamespacesContext()
{
var xaml =
@"
";
var contentControl = AvaloniaXamlLoader.Parse(xaml);
var template = contentControl.ContentTemplate;
Assert.NotNull(template);
var txt = (TextBlock)template.Build(null);
Assert.Equal((object)NonControl.StringProperty, txt.Tag);
}
[Fact]
public void Binding_To_List_AvaloniaProperty_Is_Operational()
{
using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
{
var xaml = @"
";
var window = AvaloniaXamlLoader.Parse(xaml);
var listBox = (ListBox)window.Content;
var vm = new SelectedItemsViewModel()
{
Items = new string[] { "foo", "bar", "baz" }
};
window.DataContext = vm;
Assert.Equal(vm.Items, listBox.Items);
Assert.Equal(vm.SelectedItems, listBox.SelectedItems);
}
}
private class SelectedItemsViewModel : INotifyPropertyChanged
{
public string[] Items { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private IList _selectedItems = new AvaloniaList();
public IList SelectedItems
{
get { return _selectedItems; }
set
{
_selectedItems = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItems)));
}
}
}
}
}