XamlXNameResolverTests.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using System.Collections.Generic;
  2. using System.Linq;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. using Avalonia.Controls;
  6. using Avalonia.Generators.Common;
  7. using Avalonia.Generators.Common.Domain;
  8. using Avalonia.Generators.Compiler;
  9. using Avalonia.ReactiveUI;
  10. using Avalonia.Generators.Tests.Views;
  11. using Microsoft.CodeAnalysis;
  12. using Xunit;
  13. namespace Avalonia.Generators.Tests;
  14. public class XamlXNameResolverTests
  15. {
  16. [Theory]
  17. [InlineData(View.NamedControl)]
  18. [InlineData(View.XNamedControl)]
  19. [InlineData(View.AttachedProps)]
  20. public async Task Should_Resolve_Types_From_Avalonia_Markup_File_With_Named_Control(string resource)
  21. {
  22. var xaml = await View.Load(resource);
  23. var controls = ResolveNames(xaml);
  24. Assert.NotEmpty(controls);
  25. var control = Assert.Single(controls);
  26. Assert.Equal("UserNameTextBox", control.Name);
  27. Assert.Contains(typeof(TextBox).FullName!, control.TypeName);
  28. }
  29. [Theory]
  30. [InlineData(View.NamedControls)]
  31. [InlineData(View.XNamedControls)]
  32. public async Task Should_Resolve_Types_From_Avalonia_Markup_File_With_Named_Controls(string resource)
  33. {
  34. var xaml = await View.Load(resource);
  35. var controls = ResolveNames(xaml);
  36. Assert.NotEmpty(controls);
  37. Assert.Equal(3, controls.Count);
  38. Assert.Equal("UserNameTextBox", controls[0].Name);
  39. Assert.Equal("PasswordTextBox", controls[1].Name);
  40. Assert.Equal("SignUpButton", controls[2].Name);
  41. Assert.Contains(typeof(TextBox).FullName!, controls[0].TypeName);
  42. Assert.Contains(typeof(TextBox).FullName!, controls[1].TypeName);
  43. Assert.Contains(typeof(Button).FullName!, controls[2].TypeName);
  44. }
  45. [Fact]
  46. public async Task Should_Resolve_Types_From_Avalonia_Markup_File_With_Custom_Controls()
  47. {
  48. var xaml = await View.Load(View.CustomControls);
  49. var controls = ResolveNames(xaml);
  50. Assert.NotEmpty(controls);
  51. Assert.Equal(3, controls.Count);
  52. Assert.Equal("ClrNamespaceRoutedViewHost", controls[0].Name);
  53. Assert.Equal("UriRoutedViewHost", controls[1].Name);
  54. Assert.Equal("UserNameTextBox", controls[2].Name);
  55. Assert.Contains(typeof(RoutedViewHost).FullName!, controls[0].TypeName);
  56. Assert.Contains(typeof(RoutedViewHost).FullName!, controls[1].TypeName);
  57. Assert.Contains("Controls.CustomTextBox", controls[2].TypeName);
  58. }
  59. [Fact]
  60. public async Task Should_Resolve_Types_From_Avalonia_Markup_File_When_Types_Contains_Generic_Arguments()
  61. {
  62. var xaml = await View.Load(View.ViewWithGenericBaseView);
  63. var controls = ResolveNames(xaml);
  64. Assert.Equal(2, controls.Count);
  65. var currentControl = controls[0];
  66. Assert.Equal("Root", currentControl.Name);
  67. Assert.Equal("global::Sample.App.BaseView<global::System.String>", currentControl.TypeName);
  68. currentControl = controls[1];
  69. Assert.Equal("NotAsRootNode", currentControl.Name);
  70. Assert.Contains("Sample.App.BaseView", currentControl.TypeName);
  71. Assert.Equal("global::Sample.App.BaseView<global::System.Int32>", currentControl.TypeName);
  72. }
  73. [Fact]
  74. public async Task Should_Not_Resolve_Named_Controls_From_Avalonia_Markup_File_Without_Named_Controls()
  75. {
  76. var xaml = await View.Load(View.NoNamedControls);
  77. var controls = ResolveNames(xaml);
  78. Assert.Empty(controls);
  79. }
  80. [Fact]
  81. public async Task Should_Not_Resolve_Elements_From_DataTemplates()
  82. {
  83. var xaml = await View.Load(View.DataTemplates);
  84. var controls = ResolveNames(xaml);
  85. Assert.NotEmpty(controls);
  86. Assert.Equal(2, controls.Count);
  87. Assert.Equal("UserNameTextBox", controls[0].Name);
  88. Assert.Equal("NamedListBox", controls[1].Name);
  89. Assert.Contains(typeof(TextBox).FullName!, controls[0].TypeName);
  90. Assert.Contains(typeof(ListBox).FullName!, controls[1].TypeName);
  91. }
  92. [Fact]
  93. public async Task Should_Resolve_Names_From_Complex_Views()
  94. {
  95. var xaml = await View.Load(View.SignUpView);
  96. var controls = ResolveNames(xaml);
  97. Assert.NotEmpty(controls);
  98. Assert.Equal(10, controls.Count);
  99. Assert.Equal("UserNameTextBox", controls[0].Name);
  100. Assert.Equal("UserNameValidation", controls[1].Name);
  101. Assert.Equal("PasswordTextBox", controls[2].Name);
  102. Assert.Equal("PasswordValidation", controls[3].Name);
  103. Assert.Equal("AwesomeListView", controls[4].Name);
  104. Assert.Equal("ConfirmPasswordTextBox", controls[5].Name);
  105. Assert.Equal("ConfirmPasswordValidation", controls[6].Name);
  106. Assert.Equal("SignUpButtonDescription", controls[7].Name);
  107. Assert.Equal("SignUpButton", controls[8].Name);
  108. Assert.Equal("CompoundValidation", controls[9].Name);
  109. }
  110. private static IReadOnlyList<ResolvedName> ResolveNames(string xaml)
  111. {
  112. var nameResolver = new XamlXNameResolver();
  113. // Step 1: parse XAML as xml nodes, without any type information.
  114. var classResolver = new XamlXViewResolver(MiniCompiler.CreateNoop());
  115. var classInfo = classResolver.ResolveView(xaml, CancellationToken.None);
  116. Assert.NotNull(classInfo);
  117. var names = nameResolver.ResolveXmlNames(classInfo.Xaml, CancellationToken.None);
  118. // Step 2: use compilation context to resolve types
  119. var compilation =
  120. View.CreateAvaloniaCompilation()
  121. .WithCustomTextBox()
  122. .WithBaseView();
  123. return names.ResolveNames(compilation, nameResolver).ToArray();
  124. }
  125. }