Browse Source

implement test result update logic

newNRvisualizers
Siegfried Pammer 13 years ago
parent
commit
f2cdbee3b0
  1. 6
      src/AddIns/Analysis/UnitTesting/Extensions.cs
  2. 58
      src/AddIns/Analysis/UnitTesting/Model/TestClass.cs
  3. 5
      src/AddIns/Analysis/UnitTesting/Model/TestMember.cs
  4. 47
      src/AddIns/Analysis/UnitTesting/Model/TestProject.cs
  5. 11
      src/AddIns/Analysis/UnitTesting/Nodes/ClassUnitTestNode.cs
  6. 14
      src/AddIns/Analysis/UnitTesting/Nodes/MemberUnitTestNode.cs
  7. 11
      src/AddIns/Analysis/UnitTesting/Nodes/NamespaceUnitTestNode.cs
  8. 50
      src/AddIns/Analysis/UnitTesting/TestAttributeName.cs

6
src/AddIns/Analysis/UnitTesting/Extensions.cs

@ -51,18 +51,18 @@ namespace ICSharpCode.UnitTesting
list.Insert(index, item); list.Insert(index, item);
} }
public static void UpdateTestClasses(this IList<TestClass> testClasses, IRegisteredTestFrameworks testFrameworks, IReadOnlyList<ITypeDefinition> oldTypes, IReadOnlyList<ITypeDefinition> newTypes) public static void UpdateTestClasses(this IList<TestClass> testClasses, IRegisteredTestFrameworks testFrameworks, IReadOnlyList<ITypeDefinition> oldTypes, IReadOnlyList<ITypeDefinition> newTypes, TestClass parent)
{ {
var mappings = oldTypes.FullOuterJoin(newTypes, t => t.ReflectionName, t => t.ReflectionName, Tuple.Create); var mappings = oldTypes.FullOuterJoin(newTypes, t => t.ReflectionName, t => t.ReflectionName, Tuple.Create);
foreach (Tuple<ITypeDefinition, ITypeDefinition> mapping in mappings) { foreach (Tuple<ITypeDefinition, ITypeDefinition> mapping in mappings) {
if (mapping.Item2 == null) if (mapping.Item2 == null)
testClasses.RemoveWhere(c => c.FullName == mapping.Item1.ReflectionName); testClasses.RemoveWhere(c => c.FullName == mapping.Item1.ReflectionName);
else if (mapping.Item1 == null) else if (mapping.Item1 == null)
testClasses.Add(new TestClass(testFrameworks, mapping.Item2.ReflectionName, mapping.Item2)); testClasses.Add(new TestClass(testFrameworks, mapping.Item2.ReflectionName, mapping.Item2, parent));
else { else {
var testClass = testClasses.SingleOrDefault(c => c.FullName == mapping.Item1.ReflectionName); var testClass = testClasses.SingleOrDefault(c => c.FullName == mapping.Item1.ReflectionName);
if (testClass == null) if (testClass == null)
testClasses.Add(new TestClass(testFrameworks, mapping.Item2.ReflectionName, mapping.Item2)); testClasses.Add(new TestClass(testFrameworks, mapping.Item2.ReflectionName, mapping.Item2, parent));
else else
testClass.UpdateClass(mapping.Item2); testClass.UpdateClass(mapping.Item2);
} }

58
src/AddIns/Analysis/UnitTesting/Model/TestClass.cs

@ -5,9 +5,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
using ICSharpCode.Core; using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation; using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Widgets; using ICSharpCode.SharpDevelop.Widgets;
@ -24,16 +26,19 @@ namespace ICSharpCode.UnitTesting
readonly ObservableCollection<TestClass> nestedClasses; readonly ObservableCollection<TestClass> nestedClasses;
IRegisteredTestFrameworks testFrameworks; IRegisteredTestFrameworks testFrameworks;
public TestClass(IRegisteredTestFrameworks testFrameworks, string fullName, ITypeDefinition definition) public TestClass(IRegisteredTestFrameworks testFrameworks, string fullName, ITypeDefinition definition, TestClass parent = null)
{ {
this.parts = new ObservableCollection<IUnresolvedTypeDefinition>(); this.parts = new ObservableCollection<IUnresolvedTypeDefinition>();
this.testMembers = new ObservableCollection<TestMember>(); this.testMembers = new ObservableCollection<TestMember>();
this.nestedClasses = new ObservableCollection<TestClass>(); this.nestedClasses = new ObservableCollection<TestClass>();
this.testFrameworks = testFrameworks; this.testFrameworks = testFrameworks;
this.fullName = fullName; this.fullName = fullName;
Parent = parent;
UpdateClass(definition); UpdateClass(definition);
} }
public TestClass Parent { get; private set; }
/// <summary> /// <summary>
/// Gets the underlying IClass for this test class. /// Gets the underlying IClass for this test class.
/// </summary> /// </summary>
@ -81,12 +86,23 @@ namespace ICSharpCode.UnitTesting
/// </summary> /// </summary>
public TestResultType TestResult { public TestResultType TestResult {
get { return testResult; } get { return testResult; }
set { set { SetAndNotifyPropertyChanged(ref testResult, value); }
if (testResult != value) { }
testResult = value;
OnPropertyChanged(); static TestResultType GetTestResult(TestClass testClass)
} {
} if (testClass.nestedClasses.Count == 0 && testClass.testMembers.Count == 0)
return TestResultType.None;
if (testClass.nestedClasses.Any(c => c.TestResult == TestResultType.Failure)
|| testClass.testMembers.Any(m => m.TestResult == TestResultType.Failure))
return TestResultType.Failure;
if (testClass.nestedClasses.Any(c => c.TestResult == TestResultType.None)
|| testClass.testMembers.Any(m => m.TestResult == TestResultType.None))
return TestResultType.None;
if (testClass.nestedClasses.Any(c => c.TestResult == TestResultType.Ignored)
|| testClass.testMembers.Any(m => m.TestResult == TestResultType.Ignored))
return TestResultType.Ignored;
return TestResultType.Success;
} }
/// <summary> /// <summary>
@ -94,7 +110,13 @@ namespace ICSharpCode.UnitTesting
/// </summary> /// </summary>
public void UpdateTestResult(TestResult testResult) public void UpdateTestResult(TestResult testResult)
{ {
var member = testMembers.SingleOrDefault(m => m.Method.ReflectionName == testResult.Name);
member.TestResult = testResult.ResultType;
var parent = this;
while (parent != null) {
parent.TestResult = GetTestResult(parent);
parent = parent.Parent;
}
} }
/// <summary> /// <summary>
@ -102,8 +124,16 @@ namespace ICSharpCode.UnitTesting
/// </summary> /// </summary>
public void ResetTestResults() public void ResetTestResults()
{ {
TestResult = TestResultType.None; foreach (var testClass in TreeTraversal.PostOrder(this, c => c.NestedClasses)) {
// TestMembers.ResetTestResults(); foreach (var member in testClass.Members)
member.TestResult = TestResultType.None;
testClass.TestResult = TestResultType.None;
}
var parent = this;
while (parent != null) {
parent.TestResult = TestResultType.None;
parent = parent.Parent;
}
} }
/// <summary> /// <summary>
@ -129,7 +159,7 @@ namespace ICSharpCode.UnitTesting
testMembers.AddRange(definition.Methods.Where(m => testFrameworks.IsTestMethod(m, definition.Compilation) && !testMembers.Any(dm => dm.Method.ReflectionName == m.ReflectionName)).Select(m => new TestMember((IUnresolvedMethod)m.UnresolvedMember))); testMembers.AddRange(definition.Methods.Where(m => testFrameworks.IsTestMethod(m, definition.Compilation) && !testMembers.Any(dm => dm.Method.ReflectionName == m.ReflectionName)).Select(m => new TestMember((IUnresolvedMethod)m.UnresolvedMember)));
var context = new SimpleTypeResolveContext(definition); var context = new SimpleTypeResolveContext(definition);
nestedClasses.UpdateTestClasses(testFrameworks, nestedClasses.Select(tc => new DefaultResolvedTypeDefinition(context, tc.Parts.ToArray())).ToList(), definition.NestedTypes.Where(nt => testFrameworks.IsTestClass(nt, definition.Compilation)).ToList()); nestedClasses.UpdateTestClasses(testFrameworks, nestedClasses.Select(tc => new DefaultResolvedTypeDefinition(context, tc.Parts.ToArray())).ToList(), definition.NestedTypes.Where(nt => testFrameworks.IsTestClass(nt, definition.Compilation)).ToList(), this);
} }
/// <summary> /// <summary>
@ -161,5 +191,11 @@ namespace ICSharpCode.UnitTesting
{ {
// Result = testMembers.Result; // Result = testMembers.Result;
} }
public override string ToString()
{
return string.Format("[TestClass TestResult={0}, FullName={1}]", testResult, fullName);
}
} }
} }

5
src/AddIns/Analysis/UnitTesting/Model/TestMember.cs

@ -36,5 +36,10 @@ namespace ICSharpCode.UnitTesting
} }
} }
} }
public override string ToString()
{
return string.Format("[TestMember Method={0}, TestResult={1}]", method, testResult);
}
} }
} }

47
src/AddIns/Analysis/UnitTesting/Model/TestProject.cs

@ -49,7 +49,7 @@ namespace ICSharpCode.UnitTesting
@new = e.NewParsedFile.TopLevelTypeDefinitions.Select(utd => utd.Resolve(context).GetDefinition()).Where(x => x != null && testFrameworks.IsTestClass(x, SD.ParserService.GetCompilation(project))); @new = e.NewParsedFile.TopLevelTypeDefinitions.Select(utd => utd.Resolve(context).GetDefinition()).Where(x => x != null && testFrameworks.IsTestClass(x, SD.ParserService.GetCompilation(project)));
else else
@new = Enumerable.Empty<ITypeDefinition>(); @new = Enumerable.Empty<ITypeDefinition>();
testClasses.UpdateTestClasses(testFrameworks, testClasses.Where(tc => tc.Parts.Any(td => td.ParsedFile.FileName == e.OldParsedFile.FileName)).Select(tc => new DefaultResolvedTypeDefinition(context, tc.Parts.ToArray())).ToList(), @new.ToList()); testClasses.UpdateTestClasses(testFrameworks, testClasses.Where(tc => tc.Parts.Any(td => td.ParsedFile.FileName == e.OldParsedFile.FileName)).Select(tc => new DefaultResolvedTypeDefinition(context, tc.Parts.ToArray())).ToList(), @new.ToList(), null);
} }
public IProject Project { public IProject Project {
@ -72,35 +72,32 @@ namespace ICSharpCode.UnitTesting
return null; return null;
} }
public bool FindTestInfo(string fullName, out TestClass testClass, out TestMember method) public TestClass FindTestClass(string fullName)
{ {
testClass = null;
method = null;
foreach (var tc in testClasses) { foreach (var tc in testClasses) {
foreach (var c in TreeTraversal.PostOrder(tc, c => c.NestedClasses)) { foreach (var c in TreeTraversal.PostOrder(tc, c => c.NestedClasses)) {
testClass = c; var method = c.Members.SingleOrDefault(m => fullName.Equals(m.Method.ReflectionName, StringComparison.Ordinal));
method = c.SingleOrDefault(m => fullName.Equals(m.Method.ReflectionName, StringComparison.Ordinal));
if (method != null) if (method != null)
return true; return c;
} }
} }
return false; return null;
} }
public void UpdateTestResult(TestResult result) public void UpdateTestResult(TestResult result)
{ {
TestMember member; TestClass testClass = FindTestClass(result.Name);
TestClass testClass; if (testClass != null) {
if (FindTestInfo(result.Name, out testClass, out member)) { testClass.UpdateTestResult(result);
member.TestResult = result.ResultType; TestResult = GetTestResult(testClasses);
testClass.TestResult = r
} }
} }
public void ResetTestResults() public void ResetTestResults()
{ {
foreach (var member in testClasses.SelectMany(tc => TreeTraversal.PostOrder(tc, c => c.NestedClasses)).SelectMany(c => c.Members)) foreach (var testClass in testClasses)
member.TestResult = TestResultType.None; testClass.ResetTestResults();
TestResult = TestResultType.None;
} }
TestResultType testResult; TestResultType testResult;
@ -110,12 +107,20 @@ namespace ICSharpCode.UnitTesting
/// </summary> /// </summary>
public TestResultType TestResult { public TestResultType TestResult {
get { return testResult; } get { return testResult; }
set { set { SetAndNotifyPropertyChanged(ref testResult, value); }
if (testResult != value) { }
testResult = value;
OnPropertyChanged(); static TestResultType GetTestResult(IList<TestClass> testClasses)
} {
} if (testClasses.Count == 0)
return TestResultType.None;
if (testClasses.Any(c => c.TestResult == TestResultType.Failure))
return TestResultType.Failure;
if (testClasses.Any(c => c.TestResult == TestResultType.None))
return TestResultType.None;
if (testClasses.Any(c => c.TestResult == TestResultType.Ignored))
return TestResultType.Ignored;
return TestResultType.Success;
} }
} }
} }

11
src/AddIns/Analysis/UnitTesting/Nodes/ClassUnitTestNode.cs

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel;
namespace ICSharpCode.UnitTesting namespace ICSharpCode.UnitTesting
{ {
@ -20,6 +21,16 @@ namespace ICSharpCode.UnitTesting
public ClassUnitTestNode(TestClass testClass) public ClassUnitTestNode(TestClass testClass)
{ {
this.testClass = testClass; this.testClass = testClass;
this.testClass.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) {
if (e.PropertyName == "TestResult") {
RaisePropertyChanged("Icon");
var parentNode = Parent;
while (parentNode is NamespaceUnitTestNode) {
parentNode.RaisePropertyChanged("Icon");
parentNode = parentNode.Parent;
}
}
};
testClass.Members.CollectionChanged += TestMembersCollectionChanged; testClass.Members.CollectionChanged += TestMembersCollectionChanged;
testClass.NestedClasses.CollectionChanged += NestedClassesCollectionChanged; testClass.NestedClasses.CollectionChanged += NestedClassesCollectionChanged;
LazyLoading = true; LazyLoading = true;

14
src/AddIns/Analysis/UnitTesting/Nodes/MemberUnitTestNode.cs

@ -4,6 +4,8 @@
using System; using System;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.TreeView; using ICSharpCode.TreeView;
namespace ICSharpCode.UnitTesting namespace ICSharpCode.UnitTesting
@ -21,11 +23,7 @@ namespace ICSharpCode.UnitTesting
this.testMember = testMember; this.testMember = testMember;
this.testMember.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) { this.testMember.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) {
if (e.PropertyName == "TestResult") { if (e.PropertyName == "TestResult") {
SharpTreeNode p = this; RaisePropertyChanged("Icon");
while (p != null) {
p.RaisePropertyChanged("Icon");
p = p.Parent;
}
} }
}; };
} }
@ -37,5 +35,11 @@ namespace ICSharpCode.UnitTesting
public override object Text { public override object Text {
get { return testMember.Method.Name; } get { return testMember.Method.Name; }
} }
public override void ActivateItem(System.Windows.RoutedEventArgs e)
{
var region = testMember.Method.Region;
SD.FileService.JumpToFilePosition(new FileName(region.FileName), region.BeginLine, region.BeginColumn);
}
} }
} }

11
src/AddIns/Analysis/UnitTesting/Nodes/NamespaceUnitTestNode.cs

@ -36,7 +36,16 @@ namespace ICSharpCode.UnitTesting
} }
internal override TestResultType TestResultType { internal override TestResultType TestResultType {
get { return TestResultType.None; } get {
if (Children.Count == 0) return TestResultType.None;
if (Children.OfType<UnitTestBaseNode>().Any(node => node.TestResultType == TestResultType.Failure))
return TestResultType.Failure;
if (Children.OfType<UnitTestBaseNode>().Any(node => node.TestResultType == TestResultType.None))
return TestResultType.None;
if (Children.OfType<UnitTestBaseNode>().Any(node => node.TestResultType == TestResultType.Ignored))
return TestResultType.Ignored;
return TestResultType.Success;
}
} }
} }
} }

50
src/AddIns/Analysis/UnitTesting/TestAttributeName.cs

@ -1,50 +0,0 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.UnitTesting
{
public class NUnitTestAttributeName
{
string name = String.Empty;
string qualifiedName = String.Empty;
string fullName = String.Empty;
StringComparer nameComparer;
/// <summary>
/// Creates a new instance of the NUnit Test Attribute class.
/// </summary>
/// <param name="name">The name of the attribute (e.g. Test) not
/// the full name of the attribute (e.g. TestAttribute).</param>
/// <param name="nameComparer">The string comparer to use
/// when comparing attribute names.</param>
public NUnitTestAttributeName(string name, StringComparer nameComparer)
{
this.name = name;
this.nameComparer = nameComparer;
qualifiedName = String.Concat(name, "Attribute");
fullName = String.Concat("NUnit.Framework.", name, "Attribute");
}
/// <summary>
/// Determines whether the specified attribute name is a
/// match to this attribute.
/// </summary>
public bool IsEqual(string attributeName)
{
if (nameComparer.Equals(attributeName, name) ||
nameComparer.Equals(attributeName, qualifiedName) ||
nameComparer.Equals(attributeName, fullName)) {
return true;
}
return false;
}
public bool IsEqual(IAttribute attribute)
{
return IsEqual(attribute.AttributeType.FullName);
}
}
}
Loading…
Cancel
Save