You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
6.4 KiB

  1. // Copyright (c) AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.CodeDom.Compiler;
  20. using System.IO;
  21. using System.Linq;
  22. using System.Runtime.CompilerServices;
  23. using ICSharpCode.Decompiler.Tests.Helpers;
  24. using NUnit.Framework;
  25. namespace ICSharpCode.Decompiler.Tests
  26. {
  27. public class PrettyTestRunner
  28. {
  29. const string TestCasePath = DecompilerTestBase.TestCasePath + "/Pretty";
  30. [Test]
  31. public void AllFilesHaveTests()
  32. {
  33. var testNames = typeof(PrettyTestRunner).GetMethods()
  34. .Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())
  35. .Select(m => m.Name)
  36. .ToArray();
  37. foreach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles()) {
  38. if (file.Extension.Equals(".il", StringComparison.OrdinalIgnoreCase)
  39. || file.Extension.Equals(".cs", StringComparison.OrdinalIgnoreCase)) {
  40. var testName = file.Name.Split('.')[0];
  41. Assert.Contains(testName, testNames);
  42. }
  43. }
  44. }
  45. static readonly CompilerOptions[] noRoslynOptions =
  46. {
  47. CompilerOptions.None,
  48. CompilerOptions.Optimize
  49. };
  50. static readonly CompilerOptions[] roslynOnlyOptions =
  51. {
  52. CompilerOptions.UseRoslyn,
  53. CompilerOptions.Optimize | CompilerOptions.UseRoslyn
  54. };
  55. static readonly CompilerOptions[] defaultOptions =
  56. {
  57. CompilerOptions.None,
  58. CompilerOptions.Optimize,
  59. CompilerOptions.UseRoslyn,
  60. CompilerOptions.Optimize | CompilerOptions.UseRoslyn
  61. };
  62. [Test]
  63. public void HelloWorld()
  64. {
  65. Run();
  66. Run(asmOptions: AssemblerOptions.UseDebug);
  67. }
  68. [Test]
  69. public void InlineAssignmentTest([ValueSource("noRoslynOptions")] CompilerOptions cscOptions)
  70. {
  71. Run(cscOptions: cscOptions);
  72. }
  73. [Test]
  74. public void CompoundAssignmentTest([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  75. {
  76. Run(cscOptions: cscOptions);
  77. }
  78. [Test]
  79. public void ShortCircuit([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  80. {
  81. Run(cscOptions: cscOptions);
  82. }
  83. [Test]
  84. public void ExceptionHandling([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  85. {
  86. Run(cscOptions: cscOptions);
  87. }
  88. [Test]
  89. public void AnonymousTypes([Values(CompilerOptions.None, CompilerOptions.Optimize)] CompilerOptions cscOptions)
  90. {
  91. Run(cscOptions: cscOptions);
  92. }
  93. [Test]
  94. public void Async([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  95. {
  96. Run(cscOptions: cscOptions);
  97. }
  98. [Test]
  99. public void Lock([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  100. {
  101. Run(cscOptions: cscOptions);
  102. }
  103. [Test]
  104. public void Using([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  105. {
  106. Run(cscOptions: cscOptions);
  107. }
  108. [Test, Ignore("Not implemented")]
  109. public void LiftedOperators([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  110. {
  111. try {
  112. Run(cscOptions: cscOptions);
  113. } catch (AssertionException) {
  114. Assert.Ignore("Not implemented");
  115. }
  116. }
  117. [Test]
  118. public void Loops([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  119. {
  120. Run(cscOptions: cscOptions);
  121. }
  122. [Test]
  123. public void PropertiesAndEvents([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  124. {
  125. Run(cscOptions: cscOptions);
  126. }
  127. [Test]
  128. public void AutoProperties([ValueSource("roslynOnlyOptions")] CompilerOptions cscOptions)
  129. {
  130. Run(cscOptions: cscOptions);
  131. }
  132. [Test]
  133. public void QueryExpressions([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  134. {
  135. Run(cscOptions: cscOptions);
  136. }
  137. [Test]
  138. public void TypeAnalysisTests([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  139. {
  140. Run(cscOptions: cscOptions);
  141. }
  142. [Test]
  143. public void CheckedUnchecked([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  144. {
  145. if (cscOptions.HasFlag(CompilerOptions.UseRoslyn) && cscOptions.HasFlag(CompilerOptions.Optimize)) {
  146. Assert.Ignore("Roslyn opt replaces locals with stack slots, resulting in S_* variable names.");
  147. }
  148. Run(cscOptions: cscOptions);
  149. }
  150. [Test]
  151. public void PInvoke([ValueSource("defaultOptions")] CompilerOptions cscOptions)
  152. {
  153. // This tests needs our own disassembler; ildasm has a bug with marshalinfo.
  154. Run(cscOptions: cscOptions, asmOptions: AssemblerOptions.UseOwnDisassembler);
  155. }
  156. void Run([CallerMemberName] string testName = null, AssemblerOptions asmOptions = AssemblerOptions.None, CompilerOptions cscOptions = CompilerOptions.None)
  157. {
  158. var ilFile = Path.Combine(TestCasePath, testName);
  159. if ((cscOptions & CompilerOptions.Optimize) != 0)
  160. ilFile += ".opt";
  161. if ((cscOptions & CompilerOptions.Force32Bit) != 0)
  162. ilFile += ".32";
  163. if ((cscOptions & CompilerOptions.UseDebug) != 0)
  164. ilFile += ".dbg";
  165. if ((cscOptions & CompilerOptions.UseRoslyn) != 0)
  166. ilFile += ".roslyn";
  167. ilFile += ".il";
  168. var csFile = Path.Combine(TestCasePath, testName + ".cs");
  169. if (!File.Exists(ilFile)) {
  170. // re-create .il file if necessary
  171. CompilerResults output = null;
  172. try {
  173. output = Tester.CompileCSharp(csFile, cscOptions | CompilerOptions.Library);
  174. Tester.Disassemble(output.PathToAssembly, ilFile, asmOptions);
  175. } finally {
  176. if (output != null)
  177. output.TempFiles.Delete();
  178. }
  179. }
  180. var executable = Tester.AssembleIL(ilFile, asmOptions | AssemblerOptions.Library);
  181. var decompiled = Tester.DecompileCSharp(executable);
  182. CodeAssert.FilesAreEqual(csFile, decompiled, cscOptions.HasFlag(CompilerOptions.UseRoslyn) ? null : new[] { "LEGACY_CSC" });
  183. }
  184. }
  185. }