Browse Source

testing code that helps running independent decompilation tests.

pull/52/head
Artur Zgodziski 15 years ago
parent
commit
d1fff3fdb1
  1. 114
      ICSharpCode.Decompiler/Tests/CodeSampleFileParser.cs
  2. 41
      ICSharpCode.Decompiler/Tests/CustomAttributes.code.cs
  3. 27
      ICSharpCode.Decompiler/Tests/CustomAttributes.cs
  4. 81
      ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeSamples.cs
  5. 23
      ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeTests.cs
  6. 47
      ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributes.cs
  7. 89
      ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs
  8. 16
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  9. 7
      ICSharpCode.Decompiler/Tests/TestRunner.cs
  10. 0
      ICSharpCode.Decompiler/Tests/Types/DelegateConstruction.cs
  11. 0
      ICSharpCode.Decompiler/Tests/Types/PropertiesAndEvents.cs
  12. 29
      ICSharpCode.Decompiler/Tests/Types/TypeTests.cs
  13. 0
      ICSharpCode.Decompiler/Tests/Types/ValueTypes.cs

114
ICSharpCode.Decompiler/Tests/CodeSampleFileParser.cs

@ -0,0 +1,114 @@ @@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ICSharpCode.Decompiler.Tests
{
static class CodeSampleFileParser
{
public static IEnumerable<string> ListSections(string s)
{
var query = from line in ToLines(s)
let sectionName = ReadSectionName(line)
where sectionName != null
select sectionName;
return query;
}
public static string GetSection(string sectionName, string s)
{
var lines = ToLines(s);
bool sectionFound = false;
var sectionText = new StringBuilder();
Action<string> parser = null;
Action<string> commonSectionReader = line =>
{
if (IsCommonSectionEnd(line))
parser = null;
else
sectionText.AppendLine(line);
};
Action<string> namedSectionReader = line =>
{
string name = ReadSectionName(line);
if (name == null)
sectionText.AppendLine(line);
else if (name != sectionName)
parser = null;
};
Action<string> defaultReader = line =>
{
if (IsCommonSectionStart(line))
parser = commonSectionReader;
else if (ReadSectionName(line) == sectionName)
{
parser = namedSectionReader;
sectionFound = true;
}
};
foreach(var line in lines)
{
(parser ?? defaultReader)(line);
}
if (sectionFound)
return sectionText.ToString();
else
return "";
}
public static bool IsCommentOrBlank(string s)
{
if(String.IsNullOrWhiteSpace(s))
return true;
return s.Trim().StartsWith("//");
}
public static string ConcatLines(IEnumerable<string> lines)
{
var buffer = new StringBuilder();
foreach (var line in lines)
{
buffer.AppendLine(line);
}
return buffer.ToString();
}
static string ReadSectionName(string line)
{
line = line.TrimStart();
if (line.StartsWith("//$$"))
return line.Substring(4).Trim();
else
return null;
}
static bool IsCommonSectionStart(string line)
{
return line.Trim() == "//$CS";
}
static bool IsCommonSectionEnd(string line)
{
return line.Trim() == "//$CE";
}
static IEnumerable<string> ToLines(string s)
{
var reader = new StringReader(s);
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
}

41
ICSharpCode.Decompiler/Tests/CustomAttributes.code.cs

@ -0,0 +1,41 @@ @@ -0,0 +1,41 @@
using System;
namespace aa
{
public static class CustomAtributes
{
[Flags]
public enum EnumWithFlag
{
All = 15,
None = 0,
Item1 = 1,
Item2 = 2,
Item3 = 4,
Item4 = 8
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public MyAttribute(CustomAtributes.EnumWithFlag en)
{
}
}
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.Item1 | CustomAtributes.EnumWithFlag.Item2)]
private static int field;
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.All)]
public static string Property
{
get
{
return "aa";
}
}
[Obsolete("some message")]
public static void ObsoletedMethod()
{
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field);
AttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field;
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, attributeTargets);
}
}
}

27
ICSharpCode.Decompiler/Tests/CustomAttributes.cs

@ -1,27 +0,0 @@ @@ -1,27 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
public static class CustomAtributes
{
[Flags]
public enum EnumWithFlag
{
// Item1,
Item2
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
}
[Obsolete("some message")]
public static void ObsoletedMethod()
{
//Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, (AttributeTargets)(AttributeTargets.Property | AttributeTargets.Field));
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field);
AttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field;
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, attributeTargets);
}
}

81
ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeSamples.cs

@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
//$CS
using System;
//$CE
//$$ ParameterlessAttributeUsage
namespace ParameterLessAttributeUsage
{
[Flags]
public enum EnumWithFlagsAttribute
{
None
}
}
//$$ AttributeWithEnumArgument
namespace AttributeWithEnumArgument
{
[AttributeUsage(AttributeTargets.All)]
public class MyAttributeAttribute : Attribute
{
}
}
//$$ AttributeWithEnumExpressionArgument
namespace AttributeWithEnumExpressionArgument
{
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Interface)]
public class MyAttributeAttribute : Attribute
{
}
}
//$$ AttributeWithStringExpressionArgument
namespace AttributeWithStringExpressionArgument
{
[Obsolete("message")]
public class ObsoletedClass
{
}
}
//$$ AttributeAppliedToEvent (ignored)
namespace AttributeAppliedToEvent
{
[AttributeUsage(AttributeTargets.Event)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
[MyAttribute]
public event EventHandler MyEvent;
}
}
//$$ AttributeAppliedToField
namespace AttributeAppliedToField
{
[AttributeUsage(AttributeTargets.Field)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
[MyAttribute]
public int Field;
}
}
//$$ AttributeAppliedToMethod
namespace AttributeAppliedToMethod
{
[AttributeUsage(AttributeTargets.Method)]
public class MyAttributeAttribute : Attribute
{
}
public class TestClass
{
[MyAttribute]
public void Method()
{
}
}
}

23
ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributeTests.cs

@ -0,0 +1,23 @@ @@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MbUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.CustomAttributes
{
public class CustomAttributeTests : DecompilerTestBase
{
[StaticTestFactory]
public static IEnumerable<Test> CustomAttributeSamples()
{
return GenerateSectionTests(@"CustomAttributes\CustomAttributeSamples.cs");
}
[Test]
public void CustomAttributesMultiTest()
{
ValidateFileRoundtrip(@"CustomAttributes\CustomAttributes.cs");
}
}
}

47
ICSharpCode.Decompiler/Tests/CustomAttributes/CustomAttributes.cs

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
namespace aa
{
public static class CustomAtributes
{
[Flags]
public enum EnumWithFlag
{
All = 15,
None = 0,
Item1 = 1,
Item2 = 2,
Item3 = 4,
Item4 = 8
}
[AttributeUsage(AttributeTargets.All)]
public class MyAttribute : Attribute
{
public MyAttribute(CustomAtributes.EnumWithFlag en)
{
}
}
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.Item1 | CustomAtributes.EnumWithFlag.Item2)]
private static int field;
[CustomAtributes.MyAttribute(CustomAtributes.EnumWithFlag.All)]
public static string Property
{
get
{
return "aa";
}
}
[Obsolete("some message")]
public static void ObsoletedMethod()
{
//Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, (AttributeTargets)(AttributeTargets.Property | AttributeTargets.Field));
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, AttributeTargets.Property | AttributeTargets.Field);
AttributeTargets attributeTargets = AttributeTargets.Property | AttributeTargets.Field;
Console.WriteLine("{0} $$$ {1}", AttributeTargets.Interface, attributeTargets);
}
}
}

89
ICSharpCode.Decompiler/Tests/DecompilerTestBase.cs

@ -0,0 +1,89 @@ @@ -0,0 +1,89 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mono.Cecil;
using System.IO;
using Decompiler;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using MbUnit.Framework;
namespace ICSharpCode.Decompiler.Tests
{
public abstract class DecompilerTestBase
{
protected static IEnumerable<Test> GenerateSectionTests(string samplesFileName)
{
string code = File.ReadAllText(Path.Combine(@"..\..\Tests", samplesFileName));
foreach (var sectionName in CodeSampleFileParser.ListSections(code))
{
if (sectionName.EndsWith("(ignored)", StringComparison.OrdinalIgnoreCase))
continue;
var testedSectionName = sectionName;
yield return new TestCase(testedSectionName, () =>
{
var testCode = CodeSampleFileParser.GetSection(testedSectionName, code);
System.Diagnostics.Debug.WriteLine(testCode);
var decompiledTestCode = RoundtripCode(testCode);
Assert.AreEqual(testCode, decompiledTestCode);
});
}
}
protected static void ValidateFileRoundtrip(string samplesFileName)
{
var lines = File.ReadAllLines(Path.Combine(@"..\..\Tests", samplesFileName));
var testCode = RemoveIgnorableLines(lines);
var decompiledTestCode = RoundtripCode(testCode);
Assert.AreEqual(testCode, decompiledTestCode);
}
static string RemoveIgnorableLines(IEnumerable<string> lines)
{
return CodeSampleFileParser.ConcatLines(lines.Where(l => !CodeSampleFileParser.IsCommentOrBlank(l)));
}
/// <summary>
/// Compiles and decompiles a source code.
/// </summary>
/// <param name="code">The source code to copile.</param>
/// <returns>The decompilation result of compiled source code.</returns>
static string RoundtripCode(string code)
{
AssemblyDefinition assembly = Compile(code);
AstBuilder decompiler = new AstBuilder(new DecompilerContext());
decompiler.AddAssembly(assembly);
StringWriter output = new StringWriter();
decompiler.GenerateCode(new PlainTextOutput(output));
return output.ToString();
}
static AssemblyDefinition Compile(string code)
{
CSharpCodeProvider provider = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v4.0" } });
CompilerParameters options = new CompilerParameters();
options.ReferencedAssemblies.Add("System.Core.dll");
CompilerResults results = provider.CompileAssemblyFromSource(options, code);
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);
}
finally
{
File.Delete(results.PathToAssembly);
results.TempFiles.Delete();
}
}
}
}

16
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -56,12 +56,17 @@ @@ -56,12 +56,17 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="DelegateConstruction.cs" />
<Compile Include="CustomAttributes.cs" />
<Compile Include="Loops.cs" />
<Compile Include="PropertiesAndEvents.cs" />
<Compile Include="Types\TypeTests.cs" />
<None Include="Types\DelegateConstruction.cs" />
<None Include="CustomAttributes\CustomAttributes.cs" />
<None Include="Loops.cs" />
<None Include="Types\PropertiesAndEvents.cs" />
<None Include="CustomAttributes\CustomAttributeSamples.cs" />
<Compile Include="CodeSampleFileParser.cs" />
<Compile Include="CustomAttributes\CustomAttributeTests.cs" />
<Compile Include="DecompilerTestBase.cs" />
<Compile Include="TestRunner.cs" />
<Compile Include="ValueTypes.cs" />
<None Include="Types\ValueTypes.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil\Mono.Cecil.csproj">
@ -73,5 +78,6 @@ @@ -73,5 +78,6 @@
<Name>ICSharpCode.Decompiler</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

7
ICSharpCode.Decompiler/Tests/TestRunner.cs

@ -22,10 +22,6 @@ namespace ICSharpCode.Decompiler.Tests @@ -22,10 +22,6 @@ namespace ICSharpCode.Decompiler.Tests
Console.ReadKey();
}
[Test]
//[Row(@"..\..\Tests\DelegateConstruction.cs")]
//[Row(@"..\..\Tests\Loops.cs")]
[Row(@"..\..\Tests\CustomAttributes.cs")]
public void RoundtripFile(string fileName)
{
string code = File.ReadAllText(fileName);
@ -38,6 +34,9 @@ namespace ICSharpCode.Decompiler.Tests @@ -38,6 +34,9 @@ namespace ICSharpCode.Decompiler.Tests
var decompiledCode = output.ToString();
var onlyCode = "using System;" + Environment.NewLine + StripCodeFileHeader(code);
File.WriteAllText(Path.ChangeExtension(fileName, ".decomp.cs"), decompiledCode);
File.WriteAllText(Path.ChangeExtension(fileName, ".code.cs"), onlyCode);
Assert.AreEqual(onlyCode, decompiledCode);
}

0
ICSharpCode.Decompiler/Tests/DelegateConstruction.cs → ICSharpCode.Decompiler/Tests/Types/DelegateConstruction.cs

0
ICSharpCode.Decompiler/Tests/PropertiesAndEvents.cs → ICSharpCode.Decompiler/Tests/Types/PropertiesAndEvents.cs

29
ICSharpCode.Decompiler/Tests/Types/TypeTests.cs

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MbUnit.Framework;
namespace ICSharpCode.Decompiler.Tests.Types
{
public class TypeTests : DecompilerTestBase
{
[Test]
public void ValueTypes()
{
ValidateFileRoundtrip(@"Types\ValueTypes.cs");
}
[Test]
public void PropertiesAndEvents()
{
ValidateFileRoundtrip(@"Types\PropertiesAndEvents.cs");
}
[Test]
public void DelegateConstruction()
{
ValidateFileRoundtrip(@"Types\DelegateConstruction.cs");
}
}
}

0
ICSharpCode.Decompiler/Tests/ValueTypes.cs → ICSharpCode.Decompiler/Tests/Types/ValueTypes.cs

Loading…
Cancel
Save