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 @@ -51,18 +51,18 @@ namespace ICSharpCode.UnitTesting
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);
foreach (Tuple<ITypeDefinition, ITypeDefinition> mapping in mappings) {
if (mapping.Item2 == null)
testClasses.RemoveWhere(c => c.FullName == mapping.Item1.ReflectionName);
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 {
var testClass = testClasses.SingleOrDefault(c => c.FullName == mapping.Item1.ReflectionName);
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
testClass.UpdateClass(mapping.Item2);
}

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

@ -5,9 +5,11 @@ using System; @@ -5,9 +5,11 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Widgets;
@ -24,16 +26,19 @@ namespace ICSharpCode.UnitTesting @@ -24,16 +26,19 @@ namespace ICSharpCode.UnitTesting
readonly ObservableCollection<TestClass> nestedClasses;
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.testMembers = new ObservableCollection<TestMember>();
this.nestedClasses = new ObservableCollection<TestClass>();
this.testFrameworks = testFrameworks;
this.fullName = fullName;
Parent = parent;
UpdateClass(definition);
}
public TestClass Parent { get; private set; }
/// <summary>
/// Gets the underlying IClass for this test class.
/// </summary>
@ -81,12 +86,23 @@ namespace ICSharpCode.UnitTesting @@ -81,12 +86,23 @@ namespace ICSharpCode.UnitTesting
/// </summary>
public TestResultType TestResult {
get { return testResult; }
set {
if (testResult != value) {
testResult = value;
OnPropertyChanged();
}
}
set { SetAndNotifyPropertyChanged(ref testResult, value); }
}
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>
@ -94,7 +110,13 @@ namespace ICSharpCode.UnitTesting @@ -94,7 +110,13 @@ namespace ICSharpCode.UnitTesting
/// </summary>
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>
@ -102,8 +124,16 @@ namespace ICSharpCode.UnitTesting @@ -102,8 +124,16 @@ namespace ICSharpCode.UnitTesting
/// </summary>
public void ResetTestResults()
{
TestResult = TestResultType.None;
// TestMembers.ResetTestResults();
foreach (var testClass in TreeTraversal.PostOrder(this, c => c.NestedClasses)) {
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>
@ -129,7 +159,7 @@ namespace ICSharpCode.UnitTesting @@ -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)));
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>
@ -161,5 +191,11 @@ namespace ICSharpCode.UnitTesting @@ -161,5 +191,11 @@ namespace ICSharpCode.UnitTesting
{
// 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 @@ -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 @@ -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)));
else
@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 {
@ -72,35 +72,32 @@ namespace ICSharpCode.UnitTesting @@ -72,35 +72,32 @@ namespace ICSharpCode.UnitTesting
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 c in TreeTraversal.PostOrder(tc, c => c.NestedClasses)) {
testClass = c;
method = c.SingleOrDefault(m => fullName.Equals(m.Method.ReflectionName, StringComparison.Ordinal));
var method = c.Members.SingleOrDefault(m => fullName.Equals(m.Method.ReflectionName, StringComparison.Ordinal));
if (method != null)
return true;
return c;
}
}
return false;
return null;
}
public void UpdateTestResult(TestResult result)
{
TestMember member;
TestClass testClass;
if (FindTestInfo(result.Name, out testClass, out member)) {
member.TestResult = result.ResultType;
testClass.TestResult = r
TestClass testClass = FindTestClass(result.Name);
if (testClass != null) {
testClass.UpdateTestResult(result);
TestResult = GetTestResult(testClasses);
}
}
public void ResetTestResults()
{
foreach (var member in testClasses.SelectMany(tc => TreeTraversal.PostOrder(tc, c => c.NestedClasses)).SelectMany(c => c.Members))
member.TestResult = TestResultType.None;
foreach (var testClass in testClasses)
testClass.ResetTestResults();
TestResult = TestResultType.None;
}
TestResultType testResult;
@ -110,12 +107,20 @@ namespace ICSharpCode.UnitTesting @@ -110,12 +107,20 @@ namespace ICSharpCode.UnitTesting
/// </summary>
public TestResultType TestResult {
get { return testResult; }
set {
if (testResult != value) {
testResult = value;
OnPropertyChanged();
}
}
set { SetAndNotifyPropertyChanged(ref testResult, value); }
}
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 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
namespace ICSharpCode.UnitTesting
{
@ -20,6 +21,16 @@ namespace ICSharpCode.UnitTesting @@ -20,6 +21,16 @@ namespace ICSharpCode.UnitTesting
public ClassUnitTestNode(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.NestedClasses.CollectionChanged += NestedClassesCollectionChanged;
LazyLoading = true;

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

@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.TreeView;
namespace ICSharpCode.UnitTesting
@ -21,11 +23,7 @@ namespace ICSharpCode.UnitTesting @@ -21,11 +23,7 @@ namespace ICSharpCode.UnitTesting
this.testMember = testMember;
this.testMember.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e) {
if (e.PropertyName == "TestResult") {
SharpTreeNode p = this;
while (p != null) {
p.RaisePropertyChanged("Icon");
p = p.Parent;
}
RaisePropertyChanged("Icon");
}
};
}
@ -37,5 +35,11 @@ namespace ICSharpCode.UnitTesting @@ -37,5 +35,11 @@ namespace ICSharpCode.UnitTesting
public override object Text {
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 @@ -36,7 +36,16 @@ namespace ICSharpCode.UnitTesting
}
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 @@ @@ -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