using Avalonia.Controls; using Avalonia.Headless.XUnit; using AvParser.UI; using AvParser.UI.ViewModels; using AvParser.UI.Views; using Microsoft.Extensions.DependencyInjection; namespace AvParser.UI.HeadlessTests; public class ViewLocatorTests { private static ViewLocator Locator(Action? configure = null) { var services = new ServiceCollection(); configure?.Invoke(services); return new ViewLocator(services.BuildServiceProvider()); } [Fact] public void Matches_view_models_only() { var locator = Locator(); locator.Match(new FakePage("x")).ShouldBeTrue(); locator.Match("a string").ShouldBeFalse(); locator.Match(null).ShouldBeFalse(); } [AvaloniaFact] public void Resolves_a_view_by_naming_convention() { var locator = Locator(); var viewModel = new AboutViewModel(new TestPaths()); var view = locator.Build(viewModel); view.ShouldBeOfType(); view.DataContext.ShouldBeSameAs(viewModel); } [AvaloniaFact] public void Prefers_a_registered_view_over_activation() { var registered = new AboutView(); var locator = Locator(services => services.AddSingleton(registered)); var view = locator.Build(new AboutViewModel(new TestPaths())); view.ShouldBeSameAs(registered); } [AvaloniaFact] public void Reports_a_missing_view_instead_of_throwing() { var locator = Locator(); // "FakePage" matches neither half of the convention, so the locator must report a miss // rather than resolving the view model as its own view and failing to activate it. var view = locator.Build(new FakePage("x")); view.ShouldBeOfType().Text!.ShouldContain("View not found"); } [Fact] public void Builds_a_placeholder_for_a_null_view_model() => Locator().Build(null).ShouldBeOfType(); private sealed class TestPaths : Infrastructure.Storage.IAppPaths { public string DataDirectory => Path.Combine(Path.GetTempPath(), "AvParserTests"); public string SettingsFile => Path.Combine(DataDirectory, "settings.json"); public string CustomProxiesFile => Path.Combine(DataDirectory, "proxies.custom.json"); public string ProxyStateFile => Path.Combine(DataDirectory, "proxies.state.json"); public string LogDirectory => Path.Combine(DataDirectory, "logs"); } }