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