Browse Source

WIP

newNRvisualizers
Siegfried Pammer 13 years ago
parent
commit
3db890fd58
  1. 2
      SharpDevelop.sln
  2. 40
      src/AddIns/Analysis/UnitTesting/Commands/RunTestCommands.cs
  3. 30
      src/AddIns/Analysis/UnitTesting/Extensions.cs
  4. 14
      src/AddIns/Analysis/UnitTesting/Gui/UnitTestsPad.cs
  5. 8
      src/AddIns/Analysis/UnitTesting/Interfaces/IRegisteredTestFrameworks.cs
  6. 6
      src/AddIns/Analysis/UnitTesting/Interfaces/ITestFramework.cs
  7. 4
      src/AddIns/Analysis/UnitTesting/Interfaces/ITestTreeView.cs
  8. 91
      src/AddIns/Analysis/UnitTesting/Model/TestClass.cs
  9. 19
      src/AddIns/Analysis/UnitTesting/Model/TestMember.cs
  10. 64
      src/AddIns/Analysis/UnitTesting/Model/TestProject.cs
  11. 6
      src/AddIns/Analysis/UnitTesting/NUnit/NUnitConsoleApplication.cs
  12. 7
      src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs
  13. 132
      src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestFramework.cs
  14. 4
      src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestResult.cs
  15. 4
      src/AddIns/Analysis/UnitTesting/Nodes/ClassUnitTestNode.cs
  16. 15
      src/AddIns/Analysis/UnitTesting/Nodes/MemberUnitTestNode.cs
  17. 4
      src/AddIns/Analysis/UnitTesting/Nodes/NamespaceUnitTestNode.cs
  18. 12
      src/AddIns/Analysis/UnitTesting/Nodes/ProjectUnitTestNode.cs
  19. 13
      src/AddIns/Analysis/UnitTesting/Nodes/RootUnitTestNode.cs
  20. 13
      src/AddIns/Analysis/UnitTesting/Nodes/UnitTestBaseNode.cs
  21. 47
      src/AddIns/Analysis/UnitTesting/Service/InnerClassEnumerator.cs
  22. 34
      src/AddIns/Analysis/UnitTesting/Service/RegisteredTestFrameworks.cs
  23. 22
      src/AddIns/Analysis/UnitTesting/Service/SelectedTests.cs
  24. 214
      src/AddIns/Analysis/UnitTesting/Service/TestClassCollection.cs
  25. 30
      src/AddIns/Analysis/UnitTesting/Service/TestClassEventArgs.cs
  26. 8
      src/AddIns/Analysis/UnitTesting/Service/TestDebuggerBase.cs
  27. 153
      src/AddIns/Analysis/UnitTesting/Service/TestMemberCollection.cs
  28. 30
      src/AddIns/Analysis/UnitTesting/Service/TestMemberEventArgs.cs
  29. 11
      src/AddIns/Analysis/UnitTesting/Service/TestProcessRunnerBase.cs
  30. 11
      src/AddIns/Analysis/UnitTesting/Service/TestProcessRunnerBaseContext.cs
  31. 6
      src/AddIns/Analysis/UnitTesting/Service/TestService.cs
  32. 66
      src/AddIns/Analysis/UnitTesting/Service/TestableCondition.cs
  33. 9
      src/AddIns/Analysis/UnitTesting/UnitTestApplicationStartHelper.cs
  34. 16
      src/AddIns/Analysis/UnitTesting/UnitTesting.csproj
  35. 14
      src/Main/Base/Project/Src/Util/ExtensionMethods.cs
  36. 8
      src/Main/Core/Project/Src/Services/MessageService/IMessageService.cs
  37. 2
      src/Main/Core/Project/Src/Services/MessageService/MessageService.cs
  38. 5
      src/Main/Core/Project/Src/Services/MessageService/TextWriterMessageService.cs
  39. 5
      src/Main/ICSharpCode.Core.WinForms/MessageService/WinFormsMessageService.cs

2
SharpDevelop.sln

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
# SharpDevelop 4.2.0.8742-Beta 2
# SharpDevelop 4.2.0.8774-RC
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Main", "Main", "{256F5C28-532C-44C0-8AB8-D8EC5E492E01}"
ProjectSection(SolutionItems) = postProject
EndProjectSection

40
src/AddIns/Analysis/UnitTesting/Commands/RunTestCommands.cs

@ -5,12 +5,13 @@ using System; @@ -5,12 +5,13 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Commands;
using ICSharpCode.SharpDevelop.Debugging;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Commands;
@ -54,15 +55,15 @@ namespace ICSharpCode.UnitTesting @@ -54,15 +55,15 @@ namespace ICSharpCode.UnitTesting
{
projects = new List<IProject>();
IMember m = TestableCondition.GetMember(Owner);
IClass c = (m != null) ? m.DeclaringType : TestableCondition.GetClass(Owner);
IMethod m = TestableCondition.GetMethod(Owner);
ITypeDefinition c = (m != null) ? m.DeclaringType.GetDefinition() : TestableCondition.GetClass(Owner);
IProject project = TestableCondition.GetProject(Owner);
string namespaceFilter = TestableCondition.GetNamespace(Owner);
if (project != null) {
projects.Add(project);
} else if (UnitTestsPad.Instance != null) {
projects.AddRange(UnitTestsPad.Instance.TestTreeView.GetProjects());
projects.AddRange(UnitTestsPad.Instance.GetProjects());
}
if (projects.Count > 0) {
@ -181,7 +182,7 @@ namespace ICSharpCode.UnitTesting @@ -181,7 +182,7 @@ namespace ICSharpCode.UnitTesting
/// <summary>
/// Runs the tests after building the project under test.
/// </summary>
void Run(IProject project, string namespaceFilter, IClass fixture, IMember test)
void Run(IProject project, string namespaceFilter, ITypeDefinition fixture, IMethod test)
{
BuildProjectBeforeTestRun build = new BuildProjectBeforeTestRun(project);
build.BuildComplete += delegate {
@ -232,7 +233,7 @@ namespace ICSharpCode.UnitTesting @@ -232,7 +233,7 @@ namespace ICSharpCode.UnitTesting
ShowPad(WorkbenchSingleton.Workbench.GetPad(typeof(CompilerMessageView)));
}
Task CreateTask(TestResult result)
SDTask CreateTask(TestResult result)
{
TaskType taskType = TaskType.Warning;
FileLineReference lineRef = null;
@ -249,10 +250,10 @@ namespace ICSharpCode.UnitTesting @@ -249,10 +250,10 @@ namespace ICSharpCode.UnitTesting
lineRef = FindTest(result.Name);
}
if (lineRef != null) {
return new Task(FileName.Create(lineRef.FileName),
return new SDTask(FileName.Create(lineRef.FileName),
message, lineRef.Column, lineRef.Line, taskType);
}
return new Task(null, message, 0, 0, taskType);
return new SDTask(null, message, 0, 0, taskType);
}
/// <summary>
@ -264,7 +265,7 @@ namespace ICSharpCode.UnitTesting @@ -264,7 +265,7 @@ namespace ICSharpCode.UnitTesting
if (result.Message.Length > 0) {
return result.Message;
}
return StringParser.Parse(stringResource, new string[,] {{"TestCase", result.Name}});
return StringParser.Parse(stringResource, new[] { new StringTagPair("TestCase", result.Name) });
}
/// <summary>
@ -275,11 +276,10 @@ namespace ICSharpCode.UnitTesting @@ -275,11 +276,10 @@ namespace ICSharpCode.UnitTesting
{
TestProject testProject = GetTestProject(currentProject);
if (testProject != null) {
TestMethod method = testProject.TestClasses.GetTestMethod(methodName);
TestMember method = testProject.GetTestMethod(methodName);
if (method != null) {
MemberResolveResult resolveResult = new MemberResolveResult(null, null, method.Method);
FilePosition filePos = resolveResult.GetDefinitionPosition();
return new FileLineReference(filePos.FileName, filePos.Line, filePos.Column);
var filePos = method.Method.Region;
return new FileLineReference(filePos.FileName, filePos.BeginLine, filePos.BeginColumn);
}
}
return null;
@ -293,12 +293,12 @@ namespace ICSharpCode.UnitTesting @@ -293,12 +293,12 @@ namespace ICSharpCode.UnitTesting
/// <summary>
/// Runs the test for the project after a successful build.
/// </summary>
void OnBuildComplete(BuildResults results, IProject project, string namespaceFilter, IClass fixture, IMember test)
void OnBuildComplete(BuildResults results, IProject project, string namespaceFilter, ITypeDefinition fixture, IMethod test)
{
if (results.ErrorCount == 0 && IsRunningTest) {
UnitTestApplicationStartHelper helper = new UnitTestApplicationStartHelper();
UnitTestingOptions options = new UnitTestingOptions();
UnitTestingOptions options = UnitTestingOptions.Instance;
helper.NoThread = options.NoThread;
helper.NoLogo = options.NoLogo;
helper.NoDots = options.NoDots;
@ -352,7 +352,7 @@ namespace ICSharpCode.UnitTesting @@ -352,7 +352,7 @@ namespace ICSharpCode.UnitTesting
void ResetAllTestResults()
{
if (UnitTestsPad.Instance != null) {
UnitTestsPad.Instance.TestTreeView.ResetTestResults();
UnitTestsPad.Instance.ResetTestResults();
}
}
@ -363,7 +363,7 @@ namespace ICSharpCode.UnitTesting @@ -363,7 +363,7 @@ namespace ICSharpCode.UnitTesting
TestProject GetTestProject(IProject project)
{
if (UnitTestsPad.Instance != null) {
return UnitTestsPad.Instance.TestTreeView.GetTestProject(project);
return TestService.TestableProjects.FirstOrDefault(tp => tp.Project == project);
}
return null;
}
@ -527,11 +527,11 @@ namespace ICSharpCode.UnitTesting @@ -527,11 +527,11 @@ namespace ICSharpCode.UnitTesting
base.Run();
}
public IMember SelectedMethod {
public IMethod SelectedMethod {
get { return null; }
}
public IClass SelectedClass {
public ITypeDefinition SelectedClass {
get { return null; }
}

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

@ -23,36 +23,6 @@ namespace ICSharpCode.UnitTesting @@ -23,36 +23,6 @@ namespace ICSharpCode.UnitTesting
{
public static class Extensions
{
static readonly ITypeReference testAttribute = new GetClassTypeReference("NUnit.Framework", "TestAttribute", 0);
static readonly ITypeReference testCaseAttribute = new GetClassTypeReference("NUnit.Framework", "TestCaseAttribute", 0);
public static bool IsTestProject(this IProject project)
{
if (project == null)
throw new ArgumentNullException("project");
if (project.ProjectContent == null)
return false;
return testAttribute.Resolve(SD.ParserService.GetCompilation(project).TypeResolveContext).Kind != TypeKind.Unknown;
}
public static bool IsTestMethod(this IMethod method, ICompilation compilation)
{
if (method == null)
throw new ArgumentNullException("method");
var testAttribute = Extensions.testAttribute.Resolve(compilation.TypeResolveContext);
var testCaseAttribute = Extensions.testCaseAttribute.Resolve(compilation.TypeResolveContext);
return method.Attributes.Any(a => a.AttributeType.Equals(testAttribute) || a.AttributeType.Equals(testCaseAttribute));
}
public static bool HasTests(this ITypeDefinition type, ICompilation compilation)
{
if (type == null)
throw new ArgumentNullException("type");
var testAttribute = Extensions.testAttribute.Resolve(compilation.TypeResolveContext);
var testCaseAttribute = Extensions.testCaseAttribute.Resolve(compilation.TypeResolveContext);
return type.Methods.Any(m => m.Attributes.Any(a => a.AttributeType.Equals(testAttribute) || a.AttributeType.Equals(testCaseAttribute)));
}
public static IEnumerable<TResult> FullOuterJoin<TOuter, TInner, TKey, TResult>(this IEnumerable<TOuter> outer, IEnumerable<TInner> inner, Func<TOuter,TKey> outerKeySelector, Func<TInner,TKey> innerKeySelector, Func<TOuter,TInner,TResult> resultSelector)
where TInner : class
where TOuter : class

14
src/AddIns/Analysis/UnitTesting/Gui/UnitTestsPad.cs

@ -97,10 +97,10 @@ namespace ICSharpCode.UnitTesting @@ -97,10 +97,10 @@ namespace ICSharpCode.UnitTesting
// treeView.ResetTestResults();
// }
//
// public IProject[] GetProjects()
// {
// return treeView.GetProjects();
// }
public IProject[] GetProjects()
{
return TestService.TestableProjects.Select(tp => tp.Project).ToArray();
}
// public TestProject GetTestProject(IProject project)
// {
@ -310,6 +310,12 @@ namespace ICSharpCode.UnitTesting @@ -310,6 +310,12 @@ namespace ICSharpCode.UnitTesting
{
// ProjectItemRemoved(e.ProjectItem);
}
public void ResetTestResults()
{
foreach (var testProject in TestService.TestableProjects)
testProject.ResetTestResults();
}
}

8
src/AddIns/Analysis/UnitTesting/Interfaces/IRegisteredTestFrameworks.cs

@ -14,12 +14,12 @@ namespace ICSharpCode.UnitTesting @@ -14,12 +14,12 @@ namespace ICSharpCode.UnitTesting
ITestRunner CreateTestRunner(IProject project);
ITestRunner CreateTestDebugger(IProject project);
bool IsTestMember(IUnresolvedMember member);
bool IsTestClass(IUnresolvedTypeDefinition typeDefinition);
bool IsTestMethod(IMethod method, ICompilation compilation);
bool IsTestClass(ITypeDefinition typeDefinition, ICompilation compilation);
bool IsTestProject(IProject project);
IEnumerable<IUnresolvedMember> GetTestMembersFor(IUnresolvedTypeDefinition typeDefinition);
IEnumerable<IMethod> GetTestMethodsFor(ITypeDefinition typeDefinition, ICompilation compilation);
bool IsBuildNeededBeforeTestRunForProject(IProject project);
bool IsBuildNeededBeforeTestRunForProject(IProject project);
}
}

6
src/AddIns/Analysis/UnitTesting/Interfaces/ITestFramework.cs

@ -10,11 +10,11 @@ namespace ICSharpCode.UnitTesting @@ -10,11 +10,11 @@ namespace ICSharpCode.UnitTesting
{
public interface ITestFramework
{
bool IsTestMember(IUnresolvedMember member);
bool IsTestClass(IUnresolvedTypeDefinition c);
bool IsTestMethod(IMethod method, ICompilation compilation);
bool IsTestClass(ITypeDefinition testClass, ICompilation compilation);
bool IsTestProject(IProject project);
IEnumerable<IUnresolvedMember> GetTestMembersFor(IUnresolvedTypeDefinition typeDefinition);
IEnumerable<IMethod> GetTestMethodsFor(ITypeDefinition typeDefinition);
ITestRunner CreateTestRunner();
ITestRunner CreateTestDebugger();

4
src/AddIns/Analysis/UnitTesting/Interfaces/ITestTreeView.cs

@ -13,12 +13,12 @@ namespace ICSharpCode.UnitTesting @@ -13,12 +13,12 @@ namespace ICSharpCode.UnitTesting
/// <summary>
/// Gets the selected member in the test tree view.
/// </summary>
IUnresolvedMember SelectedMember {get;}
IMethod SelectedMethod {get;}
/// <summary>
/// Gets the selected class in the test tree view.
/// </summary>
IUnresolvedTypeDefinition SelectedClass {get;}
ITypeDefinition SelectedClass {get;}
/// <summary>
/// Gets the selected project for the selected node

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

@ -9,26 +9,21 @@ using ICSharpCode.Core; @@ -9,26 +9,21 @@ using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.UnitTesting
{
/// <summary>
/// Represents a class that can be tested.
/// </summary>
public class TestClass
public class TestClass : ViewModelBase
{
string fullName;
ObservableCollection<IUnresolvedTypeDefinition> parts;
readonly ObservableCollection<TestMember> testMembers;
readonly ObservableCollection<TestClass> nestedClasses;
TestResultType testResultType;
IRegisteredTestFrameworks testFrameworks;
/// <summary>
/// Raised when the test class result is changed.
/// </summary>
public event EventHandler ResultChanged;
public TestClass(IRegisteredTestFrameworks testFrameworks, string fullName, ITypeDefinition definition)
{
this.parts = new ObservableCollection<IUnresolvedTypeDefinition>();
@ -79,16 +74,17 @@ namespace ICSharpCode.UnitTesting @@ -79,16 +74,17 @@ namespace ICSharpCode.UnitTesting
get { return parts.First().Namespace; }
}
TestResultType testResult;
/// <summary>
/// Gets the test result for this class.
/// </summary>
public TestResultType Result {
get { return testResultType; }
public TestResultType TestResult {
get { return testResult; }
set {
TestResultType previousTestResultType = testResultType;
testResultType = value;
if (previousTestResultType != testResultType) {
OnResultChanged();
if (testResult != value) {
testResult = value;
OnPropertyChanged();
}
}
}
@ -98,17 +94,7 @@ namespace ICSharpCode.UnitTesting @@ -98,17 +94,7 @@ namespace ICSharpCode.UnitTesting
/// </summary>
public void UpdateTestResult(TestResult testResult)
{
// TestMember member = null;
// string memberName = TestMember.GetMemberName(testResult.Name);
// if (memberName != null) {
// member = GetTestMember(memberName);
// if (member == null) {
// member = GetPrefixedTestMember(testResult.Name);
// }
// }
// if (member != null) {
// member.Result = testResult.ResultType;
// }
}
/// <summary>
@ -116,7 +102,7 @@ namespace ICSharpCode.UnitTesting @@ -116,7 +102,7 @@ namespace ICSharpCode.UnitTesting
/// </summary>
public void ResetTestResults()
{
Result = TestResultType.None;
TestResult = TestResultType.None;
// TestMembers.ResetTestResults();
}
@ -139,11 +125,11 @@ namespace ICSharpCode.UnitTesting @@ -139,11 +125,11 @@ namespace ICSharpCode.UnitTesting
if (!parts.Any(p => p.ParsedFile.FileName == part.ParsedFile.FileName && p.Region == part.Region))
parts.Add(part);
}
testMembers.RemoveWhere(m => !definition.Methods.Any(dm => dm.ReflectionName == m.Method.ReflectionName && dm.IsTestMethod(definition.Compilation)));
testMembers.AddRange(definition.Methods.Where(m => m.IsTestMethod(definition.Compilation) && !testMembers.Any(dm => dm.Method.ReflectionName == m.ReflectionName)).Select(m => new TestMember((IUnresolvedMethod)m.UnresolvedMember)));
testMembers.RemoveWhere(m => !definition.Methods.Any(dm => dm.ReflectionName == m.Method.ReflectionName && testFrameworks.IsTestMethod(dm, definition.Compilation)));
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 => nt.HasTests(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());
}
/// <summary>
@ -175,52 +161,5 @@ namespace ICSharpCode.UnitTesting @@ -175,52 +161,5 @@ namespace ICSharpCode.UnitTesting
{
// Result = testMembers.Result;
}
/// <summary>
/// Raises the ResultChanged event.
/// </summary>
void OnResultChanged()
{
if (ResultChanged != null) {
ResultChanged(this, new EventArgs());
}
}
/// <summary>
/// This function adds the base class as a prefix and tries to find
/// the corresponding test member.
///
/// Actual method name:
///
/// RootNamespace.TestFixture.TestFixtureBaseClass.TestMethod
/// </summary>
/// <remarks>
/// NUnit 2.4 uses the correct test method name when a test
/// class uses a base class with test methods. It does
/// not prefix the test method name with the base class name
/// in the test results returned from nunit-console. It still
/// displays the name in the NUnit GUI with the base class
/// name prefixed. Older versions of NUnit-console (2.2.9) returned
/// the test result with the test method name as follows:
///
/// RootNamespace.TestFixture.BaseTestFixture.TestMethod
///
/// The test method name would have the base class name prefixed
/// to it.
/// </remarks>
// TestMember GetPrefixedTestMember(string testResultName)
// {
// IClass baseClass = c.BaseClass;
// while (baseClass != null) {
// string memberName = TestMember.GetMemberName(testResultName);
// string actualMemberName = String.Concat(baseClass.Name, ".", memberName);
// TestMember member = GetTestMember(actualMemberName);
// if (member != null) {
// return member;
// }
// baseClass = baseClass.BaseClass;
// }
// return null;
// }
}
}
}

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

@ -3,16 +3,17 @@ @@ -3,16 +3,17 @@
using System;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.UnitTesting
{
/// <summary>
/// Represents a member that can be tested.
/// Represents a member that can be tested.
/// </summary>
public class TestMember
public class TestMember : ViewModelBase
{
IUnresolvedMethod method;
public IUnresolvedMethod Method {
get { return method; }
}
@ -23,5 +24,17 @@ namespace ICSharpCode.UnitTesting @@ -23,5 +24,17 @@ namespace ICSharpCode.UnitTesting
throw new ArgumentNullException("method");
this.method = method;
}
TestResultType testResult;
public TestResultType TestResult {
get { return testResult; }
set {
if (testResult != value) {
testResult = value;
OnPropertyChanged();
}
}
}
}
}

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

@ -13,6 +13,7 @@ using ICSharpCode.NRefactory.Utils; @@ -13,6 +13,7 @@ using ICSharpCode.NRefactory.Utils;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Parser;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Widgets;
namespace ICSharpCode.UnitTesting
{
@ -20,7 +21,7 @@ namespace ICSharpCode.UnitTesting @@ -20,7 +21,7 @@ namespace ICSharpCode.UnitTesting
/// Represents a project that has a reference to a unit testing
/// framework assembly. Currently only NUnit is supported.
/// </summary>
public class TestProject
public class TestProject : ViewModelBase
{
IProject project;
IRegisteredTestFrameworks testFrameworks;
@ -34,8 +35,8 @@ namespace ICSharpCode.UnitTesting @@ -34,8 +35,8 @@ namespace ICSharpCode.UnitTesting
var compilation = SD.ParserService.GetCompilation(project);
var classes = project.ProjectContent
.Resolve(compilation.TypeResolveContext)
.GetAllTypeDefinitions()
.Where(td => td.HasTests(compilation))
.TopLevelTypeDefinitions
.Where(td => testFrameworks.IsTestClass(td, compilation))
.Select(g => new TestClass(testFrameworks, g.ReflectionName, g));
testClasses = new ObservableCollection<TestClass>(classes);
}
@ -45,7 +46,7 @@ namespace ICSharpCode.UnitTesting @@ -45,7 +46,7 @@ namespace ICSharpCode.UnitTesting
var context = new SimpleTypeResolveContext(SD.ParserService.GetCompilation(project).MainAssembly);
IEnumerable<ITypeDefinition> @new;
if (e.NewParsedFile != null)
@new = e.NewParsedFile.TopLevelTypeDefinitions.Select(utd => utd.Resolve(context).GetDefinition()).Where(x => x != null && x.HasTests(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
@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());
@ -59,9 +60,62 @@ namespace ICSharpCode.UnitTesting @@ -59,9 +60,62 @@ namespace ICSharpCode.UnitTesting
get { return testClasses; }
}
public TestMember GetTestMethod(string fullName)
{
foreach (var tc in testClasses) {
var result = TreeTraversal.PostOrder(tc, c => c.NestedClasses)
.SelectMany(c => c.Members)
.SingleOrDefault(m => fullName.Equals(m.Method.ReflectionName, StringComparison.Ordinal));
if (result != null)
return result;
}
return null;
}
public bool FindTestInfo(string fullName, out TestClass testClass, out TestMember method)
{
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));
if (method != null)
return true;
}
}
return false;
}
public void UpdateTestResult(TestResult result)
{
TestMember member;
TestClass testClass;
if (FindTestInfo(result.Name, out testClass, out member)) {
member.TestResult = result.ResultType;
testClass.TestResult = r
}
}
public void ResetTestResults()
{
foreach (var member in testClasses.SelectMany(tc => TreeTraversal.PostOrder(tc, c => c.NestedClasses)).SelectMany(c => c.Members))
member.TestResult = TestResultType.None;
}
TestResultType testResult;
/// <summary>
/// Gets the test result for this project.
/// </summary>
public TestResultType TestResult {
get { return testResult; }
set {
if (testResult != value) {
testResult = value;
OnPropertyChanged();
}
}
}
}
}

6
src/AddIns/Analysis/UnitTesting/NUnit/NUnitConsoleCommandLine.cs → src/AddIns/Analysis/UnitTesting/NUnit/NUnitConsoleApplication.cs

@ -36,9 +36,9 @@ namespace ICSharpCode.UnitTesting @@ -36,9 +36,9 @@ namespace ICSharpCode.UnitTesting
NamespaceFilter = selectedTests.NamespaceFilter;
}
if (selectedTests.Class != null) {
Fixture = selectedTests.Class.DotNetName;
if (selectedTests.Member != null) {
Test = selectedTests.Member.Name;
Fixture = selectedTests.Class.FullName;
if (selectedTests.Method != null) {
Test = selectedTests.Method.Method.Name;
}
}
}

7
src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestDebugger.cs

@ -3,7 +3,8 @@ @@ -3,7 +3,8 @@
using System;
using System.Diagnostics;
using ICSharpCode.Core.Services;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
namespace ICSharpCode.UnitTesting
@ -14,14 +15,14 @@ namespace ICSharpCode.UnitTesting @@ -14,14 +15,14 @@ namespace ICSharpCode.UnitTesting
public NUnitTestDebugger()
: this(new UnitTestDebuggerService(),
new UnitTestMessageService(),
SD.MessageService,
new TestResultsMonitor(),
UnitTestingOptions.Instance.Clone())
{
}
public NUnitTestDebugger(IUnitTestDebuggerService debuggerService,
IUnitTestMessageService messageService,
IMessageService messageService,
ITestResultsMonitor testResultsMonitor,
UnitTestingOptions options)
: base(debuggerService, messageService, testResultsMonitor)

132
src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestFramework.cs

@ -2,130 +2,70 @@ @@ -2,130 +2,70 @@
// 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 System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.UnitTesting
{
public class NUnitTestFramework : ITestFramework
{
/// <summary>
/// Determines whether the project is a test project. A project
/// is considered to be a test project if it contains a reference
/// to the NUnit.Framework assembly.
/// </summary>
public bool IsTestProject(IProject project)
{
if (project != null) {
foreach (ProjectItem projectItem in project.Items) {
var referenceProjectItem = projectItem as ReferenceProjectItem;
if (IsNUnitFrameworkAssemblyReference(referenceProjectItem)) {
return true;
}
}
}
return false;
public bool IsBuildNeededBeforeTestRun {
get { return true; }
}
bool IsNUnitFrameworkAssemblyReference(ReferenceProjectItem referenceProjectItem)
public ITestRunner CreateTestRunner()
{
if (referenceProjectItem != null) {
string name = referenceProjectItem.ShortName;
return name.Equals("NUnit.Framework", StringComparison.OrdinalIgnoreCase);
}
return false;
return new NUnitTestRunner();
}
/// <summary>
/// Determines whether the class is a test fixture. A class
/// is considered to be a test class if it contains a TestFixture attribute.
/// </summary>
public bool IsTestClass(IClass c)
public ITestRunner CreateTestDebugger()
{
if (c == null) return false;
if (c.IsAbstract) return false;
StringComparer nameComparer = GetNameComparer(c);
if (nameComparer != null) {
NUnitTestAttributeName testAttributeName = new NUnitTestAttributeName("TestFixture", nameComparer);
foreach (IAttribute attribute in c.Attributes) {
if (testAttributeName.IsEqual(attribute)) {
return true;
}
}
}
while (c != null) {
if (HasTestMethod(c)) return true;
c = c.BaseClass;
}
return false;
}
private bool HasTestMethod(IClass c) {
return GetTestMembersFor(c).Any();
return new NUnitTestDebugger();
}
static StringComparer GetNameComparer(IClass c)
{
if (c != null) {
IProjectContent projectContent = c.ProjectContent;
if (projectContent != null) {
LanguageProperties language = projectContent.Language;
if (language != null) {
return language.NameComparer;
}
}
}
return null;
}
static readonly ITypeReference testAttribute = new GetClassTypeReference("NUnit.Framework", "TestAttribute", 0);
static readonly ITypeReference testCaseAttribute = new GetClassTypeReference("NUnit.Framework", "TestCaseAttribute", 0);
/// <summary>
/// Determines whether the method is a test method. A method
/// is considered to be a test method if it contains the NUnit Test attribute.
/// If the method has parameters it cannot be a test method.
/// Determines whether the project is a test project. A project
/// is considered to be a test project if it contains a reference
/// to the NUnit.Framework assembly.
/// </summary>
public bool IsTestMember(IMember member)
public bool IsTestProject(IProject project)
{
var method = member as IMethod;
if (method != null) {
return IsTestMethod(method);
}
return false;
}
public IEnumerable<TestMember> GetTestMembersFor(IClass @class) {
return @class.Methods.Where(IsTestMethod).Select(member => new TestMember(member));
if (project == null)
throw new ArgumentNullException("project");
if (project.ProjectContent == null)
return false;
return testAttribute.Resolve(SD.ParserService.GetCompilation(project).TypeResolveContext).Kind != TypeKind.Unknown;
}
static bool IsTestMethod(IMethod method)
public bool IsTestMethod(IMethod method, ICompilation compilation)
{
var nameComparer = GetNameComparer(method.DeclaringType);
if (nameComparer != null) {
var testAttribute = new NUnitTestAttributeName("Test", nameComparer);
foreach (IAttribute attribute in method.Attributes) {
if (testAttribute.IsEqual(attribute)) {
if (method.Parameters.Count == 0) {
return true;
}
}
}
}
return false;
}
public bool IsBuildNeededBeforeTestRun {
get { return true; }
if (method == null)
throw new ArgumentNullException("method");
var testAttribute = NUnitTestFramework.testAttribute.Resolve(compilation.TypeResolveContext);
var testCaseAttribute = NUnitTestFramework.testCaseAttribute.Resolve(compilation.TypeResolveContext);
return method.Attributes.Any(a => a.AttributeType.Equals(testAttribute) || a.AttributeType.Equals(testCaseAttribute));
}
public ITestRunner CreateTestRunner()
public bool IsTestClass(ITypeDefinition type, ICompilation compilation)
{
return new NUnitTestRunner();
if (type == null)
throw new ArgumentNullException("type");
var testAttribute = NUnitTestFramework.testAttribute.Resolve(compilation.TypeResolveContext);
var testCaseAttribute = NUnitTestFramework.testCaseAttribute.Resolve(compilation.TypeResolveContext);
return type.Methods.Any(m => m.Attributes.Any(a => a.AttributeType.Equals(testAttribute) || a.AttributeType.Equals(testCaseAttribute)));
}
public ITestRunner CreateTestDebugger()
public IEnumerable<IMethod> GetTestMethodsFor(ITypeDefinition typeDefinition)
{
return new NUnitTestDebugger();
throw new NotImplementedException();
}
}
}

4
src/AddIns/Analysis/UnitTesting/NUnit/NUnitTestResult.cs

@ -24,14 +24,14 @@ namespace ICSharpCode.UnitTesting @@ -24,14 +24,14 @@ namespace ICSharpCode.UnitTesting
if (fileLineRef != null) {
StackTraceFilePosition = CreateFilePosition(fileLineRef);
} else {
StackTraceFilePosition = FilePosition.Empty;
StackTraceFilePosition = DomRegion.Empty;
}
}
DomRegion CreateFilePosition(FileLineReference fileLineRef)
{
string fileName = Path.GetFullPath(fileLineRef.FileName);
return new FilePosition(fileName, fileLineRef.Line, fileLineRef.Column + 1);
return new DomRegion(fileName, fileLineRef.Line, fileLineRef.Column + 1);
}
}
}

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

@ -75,5 +75,9 @@ namespace ICSharpCode.UnitTesting @@ -75,5 +75,9 @@ namespace ICSharpCode.UnitTesting
public override object Text {
get { return testClass.Name; }
}
internal override TestResultType TestResultType {
get { return testClass.TestResult; }
}
}
}

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

@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using ICSharpCode.TreeView;
namespace ICSharpCode.UnitTesting
{
@ -17,6 +19,19 @@ namespace ICSharpCode.UnitTesting @@ -17,6 +19,19 @@ namespace ICSharpCode.UnitTesting
public MemberUnitTestNode(TestMember testMember)
{
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;
}
}
};
}
internal override TestResultType TestResultType {
get { return this.testMember.TestResult; }
}
public override object Text {

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

@ -34,5 +34,9 @@ namespace ICSharpCode.UnitTesting @@ -34,5 +34,9 @@ namespace ICSharpCode.UnitTesting
public override object Text {
get { return name.Substring(name.LastIndexOf('.') + 1); }
}
internal override TestResultType TestResultType {
get { return TestResultType.None; }
}
}
}

12
src/AddIns/Analysis/UnitTesting/Nodes/ProjectUnitTestNode.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Windows.Controls;
@ -28,9 +29,16 @@ namespace ICSharpCode.UnitTesting @@ -28,9 +29,16 @@ namespace ICSharpCode.UnitTesting
{
this.project = project;
project.TestClasses.CollectionChanged += TestClassesCollectionChanged;
project.PropertyChanged += ProjectPropertyChanged;
LazyLoading = true;
}
void ProjectPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "TestResult")
RaisePropertyChanged("Icon");
}
void TestClassesCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action) {
@ -142,5 +150,9 @@ namespace ICSharpCode.UnitTesting @@ -142,5 +150,9 @@ namespace ICSharpCode.UnitTesting
public override object Text {
get { return project.Project.Name; }
}
internal override TestResultType TestResultType {
get { return project.TestResult; }
}
}
}

13
src/AddIns/Analysis/UnitTesting/Nodes/RootUnitTestNode.cs

@ -56,5 +56,18 @@ namespace ICSharpCode.UnitTesting @@ -56,5 +56,18 @@ namespace ICSharpCode.UnitTesting
public override object Text {
get { return ResourceService.GetString("ICSharpCode.UnitTesting.AllTestsTreeNode.Text"); }
}
internal override TestResultType TestResultType {
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;
}
}
}
}

13
src/AddIns/Analysis/UnitTesting/Nodes/UnitTestBaseNode.cs

@ -9,18 +9,7 @@ namespace ICSharpCode.UnitTesting @@ -9,18 +9,7 @@ namespace ICSharpCode.UnitTesting
{
public abstract class UnitTestBaseNode : SharpTreeNode
{
internal virtual TestResultType TestResultType {
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;
}
}
internal abstract TestResultType TestResultType { get; }
public override object Icon {
get { return GetIcon(TestResultType); }

47
src/AddIns/Analysis/UnitTesting/Service/InnerClassEnumerator.cs

@ -1,47 +0,0 @@ @@ -1,47 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.UnitTesting
{
public class InnerClassEnumerator : IEnumerable<IClass>
{
readonly IClass _c;
public InnerClassEnumerator(IClass c)
{
_c = c;
}
#region IEnumerable<IClass> Members
public IEnumerator<IClass> GetEnumerator()
{
var result = new List<IClass>();
Visit(_c, result);
return result.GetEnumerator();
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#endregion
private void Visit(IClass c, List<IClass> resultList)
{
foreach (var innerClass in c.InnerClasses)
{
resultList.Add(innerClass);
Visit(innerClass, resultList);
}
}
}
}

34
src/AddIns/Analysis/UnitTesting/Service/RegisteredTestFrameworks.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop.Project;
@ -30,49 +31,50 @@ namespace ICSharpCode.UnitTesting @@ -30,49 +31,50 @@ namespace ICSharpCode.UnitTesting
return null;
}
public bool IsTestMember(IUnresolvedMember member)
public bool IsTestMethod(IMethod method, ICompilation compilation)
{
ITestFramework testFramework = GetTestFramework(member);
ITestFramework testFramework = GetTestFramework(method, compilation);
if (testFramework != null) {
return testFramework.IsTestMember(member);
return testFramework.IsTestMethod(method, compilation);
}
return false;
}
public IEnumerable<IUnresolvedMember> GetTestMembersFor(IUnresolvedTypeDefinition @class) {
ITestFramework testFramework = GetTestFramework(@class);
public IEnumerable<IMethod> GetTestMethodsFor(ITypeDefinition type, ICompilation compilation)
{
ITestFramework testFramework = GetTestFramework(type, compilation);
if (testFramework != null)
return testFramework.GetTestMembersFor(@class);
return new IUnresolvedMember[0];
return testFramework.GetTestMethodsFor(type);
return new IMethod[0];
}
ITestFramework GetTestFramework(IUnresolvedMember member)
ITestFramework GetTestFramework(IMethod method, ICompilation compilation)
{
if (member != null) {
return GetTestFramework(member.DeclaringTypeDefinition);
if (method != null) {
return GetTestFramework(method.DeclaringTypeDefinition, compilation);
}
return null;
}
ITestFramework GetTestFramework(IUnresolvedTypeDefinition c)
ITestFramework GetTestFramework(ITypeDefinition c, ICompilation compilation)
{
IProject project = GetProject(c);
return GetTestFrameworkForProject(project);
}
IProject GetProject(IUnresolvedTypeDefinition c)
IProject GetProject(ITypeDefinition c)
{
if (c != null && ProjectService.OpenSolution != null) {
return ProjectService.OpenSolution.FindProjectContainingFile(c.ParsedFile.FileName);
return ProjectService.OpenSolution.FindProjectContainingFile(c.Parts[0].ParsedFile.FileName);
}
return null;
}
public bool IsTestClass(IUnresolvedTypeDefinition c)
public bool IsTestClass(ITypeDefinition c, ICompilation compilation)
{
ITestFramework testFramework = GetTestFramework(c);
ITestFramework testFramework = GetTestFramework(c, compilation);
if (testFramework != null) {
return testFramework.IsTestClass(c);
return testFramework.IsTestClass(c, compilation);
}
return false;
}

22
src/AddIns/Analysis/UnitTesting/Service/SelectedTests.cs

@ -12,14 +12,14 @@ namespace ICSharpCode.UnitTesting @@ -12,14 +12,14 @@ namespace ICSharpCode.UnitTesting
{
string namespaceFilter;
TestClass c;
// TestMember member;
TestMember member;
List<IProject> projects = new List<IProject>();
public SelectedTests(IProject project, string namespaceFilter, TestClass c)//, TestMember member)
public SelectedTests(IProject project, string namespaceFilter, TestClass c, TestMember member)
{
this.namespaceFilter = namespaceFilter;
this.c = c;
// this.member = member;
this.member = member;
if (project != null) {
projects.Add(project);
@ -27,7 +27,7 @@ namespace ICSharpCode.UnitTesting @@ -27,7 +27,7 @@ namespace ICSharpCode.UnitTesting
}
public SelectedTests(IProject project)
: this(project, null, null)//, null)
: this(project, null, null, null)
{
}
@ -85,12 +85,12 @@ namespace ICSharpCode.UnitTesting @@ -85,12 +85,12 @@ namespace ICSharpCode.UnitTesting
get { return namespaceFilter; }
}
// public IUnresolvedTypeDefinition Class {
// get { return c; }
// }
//
// public IUnresolvedMember Member {
// get { return member; }
// }
public TestClass Class {
get { return c; }
}
public TestMember Method {
get { return member; }
}
}
}

214
src/AddIns/Analysis/UnitTesting/Service/TestClassCollection.cs

@ -1,214 +0,0 @@ @@ -1,214 +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 System.Collections.Generic;
using System.Collections.ObjectModel;
using ICSharpCode.Core;
namespace ICSharpCode.UnitTesting
{
public class TestClassCollection : KeyedCollection<string, TestClass>
{
TestResultType testResult = TestResultType.None;
Dictionary<string, TestClass> passedTestClasses = new Dictionary<string, TestClass>();
Dictionary<string, TestClass> failedTestClasses = new Dictionary<string, TestClass>();
Dictionary<string, TestClass> ignoredTestClasses = new Dictionary<string, TestClass>();
/// <summary>
/// Raised when the test result for this collection of
/// classes has changed.
/// </summary>
public event EventHandler ResultChanged;
/// <summary>
/// Raised when a class is added to this collection.
/// </summary>
public event TestClassEventHandler TestClassAdded;
/// <summary>
/// Raised when a class is removed from this collection.
/// </summary>
public event TestClassEventHandler TestClassRemoved;
/// <summary>
/// Gets the overall test results for the collection of
/// test classes.
/// </summary>
public TestResultType Result {
get {
return testResult;
}
}
/// <summary>
/// Sets all the test class test results back to none.
/// </summary>
public void ResetTestResults()
{
passedTestClasses.Clear();
failedTestClasses.Clear();
ignoredTestClasses.Clear();
foreach (TestClass c in this) {
c.ResetTestResults();
}
SetTestResult(TestResultType.None);
}
/// <summary>
/// Updates the test method with the specified test result.
/// </summary>
public void UpdateTestResult(TestResult testResult)
{
TestClass testClass = GetTestClassFromTestMemberName(testResult.Name);
if (testClass != null) {
testClass.UpdateTestResult(testResult);
}
}
/// <summary>
/// Gets the matching test member from this set of classes.
/// </summary>
/// <param name="fullyQualifiedName">The fully qualified
/// method name (e.g. Namespace.ClassName.MethodName).</param>
/// <returns>Null if the method cannot be found.</returns>
public TestMember GetTestMember(string fullyQualifiedName)
{
string className = TestMember.GetQualifiedClassName(fullyQualifiedName);
if (className != null) {
if (Contains(className)) {
TestClass testClass = this[className];
string memberName = TestMember.GetMemberName(fullyQualifiedName);
if (memberName != null) {
return testClass.GetTestMember(memberName);
}
} else {
LoggingService.Debug("TestClass not found: " + className);
}
} else {
LoggingService.Debug("Invalid test member name: " + fullyQualifiedName);
}
return null;
}
protected override string GetKeyForItem(TestClass item)
{
return item.QualifiedName;
}
protected override void InsertItem(int index, TestClass item)
{
item.ResultChanged += TestClassResultChanged;
base.InsertItem(index, item);
TestClassResultChanged(item, new EventArgs());
OnTestClassAdded(item);
}
protected override void RemoveItem(int index)
{
TestClass c = this[index];
c.ResultChanged -= TestClassResultChanged;
base.RemoveItem(index);
OnTestResultNone(c.Name);
OnTestClassRemoved(c);
}
protected void OnTestClassAdded(TestClass testClass)
{
if (TestClassAdded != null) {
TestClassAdded(this, new TestClassEventArgs(testClass));
}
}
protected void OnTestClassRemoved(TestClass testClass)
{
if (TestClassRemoved != null) {
TestClassRemoved(this, new TestClassEventArgs(testClass));
}
}
void TestClassResultChanged(object source, EventArgs e)
{
TestClass c = (TestClass)source;
switch (c.Result) {
case TestResultType.None:
OnTestResultNone(c.QualifiedName);
break;
case TestResultType.Failure:
SetTestResult(TestResultType.Failure);
failedTestClasses.Add(c.QualifiedName, c);
break;
case TestResultType.Success:
passedTestClasses.Add(c.QualifiedName, c);
if (passedTestClasses.Count == Count) {
SetTestResult(TestResultType.Success);
} else if (passedTestClasses.Count + ignoredTestClasses.Count == Count) {
SetTestResult(TestResultType.Ignored);
}
break;
case TestResultType.Ignored:
ignoredTestClasses.Add(c.QualifiedName, c);
if (ignoredTestClasses.Count == Count ||
ignoredTestClasses.Count + passedTestClasses.Count == Count) {
SetTestResult(TestResultType.Ignored);
}
break;
}
}
void SetTestResult(TestResultType value)
{
TestResultType previousTestResult = testResult;
testResult = value;
if (testResult != previousTestResult) {
OnResultChanged();
}
}
void OnResultChanged()
{
if (ResultChanged != null) {
ResultChanged(this, new EventArgs());
}
}
/// <summary>
/// Removes the specified test class from the list of
/// failed, passed and ignored tests and updates the
/// test result state of the test class collection.
/// </summary>
void OnTestResultNone(string qualifiedName)
{
passedTestClasses.Remove(qualifiedName);
failedTestClasses.Remove(qualifiedName);
ignoredTestClasses.Remove(qualifiedName);
if (ignoredTestClasses.Count + failedTestClasses.Count == 0) {
SetTestResult(TestResultType.None);
}
}
/// <summary>
/// Gets the test class from the specified test result.
/// </summary>
TestClass GetTestClassFromTestMemberName(string memberName)
{
if (memberName != null) {
string className = TestMember.GetQualifiedClassName(memberName);
if (className != null) {
if (Contains(className)) {
return this[className];
} else {
LoggingService.Debug("TestClass not found: " + className);
return GetTestClassFromTestMemberName(className);
}
} else {
LoggingService.Debug("Invalid TestMember.Name: " + memberName);
}
}
return null;
}
}
}

30
src/AddIns/Analysis/UnitTesting/Service/TestClassEventArgs.cs

@ -1,30 +0,0 @@ @@ -1,30 +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;
namespace ICSharpCode.UnitTesting
{
/// <summary>
/// Represents the class that will handle the TestCollection's
/// TestClassAdded or TestClassRemoved events.
/// </summary>
public delegate void TestClassEventHandler(object source, TestClassEventArgs e);
/// <summary>
/// Provides data for the TestCollection's TestClassAdded and TestClassRemoved events.
/// </summary>
public class TestClassEventArgs
{
TestClass testClass;
public TestClassEventArgs(TestClass testClass)
{
this.testClass = testClass;
}
public TestClass TestClass {
get { return testClass; }
}
}
}

8
src/AddIns/Analysis/UnitTesting/Service/TestDebuggerBase.cs

@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
using System;
using System.Diagnostics;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Debugging;
namespace ICSharpCode.UnitTesting
@ -10,19 +12,19 @@ namespace ICSharpCode.UnitTesting @@ -10,19 +12,19 @@ namespace ICSharpCode.UnitTesting
public abstract class TestDebuggerBase : TestRunnerBase
{
IUnitTestDebuggerService debuggerService;
IUnitTestMessageService messageService;
IMessageService messageService;
IDebugger debugger;
ITestResultsMonitor testResultsMonitor;
public TestDebuggerBase()
: this(new UnitTestDebuggerService(),
new UnitTestMessageService(),
SD.MessageService,
new TestResultsMonitor())
{
}
public TestDebuggerBase(IUnitTestDebuggerService debuggerService,
IUnitTestMessageService messageService,
IMessageService messageService,
ITestResultsMonitor testResultsMonitor)
{
this.debuggerService = debuggerService;

153
src/AddIns/Analysis/UnitTesting/Service/TestMemberCollection.cs

@ -1,153 +0,0 @@ @@ -1,153 +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 System.Collections.Generic;
using System.Collections.ObjectModel;
namespace ICSharpCode.UnitTesting
{
public class TestMemberCollection : KeyedCollection<string, TestMember>
{
TestResultType testResult = TestResultType.None;
Dictionary<string, TestMember> passedTestMembers = new Dictionary<string, TestMember>();
Dictionary<string, TestMember> failedTestMembers = new Dictionary<string, TestMember>();
Dictionary<string, TestMember> ignoredTestMembers = new Dictionary<string, TestMember>();
/// <summary>
/// Raised when the test result for this collection of
/// members has changed.
/// </summary>
public event EventHandler ResultChanged;
/// <summary>
/// Raised when a member is added to this collection.
/// </summary>
public event TestMemberEventHandler TestMemberAdded;
/// <summary>
/// Raised when a member is removed from this collection.
/// </summary>
public event TestMemberEventHandler TestMemberRemoved;
/// <summary>
/// Gets the overall test results for the collection of
/// test members.
/// </summary>
public TestResultType Result {
get { return testResult; }
}
/// <summary>
/// Sets all the test members test results back to none.
/// </summary>
public void ResetTestResults()
{
passedTestMembers.Clear();
failedTestMembers.Clear();
ignoredTestMembers.Clear();
foreach (TestMember member in this) {
member.Result = TestResultType.None;
}
SetTestResult(TestResultType.None);
}
protected override void InsertItem(int index, TestMember item)
{
item.ResultChanged += TestMemberResultChanged;
base.InsertItem(index, item);
TestMemberResultChanged(item, new EventArgs());
OnTestMemberAdded(item);
}
protected override string GetKeyForItem(TestMember item)
{
return item.Name;
}
protected override void RemoveItem(int index)
{
TestMember member = this[index];
member.ResultChanged -= TestMemberResultChanged;
base.RemoveItem(index);
OnTestResultNone(member.Name);
OnTestMemberRemoved(member);
}
protected void OnTestMemberAdded(TestMember testMember)
{
if (TestMemberAdded != null) {
TestMemberAdded(this, new TestMemberEventArgs(testMember));
}
}
protected void OnTestMemberRemoved(TestMember testMember)
{
if (TestMemberRemoved != null) {
TestMemberRemoved(this, new TestMemberEventArgs(testMember));
}
}
void TestMemberResultChanged(object source, EventArgs e)
{
TestMember member = (TestMember)source;
switch (member.Result) {
case TestResultType.None:
OnTestResultNone(member.Name);
break;
case TestResultType.Failure:
SetTestResult(TestResultType.Failure);
failedTestMembers.Add(member.Name, member);
break;
case TestResultType.Success:
passedTestMembers.Add(member.Name, member);
if (passedTestMembers.Count == Count) {
SetTestResult(TestResultType.Success);
} else if (passedTestMembers.Count + ignoredTestMembers.Count == Count) {
SetTestResult(TestResultType.Ignored);
}
break;
case TestResultType.Ignored:
ignoredTestMembers.Add(member.Name, member);
if (ignoredTestMembers.Count == Count ||
ignoredTestMembers.Count + passedTestMembers.Count == Count) {
SetTestResult(TestResultType.Ignored);
}
break;
}
}
void SetTestResult(TestResultType value)
{
TestResultType previousTestResult = testResult;
testResult = value;
if (testResult != previousTestResult) {
OnResultChanged();
}
}
void OnResultChanged()
{
if (ResultChanged != null) {
ResultChanged(this, new EventArgs());
}
}
/// <summary>
/// Removes the specified test member from the list of
/// failed, passed and ignored tests and updates the
/// test result state of the test members collection.
/// </summary>
void OnTestResultNone(string name)
{
passedTestMembers.Remove(name);
failedTestMembers.Remove(name);
ignoredTestMembers.Remove(name);
if (ignoredTestMembers.Count + failedTestMembers.Count == 0) {
SetTestResult(TestResultType.None);
}
}
}
}

30
src/AddIns/Analysis/UnitTesting/Service/TestMemberEventArgs.cs

@ -1,30 +0,0 @@ @@ -1,30 +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;
namespace ICSharpCode.UnitTesting
{
/// <summary>
/// Represents the member that will handle the TestCollection's
/// TestMemberAdded or TestMemberRemoved events.
/// </summary>
public delegate void TestMemberEventHandler(object source, TestMemberEventArgs e);
/// <summary>
/// Provides data for the TestCollection's TestMemberAdded and TestMemberRemoved events.
/// </summary>
public class TestMemberEventArgs
{
TestMember testMember;
public TestMemberEventArgs(TestMember testMember)
{
this.testMember = testMember;
}
public TestMember TestMember {
get { return testMember; }
}
}
}

11
src/AddIns/Analysis/UnitTesting/TestProcessRunnerBase.cs → src/AddIns/Analysis/UnitTesting/Service/TestProcessRunnerBase.cs

@ -3,7 +3,8 @@ @@ -3,7 +3,8 @@
using System;
using System.Diagnostics;
using ICSharpCode.Core.WinForms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Util;
namespace ICSharpCode.UnitTesting
@ -13,13 +14,13 @@ namespace ICSharpCode.UnitTesting @@ -13,13 +14,13 @@ namespace ICSharpCode.UnitTesting
IUnitTestProcessRunner processRunner;
ITestResultsMonitor testResultsMonitor;
IFileSystem fileSystem;
IUnitTestMessageService messageService;
IMessageService messageService;
public TestProcessRunnerBase()
: this(new UnitTestProcessRunner(),
new TestResultsMonitor(),
new UnitTestFileService(),
new UnitTestMessageService())
SD.MessageService)
{
}
@ -34,7 +35,7 @@ namespace ICSharpCode.UnitTesting @@ -34,7 +35,7 @@ namespace ICSharpCode.UnitTesting
public TestProcessRunnerBase(IUnitTestProcessRunner processRunner,
ITestResultsMonitor testResultsMonitor,
IFileSystem fileSystem,
IUnitTestMessageService messageService)
IMessageService messageService)
{
this.processRunner = processRunner;
this.testResultsMonitor = testResultsMonitor;
@ -88,7 +89,7 @@ namespace ICSharpCode.UnitTesting @@ -88,7 +89,7 @@ namespace ICSharpCode.UnitTesting
void ShowApplicationDoesNotExistMessage(string fileName)
{
string resourceString = "${res:ICSharpCode.UnitTesting.TestRunnerNotFoundMessageFormat}";
messageService.ShowFormattedErrorMessage(resourceString, fileName);
messageService.ShowErrorFormatted(resourceString, fileName);
}
public override void Stop()

11
src/AddIns/Analysis/UnitTesting/TestProcessRunnerBaseContext.cs → src/AddIns/Analysis/UnitTesting/Service/TestProcessRunnerBaseContext.cs

@ -2,7 +2,8 @@ @@ -2,7 +2,8 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using ICSharpCode.Core.WinForms;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Util;
namespace ICSharpCode.UnitTesting
@ -12,20 +13,20 @@ namespace ICSharpCode.UnitTesting @@ -12,20 +13,20 @@ namespace ICSharpCode.UnitTesting
IUnitTestProcessRunner processRunner;
ITestResultsMonitor testResultsMonitor;
IFileSystem fileSystem;
IUnitTestMessageService messageService;
IMessageService messageService;
public TestProcessRunnerBaseContext()
: this(new UnitTestProcessRunner(),
new TestResultsMonitor(),
new UnitTestFileService(),
new UnitTestMessageService())
SD.MessageService)
{
}
public TestProcessRunnerBaseContext(IUnitTestProcessRunner processRunner,
ITestResultsMonitor testResultsMonitor,
IFileSystem fileSystem,
IUnitTestMessageService messageService)
IMessageService messageService)
{
this.processRunner = processRunner;
this.testResultsMonitor = testResultsMonitor;
@ -45,7 +46,7 @@ namespace ICSharpCode.UnitTesting @@ -45,7 +46,7 @@ namespace ICSharpCode.UnitTesting
get { return fileSystem; }
}
public IUnitTestMessageService MessageService {
public IMessageService MessageService {
get { return messageService; }
}
}

6
src/AddIns/Analysis/UnitTesting/Service/TestService.cs

@ -74,13 +74,13 @@ namespace ICSharpCode.UnitTesting @@ -74,13 +74,13 @@ namespace ICSharpCode.UnitTesting
static void ProjectService_ProjectCreated(object sender, ProjectEventArgs e)
{
if (e.Project.IsTestProject())
if (RegisteredTestFrameworks.IsTestProject(e.Project))
testableProjects.Add(new TestProject(e.Project));
}
static void ProjectService_ProjectAdded(object sender, ProjectEventArgs e)
{
if (e.Project.IsTestProject())
if (RegisteredTestFrameworks.IsTestProject(e.Project))
testableProjects.Add(new TestProject(e.Project));
}
@ -110,7 +110,7 @@ namespace ICSharpCode.UnitTesting @@ -110,7 +110,7 @@ namespace ICSharpCode.UnitTesting
{
if (ProjectService.OpenSolution == null)
return Enumerable.Empty<TestProject>();
return ProjectService.OpenSolution.Projects.Where(p => p.IsTestProject()).Select(p => new TestProject(p));
return ProjectService.OpenSolution.Projects.Where(p => RegisteredTestFrameworks.IsTestProject(p)).Select(p => new TestProject(p));
}
}
}

66
src/AddIns/Analysis/UnitTesting/Service/TestableCondition.cs

@ -3,6 +3,9 @@ @@ -3,6 +3,9 @@
using System;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Bookmarks;
using ICSharpCode.SharpDevelop.Project;
@ -25,39 +28,33 @@ namespace ICSharpCode.UnitTesting @@ -25,39 +28,33 @@ namespace ICSharpCode.UnitTesting
{
}
public static IMember GetMember(object caller)
public static IMethod GetMethod(object caller)
{
ITestTreeView testTreeView = caller as ITestTreeView;
if (testTreeView != null) {
return testTreeView.SelectedMember;
}
MemberNode memberNode = caller as MemberNode;
if (memberNode != null) {
return memberNode.Member;
} else {
ClassMemberBookmark mbookmark = caller as ClassMemberBookmark;
if (mbookmark != null) {
return mbookmark.Member;
}
return testTreeView.SelectedMethod;
}
// MemberNode memberNode = caller as MemberNode;
// if (memberNode != null)
// return memberNode.Member;
// ClassMemberBookmark mbookmark = caller as ClassMemberBookmark;
// if (mbookmark != null)
// return mbookmark.Member;
return null;
}
public static IClass GetClass(object caller)
public static ITypeDefinition GetClass(object caller)
{
ITestTreeView testTreeView = caller as ITestTreeView;
if (testTreeView != null) {
return testTreeView.SelectedClass;
}
ClassNode classNode = caller as ClassNode;
if (classNode != null) {
return classNode.Class;
} else {
ClassBookmark bookmark = caller as ClassBookmark;
if (bookmark != null) {
return bookmark.Class;
}
}
// ClassNode classNode = caller as ClassNode;
// if (classNode != null)
// return classNode.Class;
// ClassBookmark bookmark = caller as ClassBookmark;
// if (bookmark != null)
// return bookmark.Class;
return null;
}
@ -67,25 +64,22 @@ namespace ICSharpCode.UnitTesting @@ -67,25 +64,22 @@ namespace ICSharpCode.UnitTesting
if (testTreeView != null) {
return testTreeView.SelectedProject;
}
IClass c = GetClassFromMemberOrCaller(caller);
ITypeDefinition c = GetClassFromMemberOrCaller(caller);
return GetProject(c);
}
static IClass GetClassFromMemberOrCaller(object caller)
static ITypeDefinition GetClassFromMemberOrCaller(object caller)
{
IMember m = GetMember(caller);
IMethod m = GetMethod(caller);
if (m != null) {
return m.DeclaringType;
return m.DeclaringType.GetDefinition();
}
return GetClass(caller);
}
static IProject GetProject(IClass c)
static IProject GetProject(ITypeDefinition c)
{
if (c != null) {
return (IProject)c.ProjectContent.Project;
}
return null;
return c != null ? c.ParentAssembly.GetProject() : null;
}
/// <summary>
@ -102,20 +96,20 @@ namespace ICSharpCode.UnitTesting @@ -102,20 +96,20 @@ namespace ICSharpCode.UnitTesting
public bool IsValid(object caller, Condition condition)
{
IMember m = GetMember(caller);
IMethod m = GetMethod(caller);
if (m != null) {
return testFrameworks.IsTestMember(m);
return testFrameworks.IsTestMethod(m, m.Compilation);
}
IClass c = GetClass(caller);
ITypeDefinition c = GetClass(caller);
if (ClassHasProject(c)) {
return testFrameworks.IsTestClass(c);
return testFrameworks.IsTestClass(c, c.Compilation);
}
return false;
}
static bool ClassHasProject(IClass c)
static bool ClassHasProject(ITypeDefinition c)
{
return (c != null) && (c.ProjectContent.Project != null);
return (c != null) && (c.ParentAssembly.GetProject() != null);
}
}
}

9
src/AddIns/Analysis/UnitTesting/UnitTestApplicationStartHelper.cs

@ -5,10 +5,9 @@ using System; @@ -5,10 +5,9 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
@ -101,7 +100,7 @@ namespace ICSharpCode.UnitTesting @@ -101,7 +100,7 @@ namespace ICSharpCode.UnitTesting
IProject project;
public void Initialize(IProject project, IClass fixture, IMember test)
public void Initialize(IProject project, ITypeDefinition fixture, IMethod test)
{
Initialize(project, null, fixture, test);
}
@ -111,7 +110,7 @@ namespace ICSharpCode.UnitTesting @@ -111,7 +110,7 @@ namespace ICSharpCode.UnitTesting
Initialize(project, namespaceFilter, null, null);
}
public void Initialize(IProject project, string namespaceFilter, IClass fixture, IMember test)
public void Initialize(IProject project, string namespaceFilter, ITypeDefinition fixture, IMethod test)
{
this.project = project;
Assemblies.Add(project.OutputAssemblyFullPath);
@ -119,7 +118,7 @@ namespace ICSharpCode.UnitTesting @@ -119,7 +118,7 @@ namespace ICSharpCode.UnitTesting
NamespaceFilter = namespaceFilter;
}
if (fixture != null) {
Fixture = fixture.DotNetName;
Fixture = fixture.ReflectionName;
if (test != null) {
Test = test.Name;
}

16
src/AddIns/Analysis/UnitTesting/UnitTesting.csproj

@ -70,7 +70,7 @@ @@ -70,7 +70,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Commands\AbstractRunTestCommand.cs" />
<Compile Include="Commands\RunTestCommands.cs" />
<Compile Include="Extensions.cs" />
<Compile Include="Gui\EmptyUnitTestsPad.cs" />
<Compile Include="Gui\UnitTestingOptionsPanel.xaml.cs">
@ -113,21 +113,34 @@ @@ -113,21 +113,34 @@
<Compile Include="Nodes\ProjectUnitTestNode.cs" />
<Compile Include="Nodes\RootUnitTestNode.cs" />
<Compile Include="Nodes\UnitTestBaseNode.cs" />
<Compile Include="NUnit\NUnitConsoleApplication.cs" />
<Compile Include="NUnit\NUnitTestDebugger.cs" />
<Compile Include="NUnit\NUnitTestFramework.cs" />
<Compile Include="NUnit\NUnitTestResult.cs" />
<Compile Include="NUnit\NUnitTestRunner.cs" />
<Compile Include="Resources\Images.cs" />
<Compile Include="RunTestCommandContext.cs" />
<Compile Include="Service\MessageReceivedEventArgs.cs" />
<Compile Include="Service\RegisteredTestFrameworks.cs" />
<Compile Include="Service\RunningTestsCondition.cs" />
<Compile Include="Service\SelectedTests.cs" />
<Compile Include="Service\TestableCondition.cs" />
<Compile Include="Service\TestDebuggerBase.cs" />
<Compile Include="Service\TestFinishedEventArgs.cs" />
<Compile Include="Service\TestFrameworkDescriptor.cs" />
<Compile Include="Service\TestFrameworkDoozer.cs" />
<Compile Include="Service\TestFrameworkFactory.cs" />
<Compile Include="Service\TestProcessRunnerBase.cs" />
<Compile Include="Service\TestProcessRunnerBaseContext.cs" />
<Compile Include="Service\TestResult.cs" />
<Compile Include="Service\TestRunnerBase.cs" />
<Compile Include="Service\TestService.cs" />
<Compile Include="TestResultsMonitor.cs" />
<Compile Include="TestResultsReader.cs" />
<Compile Include="TestResultTask.cs" />
<Compile Include="UnitTestApplicationStartHelper.cs" />
<Compile Include="UnitTestingOptions.cs" />
<Compile Include="UnitTestProcessRunner.cs" />
<None Include="PostBuildEvent.proj" />
<None Include="UnitTesting.addin">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
@ -184,6 +197,7 @@ @@ -184,6 +197,7 @@
<Folder Include="Implementation" />
<Folder Include="Interfaces" />
<Folder Include="Model" />
<Folder Include="NUnit" />
<Folder Include="Service" />
<Folder Include="Nodes" />
</ItemGroup>

14
src/Main/Base/Project/Src/Util/ExtensionMethods.cs

@ -160,6 +160,20 @@ namespace ICSharpCode.SharpDevelop @@ -160,6 +160,20 @@ namespace ICSharpCode.SharpDevelop
return null;
}
/// <summary>
/// Gets the project for which the specified assembly was created.
/// Returns null if the assembly was not created from a project.
/// </summary>
public static IProject GetProject(this IAssembly assembly)
{
if (assembly == null)
throw new ArgumentNullException("assembly");
var snapshot = assembly.Compilation as SharpDevelopSolutionSnapshot;
if (snapshot == null)
return null;
return snapshot.GetProject(assembly.UnresolvedAssembly as IProjectContent);
}
/// <summary>
/// Creates an array containing a part of the array (similar to string.Substring).
/// </summary>

8
src/Main/Core/Project/Src/Services/MessageService/IMessageService.cs

@ -17,6 +17,14 @@ namespace ICSharpCode.Core @@ -17,6 +17,14 @@ namespace ICSharpCode.Core
/// </summary>
void ShowError(string message);
/// <summary>
/// Shows an error using a message box.
/// <paramref name="formatstring"/> is first passed through the
/// <see cref="StringParser"/>,
/// then through <see cref="string.Format(string, object)"/>, using the formatitems as arguments.
/// </summary>
void ShowErrorFormatted(string formatstring, params object[] formatitems);
/// <summary>
/// Shows an exception.
/// </summary>

2
src/Main/Core/Project/Src/Services/MessageService/MessageService.cs

@ -209,7 +209,7 @@ namespace ICSharpCode.Core @@ -209,7 +209,7 @@ namespace ICSharpCode.Core
Service.ShowMessage(message, caption);
}
static string Format(string formatstring, object[] formatitems)
public static string Format(string formatstring, object[] formatitems)
{
try {
return String.Format(StringParser.Parse(formatstring), formatitems);

5
src/Main/Core/Project/Src/Services/MessageService/TextWriterMessageService.cs

@ -78,5 +78,10 @@ namespace ICSharpCode.Core.Implementation @@ -78,5 +78,10 @@ namespace ICSharpCode.Core.Implementation
writer.WriteLine(exceptionGot.ToString());
return ChooseSaveErrorResult.Ignore;
}
public void ShowErrorFormatted(string formatstring, params object[] formatitems)
{
writer.WriteLine(MessageService.Format(formatstring, formatitems));
}
}
}

5
src/Main/ICSharpCode.Core.WinForms/MessageService/WinFormsMessageService.cs

@ -196,5 +196,10 @@ namespace ICSharpCode.Core.WinForms @@ -196,5 +196,10 @@ namespace ICSharpCode.Core.WinForms
});
return r;
}
public void ShowErrorFormatted(string formatstring, params object[] formatitems)
{
ShowError(MessageService.Format(formatstring, formatitems));
}
}
}

Loading…
Cancel
Save