Skip to content
This repository has been archived by the owner on Oct 16, 2020. It is now read-only.

Commit

Permalink
Test pad refresh when base test class is changed in the editor.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomasz Tretkowski committed Oct 29, 2011
1 parent 017bac7 commit f04440b
Show file tree
Hide file tree
Showing 21 changed files with 238 additions and 62 deletions.
Expand Up @@ -156,7 +156,7 @@ public class When_enumerating_test_members : MSpecTestFrameworkFieldsConcern
static IField otherField;
static IField behavesLikeField;

static IEnumerable<IMember> result;
static IEnumerable<TestMember> result;

const string BehaviorClassName = "Test.Behavior";

Expand All @@ -182,12 +182,12 @@ public class When_enumerating_test_members : MSpecTestFrameworkFieldsConcern
Because of = () => result = sut.GetTestMembersFor(testClass);

It should_contain_field_with_it_return_type = () =>
result.ShouldContain(testSpecification);
result.Select(m => m.Member).ShouldContain(testSpecification);

It should_not_contain_field_with_arbitrary_return_type = () =>
result.ShouldNotContain(otherField);
result.Select(m => m.Member).ShouldNotContain(otherField);

It should_contain_imported_field_from_behavior = () =>
result.ShouldContain(member => member.FullyQualifiedName == "TestClass.testSpecificationInBehavior");
result.Select(m => m.Member).ShouldContain(member => member.FullyQualifiedName == "TestClass.testSpecificationInBehavior");
}
}
Expand Up @@ -58,6 +58,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Configuration\AssemblyInfo.cs" />
<Compile Include="src\BehaviorImportedTestMember.cs" />
<Compile Include="src\ClassFilterBuilder.cs" />
<Compile Include="src\MSpecApplication.cs" />
<Compile Include="src\MSpecTestDebugger.cs" />
Expand Down
@@ -0,0 +1,25 @@
/*
* Created by SharpDevelop.
* User: trecio
* Date: 2011-10-24
* Time: 23:11
*
* To change this template use Tools | Options | Coding | Edit Standard Headers.
*/
using System;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.UnitTesting;

namespace ICSharpCode.MachineSpecifications
{
/// <summary>
/// Description of BehaviorImportedClass.
/// </summary>
public class BehaviorImportedTestMember : BaseTestMember
{
public BehaviorImportedTestMember(IClass testClass, IMember behaviorMember)
: base(testClass, behaviorMember, behaviorMember.Name)
{
}
}
}
Expand Up @@ -30,20 +30,21 @@ public class MSpecTestFramework : ITestFramework
return HasSpecificationMembers(c) && !HasBehaviorAttribute(c);
}

public IEnumerable<IMember> GetTestMembersFor(IClass @class) {
public IEnumerable<TestMember> GetTestMembersFor(IClass @class) {
return GetTestMembers(@class, @class.Fields);
}

private IEnumerable<IMember> GetTestMembers(IClass testClass, IList<IField> fields)
private IEnumerable<TestMember> GetTestMembers(IClass testClass, IList<IField> fields)
{
var result = fields.Where(HasItReturnType).Cast<IMember>().ToList();
var result = fields.Where(HasItReturnType).Select(field => new TestMember(field)).ToList();
foreach (var field in fields)
if (HasBehavesLikeReturnType(field))
{
var behaviorFields = ResolveBehaviorFieldsOf(field);
var behaviorTestMembers = GetTestMembers(testClass, behaviorFields);
var decoratedTestMembers = behaviorTestMembers.Select(f => new BaseTestMember(testClass, f)).Cast<IMember>();
result.AddRange(decoratedTestMembers);
var behaviorMembers = GetTestMembers(testClass, behaviorFields);
var testMembersFromBehavior = behaviorMembers.Select(member =>
new TestMember(member.DeclaringType, new BehaviorImportedTestMember(testClass, member.Member)));
result.AddRange(testMembersFromBehavior);
}
return result;
}
Expand Down
9 changes: 7 additions & 2 deletions src/AddIns/Analysis/UnitTesting/Src/BaseTestMember.cs
Expand Up @@ -27,7 +27,12 @@ public class BaseTestMember : AbstractMember
/// the class where the method is actually defined.</param>
/// <param name="method">The base class's test member.</param>
public BaseTestMember(IClass derivedClass, IMember member)
: base(derivedClass, member.Name)
: this(derivedClass, member, member.DeclaringType.Name + "." + member.Name)
{
}

protected BaseTestMember(IClass derivedClass, IMember member, string name)
: base(derivedClass, name)
{
this.member = member;
this.ReturnType = member.ReturnType;
Expand Down Expand Up @@ -57,7 +62,7 @@ public BaseTestMember(IClass derivedClass, IMember member)
}

public override string Documentation {get;set;}

public override IMember Clone()
{
return new BaseTestMember(DeclaringType, Member);
Expand Down
Expand Up @@ -18,7 +18,7 @@ public interface IRegisteredTestFrameworks
bool IsTestClass(IClass c);
bool IsTestProject(IProject project);

IEnumerable<IMember> GetTestMembersFor(IClass @class);
IEnumerable<TestMember> GetTestMembersFor(IClass @class);

bool IsBuildNeededBeforeTestRunForProject(IProject project);
}
Expand Down
4 changes: 2 additions & 2 deletions src/AddIns/Analysis/UnitTesting/Src/NUnitTestFramework.cs
Expand Up @@ -86,8 +86,8 @@ public bool IsTestMember(IMember member)
return false;
}

public IEnumerable<IMember> GetTestMembersFor(IClass @class) {
return @class.Methods.Where(IsTestMethod);
public IEnumerable<TestMember> GetTestMembersFor(IClass @class) {
return @class.Methods.Where(IsTestMethod).Select(member => new TestMember(member));
}

static bool IsTestMethod(IMethod method)
Expand Down
Expand Up @@ -39,11 +39,11 @@ public bool IsTestMember(IMember member)
return false;
}

public IEnumerable<IMember> GetTestMembersFor(IClass @class) {
public IEnumerable<TestMember> GetTestMembersFor(IClass @class) {
ITestFramework testFramework = GetTestFramework(@class);
if (testFramework != null)
return testFramework.GetTestMembersFor(@class);
return new IMember[0];
return new TestMember[0];
}

ITestFramework GetTestFramework(IMember member)
Expand Down
33 changes: 25 additions & 8 deletions src/AddIns/Analysis/UnitTesting/Src/TestClass.cs
Expand Up @@ -2,6 +2,7 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)

using System;
using System.Linq;
using System.Collections.Generic;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
Expand Down Expand Up @@ -35,6 +36,11 @@ public TestClass(IClass c, IRegisteredTestFrameworks testFrameworks)
public IClass Class {
get { return c; }
}

/// <summary>
/// Gets the list of other (e.g. base types) classes where from which test members included in this test class come from.
/// </summary>
private readonly ICollection<string> baseClassesFQNames = new List<string>();

/// <summary>
/// Gets the test classes that exist in the specified namespace.
Expand Down Expand Up @@ -282,18 +288,19 @@ TestMemberCollection GetTestMembers(IClass c)
TestMemberCollection testMembers = new TestMemberCollection();
foreach (var member in testFrameworks.GetTestMembersFor(c))
if (!testMembers.Contains(member.Name)) {
testMembers.Add(new TestMember(member));
testMembers.Add(member);
}

// Add base class test members.
IClass declaringType = c;
while (c.BaseClass != null) {
foreach (var method in testFrameworks.GetTestMembersFor(c.BaseClass)) {
BaseTestMember baseTestMethod = new BaseTestMember(declaringType, method);
TestMember testMethod = new TestMember(c.BaseClass.Name, baseTestMethod);
if (method.IsVirtual) {
if (!testMembers.Contains(method.Name)) {
testMembers.Add(testMethod);
while (c.BaseClass != null)
{
foreach (var testMember in testFrameworks.GetTestMembersFor(c.BaseClass)) {
BaseTestMember baseTestMethod = new BaseTestMember(declaringType, testMember.Member);
TestMember testMethod = new TestMember(c, baseTestMethod);
if (testMember.Member.IsVirtual) {
if (!testMembers.Contains(testMember.Name)) {
testMembers.Add(testMethod);
}
} else {
if (!testMembers.Contains(testMethod.Name)) {
Expand All @@ -303,6 +310,11 @@ TestMemberCollection GetTestMembers(IClass c)
}
c = c.BaseClass;
}

baseClassesFQNames.Clear();
foreach (var memberDeclaringClass in testMembers.Select(member => member.DeclaringType).Distinct())
if (memberDeclaringClass != declaringType)
baseClassesFQNames.Add(memberDeclaringClass.FullyQualifiedName);
return testMembers;
}

Expand Down Expand Up @@ -361,5 +373,10 @@ TestMember GetPrefixedTestMember(string testResultName)
}
return null;
}

public bool IsDerivedFrom(IClass c)
{
return baseClassesFQNames.Contains(c.FullyQualifiedName);
}
}
}
2 changes: 1 addition & 1 deletion src/AddIns/Analysis/UnitTesting/Src/TestFramework.cs
Expand Up @@ -14,7 +14,7 @@ public interface ITestFramework
bool IsTestClass(IClass c);
bool IsTestProject(IProject project);

IEnumerable<IMember> GetTestMembersFor(IClass @class);
IEnumerable<TestMember> GetTestMembersFor(IClass @class);

ITestRunner CreateTestRunner();
ITestRunner CreateTestDebugger();
Expand Down
21 changes: 20 additions & 1 deletion src/AddIns/Analysis/UnitTesting/Src/TestMember.cs
Expand Up @@ -11,20 +11,24 @@ namespace ICSharpCode.UnitTesting
/// </summary>
public class TestMember
{
#if unused
string prefix = String.Empty;
#endif
IMember member;
TestResultType testResultType = TestResultType.None;

/// <summary>
/// Raised when the test result has changed.
/// </summary>
public event EventHandler ResultChanged;
public event EventHandler ResultChanged;

public TestMember(IMember member)
{
this.member = member;
this.DeclaringType = member.DeclaringType;
}

#if unused
/// <summary>
/// Creates a new TestMember instance.
/// </summary>
Expand All @@ -46,13 +50,26 @@ public TestMember(string prefix, IMember member)
this.member = member;
this.prefix = prefix;
}
#endif

public TestMember(IClass testClass, IMember member)
{
this.DeclaringType = testClass;
this.member = member;
}

/// <summary>
/// Gets the underlying IMember for this TestMember.
/// </summary>
public IMember Member {
get { return member; }
}

/// <summary>
/// Gets the class where the test member is actually declared.
/// In case of test member from base class it will be the base class not the
/// </summary>
public IClass DeclaringType { get; private set; }

/// <summary>
/// Updates the test member based on new information
Expand Down Expand Up @@ -82,9 +99,11 @@ public void Update(IMember member)
/// </summary>
public string Name {
get {
#if unused
if (prefix.Length > 0) {
return String.Concat(prefix, ".", member.Name);
}
#endif
return member.Name;
}
}
Expand Down
48 changes: 39 additions & 9 deletions src/AddIns/Analysis/UnitTesting/Src/TestProject.cs
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
Expand Down Expand Up @@ -188,21 +189,50 @@ TestClass CreateTestClass(IClass c)
/// </summary>
void UpdateTestClass(IClass c)
{
if (TestClasses.Contains(c.DotNetName)) {
if (IsTestClass(c)) {
if (TestClasses.Contains(c.DotNetName))
{
if (IsTestClass(c))
{
TestClass testClass = TestClasses[c.DotNetName];
testClass.UpdateClass(c);
} else {
}
else
{
// TestFixture attribute has been removed so
// remove the class from the set of TestClasses.
TestClasses.Remove(c.DotNetName);
}
} else {
// TestFixture attribute may have been recently added to
// this class so call AddNewTestClass. No need to
// check if the class is actually a test class since
// AddNewTestClass does this anyway.
AddNewTestClass(c);
}
else
{
// TestFixture attribute may have been recently added to
// this class so call AddNewTestClass. No need to
// check if the class is actually a test class since
// AddNewTestClass does this anyway.
AddNewTestClass(c);
}

var derivedTestClasses = GetTestClassesDerivedFrom(c);
if (derivedTestClasses.Any())
UpdateClassesFromProjectContent(derivedTestClasses);

}

private IEnumerable<IClass> GetTestClassesDerivedFrom(IClass c)
{
return TestClasses
.Where(testClass => testClass.IsDerivedFrom(c))
.Select(testClass => testClass.Class)
.ToArray();
}

private void UpdateClassesFromProjectContent(IEnumerable<IClass> classes)
{
foreach (var c in classes)
{
var classInProjectContent = projectContent.GetClass(c.FullyQualifiedName, c.TypeParameters.Count);
if (classInProjectContent != null)
UpdateTestClass(classInProjectContent);
}
}

Expand Down
Expand Up @@ -45,7 +45,7 @@ public void SetUpFixture()
[Test]
public void MethodName()
{
Assert.AreEqual("MyMethod", baseTestMethod.Name);
Assert.AreEqual("MyTestFixture.MyMethod", baseTestMethod.Name);
}

[Test]
Expand Down

0 comments on commit f04440b

Please sign in to comment.