Changed link from GUID to URL
[mono.git] / mcs / class / System / Test / Microsoft.CSharp / CSharpCodeProviderTest.cs
1 //
2 // Microsoft.CSharp.CSharpCodeProviderTest.cs
3 //
4 // Author:
5 // Gert Driesen (drieseng@users.sourceforge.net)
6 //
7 // (C) 2005 Novell
8 //
9
10 using System;
11 using System.CodeDom;
12 using System.CodeDom.Compiler;
13 using System.Collections.Specialized;
14 using System.Globalization;
15 using System.IO;
16 using System.Reflection;
17 using Microsoft.CSharp;
18 using NUnit.Framework;
19
20 namespace MonoTests.Microsoft.CSharp
21 {
22         [TestFixture]
23         public class CSharpCodeProviderTest
24         {
25                 private string _tempDir;
26                 private CodeDomProvider _codeProvider;
27
28                 private static readonly string _sourceLibrary1 = "public class Test1 {}";
29                 private static readonly string _sourceLibrary2 = "public class Test2 {}";
30                 private static readonly string _sourceExecutable = "public class Program { static void Main () { } }";
31
32                 [SetUp]
33                 public void SetUp ()
34                 {
35                         _codeProvider = new CSharpCodeProvider ();
36                         _tempDir = CreateTempDirectory ();
37                 }
38
39                 [TearDown]
40                 public void TearDown ()
41                 {
42                         RemoveDirectory (_tempDir);
43                 }
44
45                 [Test]
46                 public void FileExtension ()
47                 {
48                         Assert.AreEqual ("cs", _codeProvider.FileExtension);
49                 }
50
51                 [Test]
52                 public void LanguageOptionsTest ()
53                 {
54                         Assert.AreEqual (LanguageOptions.None, _codeProvider.LanguageOptions);
55                 }
56
57                 [Test]
58                 public void GeneratorSupports ()
59                 {
60                         ICodeGenerator codeGenerator = _codeProvider.CreateGenerator ();
61                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareEnums), "#1");
62                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ArraysOfArrays), "#2");
63                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.AssemblyAttributes), "#3");
64                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ChainedConstructorArguments), "#4");
65                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ComplexExpressions), "#5");
66                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareDelegates), "#6");
67                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareEnums), "#7");
68                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareEvents), "#8");
69                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareInterfaces), "#9");
70                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareValueTypes), "#10");
71                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.EntryPointMethod), "#11");
72                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.GotoStatements), "#12");
73                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.MultidimensionalArrays), "#13");
74                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.MultipleInterfaceMembers), "#14");
75                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.NestedTypes), "#15");
76                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ParameterAttributes), "#16");
77                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.PublicStaticMembers), "#17");
78                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ReferenceParameters), "#18");
79                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.ReturnTypeAttributes), "#19");
80                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.StaticConstructors), "#20");
81                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.TryCatchStatements), "#21");
82                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.Win32Resources), "#22");
83                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.DeclareIndexerProperties), "#23");
84                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.GenericTypeDeclaration), "#24");
85                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.GenericTypeReference), "#25");
86                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.PartialTypes), "#26");
87                         Assert.IsTrue (codeGenerator.Supports (GeneratorSupport.Resources), "#27");
88                 }
89
90                 [Test]
91                 public void CompileFromFile_InMemory ()
92                 {
93                         // create source file
94                         string sourceFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
95                         using (FileStream f = new FileStream (sourceFile, FileMode.Create)) {
96                                 using (StreamWriter s = new StreamWriter (f)) {
97                                         s.Write (_sourceLibrary1);
98                                         s.Close ();
99                                 }
100                                 f.Close ();
101                         }
102
103                         CompilerParameters options = new CompilerParameters ();
104                         options.GenerateExecutable = false;
105                         options.GenerateInMemory = true;
106                         options.TempFiles = new TempFileCollection (_tempDir);
107                         options.EmbeddedResources.Add (sourceFile);
108
109                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
110                         CompilerResults results = compiler.CompileAssemblyFromFile (options,
111                                 sourceFile);
112
113                         // verify compilation was successful
114                         AssertCompileResults (results, true);
115
116                         Assembly compiledAssembly = results.CompiledAssembly;
117
118                         Assert.IsNotNull (compiledAssembly, "#1");
119                         Assert.AreEqual (string.Empty, compiledAssembly.Location, "#2");
120                         Assert.IsNull (results.PathToAssembly, "#3");
121                         Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#4");
122                         
123                         // verify we don't cleanup files in temp directory too agressively
124                         string[] tempFiles = Directory.GetFiles (_tempDir);
125                         Assert.AreEqual (1, tempFiles.Length, "#5");
126                         Assert.AreEqual (sourceFile, tempFiles[0], "#6");
127                         
128                         string[] resources = compiledAssembly.GetManifestResourceNames();
129                         Assert.IsNotNull (resources, "#7");
130                         Assert.AreEqual (1, resources.Length, "#8");
131                         Assert.AreEqual ("file.cs", resources[0], "#9");
132                         Assert.IsNull (compiledAssembly.GetFile ("file.cs"), "#10");
133                         Assert.IsNotNull (compiledAssembly.GetManifestResourceStream  ("file.cs"), "#11");
134                         ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file.cs");
135                         Assert.IsNotNull (info, "#12");
136                         Assert.IsNull (info.FileName, "#13");
137                         Assert.IsNull (info.ReferencedAssembly, "#14");
138                         Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#15");
139                 }
140
141                 [Test]
142                 public void CompileFromFileBatch_Executable_InMemory ()
143                 {
144                         // create source file
145                         string sourceFile1 = Path.Combine (_tempDir, "file1." + _codeProvider.FileExtension);
146                         using (FileStream f = new FileStream (sourceFile1, FileMode.Create)) {
147                                 using (StreamWriter s = new StreamWriter (f)) {
148                                         s.Write (_sourceLibrary1);
149                                         s.Close ();
150                                 }
151                                 f.Close ();
152                         }
153
154                         string sourceFile2 = Path.Combine (_tempDir, "file2." + _codeProvider.FileExtension);
155                         using (FileStream f = new FileStream (sourceFile2, FileMode.Create)) {
156                                 using (StreamWriter s = new StreamWriter (f)) {
157                                         s.Write (_sourceExecutable);
158                                         s.Close ();
159                                 }
160                                 f.Close ();
161                         }
162
163                         CompilerParameters options = new CompilerParameters ();
164                         options.GenerateExecutable = true;
165                         options.GenerateInMemory = true;
166                         options.OutputAssembly = string.Empty;
167                         options.TempFiles = new TempFileCollection (_tempDir);
168                         options.EmbeddedResources.Add (sourceFile1);
169                         options.LinkedResources.Add (sourceFile2);
170
171                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
172                         CompilerResults results = compiler.CompileAssemblyFromFileBatch (options,
173                                 new string [] { sourceFile1, sourceFile2 });
174
175                         // verify compilation was successful
176                         AssertCompileResults (results, true);
177
178                         Assembly compiledAssembly = results.CompiledAssembly;
179
180                         Assert.IsNotNull (compiledAssembly, "#A1");
181                         Assert.AreEqual (string.Empty, compiledAssembly.Location, "#A2");
182                         Assert.IsNull (results.PathToAssembly, "#A3");
183                         Assert.IsNotNull (options.OutputAssembly, "#A4");
184                         Assert.AreEqual (".exe", Path.GetExtension (options.OutputAssembly), "#A5");
185                         Assert.AreEqual (_tempDir, Path.GetDirectoryName (options.OutputAssembly), "#A6");
186                         Assert.IsFalse (File.Exists (options.OutputAssembly), "#A7");
187
188                         Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#B1");
189                         Assert.IsNotNull (compiledAssembly.GetType ("Program"), "#B2");
190
191                         // verify we don't cleanup files in temp directory too agressively
192                         string [] tempFiles = Directory.GetFiles (_tempDir);
193                         Assert.AreEqual (2, tempFiles.Length, "#C1");
194                         Assert.IsTrue (File.Exists (sourceFile1), "#C2");
195                         Assert.IsTrue (File.Exists (sourceFile2), "#C3");
196
197                         string[] resources = compiledAssembly.GetManifestResourceNames();
198                         Assert.IsNotNull (resources, "#D1");
199                         Assert.AreEqual (2, resources.Length, "#D2");
200
201                         Assert.IsTrue (resources[0] == "file1.cs" || resources [0] == "file2.cs", "#E1");
202                         Assert.IsNull (compiledAssembly.GetFile ("file1.cs"), "#E2");
203                         Assert.IsNotNull (compiledAssembly.GetManifestResourceStream  ("file1.cs"), "#E3");
204                         ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file1.cs");
205                         Assert.IsNotNull (info, "#E4");
206                         Assert.IsNull (info.FileName, "#E5");
207                         Assert.IsNull (info.ReferencedAssembly, "#E6");
208                         Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#E7");
209
210                         Assert.IsTrue (resources[1] == "file1.cs" || resources [1] == "file2.cs", "#F1");
211                         try {
212                                 compiledAssembly.GetFile ("file2.cs");
213                                 Assert.Fail ("#F2");
214                         } catch (FileNotFoundException) {
215                         }
216                         try {
217                                 compiledAssembly.GetManifestResourceStream  ("file2.cs");
218                                 Assert.Fail ("#F3");
219                         } catch (FileNotFoundException) {
220                         }
221                         info = compiledAssembly.GetManifestResourceInfo ("file2.cs");
222                         Assert.IsNotNull (info, "#F4");
223                         Assert.IsNotNull (info.FileName, "#F5");
224                         Assert.AreEqual ("file2.cs", info.FileName, "#F6");
225                         Assert.IsNull (info.ReferencedAssembly, "#F7");
226                         Assert.AreEqual ((ResourceLocation) 0, info.ResourceLocation, "#F8");
227                 }
228
229                 [Test]
230                 public void CompileFromFileBatch_Library_InMemory ()
231                 {
232                         // create source file
233                         string sourceFile1 = Path.Combine (_tempDir, "file1." + _codeProvider.FileExtension);
234                         using (FileStream f = new FileStream (sourceFile1, FileMode.Create)) {
235                                 using (StreamWriter s = new StreamWriter (f)) {
236                                         s.Write (_sourceLibrary1);
237                                         s.Close ();
238                                 }
239                                 f.Close ();
240                         }
241
242                         string sourceFile2 = Path.Combine (_tempDir, "file2." + _codeProvider.FileExtension);
243                         using (FileStream f = new FileStream (sourceFile2, FileMode.Create)) {
244                                 using (StreamWriter s = new StreamWriter (f)) {
245                                         s.Write (_sourceLibrary2);
246                                         s.Close ();
247                                 }
248                                 f.Close ();
249                         }
250
251                         CompilerParameters options = new CompilerParameters ();
252                         options.GenerateExecutable = false;
253                         options.GenerateInMemory = true;
254                         options.TempFiles = new TempFileCollection (_tempDir);
255                         options.EmbeddedResources.Add (sourceFile1);
256                         options.LinkedResources.Add (sourceFile2);
257
258                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
259                         CompilerResults results = compiler.CompileAssemblyFromFileBatch (options,
260                                 new string [] { sourceFile1, sourceFile2 });
261
262                         // verify compilation was successful
263                         AssertCompileResults (results, true);
264
265                         Assembly compiledAssembly = results.CompiledAssembly;
266
267                         Assert.IsNotNull (compiledAssembly, "#A1");
268                         Assert.AreEqual (string.Empty, compiledAssembly.Location, "#A2");
269                         Assert.IsNull (results.PathToAssembly, "#A3");
270                         Assert.IsNotNull (options.OutputAssembly, "#A4");
271                         Assert.AreEqual (".dll", Path.GetExtension (options.OutputAssembly), "#A5");
272                         Assert.AreEqual (_tempDir, Path.GetDirectoryName (options.OutputAssembly), "#A6");
273                         Assert.IsFalse (File.Exists (options.OutputAssembly), "#A7");
274
275                         Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#B1");
276                         Assert.IsNotNull (compiledAssembly.GetType ("Test2"), "#B2");
277
278                         // verify we don't cleanup files in temp directory too agressively
279                         string [] tempFiles = Directory.GetFiles (_tempDir);
280                         Assert.AreEqual (2, tempFiles.Length, "#C1");
281                         Assert.IsTrue (File.Exists (sourceFile1), "#C2");
282                         Assert.IsTrue (File.Exists (sourceFile2), "#C3");
283
284                         string[] resources = compiledAssembly.GetManifestResourceNames();
285                         Assert.IsNotNull (resources, "#D1");
286                         Assert.AreEqual (2, resources.Length, "#D2");
287
288                         Assert.IsTrue (resources[0] == "file1.cs" || resources [0] == "file2.cs", "#E1");
289                         Assert.IsNull (compiledAssembly.GetFile ("file1.cs"), "#E2");
290                         Assert.IsNotNull (compiledAssembly.GetManifestResourceStream  ("file1.cs"), "#E3");
291                         ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file1.cs");
292                         Assert.IsNotNull (info, "#E4");
293                         Assert.IsNull (info.FileName, "#E5");
294                         Assert.IsNull (info.ReferencedAssembly, "#E6");
295                         Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#E7");
296
297                         Assert.IsTrue (resources[1] == "file1.cs" || resources [1] == "file2.cs", "#F1");
298                         try {
299                                 compiledAssembly.GetFile ("file2.cs");
300                                 Assert.Fail ("#F2");
301                         } catch (FileNotFoundException) {
302                         }
303                         try {
304                                 compiledAssembly.GetManifestResourceStream  ("file2.cs");
305                                 Assert.Fail ("#F3");
306                         } catch (FileNotFoundException) {
307                         }
308                         info = compiledAssembly.GetManifestResourceInfo ("file2.cs");
309                         Assert.IsNotNull (info, "#F4");
310                         Assert.IsNotNull (info.FileName, "#F5");
311                         Assert.AreEqual ("file2.cs", info.FileName, "#F6");
312                         Assert.IsNull (info.ReferencedAssembly, "#F7");
313                         Assert.AreEqual ((ResourceLocation) 0, info.ResourceLocation, "#F8");
314                 }
315
316                 [Test]
317                 public void CompileFromSource_InMemory ()
318                 {
319                         // create a file in temp directory to ensure that compiler is not removing
320                         // too much (temporary) files
321                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
322                         using (FileStream fs = File.Create (tempFile)) {
323                                 fs.Close ();
324                         }
325
326                         CompilerParameters options = new CompilerParameters ();
327                         options.GenerateExecutable = false;
328                         options.GenerateInMemory = true;
329                         options.TempFiles = new TempFileCollection (_tempDir);
330
331                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
332                         CompilerResults results = compiler.CompileAssemblyFromSource (options,
333                                 _sourceLibrary1);
334
335                         // verify compilation was successful
336                         AssertCompileResults (results, true);
337
338                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
339                         Assert.IsNull (results.PathToAssembly, "#2");
340                         Assert.IsNotNull (results.CompiledAssembly.GetType ("Test1"), "#3");
341
342                         // verify we don't cleanup files in temp directory too agressively
343                         string[] tempFiles = Directory.GetFiles (_tempDir);
344                         Assert.AreEqual (1, tempFiles.Length, "#4");
345                         Assert.AreEqual (tempFile, tempFiles[0], "#5");
346                 }
347
348                 [Test]
349                 public void CompileFromSource_InMemory_Twice ()
350                 {
351                         CompilerParameters options = new CompilerParameters ();
352                         options.GenerateExecutable = false;
353                         options.GenerateInMemory = true;
354
355                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
356
357                         var src_1 = "class X { ";
358
359                         CompilerResults results_1 = compiler.CompileAssemblyFromSource (options, src_1);
360                         var output_1 = options.OutputAssembly;
361
362                         var src_2 = "class X { }";
363
364                         CompilerResults results_2 = compiler.CompileAssemblyFromSource (options, src_2);
365                         var output_2 = options.OutputAssembly;
366
367                         // verify compilation was successful
368                         AssertCompileResults (results_2, true);
369
370                         Assert.AreEqual (output_1, output_2, "#1");
371                 }
372
373
374                 [Test]
375                 public void CompileFromSource_InMemory_With_Extra_Delete ()
376                 {
377                         CompilerParameters options = new CompilerParameters ();
378                         options.GenerateExecutable = false;
379                         options.GenerateInMemory = true;
380
381                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
382
383                         var src_1 = "class X { ";
384
385                         compiler.CompileAssemblyFromSource (options, src_1);
386
387                         options.TempFiles.Delete ();
388                         options.TempFiles.Delete ();
389                 }
390
391                 [Test]
392                 public void CompileFromSourceBatch_InMemory ()
393                 {
394                         // create a file in temp directory to ensure that compiler is not removing
395                         // too much (temporary) files
396                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
397                         using (FileStream fs = File.Create (tempFile)) {
398                                 fs.Close ();
399                         }
400
401                         string outputAssembly = Path.Combine (_tempDir, "sourcebatch.dll");
402
403                         CompilerParameters options = new CompilerParameters ();
404                         options.GenerateExecutable = false;
405                         options.GenerateInMemory = true;
406                         options.OutputAssembly = outputAssembly;
407                         options.TempFiles = new TempFileCollection (_tempDir);
408
409                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
410                         CompilerResults results = compiler.CompileAssemblyFromSourceBatch (options,
411                                 new string [] { _sourceLibrary1, _sourceLibrary2 });
412
413                         // verify compilation was successful
414                         AssertCompileResults (results, true);
415
416                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#A1");
417                         Assert.IsNull (results.PathToAssembly, "#A2");
418                         Assert.IsNotNull (options.OutputAssembly, "#A3");
419                         Assert.AreEqual (outputAssembly, options.OutputAssembly, "#A4");
420                         Assert.IsTrue (File.Exists (outputAssembly), "#A5");
421
422                         Assert.IsNotNull (results.CompiledAssembly.GetType ("Test1"), "#B1");
423                         Assert.IsNotNull (results.CompiledAssembly.GetType ("Test2"), "#B2");
424
425                         // verify we don't cleanup files in temp directory too agressively
426                         string[] tempFiles = Directory.GetFiles (_tempDir);
427                         Assert.AreEqual (2, tempFiles.Length, "#C1");
428                         Assert.AreEqual (tempFile, tempFiles[0], "#C2");
429                         Assert.AreEqual (outputAssembly, tempFiles [1], "#C3");
430                 }
431
432                 [Test]
433                 public void CompileFromDom_NotInMemory ()
434                 {
435                         // create a file in temp directory to ensure that compiler is not removing
436                         // too much (temporary) files
437                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
438                         using (FileStream fs = File.Create (tempFile)) {
439                                 fs.Close ();
440                         }
441
442                         // compile and verify result in separate appdomain to avoid file locks
443                         AppDomain testDomain = CreateTestDomain ();
444                         CrossDomainTester compileTester = CreateCrossDomainTester (testDomain);
445
446                         string outputAssembly = null;
447
448                         try {
449                                 outputAssembly = compileTester.CompileAssemblyFromDom (_tempDir);
450                         } finally {
451                                 AppDomain.Unload (testDomain);
452                         }
453
454                         // there should be two files in temp dir: temp file and output assembly
455                         string[] tempFiles = Directory.GetFiles (_tempDir);
456                         Assert.AreEqual (2, tempFiles.Length, "#1");
457                         Assert.IsTrue (File.Exists (outputAssembly), "#2");
458                         Assert.IsTrue (File.Exists (tempFile), "#3");
459                 }
460
461                 [Test]
462                 public void CompileFromDomBatch_NotInMemory ()
463                 {
464                         // create a file in temp directory to ensure that compiler is not removing
465                         // too much (temporary) files
466                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
467                         using (FileStream fs = File.Create (tempFile)) {
468                                 fs.Close ();
469                         }
470
471                         // compile and verify result in separate appdomain to avoid file locks
472                         AppDomain testDomain = CreateTestDomain ();
473                         CrossDomainTester compileTester = CreateCrossDomainTester (testDomain);
474
475                         string outputAssembly = null;
476                         try {
477                                 outputAssembly = compileTester.CompileAssemblyFromDomBatch (_tempDir);
478                         } finally {
479                                 AppDomain.Unload (testDomain);
480                         }
481
482                         // there should be two files in temp dir: temp file and output assembly
483                         string[] tempFiles = Directory.GetFiles (_tempDir);
484                         Assert.AreEqual (2, tempFiles.Length, "#1");
485                         Assert.IsTrue (File.Exists (outputAssembly), "#2");
486                         Assert.IsTrue (File.Exists (tempFile), "#3");
487                 }
488
489                 [Test]
490                 public void CompileFromDom_InMemory ()
491                 {
492                         // create a file in temp directory to ensure that compiler is not removing
493                         // too much (temporary) files
494                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
495                         using (FileStream fs = File.Create (tempFile)) {
496                                 fs.Close ();
497                         }
498
499                         CompilerParameters options = new CompilerParameters ();
500                         options.GenerateExecutable = false;
501                         options.GenerateInMemory = true;
502                         options.TempFiles = new TempFileCollection (_tempDir);
503
504                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
505                         CompilerResults results = compiler.CompileAssemblyFromDom (options, new CodeCompileUnit ());
506
507                         // verify compilation was successful
508                         AssertCompileResults (results, true);
509
510                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
511                         Assert.IsNull (results.PathToAssembly, "#2");
512
513                         // verify we don't cleanup files in temp directory too agressively
514                         string[] tempFiles = Directory.GetFiles (_tempDir);
515                         Assert.AreEqual (1, tempFiles.Length, "#3");
516                         Assert.AreEqual (tempFile, tempFiles[0], "#4");
517                 }
518
519                 [Test]
520                 public void CompileFromDomBatch_InMemory ()
521                 {
522                         // create a file in temp directory to ensure that compiler is not removing
523                         // too much (temporary) files
524                         string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
525                         using (FileStream fs = File.Create (tempFile)) {
526                                 fs.Close ();
527                         }
528
529                         CompilerParameters options = new CompilerParameters ();
530                         options.GenerateExecutable = false;
531                         options.GenerateInMemory = true;
532                         options.TempFiles = new TempFileCollection (_tempDir);
533
534                         ICodeCompiler compiler = _codeProvider.CreateCompiler ();
535                         CompilerResults results = compiler.CompileAssemblyFromDomBatch (options,
536                                 new CodeCompileUnit[] { new CodeCompileUnit (), new CodeCompileUnit () });
537
538                         // verify compilation was successful
539                         AssertCompileResults (results, true);
540
541                         Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
542                         Assert.IsNull (results.PathToAssembly, "#2");
543
544                         // verify we don't cleanup files in temp directory too agressively
545                         string[] tempFiles = Directory.GetFiles (_tempDir);
546                         Assert.AreEqual (1, tempFiles.Length, "#3");
547                         Assert.AreEqual (tempFile, tempFiles[0], "#4");
548                 }
549
550                 private static string CreateTempDirectory ()
551                 {
552                         // create a uniquely named zero-byte file
553                         string tempFile = Path.GetTempFileName ();
554                         // remove the temporary file
555                         File.Delete (tempFile);
556                         // create a directory named after the unique temporary file
557                         Directory.CreateDirectory (tempFile);
558                         // return the path to the temporary directory
559                         return tempFile;
560                 }
561
562                 private static void RemoveDirectory (string path)
563                 {
564                         try {
565                                 if (Directory.Exists (path)) {
566                                         string[] directoryNames = Directory.GetDirectories (path);
567                                         foreach (string directoryName in directoryNames) {
568                                                 RemoveDirectory (directoryName);
569                                         }
570                                         string[] fileNames = Directory.GetFiles (path);
571                                         foreach (string fileName in fileNames) {
572                                                 File.Delete (fileName);
573                                         }
574                                         Directory.Delete (path, true);
575                                 }
576                         } catch (Exception ex) {
577                                 throw new AssertionException ("Unable to cleanup '" + path + "'.", ex);
578                         }
579                 }
580
581                 private static void AssertCompileResults (CompilerResults results, bool allowWarnings)
582                 {
583                         foreach (CompilerError compilerError in results.Errors) {
584                                 if (allowWarnings && compilerError.IsWarning) {
585                                         continue;
586                                 }
587
588                                 throw new Exception (compilerError.ToString ());
589                         }
590                 }
591
592                 private static AppDomain CreateTestDomain ()
593                 {
594                         return AppDomain.CreateDomain ("CompileFromDom", AppDomain.CurrentDomain.Evidence,
595                                 AppDomain.CurrentDomain.SetupInformation);
596                 }
597
598                 private static CrossDomainTester CreateCrossDomainTester (AppDomain domain)
599                 {
600                         Type testerType = typeof (CrossDomainTester);
601
602                         return (CrossDomainTester) domain.CreateInstanceAndUnwrap (
603                                 testerType.Assembly.FullName, testerType.FullName, false,
604                                 BindingFlags.Public | BindingFlags.Instance, null, new object[0],
605                                 CultureInfo.InvariantCulture, new object[0], domain.Evidence);
606                 }
607
608                 // do not use the Assert class as this will introduce failures if the
609                 // nunit.framework assembly is not in the GAC
610                 private class CrossDomainTester : MarshalByRefObject
611                 {
612                         public string CompileAssemblyFromDom (string tempDir)
613                         {
614                                 CompilerParameters options = new CompilerParameters ();
615                                 options.GenerateExecutable = false;
616                                 options.GenerateInMemory = false;
617                                 options.TempFiles = new TempFileCollection (tempDir);
618
619                                 CSharpCodeProvider codeProvider = new CSharpCodeProvider ();
620                                 ICodeCompiler compiler = codeProvider.CreateCompiler ();
621                                 CompilerResults results = compiler.CompileAssemblyFromDom (options, new CodeCompileUnit ());
622
623                                 // verify compilation was successful
624                                 AssertCompileResults (results, true);
625
626                                 if (results.CompiledAssembly.Location.Length == 0)
627                                         throw new Exception ("Location should not be empty string");
628                                 if (results.PathToAssembly == null)
629                                         throw new Exception ("PathToAssembly should not be null");
630
631                                 return results.PathToAssembly;
632                         }
633
634                         public string CompileAssemblyFromDomBatch (string tempDir)
635                         {
636                                 CompilerParameters options = new CompilerParameters ();
637                                 options.GenerateExecutable = false;
638                                 options.GenerateInMemory = false;
639                                 options.TempFiles = new TempFileCollection (tempDir);
640
641                                 CSharpCodeProvider codeProvider = new CSharpCodeProvider ();
642                                 ICodeCompiler compiler = codeProvider.CreateCompiler ();
643                                 CompilerResults results = compiler.CompileAssemblyFromDomBatch (options, new CodeCompileUnit[] { new CodeCompileUnit (), new CodeCompileUnit () });
644
645                                 // verify compilation was successful
646                                 AssertCompileResults (results, true);
647
648                                 if (results.CompiledAssembly.Location.Length == 0)
649                                         throw new Exception ("Location should not be empty string");
650                                 if (results.PathToAssembly == null)
651                                         throw new Exception ("PathToAssembly should not be null");
652
653                                 return results.PathToAssembly;
654                         }
655                 }
656         }
657 }