Forge
csharpdeeb25a2
1using System.Collections.ObjectModel;
2using System.Reflection;
3using CascadeIDE.ViewModels;
4using CommunityToolkit.Mvvm.ComponentModel;
5using Xunit;
6
7namespace CascadeIDE.Tests;
8
9/// <summary>
10/// HSE: список <see cref="MainWindowViewModel"/> для <c>RaiseHybridIndexPresentationProperties</c> должен совпадать со
11/// <see cref="NotifyPropertyChangedForAttribute"/> у поля снимка HCI — один источник правды без дрейфа.
12/// </summary>
13public sealed class HybridIndexPresentationNotificationsConsistencyTests
14{
15 [Fact]
16 public void HybridIndexDependentPresentationNames_matches_observable_snapshot_notify_targets()
17 {
18 var observableField = typeof(MainWindowViewModel).GetField(
19 "_hybridIndexLast",
20 BindingFlags.Instance | BindingFlags.NonPublic);
21 Assert.NotNull(observableField);
22
23 var dependencyArrayField = typeof(MainWindowViewModel).GetField(
24 "HybridIndexDependentPresentationNames",
25 BindingFlags.Static | BindingFlags.NonPublic);
26 Assert.NotNull(dependencyArrayField);
27
28 var fromArray = ((string[])dependencyArrayField!.GetValue(null)!)
29 .ToHashSet(StringComparer.Ordinal);
30
31 var fromToolkit = CollectNotifyPropertyNames(observableField!);
32 Assert.NotEmpty(fromToolkit);
33
34 Assert.Equal(fromArray, fromToolkit);
35 }
36
37 private static HashSet<string> CollectNotifyPropertyNames(FieldInfo observableField)
38 {
39 var set = new HashSet<string>(StringComparer.Ordinal);
40
41 foreach (var cad in observableField.GetCustomAttributesData())
42 {
43 if (cad.AttributeType != typeof(NotifyPropertyChangedForAttribute))
44 continue;
45
46 foreach (var arg in cad.ConstructorArguments)
47 AddConstructorArgStrings(arg, set);
48 }
49
50 return set;
51 }
52
53 private static void AddConstructorArgStrings(CustomAttributeTypedArgument arg, HashSet<string> sink)
54 {
55 if (arg.Value is string s)
56 {
57 sink.Add(s);
58 return;
59 }
60
61 if (arg.Value is ReadOnlyCollection<CustomAttributeTypedArgument> elems)
62 {
63 foreach (var item in elems)
64 AddConstructorArgStrings(item, sink);
65 }
66 }
67}
68
View only · write via MCP/CIDE