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