diff --git a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
index 5c8366b70..b091121d3 100644
--- a/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
@@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
+using System;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -48,7 +49,7 @@ namespace ICSharpCode.Decompiler.Tests
}
}
- static readonly CompilerOptions[] noMonoOptions =
+ static readonly CompilerOptions[] noMonoOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize,
@@ -72,9 +73,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ }, executesCompiledOutput: true);
- static readonly CompilerOptions[] net40OnlyOptions =
+ static readonly CompilerOptions[] net40OnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize,
@@ -88,9 +89,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
- };
+ }, executesCompiledOutput: true);
- static readonly CompilerOptions[] defaultOptions =
+ static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize,
@@ -118,9 +119,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4,
CompilerOptions.UseMcs5_23,
CompilerOptions.Optimize | CompilerOptions.UseMcs5_23
- };
+ }, executesCompiledOutput: true);
- static readonly CompilerOptions[] roslynOnlyOptions =
+ static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
@@ -142,9 +143,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ }, executesCompiledOutput: true);
- static readonly CompilerOptions[] roslyn2OrNewerOptions =
+ static readonly CompilerOptions[] roslyn2OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
@@ -162,7 +163,7 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ }, executesCompiledOutput: true);
[Test]
public async Task Comparisons([ValueSource(nameof(defaultOptions))] CompilerOptions options)
@@ -176,8 +177,12 @@ namespace ICSharpCode.Decompiler.Tests
await RunCS(options: options);
}
+ // 32-bit execution requires a 32-bit runtime, which only exists on Windows.
+ static readonly int[] supportedBitness = OperatingSystem.IsWindows() ? new[] { 32, 64 } : new[] { 64 };
+ static readonly bool[] supportedForce32Bit = OperatingSystem.IsWindows() ? new[] { false, true } : new[] { false };
+
[Test]
- public async Task FloatingPointArithmetic([ValueSource(nameof(noMonoOptions))] CompilerOptions options, [Values(32, 64)] int bits)
+ public async Task FloatingPointArithmetic([ValueSource(nameof(noMonoOptions))] CompilerOptions options, [ValueSource(nameof(supportedBitness))] int bits)
{
// The behavior of the #1794 incorrect `(float)(double)val` cast only causes test failures
// for some runtime+compiler combinations.
@@ -260,7 +265,7 @@ namespace ICSharpCode.Decompiler.Tests
await RunCS(options: options);
}
- [Test]
+ [Test, Platform("Win")] // uses __arglist; CoreCLR only supports the vararg calling convention on Windows
public async Task UndocumentedExpressions([ValueSource(nameof(noMonoOptions))] CompilerOptions options)
{
await RunCS(options: options);
@@ -303,7 +308,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
- public async Task BitNot([Values(false, true)] bool force32Bit)
+ public async Task BitNot([ValueSource(nameof(supportedForce32Bit))] bool force32Bit)
{
CompilerOptions compiler = CompilerOptions.UseDebug;
AssemblerOptions asm = AssemblerOptions.None;
@@ -327,7 +332,7 @@ namespace ICSharpCode.Decompiler.Tests
await RunIL("NonGenericConstrainedCallVirt.il", CompilerOptions.UseRoslynLatest);
}
- [Test]
+ [Test, Platform("Win")] // 32BITREQUIRED needs the Windows 32-bit runtime
public async Task StackTests()
{
// IL contains .corflags = 32BITREQUIRED
@@ -335,7 +340,7 @@ namespace ICSharpCode.Decompiler.Tests
}
[Test]
- public async Task StackTypes([Values(false, true)] bool force32Bit)
+ public async Task StackTypes([ValueSource(nameof(supportedForce32Bit))] bool force32Bit)
{
CompilerOptions compiler = CompilerOptions.UseRoslynLatest | CompilerOptions.UseDebug;
AssemblerOptions asm = AssemblerOptions.None;
@@ -501,6 +506,12 @@ namespace ICSharpCode.Decompiler.Tests
try
{
options |= CompilerOptions.UseTestRunner;
+ if (!OperatingSystem.IsWindows() && (options & CompilerOptions.UseRoslynMask) == 0)
+ {
+ // The default (legacy csc) recompilation of the decompiled output is only
+ // available on Windows; elsewhere use the current Roslyn instead.
+ options |= CompilerOptions.UseRoslynLatest;
+ }
outputFile = await Tester.AssembleIL(Path.Combine(TestCasePath, testFileName), asmOptions).ConfigureAwait(false);
string decompiledCodeFile = await Tester.DecompileCSharp(outputFile, Tester.GetSettings(options)).ConfigureAwait(false);
decompiledOutputFile = await Tester.CompileCSharp(decompiledCodeFile, options).ConfigureAwait(false);
diff --git a/ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs b/ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs
index 21abefe72..3a75f331a 100644
--- a/ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs
+++ b/ICSharpCode.Decompiler.Tests/Helpers/RoslynToolset.cs
@@ -147,14 +147,16 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
installedCompilers.Add(SanitizeVersion(version), path);
}
+ // In the .NET ("netcore") build of the compiler toolset the executables live in a
+ // "bincore" subfolder of the tasks directory, as .dlls launched through the dotnet host.
public string GetCSharpCompiler(string version)
{
- return GetCompiler("csc.exe", version);
+ return GetCompiler(OperatingSystem.IsWindows() ? "csc.exe" : "bincore/csc.dll", version);
}
public string GetVBCompiler(string version)
{
- return GetCompiler("vbc.exe", version);
+ return GetCompiler(OperatingSystem.IsWindows() ? "vbc.exe" : "bincore/vbc.dll", version);
}
string GetCompiler(string compiler, string version)
diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
index 73801bdfc..0536e43d3 100644
--- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
+++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.VB.cs
@@ -69,6 +69,12 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
else
{
references = defaultReferences.Select(r => "-r:\"" + r + "\"");
+ if (!OperatingSystem.IsWindows())
+ {
+ // The dotnet-hosted compiler has no implicit mscorlib reference
+ // (see CompileCSharp); vbc resolves the bare name via -libpath.
+ references = references.Prepend("-r:\"mscorlib.dll\"");
+ }
libPath = RefAssembliesToolset.GetPath("legacy");
}
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
@@ -80,6 +86,24 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
$"-langversion:{languageVersion} " +
$"/optimize{(flags.HasFlag(CompilerOptions.Optimize) ? "+ " : "- ")}";
+ if (!OperatingSystem.IsWindows())
+ {
+ // The dotnet-hosted vbc has no implicit SDK path for resolving the standard
+ // libraries and the VB runtime. The My templates are disabled because they
+ // need ApplicationServices types missing from the .NET build of
+ // Microsoft.VisualBasic (the .NET SDK sets _MYTYPE=Empty for the same
+ // reason); the decompile comparison strips the My namespace anyway.
+ otherOptions += $"-sdkpath:\"{libPath}\" ";
+ otherOptions += "-define:_MYTYPE=\\\"Empty\\\" ";
+ if ((flags & CompilerOptions.UseRoslynMask) != 0 && targetFramework != null)
+ {
+ // In the .NET reference packs Microsoft.VisualBasic.dll is a
+ // type-forwarding facade, and vbc does not follow forwards when binding
+ // its runtime helpers (e.g. ProjectData); point it at the implementation.
+ otherOptions += $"-vbruntime:\"{Path.Combine(libPath, "Microsoft.VisualBasic.Core.dll")}\" ";
+ }
+ }
+
// note: the /shared switch is undocumented. It allows us to use the VBCSCompiler.exe compiler
// server to speed up testing
if (roslynVersion != "legacy")
@@ -118,8 +142,7 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
otherOptions += " \"-d:" + string.Join(",", preprocessorSymbols.Select(kv => kv.Key + "=" + kv.Value)) + "\" ";
}
- var command = Cli.Wrap(vbcPath)
- .WithArguments($"{otherOptions}-libpath:\"{libPath}\" {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
+ var command = WrapCompiler(vbcPath, $"{otherOptions}-libpath:\"{libPath}\" {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithValidation(CommandResultValidation.None);
//Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}");
diff --git a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
index 86849a323..420b4a06e 100644
--- a/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
+++ b/ICSharpCode.Decompiler.Tests/Helpers/Tester.cs
@@ -145,29 +145,67 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
{
await roslynToolset.Fetch("1.3.2", "Microsoft.Net.Compilers", "tools").ConfigureAwait(false);
await roslynToolset.Fetch("2.10.0", "Microsoft.Net.Compilers", "tools").ConfigureAwait(false);
- await roslynToolset.Fetch("3.11.0").ConfigureAwait(false);
- await roslynToolset.Fetch("4.14.0").ConfigureAwait(false);
- await roslynToolset.Fetch(roslynLatestVersion).ConfigureAwait(false);
+ // On non-Windows hosts the net472 compiler binaries cannot be executed; use the
+ // .NET build of each toolset instead. Its tasks folder is named "netcoreapp3.1"
+ // up to Roslyn 3.x and "netcore" from Roslyn 4.x on.
+ await roslynToolset.Fetch("3.11.0", sourcePath: OperatingSystem.IsWindows() ? "tasks/net472" : "tasks/netcoreapp3.1").ConfigureAwait(false);
+ await roslynToolset.Fetch("4.14.0", sourcePath: OperatingSystem.IsWindows() ? "tasks/net472" : "tasks/netcore").ConfigureAwait(false);
+ await roslynToolset.Fetch(roslynLatestVersion, sourcePath: OperatingSystem.IsWindows() ? "tasks/net472" : "tasks/netcore").ConfigureAwait(false);
await vswhereToolset.Fetch().ConfigureAwait(false);
await RefAssembliesToolset.Fetch("5.0.0", sourcePath: "ref/net5.0").ConfigureAwait(false);
await RefAssembliesToolset.Fetch("9.0.0", sourcePath: "ref/net9.0").ConfigureAwait(false);
await RefAssembliesToolset.Fetch(CurrentNetCoreRefAsmVersion, sourcePath: $"ref/net{CurrentNetCoreVersion}").ConfigureAwait(false);
- // The self-contained TestRunner builds only target Windows RIDs; the fixtures that
- // consume them (UseTestRunner) are themselves gated to Windows at runtime.
- if (OperatingSystem.IsWindows())
- {
#if DEBUG
- await BuildTestRunner("win-x86", "Debug").ConfigureAwait(false);
- await BuildTestRunner("win-x64", "Debug").ConfigureAwait(false);
+ const string testRunnerConfig = "Debug";
#else
- await BuildTestRunner("win-x86", "Release").ConfigureAwait(false);
- await BuildTestRunner("win-x64", "Release").ConfigureAwait(false);
+ const string testRunnerConfig = "Release";
#endif
+ if (OperatingSystem.IsWindows())
+ {
+ await BuildTestRunner("win-x86", testRunnerConfig).ConfigureAwait(false);
+ await BuildTestRunner("win-x64", testRunnerConfig).ConfigureAwait(false);
+ }
+ else
+ {
+ // Self-contained build for the host platform. The RID must be one of the
+ // RuntimeIdentifiers pinned in ICSharpCode.Decompiler.TestRunner.csproj.
+ await BuildTestRunner(OperatingSystem.IsMacOS() ? "osx-arm64" : "linux-x64", testRunnerConfig).ConfigureAwait(false);
}
}
+ ///
+ /// Reduces a compiler-configuration matrix to the entries usable on the current platform.
+ /// On Windows every configuration is supported. On other platforms, configurations that
+ /// depend on Windows-only tools or runtimes are removed: the legacy (pre-Roslyn) csc/vbc,
+ /// Roslyn 1.x/2.x (their packages only ship .NET Framework binaries), mcs, and Force32Bit
+ /// (requires a 32-bit runtime). When is set
+ /// (correctness-style fixtures), configurations targeting .NET Framework 4.0 are removed
+ /// as well, because their output executables only run on Windows.
+ ///
+ public static CompilerOptions[] SupportedOnCurrentPlatform(CompilerOptions[] configurations, bool executesCompiledOutput = false)
+ {
+ if (OperatingSystem.IsWindows())
+ return configurations;
+ const CompilerOptions dotnetHostedCompilers = CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.UseRoslynLatest;
+ return configurations.Where(c => (c & dotnetHostedCompilers) != 0
+ && !c.HasFlag(CompilerOptions.Force32Bit)
+ && !(executesCompiledOutput && c.HasFlag(CompilerOptions.TargetNet40))).ToArray();
+ }
+
+ ///
+ /// Wraps an external compiler invocation. The .NET Framework builds of the Roslyn
+ /// compilers (csc.exe/vbc.exe) are directly executable; the .NET builds ship as a
+ /// .dll that must be launched through the 'dotnet' host.
+ ///
+ static Command WrapCompiler(string compilerPath, string arguments)
+ {
+ if (compilerPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
+ return Cli.Wrap("dotnet").WithArguments($"\"{compilerPath}\" {arguments}");
+ return Cli.Wrap(compilerPath).WithArguments(arguments);
+ }
+
static async Task BuildTestRunner(string runtime, string config)
{
await Cli.Wrap("dotnet")
@@ -189,30 +227,32 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
ilasmPath = ResolveToolPath("ilasm");
}
string outputFile = Path.Combine(Path.GetDirectoryName(sourceFileName), Path.GetFileNameWithoutExtension(sourceFileName));
+ // Options use the '-' prefix because on Unix the ilasm option parser treats
+ // '/option' as a file path; the Windows builds accept both prefixes.
string otherOptions = " ";
if (options.HasFlag(AssemblerOptions.Force32Bit))
{
outputFile += ".32";
- otherOptions += "/32BitPreferred ";
+ otherOptions += "-32BitPreferred ";
}
if (options.HasFlag(AssemblerOptions.Library))
{
outputFile += ".dll";
- otherOptions += "/dll ";
+ otherOptions += "-dll ";
}
else
{
outputFile += ".exe";
- otherOptions += "/exe ";
+ otherOptions += "-exe ";
}
if (options.HasFlag(AssemblerOptions.UseDebug))
{
- otherOptions += "/debug ";
+ otherOptions += "-debug ";
}
var command = Cli.Wrap(ilasmPath)
- .WithArguments($"/quiet {otherOptions}/output=\"{outputFile}\" \"{sourceFileName}\"")
+ .WithArguments($"-quiet {otherOptions}-output=\"{outputFile}\" \"{sourceFileName}\"")
.WithValidation(CommandResultValidation.None);
var result = await command.ExecuteBufferedAsync().ConfigureAwait(false);
@@ -262,8 +302,9 @@ namespace ICSharpCode.Decompiler.Tests.Helpers
string ildasmPath = ResolveToolPath("ildasm");
+ // '-' option prefix: see AssembleIL.
var command = Cli.Wrap(ildasmPath)
- .WithArguments($"/utf8 /out=\"{outputFile}\" \"{sourceFileName}\"")
+ .WithArguments($"-utf8 -out=\"{outputFile}\" \"{sourceFileName}\"")
.WithValidation(CommandResultValidation.None);
var result = await command.ExecuteBufferedAsync().ConfigureAwait(false);
@@ -594,6 +635,13 @@ namespace System.Runtime.CompilerServices
refAsmPath = RefAssembliesToolset.GetPath("legacy");
libPath = "\"" + refAsmPath + "\"";
references = defaultReferences;
+ if (!OperatingSystem.IsWindows())
+ {
+ // The .NET Framework csc.exe implicitly references the mscorlib of its
+ // runtime directory; the dotnet-hosted compiler has no implicit
+ // references, so the target framework's mscorlib must be passed explicitly.
+ references = references.Prepend("mscorlib.dll");
+ }
if (flags.HasFlag(CompilerOptions.ReferenceVisualBasic))
{
references = references.Append("Microsoft.VisualBasic.dll");
@@ -688,8 +736,7 @@ namespace System.Runtime.CompilerServices
otherOptions += " -nowarn:" + string.Join(",", noWarn);
}
- var command = Cli.Wrap(cscPath)
- .WithArguments($"{otherOptions} -lib:{libPath} {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
+ var command = WrapCompiler(cscPath, $"{otherOptions} -lib:{libPath} {string.Join(" ", references)} -out:\"{Path.GetFullPath(results.PathToAssembly)}\" {string.Join(" ", sourceFileNames.Select(fn => '"' + Path.GetFullPath(fn) + '"'))}")
.WithValidation(CommandResultValidation.None);
//Console.WriteLine($"\"{command.TargetFilePath}\" {command.Arguments}");
@@ -881,9 +928,20 @@ namespace System.Runtime.CompilerServices
public static async Task<(int ExitCode, string Output, string Error)> RunWithTestRunner(string assemblyFileName, bool force32Bit)
{
- if (!OperatingSystem.IsWindows())
- Assert.Ignore("RunWithTestRunner uses a self-contained Windows test-runner build (win-x86/win-x64); not available on this platform.");
- string testRunner = Path.Combine(testRunnerBasePath, force32Bit ? "win-x86" : "win-x64", "ICSharpCode.Decompiler.TestRunner.exe");
+ string runnerRid;
+ if (OperatingSystem.IsWindows())
+ {
+ runnerRid = force32Bit ? "win-x86" : "win-x64";
+ }
+ else
+ {
+ // Safety net: 32-bit runs need a 32-bit runtime, which only exists on Windows.
+ // Configurations using Force32Bit are not enumerated on non-Windows platforms.
+ if (force32Bit)
+ Assert.Ignore("Force32Bit requires a 32-bit .NET runtime, which is only available on Windows.");
+ runnerRid = OperatingSystem.IsMacOS() ? "osx-arm64" : "linux-x64";
+ }
+ string testRunner = Path.Combine(testRunnerBasePath, runnerRid, "ICSharpCode.Decompiler.TestRunner" + ExecutableExtension);
var command = Cli.Wrap(testRunner)
.WithArguments(assemblyFileName)
.WithValidation(CommandResultValidation.None);
diff --git a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
index 1d6c29e16..6ec521e54 100644
--- a/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
@@ -273,7 +273,7 @@ namespace ICSharpCode.Decompiler.Tests
await Run();
}
- [Test]
+ [Test, Platform("Win")] // UseLegacyAssembler requires the .NET Framework ilasm
public async Task Unsafe()
{
await Run(assemblerOptions: AssemblerOptions.Library | AssemblerOptions.UseLegacyAssembler);
diff --git a/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs b/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs
index b22dcad56..e2661e557 100644
--- a/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/PdbGenerationTestRunner.cs
@@ -252,6 +252,13 @@ namespace ICSharpCode.Decompiler.Tests
{
file.Attribute("checksum").Remove();
file.Attribute("embeddedSourceLength")?.Remove();
+ var name = file.Attribute("name");
+ if (name != null)
+ {
+ // Generated document names use the platform's directory separator;
+ // the expected files were produced on Windows.
+ name.Value = name.Value.Replace('/', '\\');
+ }
file.ReplaceNodes(new XCData(file.Value.Replace("\uFEFF", "")));
}
document.Save(fileName, SaveOptions.None);
diff --git a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
index 69300d285..fc4a4f2b4 100644
--- a/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/PrettyTestRunner.cs
@@ -51,13 +51,13 @@ namespace ICSharpCode.Decompiler.Tests
}
}
- static readonly CompilerOptions[] noRoslynOptions =
+ static readonly CompilerOptions[] noRoslynOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize
- };
+ });
- static readonly CompilerOptions[] roslynOnlyWithNet40Options =
+ static readonly CompilerOptions[] roslynOnlyWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
@@ -77,9 +77,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslynOnlyOptions =
+ static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn1_3_2,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2,
@@ -91,9 +91,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslyn2OrNewerWithNet40Options =
+ static readonly CompilerOptions[] roslyn2OrNewerWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0 | CompilerOptions.TargetNet40,
@@ -111,9 +111,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslyn2OrNewerOptions =
+ static readonly CompilerOptions[] roslyn2OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn2_10_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn2_10_0,
@@ -123,9 +123,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslyn3OrNewerWithNet40Options =
+ static readonly CompilerOptions[] roslyn3OrNewerWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0 | CompilerOptions.TargetNet40,
@@ -139,9 +139,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslyn3OrNewerOptions =
+ static readonly CompilerOptions[] roslyn3OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn3_11_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn3_11_0,
@@ -149,9 +149,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslyn4OrNewerWithNet40Options =
+ static readonly CompilerOptions[] roslyn4OrNewerWithNet40Options = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
@@ -161,23 +161,23 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslyn4OrNewerOptions =
+ static readonly CompilerOptions[] roslyn4OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslyn5OrNewerOptions =
+ static readonly CompilerOptions[] roslyn5OrNewerOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] defaultOptions =
+ static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize,
@@ -199,9 +199,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] defaultOptionsWithMcs =
+ static readonly CompilerOptions[] defaultOptionsWithMcs = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize,
@@ -227,9 +227,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseMcs2_6_4,
CompilerOptions.UseMcs5_23,
CompilerOptions.Optimize | CompilerOptions.UseMcs5_23
- };
+ });
- [Test]
+ [Test, Platform("Win")] // uses the legacy (pre-Roslyn) csc, which only exists on Windows
public async Task HelloWorld()
{
await RunForLibrary();
diff --git a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs
index 619c741c0..c78387815 100644
--- a/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs
+++ b/ICSharpCode.Decompiler.Tests/TestCases/Correctness/Async.cs
@@ -291,7 +291,9 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Correctness
{
Console.WriteLine("d");
int i = 0;
- if (Console.CapsLock)
+ // An opaque condition the compiler cannot evaluate; Console.IsInputRedirected
+ // (unlike Console.CapsLock) is supported on all platforms.
+ if (Console.IsInputRedirected)
{
i++;
await Task.Delay(i);
diff --git a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
index ccea015be..5cff88e43 100644
--- a/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/UglyTestRunner.cs
@@ -51,13 +51,13 @@ namespace ICSharpCode.Decompiler.Tests
}
}
- static readonly CompilerOptions[] noRoslynOptions =
+ static readonly CompilerOptions[] noRoslynOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize
- };
+ });
- static readonly CompilerOptions[] roslynOnlyOptions =
+ static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0 | CompilerOptions.TargetNet40,
@@ -67,9 +67,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] defaultOptions =
+ static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize,
@@ -77,7 +77,7 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest | CompilerOptions.TargetNet40,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
[Test]
public async Task NoArrayInitializers([ValueSource(nameof(roslynOnlyOptions))] CompilerOptions cscOptions)
diff --git a/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs b/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs
index abd9fbea0..982f16b55 100644
--- a/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs
+++ b/ICSharpCode.Decompiler.Tests/Util/FileUtilityTests.cs
@@ -82,7 +82,9 @@ namespace ICSharpCode.Decompiler.Tests.Util
}
#endregion
- [Test]
+ // IsBaseDirectory/GetRelativePath compare path segments with the platform's
+ // case sensitivity and separator; these expectations encode the Windows behavior.
+ [Test, Platform("Win")]
public void TestIsBaseDirectory()
{
Assert.That(FileUtility.IsBaseDirectory(@"C:\a", @"C:\A\b\hello"));
@@ -106,7 +108,7 @@ namespace ICSharpCode.Decompiler.Tests.Util
Assert.That(!FileUtility.IsBaseDirectory(@"C:\", @"D:\a\b\hello"));
}
- [Test]
+ [Test, Platform("Win")] // see TestIsBaseDirectory
public void TestIsBaseDirectoryRelative()
{
Assert.That(FileUtility.IsBaseDirectory(@".", @"a\b"));
@@ -131,7 +133,7 @@ namespace ICSharpCode.Decompiler.Tests.Util
Assert.That(!FileUtility.IsBaseDirectory(@"\\server2\share", @"\\server\share\dir\subdir"));
}
- [Test]
+ [Test, Platform("Win")] // see TestIsBaseDirectory
public void TestGetRelativePath()
{
Assert.That(FileUtility.GetRelativePath(@"C:\hello\.\..\a", @"C:\.\a\blub"), Is.EqualTo(@"blub"));
@@ -149,7 +151,7 @@ namespace ICSharpCode.Decompiler.Tests.Util
Assert.That(FileUtility.GetRelativePath(@"C:\.\.\.\.\heLLo\A\..", @"C:\.\blub\.\..\.\a\.\blub"), Is.EqualTo(@"..\a\blub"));
}
- [Test]
+ [Test, Platform("Win")] // see TestIsBaseDirectory
public void RelativeGetRelativePath()
{
// Relative path
@@ -166,8 +168,9 @@ namespace ICSharpCode.Decompiler.Tests.Util
[Test]
public void GetRelativePath_Unix()
{
+ // The result is joined with the platform's directory separator.
Assert.That(FileUtility.GetRelativePath("/", "/a"), Is.EqualTo(@"a"));
- Assert.That(FileUtility.GetRelativePath("/", "/a/b"), Is.EqualTo(@"a\b"));
+ Assert.That(FileUtility.GetRelativePath("/", "/a/b"), Is.EqualTo($"a{System.IO.Path.DirectorySeparatorChar}b"));
Assert.That(FileUtility.GetRelativePath("/a", "/a/b"), Is.EqualTo(@"b"));
}
diff --git a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs
index fbd94a6bf..08c556392 100644
--- a/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs
+++ b/ICSharpCode.Decompiler.Tests/VBPrettyTestRunner.cs
@@ -51,7 +51,7 @@ namespace ICSharpCode.Decompiler.Tests
}
}
- static readonly CompilerOptions[] defaultOptions =
+ static readonly CompilerOptions[] defaultOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.None,
CompilerOptions.Optimize,
@@ -75,9 +75,9 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
- static readonly CompilerOptions[] roslynOnlyOptions =
+ static readonly CompilerOptions[] roslynOnlyOptions = Tester.SupportedOnCurrentPlatform(new[]
{
CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
CompilerOptions.Optimize | CompilerOptions.UseRoslyn1_3_2 | CompilerOptions.TargetNet40,
@@ -99,7 +99,7 @@ namespace ICSharpCode.Decompiler.Tests
CompilerOptions.Optimize | CompilerOptions.UseRoslyn4_14_0,
CompilerOptions.UseRoslynLatest,
CompilerOptions.Optimize | CompilerOptions.UseRoslynLatest,
- };
+ });
[Test]
public async Task Async([ValueSource(nameof(defaultOptions))] CompilerOptions options)