Merge pull request #600 from tr8dr/master
[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 MetaEtcNodeTest ()
197                 {
198                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
199                                                     Namespace = "Foo.Bar",
200                                                     TypeName = "Type",
201                                                     Etc = '*' };
202                         AssertUrlDesc (ast, "T:Foo.Bar.Type/*");
203                 }
204
205                 [Test]
206                 public void MetaEtcWithInnerTypeTest ()
207                 {
208                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
209                                                     Namespace = "Novell.Directory.Ldap",
210                                                     TypeName = "Connection",
211                                                     NestedType = new EcmaDesc { DescKind = EcmaDesc.Kind.Type, TypeName = "ReaderThread" },
212                                                     Etc = '*' };
213                         AssertUrlDesc (ast, "T:Novell.Directory.Ldap.Connection+ReaderThread/*");
214                 }
215
216                 [Test]
217                 public void SimpleTypeUrlParseTest ()
218                 {
219                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
220                                                     TypeName = "String",
221                                                     Namespace = "System" };
222                         AssertUrlDesc (ast, "T:System.String");
223                 }
224
225                 [Test]
226                 public void TypeWithOneGenericUrlParseTest ()
227                 {
228                         var generics = new[] {
229                                 new EcmaDesc {
230                                         DescKind = EcmaDesc.Kind.Type,
231                                         Namespace = string.Empty,
232                                         TypeName = "T"
233                                 }
234                         };
235                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
236                                                     TypeName = "String",
237                                                     Namespace = "System",
238                                                     GenericTypeArguments = generics,
239                         };
240
241                         AssertUrlDesc (ast, "T:System.String<T>");
242                 }
243
244                 [Test]
245                 public void TypeWithOneGenericUrlParseTestUsingAspNetStyleUrl ()
246                 {
247                         var generics = new[] {
248                                 new EcmaDesc {
249                                         DescKind = EcmaDesc.Kind.Type,
250                                         Namespace = string.Empty,
251                                         TypeName = "T"
252                                 }
253                         };
254                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
255                                                     TypeName = "String",
256                                                     Namespace = "System",
257                                                     GenericTypeArguments = generics,
258                         };
259
260                         AssertUrlDesc (ast, "T:System.String{T}");
261                 }
262
263                 [Test]
264                 public void TypeWithNestedGenericUrlParseTest ()
265                 {
266                         var generics = new[] {
267                                 new EcmaDesc {
268                                         DescKind = EcmaDesc.Kind.Type,
269                                         TypeName = "T",
270                                         Namespace = string.Empty
271                                 },
272                                 new EcmaDesc {
273                                         DescKind = EcmaDesc.Kind.Type,
274                                         Namespace = "System.Collections.Generic",
275                                         TypeName = "List",
276                                         GenericTypeArguments = new[] {
277                                                 new EcmaDesc {
278                                                         DescKind = EcmaDesc.Kind.Type,
279                                                         TypeName = "V",
280                                                         Namespace = string.Empty
281                                                 }
282                                         }
283                                 }
284                         };
285                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
286                                                     TypeName = "String",
287                                                     Namespace = "System",
288                                                     GenericTypeArguments = generics,
289                         };
290
291                         AssertUrlDesc (ast, "T:System.String<T, System.Collections.Generic.List<V>>");
292                 }
293
294                 [Test]
295                 public void SimpleMethodUrlParseTest ()
296                 {
297                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
298                                                     TypeName = "String",
299                                                     Namespace = "System",
300                                                     MemberName = "FooBar"
301                         };
302                         AssertUrlDesc (ast, "M:System.String.FooBar()");
303                 }
304
305                 [Test]
306                 public void MethodWithArgsUrlParseTest ()
307                 {
308                         var args = new[] {
309                                 new EcmaDesc {
310                                         DescKind = EcmaDesc.Kind.Type,
311                                         Namespace = "System",
312                                         TypeName = "String"
313                                 },
314                                 new EcmaDesc {
315                                         DescKind = EcmaDesc.Kind.Type,
316                                         TypeName = "Int32",
317                                         Namespace = string.Empty
318                                 }
319                         };
320                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
321                                                     TypeName = "String",
322                                                     Namespace = "System",
323                                                     MemberName = "FooBar",
324                                                     MemberArguments = args
325                         };
326                         AssertUrlDesc (ast, "M:System.String.FooBar(System.String, Int32)");
327                 }
328
329                 [Test]
330                 public void MethodWithArgsAndGenericsUrlParseTest ()
331                 {
332                         var args = new[] {
333                                 new EcmaDesc {
334                                         DescKind = EcmaDesc.Kind.Type,
335                                         Namespace = "System",
336                                         TypeName = "String"
337                                 },
338                                 new EcmaDesc {
339                                         DescKind = EcmaDesc.Kind.Type,
340                                         Namespace = "System.Collections.Generic",
341                                         TypeName = "Dictionary",
342                                         GenericTypeArguments = new[] {
343                                                 new EcmaDesc {
344                                                         DescKind = EcmaDesc.Kind.Type,
345                                                         TypeName = "K",
346                                                         Namespace = string.Empty
347                                                 },
348                                                 new EcmaDesc {
349                                                         DescKind = EcmaDesc.Kind.Type,
350                                                         TypeName = "V",
351                                                         Namespace = string.Empty
352                                                 }
353                                         }
354                                 }
355                         };
356
357                         var generics = new[] {
358                                 new EcmaDesc {
359                                         DescKind = EcmaDesc.Kind.Type,
360                                         TypeName = "Action",
361                                         Namespace = string.Empty,
362                                         GenericTypeArguments = new[] {
363                                                 new EcmaDesc {
364                                                         DescKind = EcmaDesc.Kind.Type,
365                                                         Namespace = "System",
366                                                         TypeName = "Single",
367                                                 },
368                                                 new EcmaDesc {
369                                                         DescKind = EcmaDesc.Kind.Type,
370                                                         TypeName = "int",
371                                                         Namespace = string.Empty
372                                                 },
373                                         }
374                                 }
375                         };
376
377                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
378                                                     TypeName = "String",
379                                                     Namespace = "System",
380                                                     MemberName = "FooBar",
381                                                     MemberArguments = args,
382                                                     GenericMemberArguments = generics
383                         };
384                         AssertUrlDesc (ast, "M:System.String.FooBar<Action<System.Single, int>>(System.String, System.Collections.Generic.Dictionary<K, V>)");
385                 }
386
387                 [Test]
388                 public void ExplicitMethodImplementationParseTest ()
389                 {
390                         var inner = new EcmaDesc {
391                                 MemberName = "Dispose",
392                                 TypeName = "IDisposable",
393                                 Namespace = "System"
394                         };
395                         var ast = new EcmaDesc {
396                                 DescKind = EcmaDesc.Kind.Method,
397                                 TypeName = "RegistryKey",
398                                 Namespace = "Microsoft.Win32",
399                                 ExplicitImplMember = inner
400                         };
401                         AssertUrlDesc (ast, "M:Microsoft.Win32.RegistryKey$System.IDisposable.Dispose");
402                 }
403
404                 [Test]
405                 public void SimpleMethodWithNumberInType ()
406                 {
407                         var ast = new EcmaDesc {
408                                 DescKind = EcmaDesc.Kind.Method,
409                                 TypeName = "ASN1",
410                                 Namespace = "Mono.Security",
411                                 MemberName = "Add"
412                         };
413                         AssertUrlDesc (ast, "M:Mono.Security.ASN1.Add");
414                 }
415
416                 [Test]
417                 public void JaggedArrayWithDimensions ()
418                 {
419                         var ast = new EcmaDesc {
420                                 DescKind = EcmaDesc.Kind.Type,
421                                 TypeName = "Int32",
422                                 Namespace = "System",
423                                 ArrayDimensions = new int[] { 3, 1, 1 }
424                         };
425                         AssertUrlDesc (ast, "T:System.Int32[,,][][]");
426                 }
427
428                 [Test]
429                 public void ExplicitIndexerImplementation ()
430                 {
431                         var explicitImpl = new EcmaDesc {
432                                 Namespace = "System.Web.SessionState",
433                                 TypeName = "IHttpSessionState",
434                                 MemberName = "Item",
435                                 MemberArguments = new [] { new EcmaDesc { DescKind = EcmaDesc.Kind.Type, Namespace = "System", TypeName = "Int32" } },
436                         };
437                         var ast = new EcmaDesc {
438                                 DescKind = EcmaDesc.Kind.Property,
439                                 TypeName = "HttpSessionStateContainer",
440                                 Namespace = "System.Web.SessionState",
441                                 ExplicitImplMember = explicitImpl,
442                         };
443                         AssertUrlDesc (ast, "P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)");
444                 }
445
446                 /*              [Test]
447                 public void TreeParsabilityTest ()
448                 {
449                         var rootTree = RootTree.LoadTree ("/home/jeremie/monodoc/");
450                         Node result;
451                         var generator = new CheckGenerator ();
452
453                         foreach (var leaf in GetLeaves (rootTree.RootNode).Where (IsEcmaNode))
454                                 AssertUrl (leaf.PublicUrl);
455                 }
456
457                 IEnumerable<Node> GetLeaves (Node node)
458                 {
459                         if (node == null)
460                                 yield break;
461
462                         if (node.IsLeaf)
463                                 yield return node;
464                         else {
465                                 foreach (var child in node.Nodes) {
466                                         if (!string.IsNullOrEmpty (child.Element) && !child.Element.StartsWith ("root:/"))
467                                                 yield return child;
468                                         foreach (var childLeaf in GetLeaves (child))
469                                                 yield return childLeaf;
470                                 }
471                         }
472                 }
473
474                 bool IsEcmaNode (Node node)
475                 {
476                         var url = node.PublicUrl;
477                         return url != null && url.Length > 2 && url[1] == ':';
478                 }*/
479         }
480 }