CSharpCodeProviderTest.cs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. //
  2. // Microsoft.CSharp.CSharpCodeProviderTest.cs
  3. //
  4. // Author:
  5. // Gert Driesen ([email protected])
  6. //
  7. // (C) 2005 Novell
  8. //
  9. using System;
  10. using System.CodeDom;
  11. using System.CodeDom.Compiler;
  12. using System.Collections.Specialized;
  13. using System.Globalization;
  14. using System.IO;
  15. using System.Reflection;
  16. using Microsoft.CSharp;
  17. using NUnit.Framework;
  18. using System.Text;
  19. using System.Linq;
  20. using MonoTests.Helpers;
  21. namespace MonoTests.Microsoft.CSharp
  22. {
  23. [TestFixture]
  24. public class CSharpCodeProviderTest
  25. {
  26. private TempDirectory _tempDirectory;
  27. private string _tempDir;
  28. private CodeDomProvider _codeProvider;
  29. private static readonly string _sourceLibrary1 = "public class Test1 {}";
  30. private static readonly string _sourceLibrary2 = "public class Test2 {}";
  31. private static readonly string _sourceLibrary3 =
  32. @"public class Test3 { public void F() { } }
  33. public class Test4 : Test3 { public void F() { } }";
  34. private static readonly string _sourceExecutable = "public class Program { static void Main () { } }";
  35. [SetUp]
  36. public void SetUp ()
  37. {
  38. _codeProvider = new CSharpCodeProvider ();
  39. _tempDirectory = new TempDirectory ();
  40. _tempDir = _tempDirectory.Path;
  41. }
  42. [TearDown]
  43. public void TearDown ()
  44. {
  45. _tempDirectory.Dispose ();
  46. }
  47. [Test]
  48. public void FileExtension ()
  49. {
  50. Assert.AreEqual ("cs", _codeProvider.FileExtension);
  51. }
  52. [Test]
  53. public void LanguageOptionsTest ()
  54. {
  55. Assert.AreEqual (LanguageOptions.None, _codeProvider.LanguageOptions);
  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. [Test]
  90. public void CompileFromFile_InMemory ()
  91. {
  92. // create source file
  93. string sourceFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
  94. using (FileStream f = new FileStream (sourceFile, FileMode.Create)) {
  95. using (StreamWriter s = new StreamWriter (f)) {
  96. s.Write (_sourceLibrary1);
  97. s.Close ();
  98. }
  99. f.Close ();
  100. }
  101. CompilerParameters options = new CompilerParameters ();
  102. options.GenerateExecutable = false;
  103. options.GenerateInMemory = true;
  104. options.TempFiles = new TempFileCollection (_tempDir);
  105. options.EmbeddedResources.Add (sourceFile);
  106. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  107. CompilerResults results = compiler.CompileAssemblyFromFile (options,
  108. sourceFile);
  109. // verify compilation was successful
  110. AssertCompileResults (results, true);
  111. Assembly compiledAssembly = results.CompiledAssembly;
  112. Assert.IsNotNull (compiledAssembly, "#1");
  113. Assert.AreEqual (string.Empty, compiledAssembly.Location, "#2");
  114. Assert.IsNull (results.PathToAssembly, "#3");
  115. Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#4");
  116. // verify we don't cleanup files in temp directory too agressively
  117. string[] tempFiles = Directory.GetFiles (_tempDir);
  118. Assert.AreEqual (1, tempFiles.Length, "#5");
  119. Assert.AreEqual (sourceFile, tempFiles[0], "#6");
  120. string[] resources = compiledAssembly.GetManifestResourceNames();
  121. Assert.IsNotNull (resources, "#7");
  122. Assert.AreEqual (1, resources.Length, "#8");
  123. Assert.AreEqual ("file.cs", resources[0], "#9");
  124. Assert.IsNull (compiledAssembly.GetFile ("file.cs"), "#10");
  125. Assert.IsNotNull (compiledAssembly.GetManifestResourceStream ("file.cs"), "#11");
  126. ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file.cs");
  127. Assert.IsNotNull (info, "#12");
  128. Assert.IsNull (info.FileName, "#13");
  129. Assert.IsNull (info.ReferencedAssembly, "#14");
  130. Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#15");
  131. }
  132. [Test]
  133. public void CompileFromFileBatch_Executable_InMemory ()
  134. {
  135. // create source file
  136. string sourceFile1 = Path.Combine (_tempDir, "file1." + _codeProvider.FileExtension);
  137. using (FileStream f = new FileStream (sourceFile1, FileMode.Create)) {
  138. using (StreamWriter s = new StreamWriter (f)) {
  139. s.Write (_sourceLibrary1);
  140. s.Close ();
  141. }
  142. f.Close ();
  143. }
  144. string sourceFile2 = Path.Combine (_tempDir, "file2." + _codeProvider.FileExtension);
  145. using (FileStream f = new FileStream (sourceFile2, FileMode.Create)) {
  146. using (StreamWriter s = new StreamWriter (f)) {
  147. s.Write (_sourceExecutable);
  148. s.Close ();
  149. }
  150. f.Close ();
  151. }
  152. CompilerParameters options = new CompilerParameters ();
  153. options.GenerateExecutable = true;
  154. options.GenerateInMemory = true;
  155. options.OutputAssembly = string.Empty;
  156. options.TempFiles = new TempFileCollection (_tempDir);
  157. options.EmbeddedResources.Add (sourceFile1);
  158. options.LinkedResources.Add (sourceFile2);
  159. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  160. CompilerResults results = compiler.CompileAssemblyFromFileBatch (options,
  161. new string [] { sourceFile1, sourceFile2 });
  162. // verify compilation was successful
  163. AssertCompileResults (results, true);
  164. Assembly compiledAssembly = results.CompiledAssembly;
  165. Assert.IsNotNull (compiledAssembly, "#A1");
  166. Assert.AreEqual (string.Empty, compiledAssembly.Location, "#A2");
  167. Assert.IsNull (results.PathToAssembly, "#A3");
  168. Assert.IsNotNull (options.OutputAssembly, "#A4");
  169. Assert.AreEqual (".exe", Path.GetExtension (options.OutputAssembly), "#A5");
  170. Assert.AreEqual (_tempDir, Path.GetDirectoryName (options.OutputAssembly), "#A6");
  171. Assert.IsFalse (File.Exists (options.OutputAssembly), "#A7");
  172. Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#B1");
  173. Assert.IsNotNull (compiledAssembly.GetType ("Program"), "#B2");
  174. // verify we don't cleanup files in temp directory too agressively
  175. string [] tempFiles = Directory.GetFiles (_tempDir);
  176. Assert.AreEqual (2, tempFiles.Length, "#C1");
  177. Assert.IsTrue (File.Exists (sourceFile1), "#C2");
  178. Assert.IsTrue (File.Exists (sourceFile2), "#C3");
  179. string[] resources = compiledAssembly.GetManifestResourceNames();
  180. Assert.IsNotNull (resources, "#D1");
  181. Assert.AreEqual (2, resources.Length, "#D2");
  182. Assert.IsTrue (resources[0] == "file1.cs" || resources [0] == "file2.cs", "#E1");
  183. Assert.IsNull (compiledAssembly.GetFile ("file1.cs"), "#E2");
  184. Assert.IsNotNull (compiledAssembly.GetManifestResourceStream ("file1.cs"), "#E3");
  185. ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file1.cs");
  186. Assert.IsNotNull (info, "#E4");
  187. Assert.IsNull (info.FileName, "#E5");
  188. Assert.IsNull (info.ReferencedAssembly, "#E6");
  189. Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#E7");
  190. Assert.IsTrue (resources[1] == "file1.cs" || resources [1] == "file2.cs", "#F1");
  191. try {
  192. compiledAssembly.GetFile ("file2.cs");
  193. Assert.Fail ("#F2");
  194. } catch (FileNotFoundException) {
  195. }
  196. try {
  197. compiledAssembly.GetManifestResourceStream ("file2.cs");
  198. Assert.Fail ("#F3");
  199. } catch (FileNotFoundException) {
  200. }
  201. info = compiledAssembly.GetManifestResourceInfo ("file2.cs");
  202. Assert.IsNotNull (info, "#F4");
  203. Assert.IsNotNull (info.FileName, "#F5");
  204. Assert.AreEqual ("file2.cs", info.FileName, "#F6");
  205. Assert.IsNull (info.ReferencedAssembly, "#F7");
  206. Assert.AreEqual ((ResourceLocation) 0, info.ResourceLocation, "#F8");
  207. }
  208. [Test]
  209. public void CompileFromFileBatch_Library_InMemory ()
  210. {
  211. // create source file
  212. string sourceFile1 = Path.Combine (_tempDir, "file1." + _codeProvider.FileExtension);
  213. using (FileStream f = new FileStream (sourceFile1, FileMode.Create)) {
  214. using (StreamWriter s = new StreamWriter (f)) {
  215. s.Write (_sourceLibrary1);
  216. s.Close ();
  217. }
  218. f.Close ();
  219. }
  220. string sourceFile2 = Path.Combine (_tempDir, "file2." + _codeProvider.FileExtension);
  221. using (FileStream f = new FileStream (sourceFile2, FileMode.Create)) {
  222. using (StreamWriter s = new StreamWriter (f)) {
  223. s.Write (_sourceLibrary2);
  224. s.Close ();
  225. }
  226. f.Close ();
  227. }
  228. CompilerParameters options = new CompilerParameters ();
  229. options.GenerateExecutable = false;
  230. options.GenerateInMemory = true;
  231. options.TempFiles = new TempFileCollection (_tempDir);
  232. options.EmbeddedResources.Add (sourceFile1);
  233. options.LinkedResources.Add (sourceFile2);
  234. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  235. CompilerResults results = compiler.CompileAssemblyFromFileBatch (options,
  236. new string [] { sourceFile1, sourceFile2 });
  237. // verify compilation was successful
  238. AssertCompileResults (results, true);
  239. Assembly compiledAssembly = results.CompiledAssembly;
  240. Assert.IsNotNull (compiledAssembly, "#A1");
  241. Assert.AreEqual (string.Empty, compiledAssembly.Location, "#A2");
  242. Assert.IsNull (results.PathToAssembly, "#A3");
  243. Assert.IsNotNull (options.OutputAssembly, "#A4");
  244. Assert.AreEqual (".dll", Path.GetExtension (options.OutputAssembly), "#A5");
  245. Assert.AreEqual (_tempDir, Path.GetDirectoryName (options.OutputAssembly), "#A6");
  246. Assert.IsFalse (File.Exists (options.OutputAssembly), "#A7");
  247. Assert.IsNotNull (compiledAssembly.GetType ("Test1"), "#B1");
  248. Assert.IsNotNull (compiledAssembly.GetType ("Test2"), "#B2");
  249. // verify we don't cleanup files in temp directory too agressively
  250. string [] tempFiles = Directory.GetFiles (_tempDir);
  251. Assert.AreEqual (2, tempFiles.Length, "#C1");
  252. Assert.IsTrue (File.Exists (sourceFile1), "#C2");
  253. Assert.IsTrue (File.Exists (sourceFile2), "#C3");
  254. string[] resources = compiledAssembly.GetManifestResourceNames();
  255. Assert.IsNotNull (resources, "#D1");
  256. Assert.AreEqual (2, resources.Length, "#D2");
  257. Assert.IsTrue (resources[0] == "file1.cs" || resources [0] == "file2.cs", "#E1");
  258. Assert.IsNull (compiledAssembly.GetFile ("file1.cs"), "#E2");
  259. Assert.IsNotNull (compiledAssembly.GetManifestResourceStream ("file1.cs"), "#E3");
  260. ManifestResourceInfo info = compiledAssembly.GetManifestResourceInfo ("file1.cs");
  261. Assert.IsNotNull (info, "#E4");
  262. Assert.IsNull (info.FileName, "#E5");
  263. Assert.IsNull (info.ReferencedAssembly, "#E6");
  264. Assert.AreEqual ((ResourceLocation.Embedded | ResourceLocation.ContainedInManifestFile), info.ResourceLocation, "#E7");
  265. Assert.IsTrue (resources[1] == "file1.cs" || resources [1] == "file2.cs", "#F1");
  266. try {
  267. compiledAssembly.GetFile ("file2.cs");
  268. Assert.Fail ("#F2");
  269. } catch (FileNotFoundException) {
  270. }
  271. try {
  272. compiledAssembly.GetManifestResourceStream ("file2.cs");
  273. Assert.Fail ("#F3");
  274. } catch (FileNotFoundException) {
  275. }
  276. info = compiledAssembly.GetManifestResourceInfo ("file2.cs");
  277. Assert.IsNotNull (info, "#F4");
  278. Assert.IsNotNull (info.FileName, "#F5");
  279. Assert.AreEqual ("file2.cs", info.FileName, "#F6");
  280. Assert.IsNull (info.ReferencedAssembly, "#F7");
  281. Assert.AreEqual ((ResourceLocation) 0, info.ResourceLocation, "#F8");
  282. }
  283. [Test]
  284. public void CompileFromSource_InMemory ()
  285. {
  286. // create a file in temp directory to ensure that compiler is not removing
  287. // too much (temporary) files
  288. string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
  289. using (FileStream fs = File.Create (tempFile)) {
  290. fs.Close ();
  291. }
  292. CompilerParameters options = new CompilerParameters ();
  293. options.GenerateExecutable = false;
  294. options.GenerateInMemory = true;
  295. options.TempFiles = new TempFileCollection (_tempDir);
  296. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  297. CompilerResults results = compiler.CompileAssemblyFromSource (options,
  298. _sourceLibrary1);
  299. // verify compilation was successful
  300. AssertCompileResults (results, true);
  301. Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
  302. Assert.IsNull (results.PathToAssembly, "#2");
  303. Assert.IsNotNull (results.CompiledAssembly.GetType ("Test1"), "#3");
  304. // verify we don't cleanup files in temp directory too agressively
  305. string[] tempFiles = Directory.GetFiles (_tempDir);
  306. Assert.AreEqual (1, tempFiles.Length, "#4");
  307. Assert.AreEqual (tempFile, tempFiles[0], "#5");
  308. }
  309. [Test]
  310. public void CompileFromSource_InMemory_Twice ()
  311. {
  312. CompilerParameters options = new CompilerParameters ();
  313. options.GenerateExecutable = false;
  314. options.GenerateInMemory = true;
  315. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  316. var src_1 = "class X { ";
  317. CompilerResults results_1 = compiler.CompileAssemblyFromSource (options, src_1);
  318. var output_1 = options.OutputAssembly;
  319. var src_2 = "class X { }";
  320. CompilerResults results_2 = compiler.CompileAssemblyFromSource (options, src_2);
  321. var output_2 = options.OutputAssembly;
  322. // verify compilation was successful
  323. AssertCompileResults (results_2, true);
  324. Assert.AreEqual (output_1, output_2, "#1");
  325. }
  326. [Test]
  327. public void CompileFromSource_InMemory_With_Extra_Delete ()
  328. {
  329. CompilerParameters options = new CompilerParameters ();
  330. options.GenerateExecutable = false;
  331. options.GenerateInMemory = true;
  332. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  333. var src_1 = "class X { ";
  334. compiler.CompileAssemblyFromSource (options, src_1);
  335. options.TempFiles.Delete ();
  336. options.TempFiles.Delete ();
  337. }
  338. [Test]
  339. public void CompileFromSourceBatch_InMemory ()
  340. {
  341. // create a file in temp directory to ensure that compiler is not removing
  342. // too much (temporary) files
  343. string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
  344. using (FileStream fs = File.Create (tempFile)) {
  345. fs.Close ();
  346. }
  347. string outputAssembly = Path.Combine (_tempDir, "sourcebatch.dll");
  348. CompilerParameters options = new CompilerParameters ();
  349. options.GenerateExecutable = false;
  350. options.GenerateInMemory = true;
  351. options.OutputAssembly = outputAssembly;
  352. options.TempFiles = new TempFileCollection (_tempDir);
  353. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  354. CompilerResults results = compiler.CompileAssemblyFromSourceBatch (options,
  355. new string [] { _sourceLibrary1, _sourceLibrary2 });
  356. // verify compilation was successful
  357. AssertCompileResults (results, true);
  358. Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#A1");
  359. Assert.IsNull (results.PathToAssembly, "#A2");
  360. Assert.IsNotNull (options.OutputAssembly, "#A3");
  361. Assert.AreEqual (outputAssembly, options.OutputAssembly, "#A4");
  362. Assert.IsTrue (File.Exists (outputAssembly), "#A5");
  363. Assert.IsNotNull (results.CompiledAssembly.GetType ("Test1"), "#B1");
  364. Assert.IsNotNull (results.CompiledAssembly.GetType ("Test2"), "#B2");
  365. // verify we don't cleanup files in temp directory too agressively
  366. string[] tempFiles = Directory.GetFiles (_tempDir);
  367. Assert.AreEqual (2, tempFiles.Length, "#C1");
  368. }
  369. [Test]
  370. public void CompileFromDom_NotInMemory ()
  371. {
  372. // create a file in temp directory to ensure that compiler is not removing
  373. // too much (temporary) files
  374. string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
  375. using (FileStream fs = File.Create (tempFile)) {
  376. fs.Close ();
  377. }
  378. // compile and verify result in separate appdomain to avoid file locks
  379. AppDomain testDomain = CreateTestDomain ();
  380. CrossDomainTester compileTester = CreateCrossDomainTester (testDomain);
  381. string outputAssembly = null;
  382. try {
  383. outputAssembly = compileTester.CompileAssemblyFromDom (_tempDir);
  384. } finally {
  385. AppDomain.Unload (testDomain);
  386. }
  387. // there should be two files in temp dir: temp file and output assembly
  388. string[] tempFiles = Directory.GetFiles (_tempDir);
  389. Assert.AreEqual (2, tempFiles.Length, "#1");
  390. Assert.IsTrue (File.Exists (outputAssembly), "#2");
  391. Assert.IsTrue (File.Exists (tempFile), "#3");
  392. }
  393. [Test]
  394. public void CompileFromDomBatch_NotInMemory ()
  395. {
  396. // create a file in temp directory to ensure that compiler is not removing
  397. // too much (temporary) files
  398. string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
  399. using (FileStream fs = File.Create (tempFile)) {
  400. fs.Close ();
  401. }
  402. // compile and verify result in separate appdomain to avoid file locks
  403. AppDomain testDomain = CreateTestDomain ();
  404. CrossDomainTester compileTester = CreateCrossDomainTester (testDomain);
  405. string outputAssembly = null;
  406. try {
  407. outputAssembly = compileTester.CompileAssemblyFromDomBatch (_tempDir);
  408. } finally {
  409. AppDomain.Unload (testDomain);
  410. }
  411. // there should be two files in temp dir: temp file and output assembly
  412. string[] tempFiles = Directory.GetFiles (_tempDir);
  413. Assert.AreEqual (2, tempFiles.Length, "#1");
  414. Assert.IsTrue (File.Exists (outputAssembly), "#2");
  415. Assert.IsTrue (File.Exists (tempFile), "#3");
  416. }
  417. [Test]
  418. public void CompileFromDom_InMemory ()
  419. {
  420. // create a file in temp directory to ensure that compiler is not removing
  421. // too much (temporary) files
  422. string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
  423. using (FileStream fs = File.Create (tempFile)) {
  424. fs.Close ();
  425. }
  426. CompilerParameters options = new CompilerParameters ();
  427. options.GenerateExecutable = false;
  428. options.GenerateInMemory = true;
  429. options.TempFiles = new TempFileCollection (_tempDir);
  430. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  431. CompilerResults results = compiler.CompileAssemblyFromDom (options, new CodeCompileUnit ());
  432. // verify compilation was successful
  433. AssertCompileResults (results, true);
  434. Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
  435. Assert.IsNull (results.PathToAssembly, "#2");
  436. // verify we don't cleanup files in temp directory too agressively
  437. string[] tempFiles = Directory.GetFiles (_tempDir);
  438. Assert.AreEqual (1, tempFiles.Length, "#3");
  439. Assert.AreEqual (tempFile, tempFiles[0], "#4");
  440. }
  441. [Test]
  442. public void CompileFromDomBatch_InMemory ()
  443. {
  444. // create a file in temp directory to ensure that compiler is not removing
  445. // too much (temporary) files
  446. string tempFile = Path.Combine (_tempDir, "file." + _codeProvider.FileExtension);
  447. using (FileStream fs = File.Create (tempFile)) {
  448. fs.Close ();
  449. }
  450. CompilerParameters options = new CompilerParameters ();
  451. options.GenerateExecutable = false;
  452. options.GenerateInMemory = true;
  453. options.TempFiles = new TempFileCollection (_tempDir);
  454. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  455. CompilerResults results = compiler.CompileAssemblyFromDomBatch (options,
  456. new CodeCompileUnit[] { new CodeCompileUnit (), new CodeCompileUnit () });
  457. // verify compilation was successful
  458. AssertCompileResults (results, true);
  459. Assert.AreEqual (string.Empty, results.CompiledAssembly.Location, "#1");
  460. Assert.IsNull (results.PathToAssembly, "#2");
  461. // verify we don't cleanup files in temp directory too agressively
  462. string[] tempFiles = Directory.GetFiles (_tempDir);
  463. Assert.AreEqual (1, tempFiles.Length, "#3");
  464. Assert.AreEqual (tempFile, tempFiles[0], "#4");
  465. }
  466. [Test]
  467. public void MultiLineWarningIsReportedAsOneWarning()
  468. {
  469. CompilerParameters options = new CompilerParameters ();
  470. options.GenerateExecutable = false;
  471. options.GenerateInMemory = true;
  472. options.TempFiles = new TempFileCollection (_tempDir);
  473. ICodeCompiler compiler = _codeProvider.CreateCompiler ();
  474. CompilerResults results = compiler.CompileAssemblyFromSource (options,
  475. _sourceLibrary3);
  476. // verify compilation was successful
  477. AssertCompileResults (results, true);
  478. }
  479. [Test]
  480. public void EncodingMismatch ()
  481. {
  482. var source = @"
  483. #warning Trigger Some Warning
  484. public class MyClass {
  485. public static string MyMethod () { return ""data""; }
  486. }";
  487. var p = new CompilerParameters () {
  488. GenerateInMemory = false,
  489. GenerateExecutable = false,
  490. IncludeDebugInformation = true,
  491. TreatWarningsAsErrors = false,
  492. TempFiles = new TempFileCollection (_tempDir, true),
  493. };
  494. var prov = new CSharpCodeProvider ();
  495. CompilerResults results;
  496. var prev = Console.OutputEncoding;
  497. try {
  498. Console.OutputEncoding = Encoding.Unicode;
  499. results = prov.CompileAssemblyFromSource (p, source);
  500. } finally {
  501. Console.OutputEncoding = prev;
  502. }
  503. Assert.IsNotNull (results.Errors);
  504. Assert.IsTrue (results.Output.Cast<string>().ToArray ()[1].Contains ("Trigger Some Warning"));
  505. }
  506. private static void AssertCompileResults (CompilerResults results, bool allowWarnings)
  507. {
  508. foreach (CompilerError compilerError in results.Errors) {
  509. if (allowWarnings && compilerError.IsWarning) {
  510. continue;
  511. }
  512. Assert.Fail (compilerError.ToString ());
  513. }
  514. }
  515. private static AppDomain CreateTestDomain ()
  516. {
  517. return AppDomain.CreateDomain ("CompileFromDom", AppDomain.CurrentDomain.Evidence,
  518. AppDomain.CurrentDomain.SetupInformation);
  519. }
  520. private static CrossDomainTester CreateCrossDomainTester (AppDomain domain)
  521. {
  522. Type testerType = typeof (CrossDomainTester);
  523. return (CrossDomainTester) domain.CreateInstanceAndUnwrap (
  524. testerType.Assembly.FullName, testerType.FullName, false,
  525. BindingFlags.Public | BindingFlags.Instance, null, new object[0],
  526. CultureInfo.InvariantCulture, new object[0], domain.Evidence);
  527. }
  528. // do not use the Assert class as this will introduce failures if the
  529. // nunit.framework assembly is not in the GAC
  530. private class CrossDomainTester : MarshalByRefObject
  531. {
  532. public string CompileAssemblyFromDom (string tempDir)
  533. {
  534. CompilerParameters options = new CompilerParameters ();
  535. options.GenerateExecutable = false;
  536. options.GenerateInMemory = false;
  537. options.TempFiles = new TempFileCollection (tempDir);
  538. CSharpCodeProvider codeProvider = new CSharpCodeProvider ();
  539. ICodeCompiler compiler = codeProvider.CreateCompiler ();
  540. CompilerResults results = compiler.CompileAssemblyFromDom (options, new CodeCompileUnit ());
  541. // verify compilation was successful
  542. AssertCompileResults (results, true);
  543. if (results.CompiledAssembly.Location.Length == 0)
  544. throw new Exception ("Location should not be empty string");
  545. if (results.PathToAssembly == null)
  546. throw new Exception ("PathToAssembly should not be null");
  547. return results.PathToAssembly;
  548. }
  549. public string CompileAssemblyFromDomBatch (string tempDir)
  550. {
  551. CompilerParameters options = new CompilerParameters ();
  552. options.GenerateExecutable = false;
  553. options.GenerateInMemory = false;
  554. options.TempFiles = new TempFileCollection (tempDir);
  555. CSharpCodeProvider codeProvider = new CSharpCodeProvider ();
  556. ICodeCompiler compiler = codeProvider.CreateCompiler ();
  557. CompilerResults results = compiler.CompileAssemblyFromDomBatch (options, new CodeCompileUnit[] { new CodeCompileUnit (), new CodeCompileUnit () });
  558. // verify compilation was successful
  559. AssertCompileResults (results, true);
  560. if (results.CompiledAssembly.Location.Length == 0)
  561. throw new Exception ("Location should not be empty string");
  562. if (results.PathToAssembly == null)
  563. throw new Exception ("PathToAssembly should not be null");
  564. return results.PathToAssembly;
  565. }
  566. }
  567. }
  568. }