PageRenderTime 39ms CodeModel.GetById 19ms app.highlight 15ms RepoModel.GetById 1ms app.codeStats 1ms

/NRefactory/ICSharpCode.NRefactory.VB.Tests/Output/VBNet/VBNetOutputTest.cs

http://github.com/icsharpcode/ILSpy
C# | 670 lines | 578 code | 88 blank | 4 comment | 1 complexity | bdd992605c2866faf14e1f73191b9087 MD5 | raw file
  1// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
  2// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
  3
  4using System;
  5using System.IO;
  6using ICSharpCode.NRefactory.VB.Ast;
  7using ICSharpCode.NRefactory.VB.Parser;
  8using ICSharpCode.NRefactory.VB.PrettyPrinter;
  9using ICSharpCode.NRefactory.VB.Visitors;
 10using NUnit.Framework;
 11
 12namespace ICSharpCode.NRefactory.VB.Tests.PrettyPrinter
 13{
 14	[TestFixture]
 15	public class VBNetOutputTest
 16	{
 17		void TestProgram(string program)
 18		{
 19			VBParser parser = ParserFactory.CreateParser(new StringReader(program));
 20			parser.Parse();
 21			Assert.AreEqual("", parser.Errors.ErrorOutput);
 22			VBNetOutputVisitor outputVisitor = new VBNetOutputVisitor();
 23			outputVisitor.Options.OutputByValModifier = true;
 24			outputVisitor.VisitCompilationUnit(parser.CompilationUnit, null);
 25			Assert.AreEqual("", outputVisitor.Errors.ErrorOutput);
 26			Assert.AreEqual(StripWhitespace(program), StripWhitespace(outputVisitor.Text));
 27		}
 28		
 29		string StripWhitespace(string text)
 30		{
 31			text = text.Trim().Replace("\t", "").Replace("\r", "").Replace("\n", " ").Replace("  ", " ");
 32			while (text.Contains("  ")) {
 33				text = text.Replace("  ", " ");
 34			}
 35			return text;
 36		}
 37		
 38		void TestTypeMember(string program)
 39		{
 40			TestProgram("Class A\n" + program + "\nEnd Class");
 41		}
 42		
 43		void TestStatement(string statement)
 44		{
 45			TestTypeMember("Sub Method()\n" + statement + "\nEnd Sub");
 46		}
 47		
 48		void TestExpression(string expression)
 49		{
 50			VBParser parser = ParserFactory.CreateParser(new StringReader(expression));
 51			Expression e = parser.ParseExpression();
 52			Assert.AreEqual("", parser.Errors.ErrorOutput);
 53			VBNetOutputVisitor outputVisitor = new VBNetOutputVisitor();
 54			e.AcceptVisitor(outputVisitor, null);
 55			Assert.AreEqual("", outputVisitor.Errors.ErrorOutput);
 56			Assert.AreEqual(StripWhitespace(expression), StripWhitespace(outputVisitor.Text));
 57		}
 58		
 59		[Test]
 60		public void Field()
 61		{
 62			TestTypeMember("Private a As Integer");
 63		}
 64		
 65		[Test]
 66		public void Method()
 67		{
 68			TestTypeMember("Sub Method()\nEnd Sub");
 69		}
 70		
 71		[Test]
 72		public void EnumWithBaseType()
 73		{
 74			TestProgram("Public Enum Foo As UShort\nEnd Enum");
 75		}
 76		
 77		[Test]
 78		public void PartialModifier()
 79		{
 80			TestProgram("Public Partial Class Foo\nEnd Class");
 81		}
 82		
 83		[Test]
 84		public void MustInheritClass()
 85		{
 86			TestProgram("Public MustInherit Class Foo\nEnd Class");
 87		}
 88		
 89		[Test]
 90		public void GenericClassDefinition()
 91		{
 92			TestProgram("Public Class Foo(Of T As {IDisposable, ICloneable})\nEnd Class");
 93		}
 94		
 95		[Test]
 96		public void GenericClassDefinitionWithBaseType()
 97		{
 98			TestProgram("Public Class Foo(Of T As IDisposable)\nInherits BaseType\nEnd Class");
 99		}
100		
101		[Test]
102		public void GenericMethodDefinition()
103		{
104			TestTypeMember("Public Sub Foo(Of T As {IDisposable, ICloneable})(ByVal arg As T)\nEnd Sub");
105		}
106		
107		[Test]
108		public void ArrayRank()
109		{
110			TestStatement("Dim a As Object(,,)");
111		}
112		
113		[Test]
114		public void ArrayInitialization()
115		{
116			TestStatement("Dim a As Object() = New Object(10) {}");
117			TestTypeMember("Private MultiDim As Integer(,) = {{1, 2}, {1, 3}}");
118			TestExpression("New Integer(, ) {{1, 1}, {1, 1}}");
119			TestTypeMember("Private _titles As String() = New String() {}");
120		}
121		
122		[Test]
123		public void MethodCallWithOptionalArguments()
124		{
125			TestExpression("M(, )");
126		}
127		
128		[Test]
129		public void IfStatement()
130		{
131			TestStatement("If a Then\n" +
132			              "\tm1()\n" +
133			              "ElseIf b Then\n" +
134			              "\tm2()\n" +
135			              "Else\n" +
136			              "\tm3()\n" +
137			              "End If");
138		}
139		
140		[Test]
141		public void ForNextLoop()
142		{
143			TestStatement("For i = 0 To 10\n" +
144			              "Next");
145			TestStatement("For i As Long = 10 To 0 Step -1\n" +
146			              "Next");
147		}
148		
149		[Test]
150		public void DoLoop()
151		{
152			TestStatement("Do\n" +
153			              "Loop");
154			TestStatement("Do\n" +
155			              "Loop While Not (i = 10)");
156		}
157		
158		[Test]
159		public void SelectCase()
160		{
161			TestStatement(@"Select Case i
162	Case 0
163	Case 1 To 4
164	Case Else
165End Select");
166		}
167		
168		[Test]
169		public void UsingStatement()
170		{
171			TestStatement(@"Using nf As New Font(), nf2 As New List(Of Font)(), nf3 = Nothing
172	Bla(nf)
173End Using");
174		}
175		
176		[Test]
177		public void UntypedVariable()
178		{
179			TestStatement("Dim x = 0");
180		}
181		
182		[Test]
183		public void UntypedField()
184		{
185			TestTypeMember("Dim x = 0");
186		}
187		
188		[Test]
189		public void Assignment()
190		{
191			TestExpression("a = b");
192		}
193		
194		[Test]
195		public void SpecialIdentifiers()
196		{
197			// Assembly, Ansi and Until are contextual keywords
198			// Custom is valid inside methods, but not valid for field names
199			TestExpression("Assembly = Ansi * [For] + Until - [Custom]");
200		}
201		
202		[Test]
203		public void DictionaryAccess()
204		{
205			TestExpression("c!key");
206		}
207		
208		[Test]
209		public void GenericMethodInvocation()
210		{
211			TestExpression("GenericMethod(Of T)(arg)");
212		}
213		
214		[Test]
215		public void SpecialIdentifierName()
216		{
217			TestExpression("[Class]");
218		}
219		
220		[Test]
221		public void GenericDelegate()
222		{
223			TestProgram("Public Delegate Function Predicate(Of T)(ByVal item As T) As String");
224		}
225		
226		[Test]
227		public void Enum()
228		{
229			TestProgram("Enum MyTest\nRed\n Green\n Blue\nYellow\n End Enum");
230		}
231		
232		[Test]
233		public void EnumWithInitializers()
234		{
235			TestProgram("Enum MyTest\nRed = 1\n Green = 2\n Blue = 4\n Yellow = 8\n End Enum");
236		}
237		
238		[Test]
239		public void SyncLock()
240		{
241			TestStatement("SyncLock a\nWork()\nEnd SyncLock");
242		}
243		
244		[Test]
245		public void Using()
246		{
247			TestStatement("Using a As New A()\na.Work()\nEnd Using");
248		}
249		
250		[Test]
251		public void Cast()
252		{
253			TestExpression("CType(a, T)");
254		}
255		
256		[Test]
257		public void DirectCast()
258		{
259			TestExpression("DirectCast(a, T)");
260		}
261		
262		[Test]
263		public void TryCast()
264		{
265			TestExpression("TryCast(a, T)");
266		}
267		
268		[Test]
269		public void PrimitiveCast()
270		{
271			TestExpression("CStr(a)");
272		}
273		
274		[Test]
275		public void TypeOfIs()
276		{
277			TestExpression("TypeOf a Is String");
278		}
279		
280		[Test]
281		public void PropertyWithAccessorAccessModifiers()
282		{
283			TestTypeMember("Public Property ExpectsValue() As Boolean\n" +
284			               "\tPublic Get\n" +
285			               "\tEnd Get\n" +
286			               "\tProtected Set\n" +
287			               "\tEnd Set\n" +
288			               "End Property");
289		}
290		
291		[Test]
292		public void AutoProperty()
293		{
294			TestTypeMember("Public Property Value()");
295			TestTypeMember("Public Property Value() As Integer");
296			TestTypeMember("Public Property Value() As Integer = 5");
297			TestTypeMember("Public Property Value() As New List()");
298		}
299		
300		[Test]
301		public void AbstractProperty()
302		{
303			TestTypeMember("Public MustOverride Property ExpectsValue() As Boolean");
304			TestTypeMember("Public MustOverride ReadOnly Property ExpectsValue() As Boolean");
305			TestTypeMember("Public MustOverride WriteOnly Property ExpectsValue() As Boolean");
306		}
307		
308		[Test]
309		public void AbstractMethod()
310		{
311			TestTypeMember("Public MustOverride Sub Run()");
312			TestTypeMember("Public MustOverride Function Run() As Boolean");
313		}
314		
315		[Test]
316		public void InterfaceImplementingMethod()
317		{
318			TestTypeMember("Public Sub Run() Implements SomeInterface.Run\nEnd Sub");
319			TestTypeMember("Public Function Run() As Boolean Implements SomeInterface.Bla\nEnd Function");
320		}
321		
322		[Test]
323		public void NamedAttributeArgument()
324		{
325			TestProgram("<Attribute(ArgName := \"value\")> _\n" +
326			            "Class Test\n" +
327			            "End Class");
328		}
329		
330		[Test]
331		public void ReturnTypeAttribute()
332		{
333			TestTypeMember("Function A() As <Attribute> String\n" +
334			               "End Function");
335		}
336		
337		[Test]
338		public void AssemblyAttribute()
339		{
340			TestProgram("<Assembly: CLSCompliant>");
341		}
342		
343		[Test]
344		public void ModuleAttribute()
345		{
346			TestProgram("<Module: SuppressMessageAttribute>");
347		}
348		
349		[Test]
350		public void Interface()
351		{
352			TestProgram("Interface ITest\n" +
353			            "Property GetterAndSetter() As Boolean\n" +
354			            "ReadOnly Property GetterOnly() As Boolean\n" +
355			            "WriteOnly Property SetterOnly() As Boolean\n" +
356			            "Sub InterfaceMethod()\n" +
357			            "Function InterfaceMethod2() As String\n" +
358			            "End Interface");
359		}
360		
361		[Test]
362		public void OnErrorStatement()
363		{
364			TestStatement("On Error Resume Next");
365		}
366		
367		[Test]
368		public void OverloadedConversionOperators()
369		{
370			TestTypeMember("Public Shared Narrowing Operator CType(ByVal xmlNode As XmlNode) As TheBug\nEnd Operator");
371			TestTypeMember("Public Shared Widening Operator CType(ByVal bugNode As TheBug) As XmlNode\nEnd Operator");
372		}
373		
374		[Test]
375		public void OverloadedTrueFalseOperators()
376		{
377			TestTypeMember("Public Shared Operator IsTrue(ByVal a As TheBug) As Boolean\nEnd Operator");
378			TestTypeMember("Public Shared Operator IsFalse(ByVal a As TheBug) As Boolean\nEnd Operator");
379		}
380		
381		[Test]
382		public void OverloadedOperators()
383		{
384			TestTypeMember("Public Shared Operator +(ByVal bugNode As TheBug, ByVal bugNode2 As TheBug) As TheBug\nEnd Operator");
385			TestTypeMember("Public Shared Operator >>(ByVal bugNode As TheBug, ByVal b As Integer) As TheBug\nEnd Operator");
386		}
387		
388		[Test]
389		public void AttributeOnParameter()
390		{
391			TestTypeMember("Sub Main(ByRef one As Integer, ByRef two As Integer, <Out> ByRef three As Integer)\nEnd Sub");
392		}
393		
394		[Test]
395		public void FieldWithoutType()
396		{
397			TestTypeMember("Dim X");
398		}
399		
400		[Test]
401		public void UsingStatementForExistingVariable()
402		{
403			TestStatement("Using obj\nEnd Using");
404		}
405		
406		[Test]
407		public void ContinueFor()
408		{
409			TestStatement("Continue For");
410		}
411		
412		[Test]
413		public void ForNextStatementWithFieldLoopVariable()
414		{
415			TestStatement("For Me.Field = 0 To 10\n" +
416			              "Next Me.Field");
417		}
418		
419		[Test]
420		public void WithStatement()
421		{
422			TestStatement("With Ejes\n" +
423			              "\t.AddLine(New Point(Me.ClientSize.Width / 2, 0), (New Point(Me.ClientSize.Width / 2, Me.ClientSize.Height)))\n" +
424			              "End With");
425		}
426		
427		[Test]
428		public void NewConstraint()
429		{
430			TestProgram("Public Class Rational(Of T, O As {IRationalMath(Of T), New})\nEnd Class");
431		}
432		
433		[Test]
434		public void StructConstraint()
435		{
436			TestProgram("Public Class Rational(Of T, O As {IRationalMath(Of T), Structure})\nEnd Class");
437		}
438		
439		[Test]
440		public void ClassConstraint()
441		{
442			TestProgram("Public Class Rational(Of T, O As {IRationalMath(Of T), Class})\nEnd Class");
443		}
444		
445		[Test]
446		public void Integer()
447		{
448			TestExpression("16");
449		}
450		
451		[Test]
452		public void Double()
453		{
454			TestExpression("1.0");
455		}
456		
457		[Test]
458		public void HexadecimalInteger()
459		{
460			TestExpression("&H10");
461		}
462		
463		[Test]
464		public void HexadecimalMinusOne()
465		{
466			TestExpression("&Hffffffff");
467		}
468		
469		[Test]
470		public void TypeCharacters()
471		{
472			TestExpression("347S");
473			TestExpression("347L");
474			TestExpression("347D");
475			TestExpression("347F");
476			TestExpression("347US");
477			TestExpression("347UI");
478			TestExpression("347UL");
479			TestExpression("\".\"C");
480		}
481		
482		[Test]
483		public void AddressOf()
484		{
485			TestExpression("AddressOf Abc");
486		}
487		
488		[Test]
489		public void ChainedConstructorCall()
490		{
491			TestExpression("MyBase.New()");
492			TestExpression("Me.New()");
493			TestExpression("MyClass.New()");
494		}
495		
496		[Test]
497		public void NewMethodCall()
498		{
499			TestExpression("something.[New]()");
500		}
501		
502		[Test]
503		public void ObjectInitializer()
504		{
505			TestExpression("New StringWriter() With { _\n" +
506			               " .NewLine = Environment.NewLine, _\n" +
507			               " .Encoding = Encoding.UTF8 _\n" +
508			               "}");
509		}
510		
511		[Test]
512		public void EventDefinition()
513		{
514			TestTypeMember("Public Event MyEvent(ByVal sender As Object)");
515		}
516		
517		[Test]
518		public void Options()
519		{
520			TestProgram("Option Strict On\n" +
521			            "Option Explicit On\n" +
522			            "Option Infer On\n" +
523			            "Option Compare Text");
524		}
525		
526		[Test]
527		public void UntypedForeach()
528		{
529			TestStatement("For Each x In myGuidArray\nNext");
530		}
531		
532		[Test]
533		public void MethodDefinitionWithOptionalParameter()
534		{
535			TestTypeMember("Sub M(Optional ByVal msg As String = Nothing, Optional ByRef output As String = Nothing)\nEnd Sub");
536		}
537		
538		[Test]
539		public void Module()
540		{
541			TestProgram("Module Test\n" +
542			            " Sub M()\n" +
543			            " End Sub\n" +
544			            "End Module");
545		}
546		
547		[Test]
548		public void WithEvents()
549		{
550			TestTypeMember("Dim WithEvents a As Button");
551		}
552				
553		[Test]
554		public void FriendWithEventsField()
555		{
556			TestTypeMember("Friend WithEvents Button1 As System.Windows.Forms.Button");
557		}
558		
559		[Test]
560		public void SimpleFunctionLambda()
561		{
562			TestExpression("Function(x) x * x");
563		}
564		
565		[Test]
566		public void SimpleFunctionLambdaWithType()
567		{
568			TestExpression("Function(x As Integer) x * x");
569		}
570		
571		[Test]
572		public void SimpleSubLambdaWithType()
573		{
574			TestExpression("Sub(x As Integer) Console.WriteLine(x)");
575		}
576		
577		[Test]
578		public void BlockSubLambdaWithType()
579		{
580			TestExpression("Sub(x As Integer)\n" +
581			               "	Console.WriteLine(x)\n" +
582			               "End Sub");
583		}
584		
585		[Test]
586		public void BlockFunctionLambdaWithType()
587		{
588			TestExpression("Function(x As Integer) As Integer\n" +
589			               "	If x < 2 Then\n" +
590			               "		Return x\n" +
591			               "	End If\n" +
592			               "	Return x * x\n" +
593			               "End Function");
594		}
595		
596		[Test]
597		public void XmlSimple()
598		{
599			TestExpression("<?xml?>\n" +
600			               "<!-- test -->\n" +
601			               "<Test>\n" +
602			               "	<A />\n" +
603			               "	<B test='a' <%= test %> />\n" +
604			               "</Test>");
605		}
606		
607		[Test]
608		public void XmlNested()
609		{
610			TestExpression(@"<menu>
611              <course name=""appetizer"">
612                  <dish>Shrimp Cocktail</dish>
613                  <dish>Escargot</dish>
614              </course>
615              <course name=""main"">
616                  <dish>Filet Mignon</dish>
617                  <dish>Garlic Potatoes</dish>
618                  <dish>Broccoli</dish>
619              </course>
620              <course name=""dessert"">
621                  <dish>Chocolate Cheesecake</dish>
622              </course>
623          </menu>");
624		}
625		
626		[Test]
627		public void XmlDocument()
628		{
629			TestExpression(@"<?xml version=""1.0""?>
630                  <menu>
631                      <course name=""appetizer"">
632                          <dish>Shrimp Cocktail</dish>
633                          <dish>Escargot</dish>
634                      </course>
635                  </menu>");
636		}
637		
638		[Test]
639		public void XmlNestedWithExpressions()
640		{
641			TestExpression(@"<?xml version=""1.0""?>
642          <menu>
643              <course name=""appetizer"">
644                  <%= From m In menu _
645                      Where m.Course = ""appetizer"" _
646                      Select <dish><%= m.Food %></dish> %>
647              </course>
648              <course name=""main"">
649                  <%= From m In menu _
650                      Where m.Course = ""main"" _
651                      Select <dish><%= m.Food %></dish> %>
652              </course>
653              <course name=""dessert"">
654                  <%= From m In menu _
655                      Where m.Course = ""dessert"" _
656                      Select <dish><%= m.Food %></dish> %>
657              </course>
658          </menu>");
659		}
660		
661		[Test]
662		public void XmlAccessExpressions()
663		{
664			TestExpression("xml.<menu>.<course>");
665			TestExpression("xml...<course>");
666			TestExpression("xml...<course>(2)");
667			TestExpression("item.@name");
668		}
669	}
670}