Merge pull request #2223 from lobrien/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                 void AssertEcmaString (string expected, EcmaDesc actual)
56                 {
57                         string actualString = actual.ToEcmaCref ();
58                         Assert.AreEqual (expected, actualString);
59                 }
60
61                 IEnumerable<EcmaDesc> GenericTypeArgumentsList (params string[] parameters) 
62                 {
63                         foreach (var p in parameters)
64                                 yield return new EcmaDesc {
65                                                 DescKind = EcmaDesc.Kind.Type,
66                                                 TypeName = p,
67                                                 Namespace = string.Empty
68                                         };
69                 }
70
71                 [Test]
72                 public void CommonMethodUrlIsValidTest ()
73                 {
74                         AssertValidUrl ("M:System.String.FooBar()");
75                         AssertValidUrl ("M:System.String.FooBar(System.String, Int32)");
76                         AssertValidUrl ("M:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>.Foo()");
77                         AssertValidUrl ("M:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>.Foo(Bleh,Bar)");
78                         AssertValidUrl ("M:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>.Foo(Bleh<V>,Bar)");
79                         AssertValidUrl ("M:Gendarme.Framework.Helpers.Log.WriteLine(string,string,object[])");
80                         AssertValidUrl ("M:Mono.Security.X509.Extensions.SubjectKeyIdentifierExtension.Decode");
81                         AssertValidUrl ("M:Mono.Security.PKCS7.IssuerAndSerialNumber");
82                 }
83
84                 [Test]
85                 public void CommonTypeUrlIsValidTest ()
86                 {
87                         AssertValidUrl ("T:Int32");
88                         AssertValidUrl ("T:System.Foo.Int32");
89                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar`1>");
90                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar<System.Blop<T, U>>>");
91                         AssertValidUrl ("T:System.Foo.Int32<T>");
92                         AssertValidUrl ("T:System.Foo.Int32<T,U>");
93                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar<System.Blop<T, U>>>");
94                         AssertValidUrl ("T:System.Foo.Int32<System.String+FooBar<System.Blop<T, U`2>>>");
95                 }
96
97                 [Test]
98                 public void CommonTypeUrlNotValidTest ()
99                 {
100                         AssertInvalidUrl ("TInt32");
101                         AssertInvalidUrl ("K:Int32");
102                         AssertInvalidUrl ("T:System..Foo.Int32");
103                         AssertInvalidUrl ("T:System.Foo.Int32<System.String+FooBar`1");
104                         AssertInvalidUrl ("T:System.Foo.Int32<System.String+FooBarSystem.Blop<T, U>>>");
105                         AssertInvalidUrl ("T:System.Foo.Int32<T,>");
106                         AssertInvalidUrl ("T:System.Foo.Int32<+FooBar<System.Blop<T, U>>>");
107                 }
108
109                 [Test]
110                 public void NamespaceValidTest ()
111                 {
112                         AssertValidUrl ("N:Foo.Bar");
113                         AssertValidUrl ("N:Foo");
114                         AssertValidUrl ("N:Foo.Bar.Baz");
115                         AssertValidUrl ("N:A.B.C");
116
117                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Namespace,
118                                                     Namespace = "Foo.Bar.Blop" };
119                         AssertUrlDesc (ast, "N:Foo.Bar.Blop");
120                 }
121
122                 [Test]
123                 public void ConstructorValidTest ()
124                 {
125                         AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule");
126                         AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule()");
127                         AssertValidUrl ("C:Gendarme.Rules.Concurrency.DecorateThreadsRule.DecorateThreadsRule(System.String)");
128                         AssertValidUrl ("C:Gendarme.Framework.Helpers.MethodSignature.MethodSignature(string,string,string[],System.Func<Mono.Cecil.MethodReference,System.Boolean>)");
129                         AssertValidUrl ("C:System.Collections.Generic.Dictionary<TKey,TValue>+KeyCollection.KeyCollection(System.Collections.Generic.Dictionary<TKey,TValue>)");
130                         AssertValidUrl ("C:Microsoft.Build.Utilities.TaskItem(System.String,System.Collections.IDictionary)");
131                 }
132
133                 [Test]
134                 public void SlashExpressionValidTest ()
135                 {
136                         AssertValidUrl ("T:Foo.Bar.Type/*");
137                         AssertValidUrl ("T:Foo.Bar.Type/M");
138                         AssertValidUrl ("T:Gendarme.Framework.Bitmask<T>/M/Equals");
139                         AssertValidUrl ("T:Gendarme.Framework.Helpers.Log/M/WriteLine<T>");
140                         AssertValidUrl ("T:System.Windows.Forms.AxHost/M/System.ComponentModel.ICustomTypeDescriptor.GetEvents");
141                 }
142
143                 [Test]
144                 public void MethodWithArgModValidTest ()
145                 {
146                         AssertValidUrl ("M:Foo.Bar.FooBar(int, System.Drawing.Imaging&)");
147                         AssertValidUrl ("M:Foo.Bar.FooBar(int@, System.Drawing.Imaging)");
148                         AssertValidUrl ("M:Foo.Bar.FooBar(int, System.Drawing.Imaging*)");
149                         AssertValidUrl ("M:Foo.Bar.FooBar(int*, System.Drawing.Imaging&)");
150                         AssertValidUrl ("M:Atk.NoOpObject.GetRunAttributes(int,int&,int&)");
151                 }
152
153                 [Test]
154                 public void MethodWithJaggedArrayArgsValidTest ()
155                 {
156                         AssertValidUrl ("M:System.Reflection.Emit.SignatureHelper.GetPropertySigHelper(System.Reflection.Module,System.Reflection.CallingConventions,Type,Type[],Type[],Type[],Type[][],Type[][])");
157                 }
158
159                 [Test]
160                 public void MethodWithInnerTypeValidTest ()
161                 {
162                         AssertValidUrl ("M:System.TimeZoneInfo+AdjustmentRule.CreateAdjustmentRule");
163                 }
164
165                 [Test]
166                 public void FieldValidTest ()
167                 {
168                         AssertValidUrl ("F:Mono.Terminal.Curses.KeyF10");
169                         AssertValidUrl ("F:Novell.Directory.Ldap.Utilclass.ExceptionMessages.NOT_IMPLEMENTED");
170                         AssertValidUrl ("F:Novell.Directory.Ldap.LdapException.NOT_ALLOWED_ON_NONLEAF");
171                 }
172
173                 [Test]
174                 public void PropertyValidTest ()
175                 {
176                         AssertValidUrl ("P:System.Foo.Bar");
177                         AssertValidUrl ("P:System.ArraySegment<T>.Array");
178                 }
179
180                 [Test]
181                 public void IndexPropertyValidTest ()
182                 {
183                         AssertValidUrl ("P:System.ComponentModel.PropertyDescriptorCollection.Item(int)");
184                         AssertValidUrl ("P:System.ComponentModel.AttributeCollection.Item(Type)");
185                         AssertValidUrl ("P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)");
186                         AssertValidUrl ("P:System.Collections.Specialized.BitVector32.Item(System.Collections.Specialized.BitVector32+Section)");
187                 }
188
189                 [Test]
190                 public void ExplicitMethodImplValidTest ()
191                 {
192                         AssertValidUrl ("M:Microsoft.Win32.RegistryKey$System.IDisposable.Dispose");
193                 }
194
195                 [Test]
196                 public void AspNetSafeUrlValidTest ()
197                 {
198                         AssertValidUrl ("M:MonoTouch.UIKit.UICollectionViewLayoutAttributes.CreateForCell{T}");
199                 }
200
201                 [Test]
202                 public void GenericTypeArgsIsNumericTest ()
203                 {
204                         var desc = parser.Parse ("T:System.Collections.Generic.Dictionary`2");
205                         Assert.IsTrue (desc.GenericTypeArgumentsIsNumeric);
206                         Assert.AreEqual (2, desc.GenericTypeArguments.Count);
207                         desc = parser.Parse ("T:System.Collections.Generic.Dictionary<TKey,TValue>");
208                         Assert.IsFalse (desc.GenericTypeArgumentsIsNumeric);
209                 }
210
211                 [Test]
212                 public void GenericTypeArgsNumericToStringTest ()
213                 {
214                         string stringCref = "T:System.Collections.Generic.Dictionary`2";
215                         var desc = parser.Parse (stringCref);
216                         Assert.IsTrue (desc.GenericTypeArgumentsIsNumeric);
217                         Assert.AreEqual (2, desc.GenericTypeArguments.Count);
218                         string generatedEcmaCref = desc.ToEcmaCref ();
219                         Assert.AreEqual (stringCref, generatedEcmaCref);
220                 }
221
222                 [Test]
223                 public void MetaEtcNodeTest ()
224                 {
225                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
226                                                     Namespace = "Foo.Bar",
227                                                     TypeName = "Type",
228                                                     Etc = '*' };
229                         AssertUrlDesc (ast, "T:Foo.Bar.Type/*");
230                 }
231
232                 [Test]
233                 public void MetaEtcWithInnerTypeTest ()
234                 {
235                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
236                                                     Namespace = "Novell.Directory.Ldap",
237                                                     TypeName = "Connection",
238                                                     NestedType = new EcmaDesc { DescKind = EcmaDesc.Kind.Type, TypeName = "ReaderThread" },
239                                                     Etc = '*' };
240                         AssertUrlDesc (ast, "T:Novell.Directory.Ldap.Connection+ReaderThread/*");
241                 }
242
243                 [Test]
244                 public void SimpleTypeUrlParseTest ()
245                 {
246                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
247                                                     TypeName = "String",
248                                                     Namespace = "System" };
249                         AssertUrlDesc (ast, "T:System.String");
250                 }
251
252                 [Test]
253                 public void TypeWithOneGenericUrlParseTest ()
254                 {
255                         var generics = new[] {
256                                 new EcmaDesc {
257                                         DescKind = EcmaDesc.Kind.Type,
258                                         Namespace = string.Empty,
259                                         TypeName = "T"
260                                 }
261                         };
262                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
263                                                     TypeName = "String",
264                                                     Namespace = "System",
265                                                     GenericTypeArguments = generics,
266                         };
267
268                         AssertUrlDesc (ast, "T:System.String<T>");
269                 }
270
271                 [Test]
272                 public void TypeWithOneGenericUrlParseTestUsingAspNetStyleUrl ()
273                 {
274                         var generics = new[] {
275                                 new EcmaDesc {
276                                         DescKind = EcmaDesc.Kind.Type,
277                                         Namespace = string.Empty,
278                                         TypeName = "T"
279                                 }
280                         };
281                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
282                                                     TypeName = "String",
283                                                     Namespace = "System",
284                                                     GenericTypeArguments = generics,
285                         };
286
287                         AssertUrlDesc (ast, "T:System.String{T}");
288                 }
289
290                 [Test]
291                 public void TypeWithNestedGenericUrlParseTest ()
292                 {
293                         var generics = new[] {
294                                 new EcmaDesc {
295                                         DescKind = EcmaDesc.Kind.Type,
296                                         TypeName = "T",
297                                         Namespace = string.Empty
298                                 },
299                                 new EcmaDesc {
300                                         DescKind = EcmaDesc.Kind.Type,
301                                         Namespace = "System.Collections.Generic",
302                                         TypeName = "List",
303                                         GenericTypeArguments = new[] {
304                                                 new EcmaDesc {
305                                                         DescKind = EcmaDesc.Kind.Type,
306                                                         TypeName = "V",
307                                                         Namespace = string.Empty
308                                                 }
309                                         }
310                                 }
311                         };
312                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Type,
313                                                     TypeName = "String",
314                                                     Namespace = "System",
315                                                     GenericTypeArguments = generics,
316                         };
317
318                         AssertUrlDesc (ast, "T:System.String<T, System.Collections.Generic.List<V>>");
319                 }
320
321                 [Test]
322                 public void SimpleMethodUrlParseTest ()
323                 {
324                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
325                                                     TypeName = "String",
326                                                     Namespace = "System",
327                                                     MemberName = "FooBar"
328                         };
329                         AssertUrlDesc (ast, "M:System.String.FooBar()");
330                 }
331
332                 [Test]
333                 public void MethodWithArgsUrlParseTest ()
334                 {
335                         var args = new[] {
336                                 new EcmaDesc {
337                                         DescKind = EcmaDesc.Kind.Type,
338                                         Namespace = "System",
339                                         TypeName = "String"
340                                 },
341                                 new EcmaDesc {
342                                         DescKind = EcmaDesc.Kind.Type,
343                                         TypeName = "Int32",
344                                         Namespace = string.Empty
345                                 }
346                         };
347                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
348                                                     TypeName = "String",
349                                                     Namespace = "System",
350                                                     MemberName = "FooBar",
351                                                     MemberArguments = args
352                         };
353                         AssertUrlDesc (ast, "M:System.String.FooBar(System.String, Int32)");
354                 }
355
356                 [Test]
357                 public void MethodWithArgsAndGenericsUrlParseTest ()
358                 {
359                         var args = new[] {
360                                 new EcmaDesc {
361                                         DescKind = EcmaDesc.Kind.Type,
362                                         Namespace = "System",
363                                         TypeName = "String"
364                                 },
365                                 new EcmaDesc {
366                                         DescKind = EcmaDesc.Kind.Type,
367                                         Namespace = "System.Collections.Generic",
368                                         TypeName = "Dictionary",
369                                         GenericTypeArguments = new[] {
370                                                 new EcmaDesc {
371                                                         DescKind = EcmaDesc.Kind.Type,
372                                                         TypeName = "K",
373                                                         Namespace = string.Empty
374                                                 },
375                                                 new EcmaDesc {
376                                                         DescKind = EcmaDesc.Kind.Type,
377                                                         TypeName = "V",
378                                                         Namespace = string.Empty
379                                                 }
380                                         }
381                                 }
382                         };
383
384                         var generics = new[] {
385                                 new EcmaDesc {
386                                         DescKind = EcmaDesc.Kind.Type,
387                                         TypeName = "Action",
388                                         Namespace = string.Empty,
389                                         GenericTypeArguments = new[] {
390                                                 new EcmaDesc {
391                                                         DescKind = EcmaDesc.Kind.Type,
392                                                         Namespace = "System",
393                                                         TypeName = "Single",
394                                                 },
395                                                 new EcmaDesc {
396                                                         DescKind = EcmaDesc.Kind.Type,
397                                                         TypeName = "int",
398                                                         Namespace = string.Empty
399                                                 },
400                                         }
401                                 }
402                         };
403
404                         var ast = new EcmaDesc () { DescKind = EcmaDesc.Kind.Method,
405                                                     TypeName = "String",
406                                                     Namespace = "System",
407                                                     MemberName = "FooBar",
408                                                     MemberArguments = args,
409                                                     GenericMemberArguments = generics
410                         };
411                         AssertUrlDesc (ast, "M:System.String.FooBar<Action<System.Single, int>>(System.String, System.Collections.Generic.Dictionary<K, V>)");
412                 }
413
414                 [Test]
415                 public void ExplicitMethodImplementationParseTest ()
416                 {
417                         var inner = new EcmaDesc {
418                                 MemberName = "Dispose",
419                                 TypeName = "IDisposable",
420                                 Namespace = "System"
421                         };
422                         var ast = new EcmaDesc {
423                                 DescKind = EcmaDesc.Kind.Method,
424                                 TypeName = "RegistryKey",
425                                 Namespace = "Microsoft.Win32",
426                                 ExplicitImplMember = inner
427                         };
428                         AssertUrlDesc (ast, "M:Microsoft.Win32.RegistryKey$System.IDisposable.Dispose");
429                 }
430
431                 [Test]
432                 public void SimpleMethodWithNumberInType ()
433                 {
434                         var ast = new EcmaDesc {
435                                 DescKind = EcmaDesc.Kind.Method,
436                                 TypeName = "ASN1",
437                                 Namespace = "Mono.Security",
438                                 MemberName = "Add"
439                         };
440                         AssertUrlDesc (ast, "M:Mono.Security.ASN1.Add");
441                 }
442
443                 [Test]
444                 public void JaggedArrayWithDimensions ()
445                 {
446                         var ast = new EcmaDesc {
447                                 DescKind = EcmaDesc.Kind.Type,
448                                 TypeName = "Int32",
449                                 Namespace = "System",
450                                 ArrayDimensions = new int[] { 3, 1, 1 }
451                         };
452                         AssertUrlDesc (ast, "T:System.Int32[,,][][]");
453                 }
454
455                 [Test]
456                 public void ExplicitIndexerImplementation ()
457                 {
458                         var explicitImpl = new EcmaDesc {
459                                 Namespace = "System.Web.SessionState",
460                                 TypeName = "IHttpSessionState",
461                                 MemberName = "Item",
462                                 MemberArguments = new [] { new EcmaDesc { DescKind = EcmaDesc.Kind.Type, Namespace = "System", TypeName = "Int32" } },
463                         };
464                         var ast = new EcmaDesc {
465                                 DescKind = EcmaDesc.Kind.Property,
466                                 TypeName = "HttpSessionStateContainer",
467                                 Namespace = "System.Web.SessionState",
468                                 ExplicitImplMember = explicitImpl,
469                         };
470                         AssertUrlDesc (ast, "P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)");
471                 }
472
473                 [Test]
474                 public void ToEcmaCref_Namespace ()
475                 {
476                         var actual = new EcmaDesc {
477                                 DescKind = EcmaDesc.Kind.Namespace,
478                                 Namespace = "System.IO",
479                         };
480
481                         AssertEcmaString ("N:System.IO", actual);
482                 }
483
484                 [Test]
485                 public void ToEcmaCref_SimpleType ()
486                 {
487                         var actual = new EcmaDesc {
488                                 DescKind = EcmaDesc.Kind.Type,
489                                 Namespace = "System.IO",
490                                 TypeName = "Path",
491                         };
492
493                         AssertEcmaString ("T:System.IO.Path", actual);
494                 }
495
496                 [Test]
497                 public void ToEcmaCref_NestedType ()
498                 {
499                         var actual = new EcmaDesc {
500                                 DescKind = EcmaDesc.Kind.Type,
501                                 Namespace = "System.IO",
502                                 TypeName = "Path",
503                                 NestedType = new EcmaDesc {
504                                         DescKind = EcmaDesc.Kind.Type,
505                                         TypeName = "TheNestedType",
506                                 },
507                         };
508
509                         AssertEcmaString ("T:System.IO.Path+TheNestedType", actual);
510                 }
511
512                 [Test]
513                 public void ToEcmaCref_NestedType_FourDeep ()
514                 {
515                         var actual = new EcmaDesc {
516                                 DescKind = EcmaDesc.Kind.Type,
517                                 Namespace = "Mono",
518                                 TypeName = "DocTest",
519                                 NestedType = new EcmaDesc {
520                                         DescKind = EcmaDesc.Kind.Type,
521                                         TypeName = "NestedClass",
522                                         NestedType = new EcmaDesc {
523                                                 DescKind = EcmaDesc.Kind.Type,
524                                                 TypeName = "Double",
525                                                 NestedType = new EcmaDesc {
526                                                         DescKind = EcmaDesc.Kind.Type,
527                                                         TypeName = "Triple",
528                                                         NestedType = new EcmaDesc {
529                                                                 DescKind = EcmaDesc.Kind.Type,
530                                                                 TypeName = "Quadruple",
531                                                         },
532                                                 },
533                                         },
534                                 },
535                         };
536
537                         string targetUrl = "T:Mono.DocTest+NestedClass+Double+Triple+Quadruple";
538                         AssertEcmaString (targetUrl, actual);
539                         AssertUrlDesc (actual, targetUrl);
540                 }
541
542                 [Test]
543                 public void ToEcmaCref_NestedType_Field ()
544                 {
545                         var actual = new EcmaDesc {
546                                 DescKind = EcmaDesc.Kind.Field,
547                                 Namespace = "System.IO",
548                                 TypeName = "Path",
549                                 NestedType = new EcmaDesc {
550                                         DescKind = EcmaDesc.Kind.Type,
551                                         TypeName = "TheNestedType",
552                                 },
553                                 MemberName = "NestedField"
554                         };
555
556                         AssertEcmaString ("F:System.IO.Path+TheNestedType.NestedField", actual);
557                 }
558
559                 [Test]
560                 public void ToEcmaCref_SimpleType_WithGenerics ()
561                 {
562                         var actual = new EcmaDesc {
563                                 DescKind = EcmaDesc.Kind.Type,
564                                 Namespace = "System.IO",
565                                 TypeName = "Path",
566                                 GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray ()
567                         };
568
569                         AssertEcmaString ("T:System.IO.Path<K>", actual);
570                 }
571
572                 [Test]
573                 public void ToEcmaCref_Nestedype_WithGenerics ()
574                 {
575                         var actual = new EcmaDesc {
576                                 DescKind = EcmaDesc.Kind.Type,
577                                 Namespace = "System.IO",
578                                 TypeName = "Path",
579                                 NestedType = new EcmaDesc {
580                                         DescKind = EcmaDesc.Kind.Type,
581                                         TypeName = "TheNestedType",
582                                 },
583                                 GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray ()
584                         };
585
586                         AssertEcmaString ("T:System.IO.Path<K>+TheNestedType", actual);
587                 }
588
589                 [Test]
590                 public void ToEcmaCref_Nestedype_WithGenericsOnBoth ()
591                 {
592                         var actual = new EcmaDesc {
593                                 DescKind = EcmaDesc.Kind.Type,
594                                 Namespace = "System.IO",
595                                 TypeName = "Path",
596                                 NestedType = new EcmaDesc {
597                                         DescKind = EcmaDesc.Kind.Type,
598                                         TypeName = "TheNestedType",
599                                         GenericTypeArguments = GenericTypeArgumentsList ("T", "V").ToArray (),
600                                 },
601                                 GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray ()
602                         };
603
604                         AssertEcmaString ("T:System.IO.Path<K>+TheNestedType<T,V>", actual);
605                 }
606
607                 [Test]
608                 public void ToEcmaCref_Nestedype_Property_WithGenericsOnBoth ()
609                 {
610                         var actual = new EcmaDesc {
611                                 DescKind = EcmaDesc.Kind.Property,
612                                 Namespace = "System.IO",
613                                 TypeName = "Path",
614                                 NestedType = new EcmaDesc {
615                                         DescKind = EcmaDesc.Kind.Type,
616                                         TypeName = "TheNestedType",
617                                         GenericTypeArguments = GenericTypeArgumentsList ("T", "V").ToArray (),
618                                 },
619                                 GenericTypeArguments = GenericTypeArgumentsList ("K").ToArray (),
620                                 MemberName = "TheProperty"
621                         };
622
623                         AssertEcmaString ("P:System.IO.Path<K>+TheNestedType<T,V>.TheProperty", actual);
624                 }
625
626                 [Test]
627                 public void ToEcmaCref_Field ()
628                 {
629                         var actual = new EcmaDesc {
630                                 DescKind = EcmaDesc.Kind.Field,
631                                 Namespace = "System.IO",
632                                 TypeName = "Path",
633                                 MemberName = "TheField"
634                         };
635
636                         AssertEcmaString ("F:System.IO.Path.TheField", actual);
637                 }
638
639                 [Test]
640                 public void ToEcmaCref_ExplicitlyImplemented_Field ()
641                 {
642                         var explicitImpl = new EcmaDesc {
643                                 Namespace = "System.Web.SessionState",
644                                 TypeName = "IHttpSessionState",
645                                 MemberName = "Item",
646                         };
647                         var actual = new EcmaDesc {
648                                 DescKind = EcmaDesc.Kind.Field,
649                                 TypeName = "HttpSessionStateContainer",
650                                 Namespace = "System.Web.SessionState",
651                                 ExplicitImplMember = explicitImpl,
652                         };
653                         AssertEcmaString ("F:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item", actual);
654                 }               
655
656                 [Test]
657                 public void ToEcmaCref_Property ()
658                 {
659                         var actual = new EcmaDesc {
660                                 DescKind = EcmaDesc.Kind.Property,
661                                 Namespace = "System.IO",
662                                 TypeName = "Path",
663                                 MemberName = "TheProperty",
664                         };
665
666                         AssertEcmaString ("P:System.IO.Path.TheProperty", actual);
667                 }
668
669                 [Test]
670                 public void ToEcmaCref_ExplicitlyImplemented_Property ()
671                 {
672                         var explicitImpl = new EcmaDesc {
673                                 Namespace = "System.Web.SessionState",
674                                 TypeName = "IHttpSessionState",
675                                 MemberName = "Item",
676                         };
677                         var actual = new EcmaDesc {
678                                 DescKind = EcmaDesc.Kind.Property,
679                                 TypeName = "HttpSessionStateContainer",
680                                 Namespace = "System.Web.SessionState",
681                                 ExplicitImplMember = explicitImpl,
682                         };
683                         AssertEcmaString ("P:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item", actual);
684                 }
685
686                 [Test]
687                 public void ToEcmaCref_ExplicitlyImplemented_Method ()
688                 {
689                         var explicitImpl = new EcmaDesc {
690                                 Namespace = "System.Web.SessionState",
691                                 TypeName = "IHttpSessionState",
692                                 MemberName = "Item",
693                                 MemberArguments = new [] {
694                                         new EcmaDesc {
695                                                 DescKind = EcmaDesc.Kind.Type,
696                                                 Namespace = "System",
697                                                 TypeName = "Int32",
698                                         },
699                                 },
700                         };
701                         var actual = new EcmaDesc {
702                                 DescKind = EcmaDesc.Kind.Method,
703                                 TypeName = "HttpSessionStateContainer",
704                                 Namespace = "System.Web.SessionState",
705                                 ExplicitImplMember = explicitImpl,
706                         };
707                         AssertEcmaString ("M:System.Web.SessionState.HttpSessionStateContainer$System.Web.SessionState.IHttpSessionState.Item(System.Int32)", actual);
708                 }
709
710                 [Test]
711                 public void ToEcmaCref_Event ()
712                 {
713                         var actual = new EcmaDesc {
714                                 DescKind = EcmaDesc.Kind.Event,
715                                 Namespace = "System.IO",
716                                 TypeName = "Path",
717                                 MemberName = "TheEvent",
718                         };
719
720                         AssertEcmaString ("E:System.IO.Path.TheEvent", actual);
721                 }
722
723                 [Test]
724                 public void ToEcmaCref_Operator ()
725                 {
726                         var actual = new EcmaDesc {
727                                 DescKind = EcmaDesc.Kind.Operator,
728                                 Namespace = "System",
729                                 TypeName = "Int32",
730                                 MemberName = "Addition",
731                         };
732
733                         AssertEcmaString ("O:System.Int32.Addition", actual);
734                 }
735
736                 [Test]
737                 public void ToEcmaCref_Operator_Conversion ()
738                 {
739                         var actual = new EcmaDesc {
740                                 DescKind = EcmaDesc.Kind.Operator,
741                                 Namespace = "System",
742                                 TypeName = "Int32",
743                                 MemberName = "ExplicitConversion",
744                                 MemberArguments = new [] { 
745                                         new EcmaDesc { 
746                                                 DescKind = EcmaDesc.Kind.Type,
747                                                 Namespace = "System",
748                                                 TypeName = "Double",
749                                         },
750                                         new EcmaDesc {
751                                                 DescKind = EcmaDesc.Kind.Type,
752                                                 Namespace = "System",
753                                                 TypeName = "Int32",
754                                         }
755                                 },
756                         };
757
758                         AssertEcmaString ("O:System.Int32.ExplicitConversion(System.Double,System.Int32)", actual);
759                 }
760
761                 [Test]
762                 public void ToEcmaCref_Method ()
763                 {
764                         var actual = new EcmaDesc {
765                                 DescKind = EcmaDesc.Kind.Method,
766                                 Namespace = "System",
767                                 TypeName = "Int32",
768                                 MemberName = "Add"
769                         };
770
771                         AssertEcmaString ("M:System.Int32.Add", actual);
772                 }
773
774                 [Test]
775                 public void ToEcmaCref_Method_Parameters ()
776                 {
777                         var actual = new EcmaDesc {
778                                 DescKind = EcmaDesc.Kind.Method,
779                                 Namespace = "System",
780                                 TypeName = "Int32",
781                                 MemberName = "Add",
782                                 MemberArguments = new [] { 
783                                         new EcmaDesc {
784                                                 DescKind = EcmaDesc.Kind.Type,
785                                                 Namespace = "System",
786                                                 TypeName = "Double",
787                                         },
788                                         new EcmaDesc {
789                                                 DescKind = EcmaDesc.Kind.Type,
790                                                 Namespace = "System",
791                                                 TypeName = "Int32",
792                                         },
793                                 },
794                         };
795
796                         AssertEcmaString ("M:System.Int32.Add(System.Double,System.Int32)", actual);
797                 }
798
799                 [Test]
800                 public void ToEcmaCref_Method_Generics ()
801                 {
802                         var actual = new EcmaDesc {
803                                 DescKind = EcmaDesc.Kind.Method,
804                                 Namespace = "System",
805                                 TypeName = "Int32",
806                                 MemberName = "Add",
807                                 GenericMemberArguments = GenericTypeArgumentsList ("T", "K").ToArray (),
808                         };
809
810                         AssertEcmaString ("M:System.Int32.Add<T,K>", actual);
811                 }
812
813                 [Test]
814                 public void ToEcmaCref_Method_Generics_PlusParameters ()
815                 {
816                         var actual = new EcmaDesc {
817                                 DescKind = EcmaDesc.Kind.Method,
818                                 Namespace = "System",
819                                 TypeName = "Int32",
820                                 MemberName = "Add",
821                                 GenericMemberArguments = GenericTypeArgumentsList ("T", "K").ToArray (),
822                                 MemberArguments = new [] { 
823                                         new EcmaDesc {
824                                                 DescKind = EcmaDesc.Kind.Type,
825                                                 Namespace = "",
826                                                 TypeName = "T",
827                                         },
828                                         new EcmaDesc {
829                                                 DescKind = EcmaDesc.Kind.Type,
830                                                 Namespace = "",
831                                                 TypeName = "K",
832                                         },
833                                 },
834                         };
835
836                         AssertEcmaString ("M:System.Int32.Add<T,K>(T,K)", actual);
837                 }
838         }
839 }