Permalink
Browse files

Merge pull request #10 from alexvictoor/master

Architecture rules engine & LCOM4 bug fixes
  • Loading branch information...
2 parents f25360d + 6ab5996 commit 0edc42acb33c0428b13c97df16b6d3ee691896b2 @grozeille committed Feb 20, 2013
Showing with 1,187 additions and 315 deletions.
  1. +77 −0 DependencyParser.Test/ArchitectureRuleEngineTest.cs
  2. +20 −0 DependencyParser.Test/CecilHelper.cs
  3. +104 −0 DependencyParser.Test/DependencyAnalyzerTest.cs
  4. +15 −1 DependencyParser.Test/DependencyParser.Test.csproj
  5. +1 −3 DependencyParser.Test/DependencyParserTest.cs
  6. +97 −0 DependencyParser.Test/DesignMeasuresTest.cs
  7. +0 −71 DependencyParser.Test/DesignMeasuresWriterTest.cs
  8. +1 −9 DependencyParser.Test/DethOfInheritanceTreeAnalyzerTest.cs
  9. +185 −20 DependencyParser.Test/Lcom4AnalyzerTest.cs
  10. +3 −12 DependencyParser.Test/ResponseForClassAnalyzerTest.cs
  11. +42 −0 DependencyParser.Test/WildcardPatternMatcherTest.cs
  12. +1 −1 DependencyParser.Test/lcom4-expected.xml
  13. BIN DependencyParser.Test/testdata/external/Spring.Core.dll
  14. +8 −15 DependencyParser.Test/testdata/test.xml
  15. +1 −0 DependencyParser.Test/types-merged-expected.xml
  16. +25 −0 DependencyParser/ArchitectureRule.cs
  17. +57 −0 DependencyParser/ArchitectureRuleEngine.cs
  18. +33 −0 DependencyParser/ArchitectureViolation.cs
  19. +135 −0 DependencyParser/DependencyAnalyzer.cs
  20. +8 −1 DependencyParser/DependencyParser.csproj
  21. +51 −15 DependencyParser/{DesignMeasuresWriter.cs → DesignMeasures.cs}
  22. +40 −3 DependencyParser/Lcom4Analyzer.cs
  23. +117 −163 DependencyParser/Program.cs
  24. +1 −1 DependencyParser/ResponseForClassAnalyzer.cs
  25. +57 −0 DependencyParser/SourceHelper.cs
  26. +58 −0 DependencyParser/SourceRegistry.cs
  27. +48 −0 DependencyParser/WildcardPatternMatcher.cs
  28. +2 −0 pom.xml
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Mono.Cecil;
+using NUnit.Framework;
+
+namespace DependencyParser.Test {
+
+
+ [NUnit.Framework.TestFixture]
+ public class ArchitectureRuleEngineTest {
+
+ private ArchitectureRuleEngine engine;
+
+
+ [SetUp]
+ public void SetUp()
+ {
+ engine = new ArchitectureRuleEngine() {};
+ }
+
+ [Test]
+ public void Should_Find_Forbidden_Dependencies()
+ {
+ engine.Init("*:DependencyParser.*");
+ var dependencies = new TypeReference[] { typeof(Foo).GetCecilType() };
+ var result =
+ engine.FindArchitectureViolation(typeof(Bar).GetCecilType(), dependencies);
+ Assert.AreEqual(1, result.Count());
+ Assert.AreEqual("DependencyParser.Test.Foo", result.First().Dependency.FullName);
+ }
+
+ [Test]
+ public void Should_Not_Used_Unrelated_Rules_For_Source_Types()
+ {
+ engine.Init("Xyz.*:DependencyParser.*");
+ var dependencies = new TypeReference[] { typeof(Foo).GetCecilType() };
+ var result =
+ engine.FindArchitectureViolation(typeof(Bar).GetCecilType(), dependencies);
+ Assert.AreEqual(0, result.Count());
+ }
+
+ [Test]
+ public void Should_Not_Used_Unrelated_Rules_For_Destination_Types()
+ {
+ engine.Init("DependencyParser.*:xyz.*");
+ var dependencies = new TypeReference[] { typeof(Foo).GetCecilType() };
+ var result =
+ engine.FindArchitectureViolation(typeof(Bar).GetCecilType(), dependencies);
+ Assert.AreEqual(0, result.Count());
+ }
+
+ [Test]
+ public void Should_Not_Report_Twice_The_Same_Forbidden_Dependency()
+ {
+ engine.Init("*:DependencyParser.*,*:DependencyParser.Test.*");
+ var dependencies = new TypeReference[] { typeof(Foo).GetCecilType() };
+ var result =
+ engine.FindArchitectureViolation(typeof(Bar).GetCecilType(), dependencies);
+ Assert.AreEqual(1, result.Count());
+ Assert.AreEqual("DependencyParser.Test.Foo", result.First().Dependency.FullName);
+ }
+
+ }
+
+ public class Foo
+ {
+
+ }
+
+ public class Bar {
+
+ }
+
+}
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Mono.Cecil;
+
+namespace DependencyParser.Test {
+
+ public static class CecilHelper {
+
+ public static TypeDefinition GetCecilType(this Type t)
+ {
+ string name = t.FullName;
+ string unit = Assembly.GetExecutingAssembly().Location;
+ var assembly = AssemblyDefinition.ReadAssembly(unit);
+ return assembly.MainModule.GetType(name);
+ }
+ }
+}
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using Mono.Cecil;
+using NUnit.Framework;
+
+namespace DependencyParser.Test {
+
+
+ [NUnit.Framework.TestFixture]
+ public class DependencyAnalyzerTest {
+
+ private DependencyAnalyzer analyzer;
+
+
+ [SetUp]
+ public void SetUp()
+ {
+ analyzer = new DependencyAnalyzer();
+ }
+
+ [Test]
+ public void Should_Find_Dependencies_From_Attributes()
+ {
+ var dependencies = analyzer.FindTypeDependencies(this.GetType().GetCecilType());
+ Assert.AreEqual(1, dependencies.Count(n => n.FullName == typeof(TestAttribute).FullName));
+ }
+
+ [Test]
+ public void Should_Find_Dependencies_From_Fields()
+ {
+ var dependencies = analyzer.FindTypeDependencies(this.GetType().GetCecilType());
+ Assert.AreEqual(1, dependencies.Count(n => n.FullName == typeof(DependencyAnalyzer).FullName));
+ }
+
+ [Test]
+ public void Should_Find_Dependencies_From_Properties()
+ {
+ var dependencies = analyzer.FindTypeDependencies(typeof(ClassWithProperty).GetCecilType());
+ Assert.IsTrue(dependencies.Contains(typeof(Thread).GetCecilType()));
+ }
+
+ [Test]
+ public void Should_Find_Dependencies_From_Parameters()
+ {
+ var dependencies = analyzer.FindTypeDependencies(typeof(ClassWithCallsOnParameters).GetCecilType());
+ Assert.IsTrue(dependencies.Contains(typeof(Thread).GetCecilType()));
+ }
+
+ [Test]
+ public void Should_Find_Dependencies_From_Array()
+ {
+ var dependencies = analyzer.FindTypeDependencies(typeof(ClassWithArray).GetCecilType());
+ Assert.IsTrue(dependencies.Contains(typeof(Thread).GetCecilType()));
+ }
+
+ [Test]
+ public void Should_Ignore_System_Dependencies()
+ {
+ var dependencies = analyzer.FindTypeDependencies(typeof(ClassWithSystemDependency).GetCecilType());
+ dependencies = analyzer.FilterSystemDependencies(dependencies);
+ Assert.AreEqual(0, dependencies.Count(n => n.FullName.Contains("Dictionary")));
+ }
+ }
+
+ public class ClassWithProperty {
+
+ public Thread MyThread { get; set; }
+ }
+
+ public abstract class ClassWithCallsOnParameters {
+
+ public void Stop(Thread thread)
+ {
+ }
+
+ public void Start(Thread thread)
+ {
+ }
+
+ }
+
+ public abstract class ClassWithArray {
+ public void Stop(Thread[] threads)
+ {
+ }
+ }
+
+ public abstract class ClassWithSystemDependency {
+
+ private IDictionary<string, string> dic = new Dictionary<string, string>();
+
+ public void Stop(Thread[] threads)
+ {
+ }
+ }
+
+ public class Thread
+ {
+
+ }
+}
@@ -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>
@@ -52,12 +56,16 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="ArchitectureRuleEngineTest.cs" />
+ <Compile Include="CecilHelper.cs" />
+ <Compile Include="DependencyAnalyzerTest.cs" />
<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" />
+ <Compile Include="WildcardPatternMatcherTest.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="lcom4-expected.xml">
@@ -69,10 +77,16 @@
<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>
</Content>
+ <Content Include="types-merged-expected.xml">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ </Content>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
@@ -14,13 +14,11 @@ 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" });
+ Program.Main(new string[] { "-a=testdata/Example.Core.dll", "-o=test.xml", "-d=yes" });
string expected = File.ReadAllText("testdata/test.xml");
string result = File.ReadAllText("test.xml");
Assert.AreEqual(expected, result);
-
-
}
}
}
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Xml;
+using Mono.Cecil;
+using NUnit.Framework;
+
+namespace DependencyParser.Test {
+
+ [NUnit.Framework.TestFixture]
+ public class DesignMeasuresTest {
+ [Test]
+ public void Should_Write_Correct_XML()
+ {
+ File.Delete("lcom4-generated.xml");
+ using (var stream = new FileStream("lcom4-generated.xml", FileMode.Create))
+ {
+ using (var writer = new XmlTextWriter(stream, Encoding.UTF8))
+ {
+ writer.Formatting = Formatting.Indented;
+ var measure = new DesignMeasures();
+ var typeDefinition = typeof(SimpleClassWithTwoFields).GetCecilType();
+ var blocks = new HashSet<HashSet<MemberReference>>();
+
+ foreach (var mth in typeDefinition.Methods)
+ {
+ var block = new HashSet<MemberReference> { mth, typeDefinition.Fields.First() };
+ blocks.Add(block);
+ }
+ measure.Type = typeDefinition;
+ measure.Lcom4Blocks = blocks;
+ measure.ResponseForClass = 42;
+ measure.DethOfInheritance = 17;
+
+ measure.Write(writer);
+ }
+ }
+ string expected = File.ReadAllText("lcom4-expected.xml");
+ string result = File.ReadAllText("lcom4-generated.xml");
+
+ Assert.AreEqual(expected, result);
+ }
+
+ [Test]
+ public void Should_Merge_Measures()
+ {
+ File.Delete("types-merged-generated.xml");
+ var measure = new DesignMeasures();
+ var typeDefinition = typeof(SimpleClassWithTwoFields).GetCecilType();
+ measure.Type = typeDefinition;
+ measure.ResponseForClass = 42;
+ measure.DethOfInheritance = 17;
+ measure.Lcom4Blocks = Enumerable.Empty<IEnumerable<MemberReference>>();
+
+ var measure2 = new DesignMeasures();
+ var typeDefinition2 = typeof(DesignMeasuresTest).GetCecilType();
+ measure2.Type = typeDefinition2;
+ measure2.ResponseForClass = 36;
+ measure2.DethOfInheritance = 42;
+ measure2.Lcom4Blocks = Enumerable.Empty<IEnumerable<MemberReference>>();
+
+ var mergedMeasures = measure.Merge(measure2);
+ using (var stream = new FileStream("types-merged-generated.xml", FileMode.Create))
+ {
+ using (var writer = new XmlTextWriter(stream, Encoding.UTF8))
+ {
+ writer.Formatting = Formatting.Indented;
+ mergedMeasures.Write(writer);
+ }
+ }
+
+ string expected = File.ReadAllText("types-merged-expected.xml");
+ string result = File.ReadAllText("types-merged-generated.xml");
+ Assert.AreEqual(expected, result);
+
+ }
+ }
+
+ public class SimpleClassWithTwoFields {
+ private int fieldA;
+
+ private int fieldB;
+
+ public void doA()
+ {
+ fieldA++;
+ }
+
+ public void doB()
+ {
+ fieldB++;
+ }
+ }
+}
Oops, something went wrong.

0 comments on commit 0edc42a

Please sign in to comment.