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