using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Xml;
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Media;
using Avalonia.Styling;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml;
public class MergeResourceIncludeTests : XamlTestBase
{
static MergeResourceIncludeTests()
{
RuntimeHelpers.RunClassConstructor(typeof(RelativeSource).TypeHandle);
}
[Theory]
[InlineData(false)]
[InlineData(true)]
public void MergeResourceInclude_Works_With_Single_Resource(bool createSourceInfo)
{
var documents = new[]
{
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources.xaml"), @"
Red
"),
new RuntimeXamlLoaderDocument(@"
Blue
")
};
var config = new RuntimeXamlLoaderConfiguration { CreateSourceInfo = createSourceInfo };
var objects = AvaloniaRuntimeXamlLoader.LoadGroup(documents, config);
var contentControl = Assert.IsType(objects[1]);
var resources = Assert.IsType(contentControl.Resources);
Assert.Empty(resources.MergedDictionaries);
var initialResource = (ISolidColorBrush)resources["brush1"]!;
Assert.Equal(Colors.Blue, initialResource.Color);
var mergedResource = (ISolidColorBrush)resources["brush2"]!;
Assert.Equal(Colors.Red, mergedResource.Color);
}
[Fact]
public void Mixing_MergeResourceInclude_And_ResourceInclude_Is_Not_Allowed()
{
var documents = new[]
{
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources1.xaml"), @"
Red
"),
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources2.xaml"), @"
Blue
"),
new RuntimeXamlLoaderDocument(@"
")
};
Assert.ThrowsAny(() => AvaloniaRuntimeXamlLoader.LoadGroup(documents));
}
[Fact]
public void MergeResourceInclude_Is_Allowed_After_ResourceInclude()
{
var documents = new[]
{
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources1.xaml"), @"
Red
"),
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources2.xaml"), @"
Blue
"),
new RuntimeXamlLoaderDocument(@"
")
};
AvaloniaRuntimeXamlLoader.LoadGroup(documents);
}
[Fact]
public void MergeResourceInclude_Works_With_Multiple_Resources()
{
var documents = new[]
{
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources1.xaml"), @"
Red
Blue
"),
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources2.xaml"), @"
Yellow
"),
new RuntimeXamlLoaderDocument(@"
Black
White
"),
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources1_2.xaml"), @"
Green
"),
};
var objects = AvaloniaRuntimeXamlLoader.LoadGroup(documents);
var resources = Assert.IsType(objects[2]);
Assert.Empty(resources.MergedDictionaries);
Assert.Equal(Colors.Red, ((ISolidColorBrush)resources["brush1"]!).Color);
Assert.Equal(Colors.Blue, ((ISolidColorBrush)resources["brush2"]!).Color);
Assert.Equal(Colors.Green, ((ISolidColorBrush)resources["brush3"]!).Color);
Assert.Equal(Colors.Yellow, ((ISolidColorBrush)resources["brush4"]!).Color);
Assert.Equal(Colors.Black, ((ISolidColorBrush)resources["brush5"]!).Color);
Assert.Equal(Colors.White, ((ISolidColorBrush)resources["brush6"]!).Color);
}
[Fact]
public void MergeResourceInclude_Works_With_ThemeDictionaries()
{
var documents = new[]
{
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources1.xaml"), @"
White
Black
Black
White
"),
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources2.xaml"), @"
Red
Blue
Blue
Red
"),
new RuntimeXamlLoaderDocument(@"
"),
};
var objects = AvaloniaRuntimeXamlLoader.LoadGroup(documents);
var resources = Assert.IsType(objects[2]);
Assert.Empty(resources.MergedDictionaries);
Assert.Equal(Colors.White, Get("brush1", ThemeVariant.Light).Color);
Assert.Equal(Colors.Black, Get("brush2", ThemeVariant.Light).Color);
Assert.Equal(Colors.Black, Get("brush1", ThemeVariant.Dark).Color);
Assert.Equal(Colors.White, Get("brush2", ThemeVariant.Dark).Color);
Assert.Equal(Colors.Red, Get("brush3", ThemeVariant.Light).Color);
Assert.Equal(Colors.Blue, Get("brush4", ThemeVariant.Light).Color);
Assert.Equal(Colors.Blue, Get("brush3", ThemeVariant.Dark).Color);
Assert.Equal(Colors.Red, Get("brush4", ThemeVariant.Dark).Color);
ISolidColorBrush Get(string key, ThemeVariant themeVariant)
{
return resources.TryGetResource(key, themeVariant, out var res) ?
(ISolidColorBrush)res! :
throw new KeyNotFoundException();
}
}
[Fact]
public void MergeResourceInclude_Fails_With_ThemeDictionaries_Duplicate_Resources()
{
var documents = new[]
{
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources1.xaml"), @"
White
"),
new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resources2.xaml"), @"
Black
"),
new RuntimeXamlLoaderDocument(@"
"),
};
Assert.ThrowsAny(() => AvaloniaRuntimeXamlLoader.LoadGroup(documents));
}
}