using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Reactive.Subjects;
using System.Text;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Presenters;
using Avalonia.Data.Core;
using Avalonia.Markup.Data;
using Avalonia.UnitTests;
using XamlX;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
{
public class CompiledBindingExtensionTests
{
[Fact]
public void ResolvesClrPropertyBasedOnDataContextType()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext
{
StringProperty = "foobar"
};
window.DataContext = dataContext;
Assert.Equal(dataContext.StringProperty, textBlock.Text);
}
}
[Fact]
public void ResolvesPathPassedByProperty()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext
{
StringProperty = "foobar"
};
window.DataContext = dataContext;
Assert.Equal(dataContext.StringProperty, textBlock.Text);
}
}
[Fact]
public void ResolvesStreamTaskBindingCorrectly()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext
{
TaskProperty = Task.FromResult("foobar")
};
window.DataContext = dataContext;
Assert.Equal(dataContext.TaskProperty.Result, textBlock.Text);
}
}
[Fact]
public void ResolvesStreamObservableBindingCorrectly()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
DelayedBinding.ApplyBindings(textBlock);
var subject = new Subject();
var dataContext = new TestDataContext
{
ObservableProperty = subject
};
window.DataContext = dataContext;
subject.OnNext("foobar");
Assert.Equal("foobar", textBlock.Text);
}
}
[Fact]
public void ResolvesIndexerBindingCorrectly()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext
{
ListProperty = { "A", "B", "C", "D", "E" }
};
window.DataContext = dataContext;
Assert.Equal(dataContext.ListProperty[3], textBlock.Text);
}
}
[Fact]
public void ResolvesArrayIndexerBindingCorrectly()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext
{
ArrayProperty = new[] { "A", "B", "C", "D", "E" }
};
window.DataContext = dataContext;
Assert.Equal(dataContext.ArrayProperty[3], textBlock.Text);
}
}
[Fact]
public void ResolvesObservableIndexerBindingCorrectly()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext
{
ObservableCollectionProperty = { "A", "B", "C", "D", "E" }
};
window.DataContext = dataContext;
Assert.Equal(dataContext.ObservableCollectionProperty[3], textBlock.Text);
dataContext.ObservableCollectionProperty[3] = "New Value";
Assert.Equal(dataContext.ObservableCollectionProperty[3], textBlock.Text);
}
}
[Fact]
public void InfersCompiledBindingDataContextFromDataContextBinding()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
var dataContext = new TestDataContext
{
StringProperty = "A"
};
window.DataContext = dataContext;
Assert.Equal(dataContext.StringProperty, textBlock.Text);
}
}
[Fact]
public void ResolvesNonIntegerIndexerBindingCorrectly()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext();
dataContext.NonIntegerIndexerProperty["Test"] = "Initial Value";
window.DataContext = dataContext;
Assert.Equal(dataContext.NonIntegerIndexerProperty["Test"], textBlock.Text);
dataContext.NonIntegerIndexerProperty["Test"] = "New Value";
Assert.Equal(dataContext.NonIntegerIndexerProperty["Test"], textBlock.Text);
}
}
[Fact]
public void InfersDataTemplateTypeFromDataTypeProperty()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var target = window.FindControl("target");
var dataContext = new TestDataContext();
dataContext.StringProperty = "Initial Value";
window.DataContext = dataContext;
window.ApplyTemplate();
target.ApplyTemplate();
((ContentPresenter)target.Presenter).UpdateChild();
Assert.Equal(dataContext.StringProperty, ((TextBlock)target.Presenter.Child).Text);
}
}
[Fact]
public void ThrowsOnUninferrableLooseDataTemplateNoDataTypeWithCompiledBindingPath()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
Assert.Throws(() => loader.Load(xaml));
}
}
[Fact]
public void ThrowsOnUninferrableDataTypeFromNonCompiledDataContextBindingWithCompiledBindingPath()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
Assert.Throws(() => loader.Load(xaml));
}
}
[Fact]
public void InfersDataTemplateTypeFromParentCollectionItemsType()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var target = window.FindControl("target");
var dataContext = new TestDataContext();
dataContext.ListProperty.Add("Test");
window.DataContext = dataContext;
window.ApplyTemplate();
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Equal(dataContext.ListProperty[0], (string)((ContentPresenter)target.Presenter.Panel.Children[0]).Content);
}
}
[Fact]
public void ThrowsOnUninferrableDataTemplateInItemsControlWithoutItemsBinding()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
Assert.Throws(() => loader.Load(xaml));
}
}
[Fact]
public void ResolvesElementNameBinding()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("text2");
var dataContext = new TestDataContext
{
StringProperty = "foobar"
};
window.DataContext = dataContext;
Assert.Equal(dataContext.StringProperty, textBlock.Text);
}
}
[Fact]
public void ResolvesElementNameBindingFromLongForm()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("text2");
var dataContext = new TestDataContext
{
StringProperty = "foobar"
};
window.DataContext = dataContext;
Assert.Equal(dataContext.StringProperty, textBlock.Text);
}
}
[Fact]
public void ResolvesRelativeSourceBindingLongForm()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var target = window.FindControl("text");
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
target.ApplyTemplate();
Assert.Equal("test", target.Text);
}
}
[Fact]
public void ResolvesSourceBindingLongForm()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var target = window.FindControl("text");
window.ApplyTemplate();
window.Presenter.ApplyTemplate();
target.ApplyTemplate();
Assert.Equal("Test".Length.ToString(), target.Text);
}
}
[Fact]
public void CompilesBindingWhenRequested()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var textBlock = window.FindControl("textBlock");
var dataContext = new TestDataContext
{
StringProperty = "foobar"
};
window.DataContext = dataContext;
Assert.Equal(dataContext.StringProperty, textBlock.Text);
}
}
[Fact]
public void ThrowsOnInvalidBindingPathOnCompiledBindingEnabledViaDirective()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
Assert.Throws(() => loader.Load(xaml));
}
}
[Fact]
public void ThrowsOnInvalidCompileBindingsDirective()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var xaml = @"
";
var loader = new AvaloniaXamlLoader();
Assert.Throws(() => loader.Load(xaml));
}
}
}
public class TestDataContext
{
public string StringProperty { get; set; }
public Task TaskProperty { get; set; }
public IObservable ObservableProperty { get; set; }
public ObservableCollection ObservableCollectionProperty { get; set; } = new ObservableCollection();
public string[] ArrayProperty { get; set; }
public List ListProperty { get; set; } = new List();
public NonIntegerIndexer NonIntegerIndexerProperty { get; set; } = new NonIntegerIndexer();
public class NonIntegerIndexer : NotifyingBase
{
private readonly Dictionary _storage = new Dictionary();
public string this[string key]
{
get
{
return _storage[key];
}
set
{
_storage[key] = value;
RaisePropertyChanged(CommonPropertyNames.IndexerName);
}
}
}
}
}