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)); } }