2
2
// The .NET Foundation licenses this file to you under the MIT license.
3
3
4
4
using System . Collections . Generic ;
5
+ using System . Collections . ObjectModel ;
5
6
using System . Diagnostics ;
6
7
using System . Linq ;
7
8
using System . Reflection ;
@@ -11,14 +12,96 @@ namespace System.Collections.Tests
11
12
{
12
13
public class DebugView_Tests
13
14
{
14
- public static IEnumerable < object [ ] > TestDebuggerAttributes_Inputs ( )
15
+ private static IEnumerable < object [ ] > TestDebuggerAttributes_GenericDictionaries ( )
16
+ {
17
+ yield return new object [ ] { new Dictionary < int , string > ( ) , new KeyValuePair < string , string > [ 0 ] } ;
18
+ yield return new object [ ] { new ReadOnlyDictionary < int , string > ( new Dictionary < int , string > ( ) ) , new KeyValuePair < string , string > [ 0 ] } ;
19
+ yield return new object [ ] { new SortedDictionary < string , int > ( ) , new KeyValuePair < string , string > [ 0 ] } ;
20
+ yield return new object [ ] { new SortedList < int , string > ( ) , new KeyValuePair < string , string > [ 0 ] } ;
21
+
22
+ yield return new object [ ] { new Dictionary < int , string > { { 1 , "One" } , { 2 , "Two" } } ,
23
+ new KeyValuePair < string , string > [ ]
24
+ {
25
+ new ( "[1]" , "\" One\" " ) ,
26
+ new ( "[2]" , "\" Two\" " ) ,
27
+ }
28
+ } ;
29
+ yield return new object [ ] { new ReadOnlyDictionary < int , string > ( new Dictionary < int , string > { { 1 , "One" } , { 2 , "Two" } } ) ,
30
+ new KeyValuePair < string , string > [ ]
31
+ {
32
+ new ( "[1]" , "\" One\" " ) ,
33
+ new ( "[2]" , "\" Two\" " ) ,
34
+ }
35
+ } ;
36
+ yield return new object [ ] { new SortedDictionary < string , int > { { "One" , 1 } , { "Two" , 2 } } ,
37
+ new KeyValuePair < string , string > [ ]
38
+ {
39
+ new ( "[\" One\" ]" , "1" ) ,
40
+ new ( "[\" Two\" ]" , "2" ) ,
41
+ }
42
+ } ;
43
+ yield return new object [ ] { new SortedList < string , double > { { "One" , 1.0 } , { "Two" , 2.0 } } ,
44
+ new KeyValuePair < string , string > [ ]
45
+ {
46
+ new ( "[\" One\" ]" , "1" ) ,
47
+ new ( "[\" Two\" ]" , "2" ) ,
48
+ }
49
+ } ;
50
+ }
51
+
52
+ private static IEnumerable < object [ ] > TestDebuggerAttributes_NonGenericDictionaries ( )
53
+ {
54
+ yield return new object [ ] { new Hashtable ( ) , new KeyValuePair < string , string > [ 0 ] } ;
55
+ yield return new object [ ] { Hashtable . Synchronized ( new Hashtable ( ) ) , new KeyValuePair < string , string > [ 0 ] } ;
56
+ yield return new object [ ] { new SortedList ( ) , new KeyValuePair < string , string > [ 0 ] } ;
57
+ yield return new object [ ] { SortedList . Synchronized ( new SortedList ( ) ) , new KeyValuePair < string , string > [ 0 ] } ;
58
+
59
+ yield return new object [ ] { new Hashtable { { "a" , 1 } , { "b" , "B" } } ,
60
+ new KeyValuePair < string , string > [ ]
61
+ {
62
+ new ( "[\" a\" ]" , "1" ) ,
63
+ new ( "[\" b\" ]" , "\" B\" " ) ,
64
+ }
65
+ } ;
66
+ yield return new object [ ] { Hashtable . Synchronized ( new Hashtable { { "a" , 1 } , { "b" , "B" } } ) ,
67
+ new KeyValuePair < string , string > [ ]
68
+ {
69
+ new ( "[\" a\" ]" , "1" ) ,
70
+ new ( "[\" b\" ]" , "\" B\" " ) ,
71
+ }
72
+ } ;
73
+ yield return new object [ ] { new SortedList { { "a" , 1 } , { "b" , "B" } } ,
74
+ new KeyValuePair < string , string > [ ]
75
+ {
76
+ new ( "[\" a\" ]" , "1" ) ,
77
+ new ( "[\" b\" ]" , "\" B\" " ) ,
78
+ }
79
+ } ;
80
+ yield return new object [ ] { SortedList . Synchronized ( new SortedList { { "a" , 1 } , { "b" , "B" } } ) ,
81
+ new KeyValuePair < string , string > [ ]
82
+ {
83
+ new ( "[\" a\" ]" , "1" ) ,
84
+ new ( "[\" b\" ]" , "\" B\" " ) ,
85
+ }
86
+ } ;
87
+ #if ! NETFRAMEWORK // ListDictionaryInternal in .Net Framework is not annotated with debugger attributes.
88
+ yield return new object [ ] { new Exception ( ) . Data , new KeyValuePair < string , string > [ 0 ] } ;
89
+ yield return new object [ ] { new Exception { Data = { { "a" , 1 } , { "b" , "B" } } } . Data ,
90
+ new KeyValuePair < string , string > [ ]
91
+ {
92
+ new ( "[\" a\" ]" , "1" ) ,
93
+ new ( "[\" b\" ]" , "\" B\" " ) ,
94
+ }
95
+ } ;
96
+ #endif
97
+ }
98
+
99
+ private static IEnumerable < object [ ] > TestDebuggerAttributes_ListInputs ( )
15
100
{
16
- yield return new object [ ] { new Dictionary < int , string > ( ) } ;
17
101
yield return new object [ ] { new HashSet < string > ( ) } ;
18
102
yield return new object [ ] { new LinkedList < object > ( ) } ;
19
103
yield return new object [ ] { new List < int > ( ) } ;
20
104
yield return new object [ ] { new Queue < double > ( ) } ;
21
- yield return new object [ ] { new SortedDictionary < string , int > ( ) } ;
22
105
yield return new object [ ] { new SortedList < int , string > ( ) } ;
23
106
yield return new object [ ] { new SortedSet < int > ( ) } ;
24
107
yield return new object [ ] { new Stack < object > ( ) } ;
@@ -30,39 +113,83 @@ public static IEnumerable<object[]> TestDebuggerAttributes_Inputs()
30
113
yield return new object [ ] { new SortedList < string , int > ( ) . Keys } ;
31
114
yield return new object [ ] { new SortedList < float , long > ( ) . Values } ;
32
115
33
- yield return new object [ ] { new Dictionary < int , string > { { 1 , "One" } , { 2 , "Two" } } } ;
34
- yield return new object [ ] { new HashSet < string > { "One" , "Two" } } ;
116
+ yield return new object [ ] { new HashSet < string > { "One" , "Two" } } ;
35
117
36
- LinkedList < object > linkedList = new LinkedList < object > ( ) ;
118
+ LinkedList < object > linkedList = new ( ) ;
37
119
linkedList . AddFirst ( 1 ) ;
38
120
linkedList . AddLast ( 2 ) ;
39
121
yield return new object [ ] { linkedList } ;
40
- yield return new object [ ] { new List < int > { 1 , 2 } } ;
122
+ yield return new object [ ] { new List < int > { 1 , 2 } } ;
41
123
42
- Queue < double > queue = new Queue < double > ( ) ;
124
+ Queue < double > queue = new ( ) ;
43
125
queue . Enqueue ( 1 ) ;
44
126
queue . Enqueue ( 2 ) ;
45
127
yield return new object [ ] { queue } ;
46
- yield return new object [ ] { new SortedDictionary < string , int > { { "One" , 1 } , { "Two" , 2 } } } ;
47
- yield return new object [ ] { new SortedList < int , string > { { 1 , "One" } , { 2 , "Two" } } } ;
48
- yield return new object [ ] { new SortedSet < int > { 1 , 2 } } ;
128
+ yield return new object [ ] { new SortedSet < int > { 1 , 2 } } ;
49
129
50
- var stack = new Stack < object > ( ) ;
130
+ Stack < object > stack = new ( ) ;
51
131
stack . Push ( 1 ) ;
52
132
stack . Push ( 2 ) ;
53
133
yield return new object [ ] { stack } ;
54
134
55
- yield return new object [ ] { new Dictionary < double , float > { { 1.0 , 1.0f } , { 2.0 , 2.0f } } . Keys } ;
56
- yield return new object [ ] { new Dictionary < float , double > { { 1.0f , 1.0 } , { 2.0f , 2.0 } } . Values } ;
57
- yield return new object [ ] { new SortedDictionary < Guid , string > { { Guid . NewGuid ( ) , "One" } , { Guid . NewGuid ( ) , "Two" } } . Keys } ;
58
- yield return new object [ ] { new SortedDictionary < long , Guid > { { 1L , Guid . NewGuid ( ) } , { 2L , Guid . NewGuid ( ) } } . Values } ;
59
- yield return new object [ ] { new SortedList < string , int > { { "One" , 1 } , { "Two" , 2 } } . Keys } ;
60
- yield return new object [ ] { new SortedList < float , long > { { 1f , 1L } , { 2f , 2L } } . Values } ;
135
+ yield return new object [ ] { new SortedList < string , int > { { "One" , 1 } , { "Two" , 2 } } . Keys } ;
136
+ yield return new object [ ] { new SortedList < float , long > { { 1f , 1L } , { 2f , 2L } } . Values } ;
137
+
138
+ yield return new object [ ] { new Dictionary < double , float > { { 1.0 , 1.0f } , { 2.0 , 2.0f } } . Keys } ;
139
+ yield return new object [ ] { new Dictionary < float , double > { { 1.0f , 1.0 } , { 2.0f , 2.0 } } . Values } ;
140
+ yield return new object [ ] { new SortedDictionary < Guid , string > { { Guid . NewGuid ( ) , "One" } , { Guid . NewGuid ( ) , "Two" } } . Keys } ;
141
+ yield return new object [ ] { new SortedDictionary < long , Guid > { { 1L , Guid . NewGuid ( ) } , { 2L , Guid . NewGuid ( ) } } . Values } ;
142
+ }
143
+
144
+ public static IEnumerable < object [ ] > TestDebuggerAttributes_InputsPresentedAsDictionary ( )
145
+ {
146
+ #if ! NETFRAMEWORK
147
+ return TestDebuggerAttributes_NonGenericDictionaries ( )
148
+ . Concat ( TestDebuggerAttributes_GenericDictionaries ( ) ) ;
149
+ #else
150
+ // In .Net Framework only non-generic dictionaries are displayed in a dictionary format by the debugger.
151
+ return TestDebuggerAttributes_NonGenericDictionaries ( ) ;
152
+ #endif
153
+ }
154
+
155
+ public static IEnumerable < object [ ] > TestDebuggerAttributes_InputsPresentedAsList ( )
156
+ {
157
+ #if ! NETFRAMEWORK
158
+ return TestDebuggerAttributes_ListInputs ( ) ;
159
+ #else
160
+ // In .Net Framework generic dictionaries are displayed in a list format by the debugger.
161
+ return TestDebuggerAttributes_GenericDictionaries ( )
162
+ . Select ( t => new [ ] { t [ 0 ] } )
163
+ . Concat ( TestDebuggerAttributes_ListInputs ( ) ) ;
164
+ #endif
165
+ }
166
+
167
+ public static IEnumerable < object [ ] > TestDebuggerAttributes_Inputs ( )
168
+ {
169
+ return TestDebuggerAttributes_InputsPresentedAsDictionary ( )
170
+ . Select ( t => new [ ] { t [ 0 ] } )
171
+ . Concat ( TestDebuggerAttributes_InputsPresentedAsList ( ) ) ;
61
172
}
62
173
63
174
[ ConditionalTheory ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . IsDebuggerTypeProxyAttributeSupported ) ) ]
64
- [ MemberData ( nameof ( TestDebuggerAttributes_Inputs ) ) ]
65
- public static void TestDebuggerAttributes ( object obj )
175
+ [ MemberData ( nameof ( TestDebuggerAttributes_InputsPresentedAsDictionary ) ) ]
176
+ public static void TestDebuggerAttributes_Dictionary ( IDictionary obj , KeyValuePair < string , string > [ ] expected )
177
+ {
178
+ DebuggerAttributes . ValidateDebuggerDisplayReferences ( obj ) ;
179
+ DebuggerAttributeInfo info = DebuggerAttributes . ValidateDebuggerTypeProxyProperties ( obj ) ;
180
+ PropertyInfo itemProperty = info . Properties . Single ( pr => pr . GetCustomAttribute < DebuggerBrowsableAttribute > ( ) . State == DebuggerBrowsableState . RootHidden ) ;
181
+ Array itemArray = ( Array ) itemProperty . GetValue ( info . Instance ) ;
182
+ List < KeyValuePair < string , string > > formatted = itemArray . Cast < object > ( )
183
+ . Select ( DebuggerAttributes . ValidateFullyDebuggerDisplayReferences )
184
+ . Select ( formattedResult => new KeyValuePair < string , string > ( formattedResult . Key , formattedResult . Value ) )
185
+ . ToList ( ) ;
186
+
187
+ CollectionAsserts . EqualUnordered ( ( ICollection ) expected , formatted ) ;
188
+ }
189
+
190
+ [ ConditionalTheory ( typeof ( PlatformDetection ) , nameof ( PlatformDetection . IsDebuggerTypeProxyAttributeSupported ) ) ]
191
+ [ MemberData ( nameof ( TestDebuggerAttributes_InputsPresentedAsList ) ) ]
192
+ public static void TestDebuggerAttributes_List ( object obj )
66
193
{
67
194
DebuggerAttributes . ValidateDebuggerDisplayReferences ( obj ) ;
68
195
DebuggerAttributeInfo info = DebuggerAttributes . ValidateDebuggerTypeProxyProperties ( obj ) ;
0 commit comments