Permalink
Browse files

Fix bugs & add source locations in xml reports

  • Loading branch information...
1 parent c381b1f commit 4fbc1a81d86641e2fc460fedeeb6f22c92d19dbf @alexvictoor alexvictoor committed Feb 11, 2013
@@ -37,6 +37,10 @@
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
+ <Reference Include="Gendarme.Framework, Version=2.11.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\packages\Mono.Gendarme.2.11.0.20121120\tools\Gendarme.Framework.dll</HintPath>
+ </Reference>
<Reference Include="Mono.Cecil">
<HintPath>..\packages\Mono.Cecil.0.9.5.4\lib\net40\Mono.Cecil.dll</HintPath>
</Reference>
@@ -55,7 +59,7 @@
<Compile Include="DependencyParserTest.cs" />
<Compile Include="DethOfInheritanceTreeAnalyzerTest.cs" />
<Compile Include="Lcom4AnalyzerTest.cs" />
- <Compile Include="DesignMeasuresWriterTest.cs" />
+ <Compile Include="DesignMeasuresTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResponseForClassAnalyzerTest.cs" />
</ItemGroup>
@@ -69,6 +73,9 @@
<Content Include="testdata\Example.Core.pdb">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
+ <Content Include="testdata\external\Spring.Core.dll">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
<Content Include="testdata\test.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<SubType>Designer</SubType>
@@ -14,7 +14,9 @@ public class DependencyParserTest {
public void Should_Create_An_XML_Report()
{
File.Delete("test.xml");
- Program.Main(new string[] { "-a=testdata/Example.Core.dll", "-o=test.xml" });
+ string assemblyPath = @"C:\work\temp\springdotnet\trunk\build\VS.Net.2010\Spring.Core\Debug\Spring.Core.dll";
+ //Program.Main(new string[] { "-a=testdata/Example.Core.dll", "-o=test.xml" });
+ Program.Main(new string[] { "-a="+assemblyPath, "-o=test-spring.xml" });
string expected = File.ReadAllText("testdata/test.xml");
string result = File.ReadAllText("test.xml");
@@ -11,7 +11,7 @@
namespace DependencyParser.Test {
[NUnit.Framework.TestFixture]
- public class DesignMeasuresWriterTest {
+ public class DesignMeasuresTest {
[Test]
public void Should_Generate()
{
@@ -21,7 +21,7 @@ public void Should_Generate()
using (var writer = new XmlTextWriter(stream, Encoding.UTF8))
{
writer.Formatting = Formatting.Indented;
- var designWriter = new DesignMeasuresWriter();
+ var designWriter = new DesignMeasures();
var typeDefinition = getType("DependencyParser.Test.SimpleClassWithTwoFields");
var blocks = new HashSet<HashSet<MemberReference>>();
@@ -30,13 +30,12 @@ public void Should_Generate()
var block = new HashSet<MemberReference> { mth, typeDefinition.Fields.First() };
blocks.Add(block);
}
- designWriter.Xml = writer;
designWriter.Type = typeDefinition;
designWriter.Lcom4Blocks = blocks;
designWriter.ResponseForClass = 42;
designWriter.DethOfInheritance = 17;
- designWriter.Write();
+ designWriter.Write(writer);
}
}
string expected = File.ReadAllText("lcom4-expected.xml");
@@ -1,8 +1,11 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
+using System.Threading;
+using Gendarme.Framework;
using Mono.Cecil;
using NUnit.Framework;
@@ -20,6 +23,14 @@ public void Should_Find_One_Block_On_A_Simple_Class()
}
[Test]
+ public void Should_Find_Two_Blocks_On_A_Simple_Stateless_Class()
+ {
+ var analyzer = new Lcom4Analyzer();
+ var blocks = analyzer.FindLcomBlocks(GetType("DependencyParser.Test.SimpleCalculator"));
+ Assert.AreEqual(2, blocks.Count);
+ }
+
+ [Test]
public void Should_Find_One_Block_On_A_Class_With_Strong_Cohesion()
{
var analyzer = new Lcom4Analyzer();
@@ -69,6 +80,22 @@ public void Should_Take_In_Account_Calls_To_Abstract_Methods()
}
[Test]
+ public void Should_Ignore_Empty_Methods()
+ {
+ var analyzer = new Lcom4Analyzer();
+ var blocks = analyzer.FindLcomBlocks(GetType("DependencyParser.Test.ClassWithEmptyMethods"));
+ Assert.AreEqual(0, blocks.Count);
+ }
+
+ [Test]
+ public void Should_Take_In_Account_Calls_Ignore_Empty_Methods()
+ {
+ var analyzer = new Lcom4Analyzer();
+ var blocks = analyzer.FindLcomBlocks(GetType("DependencyParser.Test.ClassWithCallsToEmptyMethods"));
+ Assert.AreEqual(1, blocks.Count);
+ }
+
+ [Test]
public void Should_Ignore_Constructors()
{
var analyzer = new Lcom4Analyzer();
@@ -142,6 +169,28 @@ public void Should_Not_Take_In_Account_Static_Methods()
Assert.AreEqual(1, blocks.Count);
}
+ [Test]
+ public void Should_Take_In_Account_Field_References()
+ {
+ var definition = AssemblyDefinition.ReadAssembly(@"testdata\external\Spring.Core.dll", new ReaderParameters { AssemblyResolver = AssemblyResolver.Resolver });
+
+ var clientType = definition.MainModule.GetType("Spring.Collections.Generic", "ReadOnlyDictionary`2");
+ var analyzer = new Lcom4Analyzer();
+ var blocks = analyzer.FindLcomBlocks(clientType);
+ Assert.AreEqual(12, blocks.Count);
+ }
+
+ [Test]
+ public void Should_Ignore_Empty_Virtual_Methods()
+ {
+ var definition = AssemblyDefinition.ReadAssembly(@"testdata\external\Spring.Core.dll", new ReaderParameters { AssemblyResolver = AssemblyResolver.Resolver });
+
+ var clientType = definition.MainModule.GetType("Spring.Expressions.Parser.antlr.debug", "ParserListenerBase");
+ var analyzer = new Lcom4Analyzer();
+ var blocks = analyzer.FindLcomBlocks(clientType);
+ Assert.AreEqual(0, blocks.Count);
+ }
+
private TypeDefinition GetType(string name)
{
string unit = Assembly.GetExecutingAssembly().Location;
@@ -175,6 +224,19 @@ public void Decrement()
}
}
+ public class SimpleCalculator {
+
+ public int Add(int x, int y)
+ {
+ return x + y;
+ }
+
+ public int Sub(int x, int y)
+ {
+ return x - y;
+ }
+ }
+
public class SimpleClassWithCtr {
private int fieldA;
@@ -312,6 +374,38 @@ public void DoB()
}
+ public class ClassWithEmptyMethods {
+
+ public void Foo()
+ {
+ }
+
+ public void Bar()
+ {
+ }
+
+ public virtual void VirBar()
+ {
+ }
+ }
+
+ public class ClassWithCallsToEmptyMethods {
+
+ public void Foo()
+ {
+ VirBar();
+ }
+
+ public void Bar()
+ {
+ VirBar();
+ }
+
+ public virtual void VirBar()
+ {
+ }
+ }
+
public class SimpleDisposableClass : IDisposable
{
public void DoSomething()
@@ -441,4 +535,28 @@ public static SimpleClassWithStaticMethod create()
return new SimpleClassWithStaticMethod();
}
}
+
+ public abstract class ClassWithExternalCalls {
+ /// <summary>
+ /// Inner storage for ReadOnlyDictionary
+ /// </summary>
+ private readonly Thread _thread;
+
+ public ClassWithExternalCalls(Thread thread)
+ {
+ thread = _thread;
+ }
+
+
+ public void Stop()
+ {
+ _thread.Abort();
+ }
+
+ public void Start()
+ {
+ _thread.Start();
+ }
+
+ }
}
@@ -1,4 +1,4 @@
-<type fullName="DependencyParser.Test.SimpleClassWithTwoFields" rfc="42" dit="17">
+<type fullName="DependencyParser.Test.SimpleClassWithTwoFields" source="" rfc="42" dit="17">
<block>
<element type="Field" name="fieldA" />
<element type="Method" name="System.Void doA()" />
Binary file not shown.
@@ -25,10 +25,7 @@
<From fullname="Example.Core.SampleMeasure" />
</TypeReferences>
<Design>
- <type fullName="&lt;Module&gt;" rfc="0" dit="0" />
- <type fullName="Example.Core.IMoney" rfc="0" dit="0" />
- <type fullName="Example.Core.Model.SubType" rfc="1" dit="1" />
- <type fullName="Example.Core.Money" rfc="24" dit="1">
+ <type fullName="Example.Core.Money" source="c:\work\sonar-cs\dotnet\tools\dotnet-tools-commons\src\test\resources\solution\Example\Example.Core\Money.cs" rfc="24" dit="1">
<block>
<element type="Field" name="fAmount" />
<element type="Field" name="fCurrency" />
@@ -47,8 +44,7 @@
<element type="Method" name="Example.Core.IMoney Subtract(Example.Core.IMoney)" />
</block>
</type>
- <type fullName="Example.Core.Alex" rfc="3" dit="1" />
- <type fullName="Example.Core.MoneyBag" rfc="44" dit="1">
+ <type fullName="Example.Core.MoneyBag" source="c:\work\sonar-cs\dotnet\tools\dotnet-tools-commons\src\test\resources\solution\Example\Example.Core\MoneyBag.cs" rfc="44" dit="1">
<block>
<element type="Field" name="fMonies" />
<element type="Method" name="Example.Core.IMoney AddMoney(Example.Core.Money)" />
@@ -67,7 +63,7 @@
<element type="Method" name="Example.Core.IMoney Subtract(Example.Core.IMoney)" />
</block>
</type>
- <type fullName="Example.Core.SampleMeasure" rfc="14" dit="1">
+ <type fullName="Example.Core.SampleMeasure" source="c:\work\sonar-cs\dotnet\tools\dotnet-tools-commons\src\test\resources\solution\Example\Example.Core\SampleMeasure.cs" rfc="14" dit="1">
<block>
<element type="Field" name="Size (property)" />
<element type="Field" name="actual" />
@@ -78,6 +74,9 @@
<element type="Method" name="System.String Compute(System.Int32)" />
</block>
</type>
+ <type fullName="&lt;Module&gt;" source="" rfc="0" dit="0" />
+ <type fullName="Example.Core.IMoney" source="" rfc="0" dit="0" />
+ <type fullName="Example.Core.Model.SubType" source="" rfc="1" dit="1" />
</Design>
</Assembly>
</Dependencies>
@@ -80,10 +80,12 @@
<ItemGroup>
<Compile Include="DethOfInheritanceTreeAnalyzer.cs" />
<Compile Include="Lcom4Analyzer.cs" />
- <Compile Include="DesignMeasuresWriter.cs" />
+ <Compile Include="DesignMeasures.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResponseForClassAnalyzer.cs" />
+ <Compile Include="SourceHelper.cs" />
+ <Compile Include="SourceRegistry.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
@@ -11,12 +11,10 @@ namespace DependencyParser {
/// <summary>
/// TODO: Update summary.
/// </summary>
- public class DesignMeasuresWriter {
+ public class DesignMeasures {
private static readonly ReferenceComparer comparer = new ReferenceComparer();
- public XmlTextWriter Xml { set; private get; }
-
public TypeDefinition Type { set; private get; }
public int ResponseForClass { set; private get; }
@@ -25,20 +23,32 @@ public class DesignMeasuresWriter {
public IEnumerable<IEnumerable<MemberReference>> Lcom4Blocks { set; private get; }
- public void Write()
+
+ public DesignMeasures Merge(DesignMeasures measures)
+ {
+ return new DesignMeasures() {
+ Type = Type,
+ ResponseForClass = Math.Max(ResponseForClass, measures.ResponseForClass),
+ DethOfInheritance = Math.Max(DethOfInheritance, measures.DethOfInheritance),
+ Lcom4Blocks = Lcom4Blocks.Union(measures.Lcom4Blocks)
+ };
+ }
+
+ public void Write(XmlTextWriter xml)
{
- Xml.WriteStartElement("type");
- Xml.WriteAttributeString("fullName", Type.FullName);
- Xml.WriteAttributeString("rfc", ResponseForClass.ToString());
- Xml.WriteAttributeString("dit", DethOfInheritance.ToString());
+ xml.WriteStartElement("type");
+ xml.WriteAttributeString("fullName", Type.FullName);
+ xml.WriteAttributeString("source", Type.GetSourcePath());
+ xml.WriteAttributeString("rfc", ResponseForClass.ToString());
+ xml.WriteAttributeString("dit", DethOfInheritance.ToString());
foreach (var block in Lcom4Blocks)
{
var orderedBlock = block.OrderBy(x => x, comparer);
- Xml.WriteStartElement("block");
+ xml.WriteStartElement("block");
foreach (var memberReference in orderedBlock)
{
- Xml.WriteStartElement("element");
+ xml.WriteStartElement("element");
var method = memberReference as MethodDefinition;
string name;
string elementType;
@@ -51,13 +61,13 @@ public void Write()
elementType = "Method";
name = BuildSignature(method);
}
- Xml.WriteAttributeString("type", elementType);
- Xml.WriteAttributeString("name", name);
- Xml.WriteEndElement();
+ xml.WriteAttributeString("type", elementType);
+ xml.WriteAttributeString("name", name);
+ xml.WriteEndElement();
}
- Xml.WriteEndElement();
+ xml.WriteEndElement();
}
- Xml.WriteEndElement();
+ xml.WriteEndElement();
}
private string BuildFieldName(FieldDefinition field)
Oops, something went wrong.

0 comments on commit 4fbc1a8

Please sign in to comment.