#nullable enable using System; using System.Collections.Generic; using Avalonia.Controls; using Avalonia.Media; using Avalonia.Styling; using Avalonia.UnitTests; using Xunit; namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions { public class ResourceIncludeTests : XamlTestBase { [Theory] [InlineData(false)] [InlineData(true)] public void ResourceInclude_Loads_ResourceDictionary(bool createSourceInfo) { var documents = new[] { new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resource.xaml"), @" #ff506070 "), new RuntimeXamlLoaderDocument(@" ") }; var config = new RuntimeXamlLoaderConfiguration { CreateSourceInfo = createSourceInfo }; using (StartWithResources()) { var compiled = AvaloniaRuntimeXamlLoader.LoadGroup(documents, config); var userControl = Assert.IsType(compiled[1]); var border = userControl.GetControl("border"); var brush = (ISolidColorBrush)border.Background!; Assert.Equal(0xff506070, brush.Color.ToUInt32()); } } [Fact] public void Missing_ResourceKey_In_ResourceInclude_Does_Not_Cause_StackOverflow() { var app = Application.Current; var documents = new[] { new RuntimeXamlLoaderDocument(new Uri("avares://Tests/Resource.xaml"), @" "), new RuntimeXamlLoaderDocument(app, @" ") }; using (StartWithResources()) { try { AvaloniaRuntimeXamlLoader.LoadGroup(documents); } catch (KeyNotFoundException) { } } } [Fact] public void ResourceInclude_Should_Be_Allowed_To_Have_Key_In_Custom_Container() { var app = Application.Current; var documents = new[] { new RuntimeXamlLoaderDocument(new Uri("avares://Demo/en-us.axaml"), @" OK "), new RuntimeXamlLoaderDocument(app, @" ") }; using (StartWithResources()) { var groups = AvaloniaRuntimeXamlLoader.LoadGroup(documents); var res = Assert.IsType(groups[1]); Assert.True(res.TryGetResource("OkButton", null, out var val)); Assert.Equal("OK", val); } } private IDisposable StartWithResources(params (string, string)[] assets) { var assetLoader = new MockAssetLoader(assets); var services = new TestServices(assetLoader: assetLoader); return UnitTestApplication.Start(services); } } // See https://github.com/AvaloniaUI/Avalonia/issues/11172 public class LocaleCollection : ResourceProvider { private readonly Dictionary _langs = new(); public override bool HasResources => true; public override bool TryGetResource(object key, ThemeVariant? theme, out object? value) { if (_langs.TryGetValue("English", out var res)) { return res.TryGetResource(key, theme, out value); } value = null; return false; } // Allow Avalonia to use this class as a collection, requires x:Key on the IResourceProvider public void Add(object k, IResourceProvider v) => _langs.Add(k, v); } }