* VBCodeGenerator.cs: Fixed generated code for abstract properties.
[mono.git] / mcs / class / System / Test / Microsoft.VisualBasic / VBCodeProviderTest.cs
1 //
2 // Microsoft.VisualBasic.VBCodeProvider.cs
3 //
4 // Author:
5 //   Jochen Wezel (jwezel@compumaster.de)
6 //
7 // (C) 2003 Jochen Wezel (CompuMaster GmbH)
8 //
9 // Last modifications:
10 // 2003-12-10 JW: publishing of this file
11 //
12
13 using System;
14 using System.CodeDom;
15 using System.CodeDom.Compiler;
16 using System.Collections.Specialized;
17 using System.Globalization;
18 using System.Reflection;
19 using System.Diagnostics;
20 using System.IO;
21 using System.Text;
22 using Microsoft.VisualBasic;
23 using NUnit.Framework;
24
25 namespace MonoTests.Microsoft.VisualBasic
26 {
27         enum OsType
28         {
29                 Windows,
30                 Unix,
31                 Mac
32         }
33
34         [TestFixture]
35         [Category ("NotWorking")] // we cannot rely on vbnc being available
36         public class VBCodeProviderTest
37         {
38                 private string _tempDir;
39                 private CodeDomProvider _codeProvider;
40                 private static OsType OS;
41                 private static char DSC = Path.DirectorySeparatorChar;
42
43                 private static readonly string _sourceLibrary1 = "Public Class Test1" +
44                         Environment.NewLine + "End Class";
45                 private static readonly string _sourceLibrary2 = "Public Class Test2" +
46                         Environment.NewLine + "End Class";
47                 private static readonly string _sourceExecutable = @"
48                         Public Class Program
49                         Public Sub Main
50                         End Sub
51                         End Class";
52
53                 [SetUp]
54                 public void GetReady ()
55                 {
56                         if ('/' == DSC) {
57                                 OS = OsType.Unix;
58                         } else if ('\\' == DSC) {
59                                 OS = OsType.Windows;
60                         } else {
61                                 OS = OsType.Mac;
62                         }
63
64                         _codeProvider = new VBCodeProvider ();
65                         _tempDir = CreateTempDirectory ();
66                 }
67
68                 [TearDown]
69                 public void TearDown ()
70                 {
71                         RemoveDirectory (_tempDir);
72                 }
73
74                 [Test]
75                 public void FileExtension ()
76                 {
77                         Assert.AreEqual ("vb", _codeProvider.FileExtension, "#JW10");
78                 }
79
80                 [Test]
81                 public void LanguageOptionsTest ()
82                 {
83                         Assert.AreEqual (LanguageOptions.CaseInsensitive, _codeProvider.LanguageOptions, "#JW20");
84                 }
85
86                 [Test]
87                 public void GeneratorSupports ()
88                 {
89                         ICodeGenerator codeGenerator = _codeProvider.CreateGenerator ();
90                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareEnums), "#1");
91                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ArraysOfArrays), "#2");
92                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.AssemblyAttributes), "#3");
93                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ChainedConstructorArguments), "#4");
94                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ComplexExpressions), "#5");
95                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareDelegates), "#6");
96                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareEnums), "#7");
97                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareEvents), "#8");
98                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareInterfaces), "#9");
99                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareValueTypes), "#10");
100                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.EntryPointMethod), "#11");
101                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.GotoStatements), "#12");
102                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.MultidimensionalArrays), "#13");
103                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.MultipleInterfaceMembers), "#14");
104                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.NestedTypes), "#15");
105                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ParameterAttributes), "#16");
106                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.PublicStaticMembers), "#17");
107                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ReferenceParameters), "#18");
108                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ReturnTypeAttributes), "#19");
109                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.StaticConstructors), "#20");
110                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.TryCatchStatements), "#21");
111                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.Win32Resources), "#22");
112 #if NET_2_0
113                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareIndexerProperties), "#23");
114                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.GenericTypeDeclaration), "#24");
115                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.GenericTypeReference), "#25");
116                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.PartialTypes), "#26");
117                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.Resources), "#27");
118 #endif
119                 }
120
121                 [Test]
122                 [Category ("NotWorking")] // we cannot rely on vbnc being available
123                 public void CreateCompiler ()
124                 {
125                         // Prepare the compilation
126                         ICodeCompiler codeCompiler = _codeProvider.CreateCompiler ();
127                         Assert.IsNotNull (codeCompiler, "#JW30 - CreateCompiler");
128
129                         CompilerParameters options = new CompilerParameters ();
130                         options.GenerateExecutable = true;
131                         options.IncludeDebugInformation = true;
132                         options.TreatWarningsAsErrors = true;
133
134                         // process compilation
135                         CompilerResults compilerResults = codeCompiler.CompileAssemblyFromSource (options,
136                                 "public class TestModule" + Environment.NewLine + "public shared sub Main()"
137                                 + Environment.NewLine + "System.Console.Write(\"Hello world!\")"
138                                 + Environment.NewLine + "End Sub" + Environment.NewLine + "End Class");
139
140                         // Analyse the compilation success/messages
141                         StringCollection MyOutput = compilerResults.Output;
142                         string MyOutStr = "";
143                         foreach (string MyStr in MyOutput) {
144                                 MyOutStr += MyStr + Environment.NewLine + Environment.NewLine;
145                         }
146
147                         if (compilerResults.Errors.Count != 0) {
148                                 Assert.Fail ("#JW31 - Hello world compilation: " + MyOutStr);
149                         }
150
151                         try {
152                                 Assembly MyAss = compilerResults.CompiledAssembly;
153                         } catch (Exception ex) {
154                                 Assert.Fail ("#JW32 - compilerResults.CompiledAssembly hasn't been an expected object" +
155                                                 Environment.NewLine + ex.Message + Environment.NewLine + ex.StackTrace);
156                         }
157
158                         // Execute the test app
159                         ProcessStartInfo NewProcInfo = new ProcessStartInfo ();
160                         if (Windows) {
161                                 NewProcInfo.FileName = compilerResults.CompiledAssembly.Location;
162                         } else {
163                                 NewProcInfo.FileName = "mono";
164                                 NewProcInfo.Arguments = compilerResults.CompiledAssembly.Location;
165                         }
166                         NewProcInfo.RedirectStandardOutput = true;
167                         NewProcInfo.UseShellExecute = false;
168                         NewProcInfo.CreateNoWindow = true;
169                         string TestAppOutput = "";
170                         try {
171                                 Process MyProc = Process.Start (NewProcInfo);
172                                 MyProc.WaitForExit ();
173                                 TestAppOutput = MyProc.StandardOutput.ReadToEnd ();
174                                 MyProc.Close ();
175                                 MyProc.Dispose ();
176                         } catch (Exception ex) {
177                                 Assert.Fail ("#JW34 - " + ex.Message + Environment.NewLine + ex.StackTrace);
178                         }
179                         Assert.AreEqual ("Hello world!", TestAppOutput, "#JW33 - Application output");
180
181                         // Clean up
182                         try {
183                                 File.Delete (NewProcInfo.FileName);
184                         } catch { }
185                 }
186
187                 [Test]
188                 public void CreateGenerator ()
189                 {
190                         ICodeGenerator MyVBCodeGen;
191                         MyVBCodeGen = _codeProvider.CreateGenerator ();
192                         Assert.IsNotNull (MyVBCodeGen, "#JW40 - CreateGenerator");
193                         Assert.IsTrue (MyVBCodeGen.Supports (GeneratorSupport.DeclareEnums), "#JW41");
194                 }
195
196                 [Test]
197                 [Category ("NotWorking")] // we cannot rely on vbnc being available
198                 public void CompileFromFile_InMemory ()
199                 {
200                         // create vb source file
201                         string sourceFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
202                         using (FileStream f = new FileStream (sourceFile, FileMode.Create)) {
203                                 using (StreamWriter s = new StreamWriter (f)) {
204                                         s.Write (_sourceLibrary1);
205                                         s.Close ();
206                                 }
207                                 f.Close ();
208                         }
209
210                         CompilerParameters options = new CompilerParameters ();
211                         options.GenerateExecutable = false;
212                         options.GenerateInMemory = true;
213                         options.TempFiles = new TempFileCollection (_tempDir);
214 #if NET_2_0
215                         options.EmbeddedResources.Add (sourceFile);
216 #endif
217
218                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
219                         CompilerResults results = compiler.CompileAssemblyFromFile (options,
220                                 sourceFile);
221
222                         // verify compilation was successful
223                         AssertCompileResults (results, true);
224
225                         Assembly compiledAssembly = results.CompiledAssembly;
226
227                         Assert.IsNotNull (compiledAssembly, "#1");
228                         Assert.AreEqual (string.Empty, compiledAssembly.Location, "#2");
229                         Assert.IsNull (results.PathToAssembly, "#3");
230                         Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#4");
231
232                         // verify we don't cleanup files in temp directory too agressively
233                         string[] tempFiles = Directory.GetFiles (_tempDir);
234                         Assert.AreEqual (1, tempFiles.Length, "#5");
235                         Assert.AreEqual (sourceFile, tempFiles[0], "#6");
236
237 #if NET_2_0
238                         string[] resources = compiledAssembly.GetManifestResourceNames();
239                         Assert.IsNotNull (resources, "#7");
240                         Assert.AreEqual (1, resources.Length, "#8");
241                         Assert.AreEqual ("file.vb", resources[0], "#9");
242                         Assert.IsNull (compiledAssembly.GetFile ("file.vb"), "#10");
243                         Assert.IsNotNull (compiledAssembly.GetManifestResourceStream  ("file.vb"), "#11");
244 #endif
245                 }
246
247                 [Test]
248                 [Category ("NotWorking")] // we cannot rely on vbnc being available
249                 public void CompileFromFileBatch_Executable_InMemory ()
250                 {
251                         // create vb source file
252                         string sourceFile1 = Path.Combine (_tempDir, "file1." + _codeProvider.FileExtension);
253                         using (FileStream f = new FileStream (sourceFile1, FileMode.Create)) {
254                                 using (StreamWriter s = new StreamWriter (f)) {
255                                         s.Write (_sourceLibrary1);
256                                         s.Close ();
257                                 }
258                                 f.Close ();
259                         }
260
261                         string sourceFile2 = Path.Combine (_tempDir, "file2." + _codeProvider.FileExtension);
262                         using (FileStream f = new FileStream (sourceFile2, FileMode.Create)) {
263                                 using (StreamWriter s = new StreamWriter (f)) {
264                                         s.Write (_sourceExecutable);
265                                         s.Close ();
266                                 }
267                                 f.Close ();
268                         }
269
270                         CompilerParameters options = new CompilerParameters ();
271                         options.GenerateExecutable = false;
272                         options.GenerateInMemory = true;
273                         options.OutputAssembly = string.Empty;
274                         options.TempFiles = new TempFileCollection (_tempDir);
275 #if NET_2_0
276                         options.EmbeddedResources.Add (sourceFile1);
277                         options.LinkedResources.Add (sourceFile2);
278 #endif
279
280                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
281                         CompilerResults results = compiler.CompileAssemblyFromFileBatch (options,
282                                 new string [] { sourceFile1, sourceFile2 });
283
284                         // verify compilation was successful
285                         AssertCompileResults (results, true);
286
287                         Assembly compiledAssembly = results.CompiledAssembly;
288
289                         Assert.IsNotNull (compiledAssembly, "#A1");
290                         Assert.AreEqual (string.Empty, compiledAssembly.Location, "#A2");
291                         Assert.IsNull (results.PathToAssembly, "#A3");
292                         Assert.IsNotNull (options.OutputAssembly, "#A4");
293                         Assert.AreEqual (".dll", Path.GetExtension (options.OutputAssembly), "#A5");
294                         Assert.AreEqual (_tempDir, Path.GetDirectoryName (options.OutputAssembly), "#A6");
295                         Assert.IsFalse (File.Exists (options.OutputAssembly), "#A7");
296
297                         Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#B1");
298                         Assert.IsNotNull (compiledAssembly.GetType ("Program"), "#B2");
299
300                         // verify we don't cleanup files in temp directory too agressively
301                         string [] tempFiles = Directory.GetFiles (_tempDir);
302                         Assert.AreEqual (2, tempFiles.Length, "#C1");
303                         Assert.IsTrue (File.Exists (sourceFile1), "#C2");
304                         Assert.IsTrue (File.Exists (sourceFile2), "#C3");
305
306 #if NET_2_0
307                         string[] resources = compiledAssembly.GetManifestResourceNames();
308                         Assert.IsNotNull (resources, "#D1");
309                         Assert.AreEqual (2, resources.Length, "#D2");
310
311                         Assert.AreEqual ("file1.vb", resources[0], "#E1");
312                         Assert.IsNull (compiledAssembly.GetFile ("file1.vb"), "#E2");
313                         Assert.IsNotNull (compiledAssembly.GetManifestResourceStream  ("file1.vb"), "#E3");
314                         ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file1.vb");
315                         Assert.IsNotNull (info, "#E4");
316                         Assert.IsNull (info.FileName, "#E5");
317                         Assert.IsNull (info.ReferencedAssembly, "#E6");
318                         Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#E7");
319
320                         Assert.AreEqual ("file2.vb", resources[1], "#F1");
321                         try {
322                                 compiledAssembly.GetFile ("file2.vb");
323                                 Assert.Fail ("#F2");
324                         } catch (FileNotFoundException) {
325                         }
326                         try {
327                                 compiledAssembly.GetManifestResourceStream  ("file2.vb");
328                                 Assert.Fail ("#F3");
329                         } catch (FileNotFoundException) {
330                         }
331                         info = compiledAssembly.GetManifestResourceInfo ("file2.vb");
332                         Assert.IsNotNull (info, "#F4");
333                         Assert.IsNotNull (info.FileName, "#F5");
334                         Assert.AreEqual ("file2.vb", info.FileName, "#F6");
335                         Assert.IsNull (info.ReferencedAssembly, "#F7");
336                         Assert.AreEqual ((ResourceLocation) 0, info.ResourceLocation, "#F8");
337 #endif
338                 }
339
340                 [Test]
341                 [Category ("NotWorking")] // we cannot rely on vbnc being available
342                 public void CompileFromFileBatch_Library_InMemory ()
343                 {
344                         // create vb source file
345                         string sourceFile1 = Path.Combine (_tempDir, "file1." + _codeProvider.FileExtension);
346                         using (FileStream f = new FileStream (sourceFile1, FileMode.Create)) {
347                                 using (StreamWriter s = new StreamWriter (f)) {
348                                         s.Write (_sourceLibrary1);
349                                         s.Close ();
350                                 }
351                                 f.Close ();
352                         }
353
354                         string sourceFile2 = Path.Combine (_tempDir, "file2." + _codeProvider.FileExtension);
355                         using (FileStream f = new FileStream (sourceFile2, FileMode.Create)) {
356                                 using (StreamWriter s = new StreamWriter (f)) {
357                                         s.Write (_sourceLibrary2);
358                                         s.Close ();
359                                 }
360                                 f.Close ();
361                         }
362
363                         CompilerParameters options = new CompilerParameters ();
364                         options.GenerateExecutable = false;
365                         options.GenerateInMemory = true;
366                         options.TempFiles = new TempFileCollection (_tempDir);
367 #if NET_2_0
368                         options.EmbeddedResources.Add (sourceFile1);
369                         options.LinkedResources.Add (sourceFile2);
370 #endif
371
372                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
373                         CompilerResults results = compiler.CompileAssemblyFromFileBatch (options,
374                                 new string[] { sourceFile1, sourceFile2 });
375
376                         // verify compilation was successful
377                         AssertCompileResults (results, true);
378
379                         Assembly compiledAssembly = results.CompiledAssembly;
380
381                         Assert.IsNotNull (compiledAssembly, "#A1");
382                         Assert.AreEqual (string.Empty, compiledAssembly.Location, "#A2");
383                         Assert.IsNull (results.PathToAssembly, "#A3");
384                         Assert.IsNotNull (options.OutputAssembly, "#A4");
385                         Assert.AreEqual (".dll", Path.GetExtension (options.OutputAssembly), "#A5");
386                         Assert.AreEqual (_tempDir, Path.GetDirectoryName (options.OutputAssembly), "#A6");
387                         Assert.IsFalse (File.Exists (options.OutputAssembly), "#A7");
388
389                         Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#B1");
390                         Assert.IsNotNull (compiledAssembly.GetType ("Test2"), "#B2");
391
392                         // verify we don't cleanup files in temp directory too agressively
393                         string[] tempFiles = Directory.GetFiles (_tempDir);
394                         Assert.AreEqual (2, tempFiles.Length, "#C1");
395                         Assert.IsTrue (File.Exists (sourceFile1), "#C2");
396                         Assert.IsTrue (File.Exists (sourceFile2), "#C3");
397
398 #if NET_2_0
399                         string[] resources = compiledAssembly.GetManifestResourceNames();
400                         Assert.IsNotNull (resources, "#D1");
401                         Assert.AreEqual (2, resources.Length, "#D2");
402
403                         Assert.AreEqual ("file1.vb", resources[0], "#E1");
404                         Assert.IsNull (compiledAssembly.GetFile ("file1.vb"), "#E2");
405                         Assert.IsNotNull (compiledAssembly.GetManifestResourceStream  ("file1.vb"), "#E3");
406                         ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file1.vb");
407                         Assert.IsNotNull (info, "#E4");
408                         Assert.IsNull (info.FileName, "#E5");
409                         Assert.IsNull (info.ReferencedAssembly, "#E6");
410                         Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#E7");
411
412                         Assert.AreEqual ("file2.vb", resources[1], "#F1");
413                         try {
414                                 compiledAssembly.GetFile ("file2.vb");
415                                 Assert.Fail ("#F2");
416                         } catch (FileNotFoundException) {
417                         }
418                         try {
419                                 compiledAssembly.GetManifestResourceStream  ("file2.vb");
420                                 Assert.Fail ("#F3");
421                         } catch (FileNotFoundException) {
422                         }
423                         info = compiledAssembly.GetManifestResourceInfo ("file2.vb");
424                         Assert.IsNotNull (info, "#F4");
425                         Assert.IsNotNull (info.FileName, "#F5");
426                         Assert.AreEqual ("file2.vb", info.FileName, "#F6");
427                         Assert.IsNull (info.ReferencedAssembly, "#F7");
428                         Assert.AreEqual ((ResourceLocation) 0, info.ResourceLocation, "#F8");
429 #endif
430                 }
431
432                 [Test]
433                 [Category ("NotWorking")] // we cannot rely on vbnc being available
434                 public void CompileFromSource_InMemory ()
435                 {
436                         // create a file in temp directory to ensure that compiler is not removing
437                         // too much (temporary) files
438                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
439                         using (FileStream fs = File.Create (tempFile)) {
440                                 fs.Close ();
441                         }
442
443                         CompilerParameters options = new CompilerParameters ();
444                         options.GenerateExecutable = false;
445                         options.GenerateInMemory = true;
446                         options.TempFiles = new TempFileCollection (_tempDir);
447
448                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
449                         CompilerResults results = compiler.CompileAssemblyFromSource (options,
450                                 _sourceLibrary1);
451
452                         // verify compilation was successful
453                         AssertCompileResults (results, true);
454
455                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
456                         Assert.IsNull (results.PathToAssembly, "#2");
457                         Assert.IsNotNull (results.CompiledAssembly.GetType ("Test1"), "#3");
458
459                         // verify we don't cleanup files in temp directory too agressively
460                         string[] tempFiles = Directory.GetFiles (_tempDir);
461                         Assert.AreEqual (1, tempFiles.Length, "#4");
462                         Assert.AreEqual (tempFile, tempFiles[0], "#5");
463                 }
464
465                 [Test]
466                 [Category ("NotWorking")] // we cannot rely on vbnc being available
467                 public void CompileFromSourceBatch_InMemory ()
468                 {
469                         // create a file in temp directory to ensure that compiler is not removing
470                         // too much (temporary) files
471                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
472                         using (FileStream fs = File.Create (tempFile)) {
473                                 fs.Close ();
474                         }
475
476                         string outputAssembly = Path.Combine (_tempDir, "sourcebatch.dll");
477
478                         CompilerParameters options = new CompilerParameters ();
479                         options.GenerateExecutable = false;
480                         options.GenerateInMemory = true;
481                         options.OutputAssembly = outputAssembly;
482                         options.TempFiles = new TempFileCollection (_tempDir);
483
484                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
485                         CompilerResults results = compiler.CompileAssemblyFromSourceBatch (options,
486                                 new string[] { _sourceLibrary1, _sourceLibrary2 });
487
488                         // verify compilation was successful
489                         AssertCompileResults (results, true);
490
491                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#A1");
492                         Assert.IsNull (results.PathToAssembly, "#A2");
493                         Assert.IsNotNull (options.OutputAssembly, "#A3");
494                         Assert.AreEqual (outputAssembly, options.OutputAssembly, "#A4");
495                         Assert.IsTrue (File.Exists (outputAssembly), "#A5");
496
497                         Assert.IsNotNull (results.CompiledAssembly.GetType ("Test1"), "#B1");
498                         Assert.IsNotNull (results.CompiledAssembly.GetType ("Test2"), "#B2");
499
500                         // verify we don't cleanup files in temp directory too agressively
501                         string[] tempFiles = Directory.GetFiles (_tempDir);
502                         Assert.AreEqual (2, tempFiles.Length, "#C1");
503                         Assert.AreEqual (tempFile, tempFiles[0], "#C2");
504                         Assert.AreEqual (outputAssembly, tempFiles [1], "#C3");
505                 }
506
507                 [Test]
508                 [Category ("NotWorking")] // we cannot rely on vbnc being available
509                 public void CompileFromDom_NotInMemory ()
510                 {
511                         // create a file in temp directory to ensure that compiler is not removing
512                         // too much (temporary) files
513                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
514                         using (FileStream fs = File.Create (tempFile)) {
515                                 fs.Close ();
516                         }
517
518                         // compile and verify result in separate appdomain to avoid file locks
519                         AppDomain testDomain = CreateTestDomain ();
520                         CrossDomainTester compileTester = CreateCrossDomainTester (testDomain);
521
522                         string outputAssembly = null;
523
524                         try {
525                                 outputAssembly = compileTester.CompileAssemblyFromDom (_tempDir);
526                         } finally {
527                                 AppDomain.Unload (testDomain);
528                         }
529
530                         // there should be two files in temp dir: temp file and output assembly
531                         string[] tempFiles = Directory.GetFiles (_tempDir);
532                         Assert.AreEqual (2, tempFiles.Length, "#1");
533                         Assert.IsTrue (File.Exists (outputAssembly), "#2");
534                         Assert.IsTrue (File.Exists (tempFile), "#3");
535                 }
536
537                 [Test]
538                 [Category ("NotWorking")] // we cannot rely on vbnc being available
539                 public void CompileFromDomBatch_NotInMemory ()
540                 {
541                         // create a file in temp directory to ensure that compiler is not removing
542                         // too much (temporary) files
543                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
544                         using (FileStream fs = File.Create (tempFile)) {
545                                 fs.Close ();
546                         }
547
548                         // compile and verify result in separate appdomain to avoid file locks
549                         AppDomain testDomain = CreateTestDomain ();
550                         CrossDomainTester compileTester = CreateCrossDomainTester (testDomain);
551
552                         string outputAssembly = null;
553
554                         try {
555                                 outputAssembly = compileTester.CompileAssemblyFromDomBatch (_tempDir);
556                         } finally {
557                                 AppDomain.Unload (testDomain);
558                         }
559
560                         // there should be two files in temp dir: temp file and output assembly
561                         string[] tempFiles = Directory.GetFiles (_tempDir);
562                         Assert.AreEqual (2, tempFiles.Length, "#1");
563                         Assert.IsTrue (File.Exists (outputAssembly), "#2");
564                         Assert.IsTrue (File.Exists (tempFile), "#3");
565                 }
566
567                 [Test]
568                 [Category ("NotWorking")] // we cannot rely on vbnc being available
569                 public void CompileFromDom_InMemory ()
570                 {
571                         // create a file in temp directory to ensure that compiler is not removing
572                         // too much (temporary) files
573                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
574                         using (FileStream fs = File.Create (tempFile)) {
575                                 fs.Close ();
576                         }
577
578                         CompilerParameters options = new CompilerParameters ();
579                         options.GenerateExecutable = false;
580                         options.GenerateInMemory = true;
581                         options.TempFiles = new TempFileCollection (_tempDir);
582
583                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
584                         CompilerResults results = compiler.CompileAssemblyFromDom (options, new CodeCompileUnit ());
585
586                         // verify compilation was successful
587                         AssertCompileResults (results, true);
588
589                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
590                         Assert.IsNull (results.PathToAssembly, "#2");
591
592                         // verify we don't cleanup files in temp directory too agressively
593                         string[] tempFiles = Directory.GetFiles (_tempDir);
594                         Assert.AreEqual (1, tempFiles.Length, "#3");
595                         Assert.AreEqual (tempFile, tempFiles[0], "#4");
596                 }
597
598                 [Test]
599                 [Category ("NotWorking")] // we cannot rely on vbnc being available
600                 public void CompileFromDomBatch_InMemory ()
601                 {
602                         // create a file in temp directory to ensure that compiler is not removing
603                         // too much (temporary) files
604                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
605                         using (FileStream fs = File.Create (tempFile)) {
606                                 fs.Close ();
607                         }
608
609                         CompilerParameters options = new CompilerParameters ();
610                         options.GenerateExecutable = false;
611                         options.GenerateInMemory = true;
612                         options.TempFiles = new TempFileCollection (_tempDir);
613
614                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
615                         CompilerResults results = compiler.CompileAssemblyFromDomBatch (options,
616                                 new CodeCompileUnit[] { new CodeCompileUnit (), new CodeCompileUnit () });
617
618                         // verify compilation was successful
619                         AssertCompileResults (results, true);
620
621                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
622                         Assert.IsNull (results.PathToAssembly, "#2");
623
624                         // verify we don't cleanup files in temp directory too agressively
625                         string[] tempFiles = Directory.GetFiles (_tempDir);
626                         Assert.AreEqual (1, tempFiles.Length, "#3");
627                         Assert.AreEqual (tempFile, tempFiles[0], "#4");
628                 }
629
630                 //TODO: [Test]
631                 public void CreateParser ()
632                 {
633                         //System.CodeDom.Compiler.ICodeParser CreateParser()
634                 }
635
636                 //TODO: [Test]
637                 public void CreateObjRef ()
638                 {
639                         //System.Runtime.Remoting.ObjRef CreateObjRef(System.Type requestedType)
640                 }
641
642                 bool Windows
643                 {
644                         get {
645                                 return OS == OsType.Windows;
646                         }
647                 }
648
649                 bool Unix
650                 {
651                         get {
652                                 return OS == OsType.Unix;
653                         }
654                 }
655
656                 bool Mac
657                 {
658                         get {
659                                 return OS == OsType.Mac;
660                         }
661                 }
662
663                 private static string CreateTempDirectory ()
664                 {
665                         // create a uniquely named zero-byte file
666                         string tempFile = Path.GetTempFileName ();
667                         // remove the temporary file
668                         File.Delete (tempFile);
669                         // create a directory named after the unique temporary file
670                         Directory.CreateDirectory (tempFile);
671                         // return the path to the temporary directory
672                         return tempFile;
673                 }
674
675                 private static void RemoveDirectory (string path)
676                 {
677                         try {
678                                 if (Directory.Exists (path)) {
679                                         string[] directoryNames = Directory.GetDirectories (path);
680                                         foreach (string directoryName in directoryNames) {
681                                                 RemoveDirectory (directoryName);
682                                         }
683                                         string[] fileNames = Directory.GetFiles (path);
684                                         foreach (string fileName in fileNames) {
685                                                 File.Delete (fileName);
686                                         }
687                                         Directory.Delete (path, true);
688                                 }
689                         } catch (Exception ex) {
690                                 throw new AssertionException ("Unable to cleanup '" + path + "'.", ex);
691                         }
692                 }
693
694                 private static void AssertCompileResults (CompilerResults results, bool allowWarnings)
695                 {
696                         foreach (CompilerError compilerError in results.Errors) {
697                                 if (allowWarnings && compilerError.IsWarning) {
698                                         continue;
699                                 }
700
701                                 throw new Exception (compilerError.ToString ());
702                         }
703                 }
704
705                 private static AppDomain CreateTestDomain ()
706                 {
707                         return AppDomain.CreateDomain ("CompileFromDom", AppDomain.CurrentDomain.Evidence,
708                                 AppDomain.CurrentDomain.SetupInformation);
709                 }
710
711                 private static CrossDomainTester CreateCrossDomainTester (AppDomain domain)
712                 {
713                         Type testerType = typeof (CrossDomainTester);
714
715                         return (CrossDomainTester) domain.CreateInstanceAndUnwrap (
716                                 testerType.Assembly.FullName, testerType.FullName, false,
717                                 BindingFlags.Public | BindingFlags.Instance, null, new object[0],
718                                 CultureInfo.InvariantCulture, new object[0], null);
719                 }
720
721                 // do not use the Assert class as this will introduce failures if the
722                 // nunit.framework assembly is not in the GAC
723                 private class CrossDomainTester : MarshalByRefObject
724                 {
725                         public string CompileAssemblyFromDom (string tempDir)
726                         {
727                                 CompilerParameters options = new CompilerParameters ();
728                                 options.GenerateExecutable = false;
729                                 options.GenerateInMemory = false;
730                                 options.TempFiles = new TempFileCollection (tempDir);
731
732                                 VBCodeProvider codeProvider = new VBCodeProvider ();
733                                 ICodeCompiler compiler = codeProvider.CreateCompiler ();
734                                 CompilerResults results = compiler.CompileAssemblyFromDom (options, new CodeCompileUnit ());
735
736                                 // verify compilation was successful
737                                 AssertCompileResults (results, true);
738
739                                 if (results.CompiledAssembly.Location.Length == 0)
740                                         throw new Exception ("Location should not be empty string");
741                                 if (results.PathToAssembly == null)
742                                         throw new Exception ("PathToAssembly should not be null");
743
744                                 return results.PathToAssembly;
745                         }
746
747                         public string CompileAssemblyFromDomBatch (string tempDir)
748                         {
749                                 CompilerParameters options = new CompilerParameters ();
750                                 options.GenerateExecutable = false;
751                                 options.GenerateInMemory = false;
752                                 options.TempFiles = new TempFileCollection (tempDir);
753
754                                 VBCodeProvider codeProvider = new VBCodeProvider ();
755                                 ICodeCompiler compiler = codeProvider.CreateCompiler ();
756                                 CompilerResults results = compiler.CompileAssemblyFromDomBatch (options, new CodeCompileUnit[] { new CodeCompileUnit (), new CodeCompileUnit () });
757
758                                 // verify compilation was successful
759                                 AssertCompileResults (results, true);
760
761                                 if (results.CompiledAssembly.Location.Length == 0)
762                                         throw new Exception ("Location should not be empty string");
763                                 if (results.PathToAssembly == null)
764                                         throw new Exception ("PathToAssembly should not be null");
765
766                                 return results.PathToAssembly;
767                         }
768                 }
769         }
770 }