Browse Source

add new TestRunner

pull/728/head
Siegfried Pammer 11 years ago
parent
commit
125cd1fdfc
  1. 72
      ICSharpCode.Decompiler/Tests/Helpers/Tester.cs
  2. 6
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  3. 13
      ICSharpCode.Decompiler/Tests/TestCases/HelloWorld.cs
  4. 228
      ICSharpCode.Decompiler/Tests/TestRunner.cs
  5. 5
      ILSpy.sln
  6. 84
      Rebracer.xml

72
ICSharpCode.Decompiler/Tests/Helpers/Tester.cs

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.NRefactory.CSharp;
using Microsoft.CSharp;
using Mono.Cecil;
namespace ICSharpCode.Decompiler.Tests.Helpers
{
public static class Tester
{
public static string CompileCSharp(string sourceFileName, bool optimize = false, bool useDebug = true)
{
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.GenerateExecutable = true;
options.CompilerOptions = "/unsafe /o" + (optimize ? "+" : "-") + (useDebug ? " /debug" : "");
options.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = provider.CompileAssemblyFromFile(options, sourceFileName);
if (results.Errors.Count > 0) {
StringBuilder b = new StringBuilder("Compiler error:");
foreach (var error in results.Errors) {
b.AppendLine(error.ToString());
}
throw new Exception(b.ToString());
}
return results.PathToAssembly;
}
public static int Run(string assemblyFileName, out string output, out string error)
{
ProcessStartInfo info = new ProcessStartInfo(assemblyFileName);
info.RedirectStandardError = true;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
Process process = Process.Start(info);
var outputTask = process.StandardOutput.ReadToEndAsync();
var errorTask = process.StandardError.ReadToEndAsync();
Task.WaitAll(outputTask, errorTask);
output = outputTask.Result;
error = errorTask.Result;
return process.ExitCode;
}
public static string DecompileCSharp(string assemblyFileName)
{
CSharpDecompiler decompiler = new CSharpDecompiler(AssemblyDefinition.ReadAssembly(assemblyFileName).MainModule);
var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile();
new Helpers.RemoveCompilerAttribute().Run(syntaxTree);
StringWriter output = new StringWriter();
var visitor = new CSharpOutputVisitor(output, FormattingOptionsFactory.CreateSharpDevelop());
syntaxTree.AcceptVisitor(visitor);
string fileName = Path.GetTempFileName();
File.WriteAllText(fileName, output.ToString());
return fileName;
}
}
}

6
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -90,6 +90,12 @@ @@ -90,6 +90,12 @@
<Compile Include="ExceptionHandling.cs" />
<Compile Include="Helpers\CodeAssert.cs" />
<Compile Include="Helpers\RemoveCompilerAttribute.cs" />
<Compile Include="Helpers\Tester.cs" />
<Compile Include="TestCases\HelloWorld.cs" />
<Compile Include="TestRunner.cs" />
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

13
ICSharpCode.Decompiler/Tests/TestCases/HelloWorld.cs

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
using System;
namespace HelloWorld
{
class HelloWorld
{
public static int Main(string[] args)
{
Console.WriteLine("Hello World!");
return 0;
}
}
}

228
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -1,32 +1,10 @@ @@ -1,32 +1,10 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.CodeDom.Compiler;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using DiffLib;
using ICSharpCode.Decompiler.Ast;
using System.Threading.Tasks;
using ICSharpCode.Decompiler.Tests.Helpers;
using Microsoft.CSharp;
using Mono.Cecil;
using NUnit.Framework;
namespace ICSharpCode.Decompiler.Tests
@ -34,187 +12,55 @@ namespace ICSharpCode.Decompiler.Tests @@ -34,187 +12,55 @@ namespace ICSharpCode.Decompiler.Tests
[TestFixture]
public class TestRunner
{
[Test]
public void Async()
{
TestFile(@"..\..\Tests\Async.cs");
}
[Test, Ignore("disambiguating overloads is not yet implemented")]
public void CallOverloadedMethod()
{
TestFile(@"..\..\Tests\CallOverloadedMethod.cs");
}
[Test, Ignore("unncessary primitive casts")]
public void CheckedUnchecked()
{
TestFile(@"..\..\Tests\CheckedUnchecked.cs");
}
[Test, Ignore("Missing cast on null")]
public void DelegateConstruction()
{
TestFile(@"..\..\Tests\DelegateConstruction.cs");
}
[Test, Ignore("Not yet implemented")]
public void ExpressionTrees()
{
TestFile(@"..\..\Tests\ExpressionTrees.cs");
}
[Test]
public void ExceptionHandling()
{
TestFile(@"..\..\Tests\ExceptionHandling.cs", optimize: false);
}
[Test]
public void Generics()
{
TestFile(@"..\..\Tests\Generics.cs");
}
[Test]
public void CustomShortCircuitOperators()
{
TestFile(@"..\..\Tests\CustomShortCircuitOperators.cs");
}
[Test]
public void ControlFlowWithDebug()
{
TestFile(@"..\..\Tests\ControlFlow.cs", optimize: false, useDebug: true);
}
[Test]
public void DoubleConstants()
{
TestFile(@"..\..\Tests\DoubleConstants.cs");
}
[Test]
public void IncrementDecrement()
{
TestFile(@"..\..\Tests\IncrementDecrement.cs");
}
[Test]
public void InitializerTests()
{
TestFile(@"..\..\Tests\InitializerTests.cs");
}
const string TestCasePath = @"..\..\Tests\TestCases";
[Test]
public void LiftedOperators()
public void AllFilesHaveTests()
{
TestFile(@"..\..\Tests\LiftedOperators.cs");
}
[Test]
public void Loops()
{
TestFile(@"..\..\Tests\Loops.cs");
}
[Test]
public void MultidimensionalArray()
{
TestFile(@"..\..\Tests\MultidimensionalArray.cs");
}
[Test]
public void PInvoke()
{
TestFile(@"..\..\Tests\PInvoke.cs");
}
[Test]
public void PropertiesAndEvents()
{
TestFile(@"..\..\Tests\PropertiesAndEvents.cs");
}
[Test]
public void QueryExpressions()
{
TestFile(@"..\..\Tests\QueryExpressions.cs");
}
[Test, Ignore("switch transform doesn't recreate the exact original switch")]
public void Switch()
{
TestFile(@"..\..\Tests\Switch.cs");
}
[Test]
public void UndocumentedExpressions()
{
TestFile(@"..\..\Tests\UndocumentedExpressions.cs");
}
[Test, Ignore("has incorrect casts to IntPtr")]
public void UnsafeCode()
{
TestFile(@"..\..\Tests\UnsafeCode.cs");
}
[Test]
public void ValueTypes()
{
TestFile(@"..\..\Tests\ValueTypes.cs");
}
[Test, Ignore("Redundant yield break; not removed")]
public void YieldReturn()
{
TestFile(@"..\..\Tests\YieldReturn.cs");
var testNames = typeof(TestRunner).GetMethods()
.Where(m => m.GetCustomAttributes(typeof(TestAttribute), false).Any())
.Select(m => m.Name)
.ToArray();
foreach (var file in new DirectoryInfo(TestCasePath).EnumerateFiles()) {
var testName = Path.GetFileNameWithoutExtension(file.Name);
Assert.Contains(testName, testNames);
}
}
[Test]
public void TypeAnalysis()
public void HelloWorld()
{
TestFile(@"..\..\Tests\TypeAnalysisTests.cs");
}
static void TestFile(string fileName, bool useDebug = false)
{
TestFile(fileName, false, useDebug);
TestFile(fileName, true, useDebug);
TestCompileDecompileCompileOutputAll("HelloWorld.cs");
}
static void TestFile(string fileName, bool optimize, bool useDebug = false)
void TestCompileDecompileCompileOutputAll(string testFileName)
{
string code = File.ReadAllText(fileName);
AssemblyDefinition assembly = Compile(code, optimize, useDebug);
AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule));
decompiler.AddAssembly(assembly);
new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree);
StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output));
CodeAssert.AreEqual(code, output.ToString());
TestCompileDecompileCompileOutput(testFileName, optimize: false, useDebug: true);
TestCompileDecompileCompileOutput(testFileName, optimize: false, useDebug: false);
TestCompileDecompileCompileOutput(testFileName, optimize: true, useDebug: true);
TestCompileDecompileCompileOutput(testFileName, optimize: true, useDebug: false);
}
static AssemblyDefinition Compile(string code, bool optimize, bool useDebug)
void TestCompileDecompileCompileOutput(string testFileName, bool optimize = false, bool useDebug = true)
{
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.CompilerOptions = "/unsafe /o" + (optimize ? "+" : "-") + (useDebug ? " /debug": "");
options.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = provider.CompileAssemblyFromSource(options, code);
string outputFile = null, decompiledOutputFile = null;
string output1, output2, error1, error2;
try {
if (results.Errors.Count > 0) {
StringBuilder b = new StringBuilder("Compiler error:");
foreach (var error in results.Errors) {
b.AppendLine(error.ToString());
}
throw new Exception(b.ToString());
}
return AssemblyDefinition.ReadAssembly(results.PathToAssembly);
outputFile = Tester.CompileCSharp(Path.Combine(TestCasePath, "HelloWorld.cs"), optimize, useDebug);
string decompiledCodeFile = Tester.DecompileCSharp(outputFile);
decompiledOutputFile = Tester.CompileCSharp(decompiledCodeFile, optimize, useDebug);
int result1 = Tester.Run(outputFile, out output1, out error1);
int result2 = Tester.Run(decompiledOutputFile, out output2, out error2);
Assert.AreEqual(result1, result2);
Assert.AreEqual(output1, output2);
Assert.AreEqual(error1, error2);
} finally {
File.Delete(results.PathToAssembly);
results.TempFiles.Delete();
if (outputFile != null)
File.Delete(outputFile);
if (decompiledOutputFile != null)
File.Delete(decompiledOutputFile);
}
}
}

5
ILSpy.sln

@ -34,6 +34,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.CSha @@ -34,6 +34,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.CSha
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.Cecil", "NRefactory\ICSharpCode.NRefactory.Cecil\ICSharpCode.NRefactory.Cecil.csproj", "{2B8F4F83-C2B3-4E84-A27B-8DEE1BE0E006}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7BB4F277-CB4E-432D-B503-841CE1918294}"
ProjectSection(SolutionItems) = preProject
Rebracer.xml = Rebracer.xml
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

84
Rebracer.xml

@ -0,0 +1,84 @@ @@ -0,0 +1,84 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!--Rebracer Solution Settings File-->
<!--This file contains Visual Studio settings for ILSpy.sln.-->
<!--Rebracer uses this file to apply settings for this solution-->
<!--when the solution is opened.-->
<!--Install Rebracer from http://visualstudiogallery.msdn.microsoft.com/410e9b9f-65f3-4495-b68e-15567e543c58 -->
<!--See https://github.com/SLaks/Rebracer for more information-->
<UserSettings>
<ToolsOptions>
<ToolsOptionsCategory name="Environment">
<ToolsOptionsSubCategory name="TaskList">
<PropertyValue name="CommentTokens" ArrayType="VT_VARIANT" ArrayElementCount="4">
<PropertyValue name="0">TODO:2</PropertyValue>
<PropertyValue name="1">HACK:2</PropertyValue>
<PropertyValue name="2">UNDONE:2</PropertyValue>
<PropertyValue name="3">UnresolvedMergeConflict:3</PropertyValue>
</PropertyValue>
<PropertyValue name="ConfirmTaskDeletion">true</PropertyValue>
<PropertyValue name="DontShowFilePaths">true</PropertyValue>
<PropertyValue name="WarnOnAddingHiddenItem">false</PropertyValue>
</ToolsOptionsSubCategory>
</ToolsOptionsCategory>
<ToolsOptionsCategory name="TextEditor">
<ToolsOptionsSubCategory name="CSharp-Specific">
<PropertyValue name="AutoComment">1</PropertyValue>
<PropertyValue name="BringUpOnIdentifier">1</PropertyValue>
<PropertyValue name="Formatting_TriggerOnBlockCompletion">1</PropertyValue>
<PropertyValue name="Formatting_TriggerOnPaste">1</PropertyValue>
<PropertyValue name="Formatting_TriggerOnStatementCompletion">1</PropertyValue>
<PropertyValue name="Indent_BlockContents">1</PropertyValue>
<PropertyValue name="Indent_Braces">0</PropertyValue>
<PropertyValue name="Indent_CaseContents">1</PropertyValue>
<PropertyValue name="Indent_CaseLabels">0</PropertyValue>
<PropertyValue name="Indent_FlushLabelsLeft">0</PropertyValue>
<PropertyValue name="Indent_UnindentLabels">2</PropertyValue>
<PropertyValue name="InsertNewlineOnEnterWithWholeWord">0</PropertyValue>
<PropertyValue name="NewLines_AnonymousTypeInitializer_EachMember">1</PropertyValue>
<PropertyValue name="NewLines_Braces_AnonymousMethod">0</PropertyValue>
<PropertyValue name="NewLines_Braces_AnonymousTypeInitializer">0</PropertyValue>
<PropertyValue name="NewLines_Braces_CollectionInitializer">0</PropertyValue>
<PropertyValue name="NewLines_Braces_ControlFlow">0</PropertyValue>
<PropertyValue name="NewLines_Braces_LambdaExpressionBody">0</PropertyValue>
<PropertyValue name="NewLines_Braces_Method">1</PropertyValue>
<PropertyValue name="NewLines_Braces_ObjectInitializer">1</PropertyValue>
<PropertyValue name="NewLines_Braces_Type">1</PropertyValue>
<PropertyValue name="NewLines_Keywords_Catch">0</PropertyValue>
<PropertyValue name="NewLines_Keywords_Else">0</PropertyValue>
<PropertyValue name="NewLines_Keywords_Finally">0</PropertyValue>
<PropertyValue name="NewLines_ObjectInitializer_EachMember">1</PropertyValue>
<PropertyValue name="NewLines_QueryExpression_EachClause">1</PropertyValue>
<PropertyValue name="ShowKeywords">1</PropertyValue>
<PropertyValue name="ShowSnippets">1</PropertyValue>
<PropertyValue name="SortUsings_PlaceSystemFirst">1</PropertyValue>
<PropertyValue name="Space_AfterBasesColon">1</PropertyValue>
<PropertyValue name="Space_AfterCast">0</PropertyValue>
<PropertyValue name="Space_AfterComma">1</PropertyValue>
<PropertyValue name="Space_AfterDot">0</PropertyValue>
<PropertyValue name="Space_AfterMethodCallName">0</PropertyValue>
<PropertyValue name="Space_AfterMethodDeclarationName">0</PropertyValue>
<PropertyValue name="Space_AfterSemicolonsInForStatement">1</PropertyValue>
<PropertyValue name="Space_AroundBinaryOperator">1</PropertyValue>
<PropertyValue name="Space_BeforeBasesColon">1</PropertyValue>
<PropertyValue name="Space_BeforeComma">0</PropertyValue>
<PropertyValue name="Space_BeforeDot">0</PropertyValue>
<PropertyValue name="Space_BeforeOpenSquare">0</PropertyValue>
<PropertyValue name="Space_BeforeSemicolonsInForStatement">0</PropertyValue>
<PropertyValue name="Space_BetweenEmptyMethodCallParentheses">0</PropertyValue>
<PropertyValue name="Space_BetweenEmptyMethodDeclarationParentheses">0</PropertyValue>
<PropertyValue name="Space_BetweenEmptySquares">0</PropertyValue>
<PropertyValue name="Space_InControlFlowConstruct">1</PropertyValue>
<PropertyValue name="Space_WithinCastParentheses">0</PropertyValue>
<PropertyValue name="Space_WithinExpressionParentheses">0</PropertyValue>
<PropertyValue name="Space_WithinMethodCallParentheses">0</PropertyValue>
<PropertyValue name="Space_WithinMethodDeclarationParentheses">0</PropertyValue>
<PropertyValue name="Space_WithinOtherParentheses">0</PropertyValue>
<PropertyValue name="Space_WithinSquares">0</PropertyValue>
<PropertyValue name="Wrapping_IgnoreSpacesAroundBinaryOperators">0</PropertyValue>
<PropertyValue name="Wrapping_IgnoreSpacesAroundVariableDeclaration">0</PropertyValue>
<PropertyValue name="Wrapping_KeepStatementsOnSingleLine">1</PropertyValue>
<PropertyValue name="Wrapping_PreserveSingleLine">1</PropertyValue>
</ToolsOptionsSubCategory>
</ToolsOptionsCategory>
</ToolsOptions>
</UserSettings>
Loading…
Cancel
Save