Merge pull request #1659 from alexanderkyte/stringbuilder-referencesource
[mono.git] / mcs / class / monodoc / Test / Monodoc.Ecma / EcmaUrlTests.cs
1 using System;
2 using System.IO;
3 using System.Linq;
4 using System.Collections.Generic;
5
6 using NUnit.Framework;
7
8 using Monodoc;
9 using Monodoc.Ecma;
10
11 namespace MonoTests.Monodoc.Ecma
12 {
13         [TestFixture]
14         public class EcmaUrlTests
15         {
16                 EcmaUrlParser parser;
17
18                 [SetUp]
19                 public void Setup ()
20                 {
21                         parser = new EcmaUrlParser ();
22                 }
23                 
24                 void AssertValidUrl (string url)
25                 {
26                         try {
27                                 parser.IsValid (url);
28                         } catch {
29                                 Assert.Fail (string.Format ("URL '{0}' deemed not valid", url));
30                         }
31                 }
32
33                 void AssertInvalidUrl (string url)
34                 {
35                         try {
36                                 parser.IsValid (url);
37                         } catch {
38                                 return;
39                         }
40                         Assert.Fail (string.Format ("URL '{0}' deemed valid", url));
41                 }
42
43                 void AssertUrlDesc (EcmaDesc expected, string url)
44                 {
45                         EcmaDesc actual = null;
46                         try {
47                                 actual = parser.Parse (url);
48                         } catch (Exception e) {
49                                 Assert.Fail (string.Format ("URL '{0}' deemed not valid: {1}{2}", url, Environment.NewLine, e.ToString ()));
50                         }
51
52                         Assert.AreEqual (expected, actual, "Converted URL differs");
53                 }
54
55                 [Test]
56                 public void CommonMethodUrlIsValidTest ()
57                 {
58                         AssertValidUrl ("M:System.String.FooBar()");
59                         AssertValidUrl ("M:System.String.FooBar(System.String, Int32)");
60                         AssertValidUrl ("M:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>.Foo()");
61                         AssertValidUrl ("M:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>.Foo(Bleh,Bar)");
62                         AssertValidUrl ("M:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>.Foo(Bleh<V>,Bar)");
63                         AssertValidUrl ("M:Gendarme.Framework.Helpers.Log.WriteLine(string,string,object[])");
64                         AssertValidUrl ("M:Mono.Security.X509.Extensions.SubjectKeyIdentifierExtension.Decode");
65                         AssertValidUrl ("M:Mono.Security.PKCS7.IssuerAndSerialNumber");
66                 }
67
68                 [Test]
69                 public void CommonTypeUrlIsValidTest ()
70                 {
71                         AssertValidUrl ("T:Int32");
72                         AssertValidUrl ("T:System.Foo.Int32");
73                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar`1>");
74                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar<System.Blop<T, U>>>");
75                         AssertValidUrl ("T:System.Foo.Int32<T>");
76                         AssertValidUrl ("T:System.Foo.Int32<T,U>");
77                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar<System.Blop<T, U>>>");
78                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>");
79                 }
80
81                 [Test]
82                 public void CommonTypeUrlNotValidTest ()
83                 {
84                         AssertInvalidUrl ("TInt32");
85                         AssertInvalidUrl ("K:Int32");
86                         AssertInvalidUrl ("T:System..Foo.Int32");
87                         AssertInvalidUrl ("T:System.Foo.Int32<System.String+FooBar`1");
88                         AssertInvalidUrl ("T:System.Foo.Int32<System.String+FooBarSystem.Blop<T, U>>>");
89                         AssertInvalidUrl ("T:System.Foo.Int32<T,>");
90                         AssertInvalidUrl ("T:System.Foo.Int32<+FooBar<System.Blop<T, U>>>");
91                 }
92
93                 [Test]
94                 public void NamespaceValidTest ()
95                 {
96                         AssertValidUrl ("N:Foo.Bar");
97                         AssertValidUrl ("N:Foo");
98                         AssertValidUrl ("N:Foo.Bar.Baz");
99                         AssertValidUrl ("N:A.B.C");
100
101                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Namespace,
102                                                     Namespace = "Foo.Bar.Blop" };
103                         AssertUrlDesc (ast, "N:Foo.Bar.Blop");
104                 }
105
106                 [Test]
107                 public void ConstructorValidTest ()
108                 {
109                         AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule");
110                         AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule()");
111                         AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule(System.String)");
112                         AssertValidUrl ("C:Gendarme.Framework.Helpers.MethodSignature.MethodSignature(string,string,string[],System.Func<Mono.Cecil.MethodReference,System.Boolean>)");
113                         AssertValidUrl ("C:System.Collections.Generic.Dictionary<TKey,TValue>+KeyCollection.KeyCollection(System.Collections.Generic.Dictionary<TKey,TValue>)");
114                         AssertValidUrl ("C:Microsoft.Build.Utilities.TaskItem(System.String,System.Collections.IDictionary)");
115                 }
116
117                 [Test]
118                 public void SlashExpressionValidTest ()
119                 {
120                         AssertValidUrl ("T:Foo.Bar.Type/*");
121                         AssertValidUrl ("T:Foo.Bar.Type/M");
122                         AssertValidUrl ("T:Gendarme.Framework.Bitmask<T>/M/Equals");
123                         AssertValidUrl ("T:Gendarme.Framework.Helpers.Log/M/WriteLine<T>");
124                         AssertValidUrl ("T:System.Windows.Forms.AxHost/M/System.ComponentModel.ICustomTypeDescriptor.GetEvents");
125                 }
126
127                 [Test]
128                 public void MethodWithArgModValidTest ()
129                 {
130                         AssertValidUrl ("M:Foo.Bar.FooBar(int, System.Drawing.Imaging&)");
131                         AssertValidUrl ("M:Foo.Bar.FooBar(int@, System.Drawing.Imaging)");
132                         AssertValidUrl ("M:Foo.Bar.FooBar(int, System.Drawing.Imaging*)");
133                         AssertValidUrl ("M:Foo.Bar.FooBar(int*, System.Drawing.Imaging&)");
134                         AssertValidUrl ("M:Atk.NoOpObject.GetRunAttributes(int,int&,int&)");
135                 }
136
137                 [Test]
138                 public void MethodWithJaggedArrayArgsValidTest ()
139                 {
140                         AssertValidUrl ("M:System.Reflection.Emit.SignatureHelper.GetPropertySigHelper(System.Reflection.Module,System.Reflection.CallingConventions,Type,Type[],Type[],Type[],Type[][],Type[][])");
141                 }
142
143                 [Test]
144                 public void MethodWithInnerTypeValidTest ()
145                 {
146                         AssertValidUrl ("M:System.TimeZoneInfo+AdjustmentRule.CreateAdjustmentRule");
147                 }
148
149                 [Test]
150                 public void FieldValidTest ()
151                 {
152                         AssertValidUrl ("F:Mono.Terminal.Curses.KeyF10");
153                         AssertValidUrl ("F:Novell.Directory.Ldap.Utilclass.ExceptionMessages.NOT_IMPLEMENTED");
154                         AssertValidUrl ("F:Novell.Directory.Ldap.LdapException.NOT_ALLOWED_ON_NONLEAF");
155                 }
156
157                 [Test]
158                 public void PropertyValidTest ()
159                 {
160                         AssertValidUrl ("P:System.Foo.Bar");
161                         AssertValidUrl ("P:System.ArraySegment<T>.Array");
162                 }
163
164                 [Test]
165                 public void IndexPropertyValidTest ()
166                 {
167                         AssertValidUrl ("P:System.ComponentModel.PropertyDescriptorCollection.Item(int)");
168                         AssertValidUrl ("P:System.ComponentModel.AttributeCollection.Item(Type)");
169                         AssertValidUrl ("P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)");
170                         AssertValidUrl ("P:System.Collections.Specialized.BitVector32.Item(System.Collections.Specialized.BitVector32+Section)");
171                 }
172
173                 [Test]
174                 public void ExplicitMethodImplValidTest ()
175                 {
176                         AssertValidUrl ("M:Microsoft.Win32.RegistryKey$System.IDisposable.Dispose");
177                 }
178
179                 [Test]
180                 public void AspNetSafeUrlValidTest ()
181                 {
182                         AssertValidUrl ("M:MonoTouch.UIKit.UICollectionViewLayoutAttributes.CreateForCell{T}");
183                 }
184
185                 [Test]
186                 public void GenericTypeArgsIsNumericTest ()
187                 {
188                         var desc = parser.Parse ("T:System.Collections.Generic.Dictionary`2");
189                         Assert.IsTrue (desc.GenericTypeArgumentsIsNumeric);
190                         Assert.AreEqual (2, desc.GenericTypeArguments.Count);
191                         desc = parser.Parse ("T:System.Collections.Generic.Dictionary<TKey,TValue>");
192                         Assert.IsFalse (desc.GenericTypeArgumentsIsNumeric);
193                 }
194
195                 [Test]
196                 public void GenericTypeArgsNumericToStringTest ()
197                 {
198                         string stringCref = "T:System.Collections.Generic.Dictionary`2";
199                         var desc = parser.Parse (stringCref);
200                         Assert.IsTrue (desc.GenericTypeArgumentsIsNumeric);
201                         Assert.AreEqual (2, desc.GenericTypeArguments.Count);
202                         string generatedEcmaCref = desc.ToEcmaCref ();
203                         Assert.AreEqual (stringCref, generatedEcmaCref);
204                 }
205
206                 [Test]
207                 public void MetaEtcNodeTest ()
208                 {
209                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
210                                                     Namespace = "Foo.Bar",
211                                                     TypeName = "Type",
212                                                     Etc = '*' };
213                         AssertUrlDesc (ast, "T:Foo.Bar.Type/*");
214                 }
215
216                 [Test]
217                 public void MetaEtcWithInnerTypeTest ()
218                 {
219                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
220                                                     Namespace = "Novell.Directory.Ldap",
221                                                     TypeName = "Connection",
222                                                     NestedType = new EcmaDesc { DescKind = EcmaDesc.Kind.Type, TypeName = "ReaderThread" },
223                                                     Etc = '*' };
224                         AssertUrlDesc (ast, "T:Novell.Directory.Ldap.Connection+ReaderThread/*");
225                 }
226
227                 [Test]
228                 public void SimpleTypeUrlParseTest ()
229                 {
230                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
231                                                     TypeName = "String",
232                                                     Namespace = "System" };
233                         AssertUrlDesc (ast, "T:System.String");
234                 }
235
236                 [Test]
237                 public void TypeWithOneGenericUrlParseTest ()
238                 {
239                         var generics = new[] {
240                                 new EcmaDesc {
241                                         DescKind = EcmaDesc.Kind.Type,
242                                         Namespace = string.Empty,
243                                         TypeName = "T"
244                                 }
245                         };
246                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
247                                                     TypeName = "String",
248                                                     Namespace = "System",
249                                                     GenericTypeArguments = generics,
250                         };
251
252                         AssertUrlDesc (ast, "T:System.String<T>");
253                 }
254
255                 [Test]
256                 public void TypeWithOneGenericUrlParseTestUsingAspNetStyleUrl ()
257                 {
258                         var generics = new[] {
259                                 new EcmaDesc {
260                                         DescKind = EcmaDesc.Kind.Type,
261                                         Namespace = string.Empty,
262                                         TypeName = "T"
263                                 }
264                         };
265                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
266                                                     TypeName = "String",
267                                                     Namespace = "System",
268                                                     GenericTypeArguments = generics,
269                         };
270
271                         AssertUrlDesc (ast, "T:System.String{T}");
272                 }
273
274                 [Test]
275                 public void TypeWithNestedGenericUrlParseTest ()
276                 {
277                         var generics = new[] {
278                                 new EcmaDesc {
279                                         DescKind = EcmaDesc.Kind.Type,
280                                         TypeName = "T",
281                                         Namespace = string.Empty
282                                 },
283                                 new EcmaDesc {
284                                         DescKind = EcmaDesc.Kind.Type,
285                                         Namespace = "System.Collections.Generic",
286                                         TypeName = "List",
287                                         GenericTypeArguments = new[] {
288                                                 new EcmaDesc {
289                                                         DescKind = EcmaDesc.Kind.Type,
290                                                         TypeName = "V",
291                                                         Namespace = string.Empty
292                                                 }
293                                         }
294                                 }
295                         };
296                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
297                                                     TypeName = "String",
298                                                     Namespace = "System",
299                                                     GenericTypeArguments = generics,
300                         };
301
302                         AssertUrlDesc (ast, "T:System.String<T, System.Collections.Generic.List<V>>");
303                 }
304
305                 [Test]
306                 public void SimpleMethodUrlParseTest ()
307                 {
308                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
309                                                     TypeName = "String",
310                                                     Namespace = "System",
311                                                     MemberName = "FooBar"
312                         };
313                         AssertUrlDesc (ast, "M:System.String.FooBar()");
314                 }
315
316                 [Test]
317                 public void MethodWithArgsUrlParseTest ()
318                 {
319                         var args = new[] {
320                                 new EcmaDesc {
321                                         DescKind = EcmaDesc.Kind.Type,
322                                         Namespace = "System",
323                                         TypeName = "String"
324                                 },
325                                 new EcmaDesc {
326                                         DescKind = EcmaDesc.Kind.Type,
327                                         TypeName = "Int32",
328                                         Namespace = string.Empty
329                                 }
330                         };
331                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
332                                                     TypeName = "String",
333                                                     Namespace = "System",
334                                                     MemberName = "FooBar",
335                                                     MemberArguments = args
336                         };
337                         AssertUrlDesc (ast, "M:System.String.FooBar(System.String, Int32)");
338                 }
339
340                 [Test]
341                 public void MethodWithArgsAndGenericsUrlParseTest ()
342                 {
343                         var args = new[] {
344                                 new EcmaDesc {
345                                         DescKind = EcmaDesc.Kind.Type,
346                                         Namespace = "System",
347                                         TypeName = "String"
348                                 },
349                                 new EcmaDesc {
350                                         DescKind = EcmaDesc.Kind.Type,
351                                         Namespace = "System.Collections.Generic",
352                                         TypeName = "Dictionary",
353                                         GenericTypeArguments = new[] {
354                                                 new EcmaDesc {
355                                                         DescKind = EcmaDesc.Kind.Type,
356                                                         TypeName = "K",
357                                                         Namespace = string.Empty
358                                                 },
359                                                 new EcmaDesc {
360                                                         DescKind = EcmaDesc.Kind.Type,
361                                                         TypeName = "V",
362                                                         Namespace = string.Empty
363                                                 }
364                                         }
365                                 }
366                         };
367
368                         var generics = new[] {
369                                 new EcmaDesc {
370                                         DescKind = EcmaDesc.Kind.Type,
371                                         TypeName = "Action",
372                                         Namespace = string.Empty,
373                                         GenericTypeArguments = new[] {
374                                                 new EcmaDesc {
375                                                         DescKind = EcmaDesc.Kind.Type,
376                                                         Namespace = "System",
377                                                         TypeName = "Single",
378                                                 },
379                                                 new EcmaDesc {
380                                                         DescKind = EcmaDesc.Kind.Type,
381                                                         TypeName = "int",
382                                                         Namespace = string.Empty
383                                                 },
384                                         }
385                                 }
386                         };
387
388                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
389                                                     TypeName = "String",
390                                                     Namespace = "System",
391                                                     MemberName = "FooBar",
392                                                     MemberArguments = args,
393                                                     GenericMemberArguments = generics
394                         };
395                         AssertUrlDesc (ast, "M:System.String.FooBar<Action<System.Single, int>>(System.String, System.Collections.Generic.Dictionary<K, V>)");
396                 }
397
398                 [Test]
399                 public void ExplicitMethodImplementationParseTest ()
400                 {
401                         var inner = new EcmaDesc {
402                                 MemberName = "Dispose",
403                                 TypeName = "IDisposable",
404                                 Namespace = "System"
405                         };
406                         var ast = new EcmaDesc {
407                                 DescKind = EcmaDesc.Kind.Method,
408                                 TypeName = "RegistryKey",
409                                 Namespace = "Microsoft.Win32",
410                                 ExplicitImplMember = inner
411                         };
412                         AssertUrlDesc (ast, "M:Microsoft.Win32.RegistryKey$System.IDisposable.Dispose");
413                 }
414
415                 [Test]
416                 public void SimpleMethodWithNumberInType ()
417                 {
418                         var ast = new EcmaDesc {
419                                 DescKind = EcmaDesc.Kind.Method,
420                                 TypeName = "ASN1",
421                                 Namespace = "Mono.Security",
422                                 MemberName = "Add"
423                         };
424                         AssertUrlDesc (ast, "M:Mono.Security.ASN1.Add");
425                 }
426
427                 [Test]
428                 public void JaggedArrayWithDimensions ()
429                 {
430                         var ast = new EcmaDesc {
431                                 DescKind = EcmaDesc.Kind.Type,
432                                 TypeName = "Int32",
433                                 Namespace = "System",
434                                 ArrayDimensions = new int[] { 3, 1, 1 }
435                         };
436                         AssertUrlDesc (ast, "T:System.Int32[,,][][]");
437                 }
438
439                 [Test]
440                 public void ExplicitIndexerImplementation ()
441                 {
442                         var explicitImpl = new EcmaDesc {
443                                 Namespace = "System.Web.SessionState",
444                                 TypeName = "IHttpSessionState",
445                                 MemberName = "Item",
446                                 MemberArguments = new [] { new EcmaDesc { DescKind = EcmaDesc.Kind.Type, Namespace = "System", TypeName = "Int32" } },
447                         };
448                         var ast = new EcmaDesc {
449                                 DescKind = EcmaDesc.Kind.Property,
450                                 TypeName = "HttpSessionStateContainer",
451                                 Namespace = "System.Web.SessionState",
452                                 ExplicitImplMember = explicitImpl,
453                         };
454                         AssertUrlDesc (ast, "P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)");
455                 }
456
457                 /*              [Test]
458                 public void TreeParsabilityTest ()
459                 {
460                         var rootTree = RootTree.LoadTree ("/home/jeremie/monodoc/");
461                         Node result;
462                         var generator = new CheckGenerator ();
463
464                         foreach (var leaf in GetLeaves (rootTree.RootNode).Where (IsEcmaNode))
465                                 AssertUrl (leaf.PublicUrl);
466                 }
467
468                 IEnumerable<Node> GetLeaves (Node node)
469                 {
470                         if (node == null)
471                                 yield break;
472
473                         if (node.IsLeaf)
474                                 yield return node;
475                         else {
476                                 foreach (var child in node.Nodes) {
477                                         if (!string.IsNullOrEmpty (child.Element) && !child.Element.StartsWith ("root:/"))
478                                                 yield return child;
479                                         foreach (var childLeaf in GetLeaves (child))
480                                                 yield return childLeaf;
481                                 }
482                         }
483                 }
484
485                 bool IsEcmaNode (Node node)
486                 {
487                         var url = node.PublicUrl;
488                         return url != null && url.Length > 2 && url[1] == ':';
489                 }*/
490         }
491 }