55 changed files with 138 additions and 4969 deletions
@ -1,73 +0,0 @@
@@ -1,73 +0,0 @@
|
||||
<Components version="1.0"> |
||||
<System.Windows.Forms.UserControl> |
||||
<Name value="UnitTestingOptionsPanel" /> |
||||
<ClientSize value="{Width=450, Height=281}" /> |
||||
<Controls> |
||||
<System.Windows.Forms.GroupBox> |
||||
<Name value="groupBox" /> |
||||
<Location value="10, 13" /> |
||||
<UseCompatibleTextRendering value="True" /> |
||||
<Text value="${res:ICSharpCode.NUnitPad.NUnitPadContent.PadName}" /> |
||||
<Size value="432, 241" /> |
||||
<Anchor value="Top, Left, Right" /> |
||||
<TabIndex value="1" /> |
||||
<Controls> |
||||
<System.Windows.Forms.CheckBox> |
||||
<Name value="createXmlOutputFileCheckBox" /> |
||||
<Location value="6, 179" /> |
||||
<Text value="${res:ICSharpCode.UnitTesting.OptionsPanel.CreateXmlOutputFile}" /> |
||||
<TabIndex value="6" /> |
||||
<Size value="420, 24" /> |
||||
<UseVisualStyleBackColor value="True" /> |
||||
<Anchor value="Top, Left, Right" /> |
||||
</System.Windows.Forms.CheckBox> |
||||
<System.Windows.Forms.CheckBox> |
||||
<Name value="threadCheckBox" /> |
||||
<Location value="6, 149" /> |
||||
<Text value="${res:ICSharpCode.UnitTesting.OptionsPanel.Thread}" /> |
||||
<TabIndex value="5" /> |
||||
<Size value="420, 24" /> |
||||
<UseVisualStyleBackColor value="True" /> |
||||
<Anchor value="Top, Left, Right" /> |
||||
</System.Windows.Forms.CheckBox> |
||||
<System.Windows.Forms.CheckBox> |
||||
<Name value="shadowCopyCheckBox" /> |
||||
<Location value="6, 119" /> |
||||
<Text value="${res:ICSharpCode.UnitTesting.OptionsPanel.ShadowCopy}" /> |
||||
<TabIndex value="4" /> |
||||
<Size value="420, 24" /> |
||||
<UseVisualStyleBackColor value="True" /> |
||||
<Anchor value="Top, Left, Right" /> |
||||
</System.Windows.Forms.CheckBox> |
||||
<System.Windows.Forms.CheckBox> |
||||
<Name value="showProgressCheckBox" /> |
||||
<Location value="6, 89" /> |
||||
<Text value="${res:ICSharpCode.UnitTesting.OptionsPanel.ShowProgress}" /> |
||||
<TabIndex value="3" /> |
||||
<Size value="420, 24" /> |
||||
<UseVisualStyleBackColor value="True" /> |
||||
<Anchor value="Top, Left, Right" /> |
||||
</System.Windows.Forms.CheckBox> |
||||
<System.Windows.Forms.CheckBox> |
||||
<Name value="labelsCheckBox" /> |
||||
<Location value="6, 29" /> |
||||
<Text value="${res:ICSharpCode.UnitTesting.OptionsPanel.LabelEachTest}" /> |
||||
<TabIndex value="2" /> |
||||
<Size value="420, 24" /> |
||||
<UseVisualStyleBackColor value="True" /> |
||||
<Anchor value="Top, Left, Right" /> |
||||
</System.Windows.Forms.CheckBox> |
||||
<System.Windows.Forms.CheckBox> |
||||
<Name value="showLogoCheckBox" /> |
||||
<Location value="6, 59" /> |
||||
<Text value="${res:ICSharpCode.UnitTesting.OptionsPanel.ShowLogo}" /> |
||||
<TabIndex value="1" /> |
||||
<Size value="420, 24" /> |
||||
<UseVisualStyleBackColor value="True" /> |
||||
<Anchor value="Top, Left, Right" /> |
||||
</System.Windows.Forms.CheckBox> |
||||
</Controls> |
||||
</System.Windows.Forms.GroupBox> |
||||
</Controls> |
||||
</System.Windows.Forms.UserControl> |
||||
</Components> |
@ -1,398 +0,0 @@
@@ -1,398 +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.IO; |
||||
using System.Linq; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.SharpDevelop.Project.Commands; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public abstract class AbstractRunTestCommand : AbstractMenuCommand |
||||
{ |
||||
static AbstractRunTestCommand runningTestCommand; |
||||
IUnitTestsPad unitTestsPad; |
||||
SelectedTests selectedTests; |
||||
IRunTestCommandContext context; |
||||
ITestRunner testRunner; |
||||
IProgressMonitor testProgressMonitor; |
||||
int totalProjectCount; |
||||
|
||||
public AbstractRunTestCommand() |
||||
: this(new RunTestCommandContext()) |
||||
{ |
||||
} |
||||
|
||||
public AbstractRunTestCommand(IRunTestCommandContext context) |
||||
{ |
||||
this.context = context; |
||||
} |
||||
|
||||
protected IRunTestCommandContext Context { |
||||
get { return context; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the running test command.
|
||||
/// </summary>
|
||||
public static AbstractRunTestCommand RunningTestCommand { |
||||
get { return runningTestCommand; } |
||||
set { runningTestCommand = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether a test is currently running.
|
||||
/// </summary>
|
||||
public static bool IsRunningTest { |
||||
get { return runningTestCommand != null; } |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
GetUnitTestsPad(); |
||||
|
||||
selectedTests = GetSelectedTests(); |
||||
if (selectedTests.HasProjects) { |
||||
runningTestCommand = this; |
||||
BeforeRun(); |
||||
BuildAndRunTests(); |
||||
} |
||||
} |
||||
|
||||
SelectedTests GetSelectedTests() |
||||
{ |
||||
return new SelectedTests(Owner, unitTestsPad.GetProjects()); |
||||
} |
||||
|
||||
void GetUnitTestsPad() |
||||
{ |
||||
unitTestsPad = context.OpenUnitTestsPad; |
||||
if (unitTestsPad == null) { |
||||
unitTestsPad = CreateEmptyUnitTestsPad(); |
||||
} |
||||
} |
||||
|
||||
EmptyUnitTestsPad CreateEmptyUnitTestsPad() |
||||
{ |
||||
return new EmptyUnitTestsPad(context.OpenSolution); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets the initial workbench state before starting
|
||||
/// a test run.
|
||||
/// </summary>
|
||||
void BeforeRun() |
||||
{ |
||||
ClearTasks(); |
||||
ClearUnitTestCategoryText(); |
||||
|
||||
ShowUnitTestsPad(); |
||||
ShowOutputPad(); |
||||
|
||||
UpdateUnitTestsPadToolbar(); |
||||
ResetAllTestResultsInUnitTestsPad(); |
||||
|
||||
OnBeforeBuild(); |
||||
} |
||||
|
||||
void BuildAndRunTests() |
||||
{ |
||||
if (IsBuildNeededBeforeTestRun()) { |
||||
BuildProjectBeforeRunningTests(selectedTests); |
||||
} else { |
||||
context.SaveAllFilesCommand.SaveAllFiles(); |
||||
RunTests(selectedTests); |
||||
} |
||||
} |
||||
|
||||
bool IsBuildNeededBeforeTestRun() |
||||
{ |
||||
return selectedTests.Projects.Any(p => context.RegisteredTestFrameworks.IsBuildNeededBeforeTestRunForProject(p)); |
||||
} |
||||
|
||||
void ClearTasks() |
||||
{ |
||||
context.TaskService.BuildMessageViewCategory.ClearText(); |
||||
context.TaskService.InUpdate = true; |
||||
context.TaskService.ClearExceptCommentTasks(); |
||||
context.TaskService.InUpdate = false; |
||||
} |
||||
|
||||
void ClearUnitTestCategoryText() |
||||
{ |
||||
context.UnitTestCategory.ClearText(); |
||||
} |
||||
|
||||
void ShowUnitTestsPad() |
||||
{ |
||||
unitTestsPad.BringToFront(); |
||||
} |
||||
|
||||
void StopProgressMonitor() |
||||
{ |
||||
if (testProgressMonitor != null) { |
||||
testProgressMonitor.Dispose(); |
||||
testProgressMonitor = null; |
||||
} |
||||
} |
||||
|
||||
void UpdateUnitTestsPadToolbar() |
||||
{ |
||||
unitTestsPad.UpdateToolbar(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called before the build is started (even if no build needs to be performed).
|
||||
/// If multiple projects are to be tested this is called only once.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeBuild() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called before all tests are run (after the build has finished successfully).
|
||||
/// If multiple projects are to be tested this is called only once.
|
||||
/// </summary>
|
||||
protected virtual void OnBeforeRunTests() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the tests after building the project(s) under test.
|
||||
/// </summary>
|
||||
void BuildProjectBeforeRunningTests(SelectedTests selectedTests) |
||||
{ |
||||
BuildProject build = CreateBuildProjectBeforeTestRun(selectedTests); |
||||
build.BuildComplete += delegate { |
||||
OnBuildComplete(build.LastBuildResults, selectedTests); |
||||
}; |
||||
build.Run(); |
||||
} |
||||
|
||||
BuildProject CreateBuildProjectBeforeTestRun(SelectedTests selectedTests) |
||||
{ |
||||
IEnumerable<IProject> projects = GetProjectsRequiringBuildBeforeTestRun(selectedTests); |
||||
return context.BuildProjectFactory.CreateBuildProjectBeforeTestRun(projects); |
||||
} |
||||
|
||||
IEnumerable<IProject> GetProjectsRequiringBuildBeforeTestRun(SelectedTests selectedTests) |
||||
{ |
||||
return selectedTests |
||||
.Projects |
||||
.Where(p => context.RegisteredTestFrameworks.IsBuildNeededBeforeTestRunForProject(p)); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Stops running the tests.
|
||||
/// </summary>
|
||||
public void Stop() |
||||
{ |
||||
StopActiveTestRunner(); |
||||
|
||||
runningTestCommand = null; |
||||
UpdateUnitTestsPadToolbar(); |
||||
|
||||
OnStop(); |
||||
} |
||||
|
||||
void StopActiveTestRunner() |
||||
{ |
||||
if (testRunner != null) { |
||||
testRunner.Stop(); |
||||
testRunner.Dispose(); |
||||
testRunner = null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called after all tests have been run even if there have
|
||||
/// been errors. If multiple projects are to be tested this is called only once.
|
||||
/// </summary>
|
||||
protected virtual void OnAfterRunTests() |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called by derived classes when a single test run
|
||||
/// is finished.
|
||||
/// </summary>
|
||||
protected void TestRunCompleted() |
||||
{ |
||||
StopActiveTestRunner(); |
||||
selectedTests.RemoveFirstProject(); |
||||
if (selectedTests.HasProjects) { |
||||
RunTests(selectedTests); |
||||
} else { |
||||
StopProgressMonitor(); |
||||
runningTestCommand = null; |
||||
UpdateUnitTestsPadToolbar(); |
||||
ShowErrorList(); |
||||
OnAfterRunTests(); |
||||
} |
||||
} |
||||
|
||||
void TestFinished(object source, TestFinishedEventArgs e) |
||||
{ |
||||
context.Workbench.SafeThreadAsyncCall(ShowResult, e.Result); |
||||
} |
||||
|
||||
protected void ShowResult(TestResult result) |
||||
{ |
||||
if (IsTestResultFailureOrIsIgnored(result)) { |
||||
AddTaskForTestResult(result); |
||||
UpdateProgressMonitorStatus(result); |
||||
} |
||||
UpdateTestResult(result); |
||||
} |
||||
|
||||
bool IsTestResultFailureOrIsIgnored(TestResult result) |
||||
{ |
||||
return result.IsFailure || result.IsIgnored; |
||||
} |
||||
|
||||
void AddTaskForTestResult(TestResult testResult) |
||||
{ |
||||
TestProject project = GetTestProjectForProject(selectedTests.Project); |
||||
Task task = TestResultTask.Create(testResult, project); |
||||
context.TaskService.Add(task); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called when the test run should be stopped.
|
||||
/// </summary>
|
||||
protected virtual void OnStop() |
||||
{ |
||||
} |
||||
|
||||
void ShowOutputPad() |
||||
{ |
||||
ShowPad(context.Workbench.GetPad(typeof(CompilerMessageView))); |
||||
} |
||||
|
||||
protected void ShowPad(PadDescriptor padDescriptor) |
||||
{ |
||||
context.Workbench.SafeThreadAsyncCall(padDescriptor.BringPadToFront); |
||||
} |
||||
|
||||
void ShowErrorList() |
||||
{ |
||||
if (HasErrorsThatShouldBeDisplayed()) { |
||||
ShowPad(context.Workbench.GetPad(typeof(ErrorListPad))); |
||||
} |
||||
} |
||||
|
||||
bool HasErrorsThatShouldBeDisplayed() |
||||
{ |
||||
return context.TaskService.SomethingWentWrong && |
||||
context.BuildOptions.ShowErrorListAfterBuild; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Runs the test for the project after a successful build.
|
||||
/// </summary>
|
||||
void OnBuildComplete(BuildResults results, SelectedTests selectedTests) |
||||
{ |
||||
if (BuildHasNoErrorsAndStillRunningTests(results)) { |
||||
RunTests(selectedTests); |
||||
} else { |
||||
if (IsRunningTest) { |
||||
Stop(); |
||||
} |
||||
ShowErrorList(); |
||||
} |
||||
} |
||||
|
||||
bool BuildHasNoErrorsAndStillRunningTests(BuildResults results) |
||||
{ |
||||
return (results.ErrorCount == 0) && IsRunningTest; |
||||
} |
||||
|
||||
void RunTests(SelectedTests selectedTests) |
||||
{ |
||||
if (testProgressMonitor == null) { |
||||
OnBeforeRunTests(); |
||||
testProgressMonitor = context.StatusBarService.CreateProgressMonitor(); |
||||
totalProjectCount = selectedTests.ProjectsCount; |
||||
} |
||||
testProgressMonitor.TaskName = GetProgressMonitorLabel(selectedTests.Project); |
||||
testProgressMonitor.Progress = GetProgress(selectedTests.ProjectsCount); |
||||
|
||||
testRunner = CreateTestRunner(selectedTests.Project); |
||||
if (testRunner != null) { |
||||
StartTestRunner(); |
||||
} |
||||
} |
||||
|
||||
void StartTestRunner() |
||||
{ |
||||
testRunner.MessageReceived += TestRunnerMessageReceived; |
||||
testRunner.AllTestsFinished += AllTestsFinished; |
||||
testRunner.TestFinished += TestFinished; |
||||
testRunner.Start(selectedTests); |
||||
} |
||||
|
||||
string GetProgressMonitorLabel(IProject project) |
||||
{ |
||||
StringTagPair tagPair = new StringTagPair("Name", project.Name); |
||||
return StringParser.Parse("${res:ICSharpCode.UnitTesting.StatusBarProgressLabel}", tagPair); |
||||
} |
||||
|
||||
double GetProgress(int projectsLeftToRunCount) |
||||
{ |
||||
return (double)(totalProjectCount - projectsLeftToRunCount) / totalProjectCount; |
||||
} |
||||
|
||||
protected virtual ITestRunner CreateTestRunner(IProject project) |
||||
{ |
||||
return null; |
||||
} |
||||
|
||||
protected virtual void TestRunnerMessageReceived(object source, MessageReceivedEventArgs e) |
||||
{ |
||||
context.UnitTestCategory.AppendLine(e.Message); |
||||
} |
||||
|
||||
void AllTestsFinished(object source, EventArgs e) |
||||
{ |
||||
context.Workbench.SafeThreadAsyncCall(TestRunCompleted); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Clears the test results in the test tree view for all the
|
||||
/// displayed projects.
|
||||
/// </summary>
|
||||
void ResetAllTestResultsInUnitTestsPad() |
||||
{ |
||||
unitTestsPad.ResetTestResults(); |
||||
} |
||||
|
||||
TestProject GetTestProjectForProject(IProject project) |
||||
{ |
||||
return unitTestsPad.GetTestProject(project); |
||||
} |
||||
|
||||
void UpdateTestResult(TestResult result) |
||||
{ |
||||
TestProject testProject = GetTestProjectForProject(selectedTests.Project); |
||||
if (testProject != null) { |
||||
testProject.UpdateTestResult(result); |
||||
} |
||||
} |
||||
|
||||
void UpdateProgressMonitorStatus(TestResult result) |
||||
{ |
||||
if (testProgressMonitor != null) { |
||||
if (result.IsFailure) { |
||||
testProgressMonitor.Status = OperationStatus.Error; |
||||
} else if (result.IsIgnored && testProgressMonitor.Status == OperationStatus.Normal) { |
||||
testProgressMonitor.Status = OperationStatus.Warning; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,71 +0,0 @@
@@ -1,71 +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.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a test member that exists in a base class.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// In order to have the Unit Test tree run the correct
|
||||
/// test when we have a class that has a base class with
|
||||
/// test members is to return the derived class from the
|
||||
/// DeclaringType's property. Otherwise the base class
|
||||
/// member is tested and the derived class is not used.
|
||||
/// </remarks>
|
||||
public class BaseTestMember : AbstractMember |
||||
{ |
||||
IMember member; |
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the BaseTestMember.
|
||||
/// </summary>
|
||||
/// <param name="derivedClass">The derived class and not
|
||||
/// the class where the method is actually defined.</param>
|
||||
/// <param name="method">The base class's test member.</param>
|
||||
public BaseTestMember(IClass derivedClass, IMember member) |
||||
: this(derivedClass, member, member.DeclaringType.Name + "." + member.Name) |
||||
{ |
||||
} |
||||
|
||||
protected BaseTestMember(IClass derivedClass, IMember member, string name) |
||||
: base(derivedClass, name) |
||||
{ |
||||
this.member = member; |
||||
this.ReturnType = member.ReturnType; |
||||
this.Modifiers = member.Modifiers; |
||||
this.Region = member.Region; |
||||
this.BodyRegion = member.BodyRegion; |
||||
this.Documentation = member.Documentation; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the actual method used to create this object.
|
||||
/// </summary>
|
||||
public IMember Member { |
||||
get { return member; } |
||||
} |
||||
|
||||
public override EntityType EntityType { |
||||
get { |
||||
return member.EntityType; |
||||
} |
||||
} |
||||
|
||||
public override string DocumentationTag { |
||||
get { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public override string Documentation {get;set;} |
||||
|
||||
public override IMember Clone() |
||||
{ |
||||
return new BaseTestMember(DeclaringType, Member); |
||||
} |
||||
} |
||||
} |
@ -1,13 +0,0 @@
@@ -1,13 +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; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IAddInTree |
||||
{ |
||||
List<T> BuildItems<T>(string path, object caller); |
||||
} |
||||
} |
@ -1,12 +0,0 @@
@@ -1,12 +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 |
||||
{ |
||||
public interface IBuildOptions |
||||
{ |
||||
bool ShowErrorListAfterBuild { get; } |
||||
} |
||||
} |
@ -1,15 +0,0 @@
@@ -1,15 +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 ICSharpCode.SharpDevelop.Project; |
||||
using ICSharpCode.SharpDevelop.Project.Commands; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IBuildProjectFactory |
||||
{ |
||||
BuildProject CreateBuildProjectBeforeTestRun(IEnumerable<IProject> projects); |
||||
} |
||||
} |
@ -1,12 +0,0 @@
@@ -1,12 +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 |
||||
{ |
||||
public interface IFileSystem |
||||
{ |
||||
bool FileExists(string fileName); |
||||
} |
||||
} |
@ -1,25 +0,0 @@
@@ -1,25 +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 ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IRegisteredTestFrameworks |
||||
{ |
||||
ITestFramework GetTestFrameworkForProject(IProject project); |
||||
ITestRunner CreateTestRunner(IProject project); |
||||
ITestRunner CreateTestDebugger(IProject project); |
||||
|
||||
bool IsTestMember(IMember member); |
||||
bool IsTestClass(IClass c); |
||||
bool IsTestProject(IProject project); |
||||
|
||||
IEnumerable<TestMember> GetTestMembersFor(IClass @class); |
||||
|
||||
bool IsBuildNeededBeforeTestRunForProject(IProject project); |
||||
} |
||||
} |
@ -1,25 +0,0 @@
@@ -1,25 +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.Core.Services; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IRunTestCommandContext |
||||
{ |
||||
IRegisteredTestFrameworks RegisteredTestFrameworks { get; } |
||||
IUnitTestTaskService TaskService { get; } |
||||
IUnitTestWorkbench Workbench { get; } |
||||
IBuildProjectFactory BuildProjectFactory { get; } |
||||
IBuildOptions BuildOptions { get; } |
||||
MessageViewCategory UnitTestCategory { get; } |
||||
IUnitTestsPad OpenUnitTestsPad { get; } |
||||
IUnitTestMessageService MessageService { get; } |
||||
IUnitTestSaveAllFilesCommand SaveAllFilesCommand { get; } |
||||
IStatusBarService StatusBarService { get; } |
||||
Solution OpenSolution { get; } |
||||
} |
||||
} |
@ -1,12 +0,0 @@
@@ -1,12 +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 |
||||
{ |
||||
public interface ITestFrameworkFactory |
||||
{ |
||||
ITestFramework Create(string className); |
||||
} |
||||
} |
@ -1,20 +0,0 @@
@@ -1,20 +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 |
||||
{ |
||||
public interface ITestResultsMonitor : IDisposable |
||||
{ |
||||
event TestFinishedEventHandler TestFinished; |
||||
|
||||
string FileName { get; set; } |
||||
|
||||
void Stop(); |
||||
void Start(); |
||||
void Read(); |
||||
|
||||
long InitialFilePosition { get; set; } |
||||
} |
||||
} |
@ -1,17 +0,0 @@
@@ -1,17 +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.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface ITestRunner : IDisposable |
||||
{ |
||||
event TestFinishedEventHandler TestFinished; |
||||
event EventHandler AllTestsFinished; |
||||
event MessageReceivedEventHandler MessageReceived; |
||||
void Start(SelectedTests selectedTests); |
||||
void Stop(); |
||||
} |
||||
} |
@ -1,33 +0,0 @@
@@ -1,33 +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 ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
using System; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface ITestTreeView |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the selected member in the test tree view.
|
||||
/// </summary>
|
||||
IMember SelectedMember {get;} |
||||
|
||||
/// <summary>
|
||||
/// Gets the selected class in the test tree view.
|
||||
/// </summary>
|
||||
IClass SelectedClass {get;} |
||||
|
||||
/// <summary>
|
||||
/// Gets the selected project for the selected node
|
||||
/// in the test tree view.
|
||||
/// </summary>
|
||||
IProject SelectedProject {get;} |
||||
|
||||
/// <summary>
|
||||
/// Gets the namespace for the selected namespace node.
|
||||
/// </summary>
|
||||
string SelectedNamespace {get;} |
||||
} |
||||
} |
@ -1,15 +0,0 @@
@@ -1,15 +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.Data; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IUnitTestDebuggerService |
||||
{ |
||||
bool IsDebuggerLoaded { get; } |
||||
IDebugger CurrentDebugger { get; } |
||||
} |
||||
} |
@ -1,13 +0,0 @@
@@ -1,13 +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 |
||||
{ |
||||
public interface IUnitTestFileService : IFileSystem |
||||
{ |
||||
void OpenFile(string fileName); |
||||
void JumpToFilePosition(string fileName, int line, int column); |
||||
} |
||||
} |
@ -1,13 +0,0 @@
@@ -1,13 +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 |
||||
{ |
||||
public interface IUnitTestMessageService |
||||
{ |
||||
bool AskQuestion(string question, string caption); |
||||
void ShowFormattedErrorMessage(string format, string item); |
||||
} |
||||
} |
@ -1,24 +0,0 @@
@@ -1,24 +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 ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IUnitTestProcessRunner |
||||
{ |
||||
bool LogStandardOutputAndError { get; set; } |
||||
string WorkingDirectory { get; set; } |
||||
|
||||
Dictionary<string, string> EnvironmentVariables { get; } |
||||
|
||||
void Start(string command, string arguments); |
||||
void Kill(); |
||||
|
||||
event LineReceivedEventHandler OutputLineReceived; |
||||
event LineReceivedEventHandler ErrorLineReceived; |
||||
event EventHandler ProcessExited; |
||||
} |
||||
} |
@ -1,12 +0,0 @@
@@ -1,12 +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 |
||||
{ |
||||
public interface IUnitTestSaveAllFilesCommand |
||||
{ |
||||
void SaveAllFiles(); |
||||
} |
||||
} |
@ -1,20 +0,0 @@
@@ -1,20 +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.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IUnitTestTaskService |
||||
{ |
||||
MessageViewCategory BuildMessageViewCategory { get; } |
||||
bool InUpdate { get; set; } |
||||
void ClearExceptCommentTasks(); |
||||
void Add(Task task); |
||||
bool SomethingWentWrong { get; } |
||||
bool HasCriticalErrors(bool treatWarningsAsErrors); |
||||
} |
||||
} |
@ -1,15 +0,0 @@
@@ -1,15 +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.SharpDevelop; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IUnitTestWorkbench |
||||
{ |
||||
PadDescriptor GetPad(Type type); |
||||
void SafeThreadAsyncCall(Action method); |
||||
void SafeThreadAsyncCall<A>(Action<A> method, A arg1); |
||||
} |
||||
} |
@ -1,18 +0,0 @@
@@ -1,18 +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.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface IUnitTestsPad |
||||
{ |
||||
void UpdateToolbar(); |
||||
void BringToFront(); |
||||
void ResetTestResults(); |
||||
IProject[] GetProjects(); |
||||
TestProject GetTestProject(IProject project); |
||||
void CollapseAll(); |
||||
} |
||||
} |
@ -1,47 +0,0 @@
@@ -1,47 +0,0 @@
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Text; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
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); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,250 +0,0 @@
@@ -1,250 +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.Diagnostics; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class NUnitConsoleApplication |
||||
{ |
||||
public NUnitConsoleApplication(SelectedTests selectedTests, UnitTestingOptions options) |
||||
{ |
||||
Initialize(selectedTests); |
||||
InitializeOptions(options); |
||||
} |
||||
|
||||
public NUnitConsoleApplication(SelectedTests selectedTests) |
||||
{ |
||||
Initialize(selectedTests); |
||||
} |
||||
|
||||
void Initialize(SelectedTests selectedTests) |
||||
{ |
||||
this.selectedTests = selectedTests; |
||||
this.project = selectedTests.Project; |
||||
Assemblies.Add(project.OutputAssemblyFullPath); |
||||
if (selectedTests.NamespaceFilter != null) { |
||||
NamespaceFilter = selectedTests.NamespaceFilter; |
||||
} |
||||
if (selectedTests.Class != null) { |
||||
Fixture = selectedTests.Class.DotNetName; |
||||
if (selectedTests.Member != null) { |
||||
Test = selectedTests.Member.Name; |
||||
} |
||||
} |
||||
} |
||||
|
||||
void InitializeOptions(UnitTestingOptions options) |
||||
{ |
||||
NoThread = options.NoThread; |
||||
NoLogo = options.NoLogo; |
||||
NoDots = options.NoDots; |
||||
Labels = options.Labels; |
||||
ShadowCopy = !options.NoShadow; |
||||
|
||||
if (options.CreateXmlOutputFile) { |
||||
GenerateXmlOutputFileName(); |
||||
} |
||||
} |
||||
|
||||
void GenerateXmlOutputFileName() |
||||
{ |
||||
string directory = Path.GetDirectoryName(project.OutputAssemblyFullPath); |
||||
string fileName = project.AssemblyName + "-TestResult.xml"; |
||||
XmlOutputFile = Path.Combine(directory, fileName); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// returns full/path/to/Tools/NUnit
|
||||
/// </summary>
|
||||
string WorkingDirectory { |
||||
get { return Path.Combine(FileUtility.ApplicationRootPath, @"bin\Tools\NUnit"); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// returns full/path/to/Tools/NUnit/nunit-console.exe or nunit-console-x86.exe if the
|
||||
/// project platform target is x86.
|
||||
/// </summary>
|
||||
public string FileName { |
||||
get { |
||||
string exe = "nunit-console"; |
||||
if (ProjectUsesDotnet20Runtime(project)) { |
||||
exe += "-dotnet2"; |
||||
} |
||||
if (IsPlatformTarget32Bit(project)) { |
||||
exe += "-x86"; |
||||
} |
||||
exe += ".exe"; |
||||
return Path.Combine(WorkingDirectory, exe); |
||||
} |
||||
} |
||||
|
||||
public readonly List<string> Assemblies = new List<string>(); |
||||
|
||||
/// <summary>
|
||||
/// Use shadow copy assemblies. Default = true.
|
||||
/// </summary>
|
||||
public bool ShadowCopy = true; |
||||
|
||||
/// <summary>
|
||||
/// Disables the use of a separate thread to run tests on separate thread. Default = false;
|
||||
/// </summary>
|
||||
public bool NoThread = false; |
||||
|
||||
/// <summary>
|
||||
/// Use /nologo directive.
|
||||
/// </summary>
|
||||
public bool NoLogo = false; |
||||
|
||||
/// <summary>
|
||||
/// Use /labels directive.
|
||||
/// </summary>
|
||||
public bool Labels = false; |
||||
|
||||
/// <summary>
|
||||
/// Use /nodots directive.
|
||||
/// </summary>
|
||||
public bool NoDots = false; |
||||
|
||||
/// <summary>
|
||||
/// File to write xml output to. Default = null.
|
||||
/// </summary>
|
||||
public string XmlOutputFile; |
||||
|
||||
/// <summary>
|
||||
/// Fixture to test. Null = test all fixtures.
|
||||
/// </summary>
|
||||
public string Fixture; |
||||
|
||||
/// <summary>
|
||||
/// Test to run. Null = run all tests. Only valid together with the Fixture property.
|
||||
/// </summary>
|
||||
public string Test; |
||||
|
||||
/// <summary>
|
||||
/// File to write test results to.
|
||||
/// </summary>
|
||||
public string Results; |
||||
|
||||
/// <summary>
|
||||
/// The namespace that tests need to be a part of if they are to
|
||||
/// be run.
|
||||
/// </summary>
|
||||
public string NamespaceFilter; |
||||
|
||||
IProject project; |
||||
SelectedTests selectedTests; |
||||
|
||||
public SelectedTests SelectedTests { |
||||
get { return selectedTests; } |
||||
} |
||||
|
||||
public IProject Project { |
||||
get { return project; } |
||||
} |
||||
|
||||
public ProcessStartInfo GetProcessStartInfo() |
||||
{ |
||||
ProcessStartInfo startInfo = new ProcessStartInfo(); |
||||
startInfo.FileName = FileName; |
||||
startInfo.Arguments = GetArguments(); |
||||
startInfo.WorkingDirectory = WorkingDirectory; |
||||
return startInfo; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the full command line to run the unit test application.
|
||||
/// This is the combination of the UnitTestApplication and
|
||||
/// the command line arguments.
|
||||
/// </summary>
|
||||
public string GetCommandLine() |
||||
{ |
||||
return String.Format("\"{0}\" {1}", FileName, GetArguments()); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the arguments to use on the command line to run NUnit.
|
||||
/// </summary>
|
||||
public string GetArguments() |
||||
{ |
||||
StringBuilder b = new StringBuilder(); |
||||
foreach (string assembly in Assemblies) { |
||||
if (b.Length > 0) |
||||
b.Append(' '); |
||||
b.Append('"'); |
||||
b.Append(assembly); |
||||
b.Append('"'); |
||||
} |
||||
if (!ShadowCopy) |
||||
b.Append(" /noshadow"); |
||||
if (NoThread) |
||||
b.Append(" /nothread"); |
||||
if (NoLogo) |
||||
b.Append(" /nologo"); |
||||
if (Labels) |
||||
b.Append(" /labels"); |
||||
if (NoDots) |
||||
b.Append(" /nodots"); |
||||
if (XmlOutputFile != null) { |
||||
b.Append(" /xml=\""); |
||||
b.Append(XmlOutputFile); |
||||
b.Append('"'); |
||||
} |
||||
if (Results != null) { |
||||
b.Append(" /results=\""); |
||||
b.Append(Results); |
||||
b.Append('"'); |
||||
} |
||||
string run = null; |
||||
if (NamespaceFilter != null) { |
||||
run = NamespaceFilter; |
||||
} else if (Fixture != null) { |
||||
if (Test != null) { |
||||
run = Fixture + "." + Test; |
||||
} else { |
||||
run = Fixture; |
||||
} |
||||
} else if (Test != null) { |
||||
run = Test; |
||||
} |
||||
if (run != null) { |
||||
b.Append(" /run=\""); |
||||
b.Append(run); |
||||
b.Append('"'); |
||||
} |
||||
return b.ToString(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Checks that the project's PlatformTarget is x86 for the active configuration.
|
||||
/// </summary>
|
||||
bool IsPlatformTarget32Bit(IProject project) |
||||
{ |
||||
MSBuildBasedProject msbuildProject = project as MSBuildBasedProject; |
||||
if (msbuildProject != null) { |
||||
string platformTarget = msbuildProject.GetEvaluatedProperty("PlatformTarget"); |
||||
return String.Compare(platformTarget, "x86", true) == 0; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
bool ProjectUsesDotnet20Runtime(IProject project) |
||||
{ |
||||
var p = project as ICSharpCode.SharpDevelop.Project.Converter.IUpgradableProject; |
||||
if (p != null && p.CurrentTargetFramework != null) { |
||||
return p.CurrentTargetFramework.SupportedRuntimeVersion == "v2.0.50727"; |
||||
} |
||||
return false; |
||||
} |
||||
} |
||||
} |
@ -1,44 +0,0 @@
@@ -1,44 +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.Diagnostics; |
||||
using ICSharpCode.Core.Services; |
||||
using ICSharpCode.SharpDevelop.Debugging; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class NUnitTestDebugger : TestDebuggerBase |
||||
{ |
||||
UnitTestingOptions options; |
||||
|
||||
public NUnitTestDebugger() |
||||
: this(new UnitTestDebuggerService(), |
||||
new UnitTestMessageService(), |
||||
new TestResultsMonitor(), |
||||
new UnitTestingOptions()) |
||||
{ |
||||
} |
||||
|
||||
public NUnitTestDebugger(IUnitTestDebuggerService debuggerService, |
||||
IUnitTestMessageService messageService, |
||||
ITestResultsMonitor testResultsMonitor, |
||||
UnitTestingOptions options) |
||||
: base(debuggerService, messageService, testResultsMonitor) |
||||
{ |
||||
this.options = options; |
||||
} |
||||
|
||||
protected override ProcessStartInfo GetProcessStartInfo(SelectedTests selectedTests) |
||||
{ |
||||
NUnitConsoleApplication app = new NUnitConsoleApplication(selectedTests, options); |
||||
app.Results = base.TestResultsMonitor.FileName; |
||||
return app.GetProcessStartInfo(); |
||||
} |
||||
|
||||
protected override TestResult CreateTestResultForTestFramework(TestResult testResult) |
||||
{ |
||||
return new NUnitTestResult(testResult); |
||||
} |
||||
} |
||||
} |
@ -1,132 +0,0 @@
@@ -1,132 +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.Linq; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
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; |
||||
} |
||||
|
||||
bool IsNUnitFrameworkAssemblyReference(ReferenceProjectItem referenceProjectItem) |
||||
{ |
||||
if (referenceProjectItem != null) { |
||||
string name = referenceProjectItem.ShortName; |
||||
return name.Equals("NUnit.Framework", StringComparison.OrdinalIgnoreCase); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <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) |
||||
{ |
||||
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(); |
||||
} |
||||
|
||||
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; |
||||
} |
||||
|
||||
/// <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.
|
||||
/// </summary>
|
||||
public bool IsTestMember(IMember member) |
||||
{ |
||||
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)); |
||||
} |
||||
|
||||
static bool IsTestMethod(IMethod method) |
||||
{ |
||||
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; } |
||||
} |
||||
|
||||
public ITestRunner CreateTestRunner() |
||||
{ |
||||
return new NUnitTestRunner(); |
||||
} |
||||
|
||||
public ITestRunner CreateTestDebugger() |
||||
{ |
||||
return new NUnitTestDebugger(); |
||||
} |
||||
} |
||||
} |
@ -1,37 +0,0 @@
@@ -1,37 +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.IO; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class NUnitTestResult : TestResult |
||||
{ |
||||
public NUnitTestResult(TestResult testResult) |
||||
: base(testResult.Name) |
||||
{ |
||||
Message = testResult.Message; |
||||
ResultType = testResult.ResultType; |
||||
StackTrace = testResult.StackTrace; |
||||
} |
||||
|
||||
protected override void OnStackTraceChanged() |
||||
{ |
||||
FileLineReference fileLineRef = OutputTextLineParser.GetNUnitOutputFileLineReference(StackTrace, true); |
||||
if (fileLineRef != null) { |
||||
StackTraceFilePosition = CreateFilePosition(fileLineRef); |
||||
} else { |
||||
StackTraceFilePosition = FilePosition.Empty; |
||||
} |
||||
} |
||||
|
||||
FilePosition CreateFilePosition(FileLineReference fileLineRef) |
||||
{ |
||||
string fileName = Path.GetFullPath(fileLineRef.FileName); |
||||
return new FilePosition(fileName, fileLineRef.Line, fileLineRef.Column + 1); |
||||
} |
||||
} |
||||
} |
@ -1,38 +0,0 @@
@@ -1,38 +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.Diagnostics; |
||||
using ICSharpCode.SharpDevelop.Util; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class NUnitTestRunner : TestProcessRunnerBase |
||||
{ |
||||
UnitTestingOptions options; |
||||
|
||||
public NUnitTestRunner() |
||||
: this(new TestProcessRunnerBaseContext(), |
||||
new UnitTestingOptions()) |
||||
{ |
||||
} |
||||
|
||||
public NUnitTestRunner(TestProcessRunnerBaseContext context, UnitTestingOptions options) |
||||
: base(context) |
||||
{ |
||||
this.options = options; |
||||
} |
||||
|
||||
protected override ProcessStartInfo GetProcessStartInfo(SelectedTests selectedTests) |
||||
{ |
||||
NUnitConsoleApplication app = new NUnitConsoleApplication(selectedTests, options); |
||||
app.Results = base.TestResultsMonitor.FileName; |
||||
return app.GetProcessStartInfo(); |
||||
} |
||||
|
||||
protected override TestResult CreateTestResultForTestFramework(TestResult testResult) |
||||
{ |
||||
return new NUnitTestResult(testResult); |
||||
} |
||||
} |
||||
} |
@ -1,116 +0,0 @@
@@ -1,116 +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 ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class RegisteredTestFrameworks : IRegisteredTestFrameworks |
||||
{ |
||||
List<TestFrameworkDescriptor> testFrameworkDescriptors; |
||||
public const string AddInPath = "/SharpDevelop/UnitTesting/TestFrameworks"; |
||||
|
||||
public RegisteredTestFrameworks(IAddInTree addInTree) |
||||
{ |
||||
testFrameworkDescriptors = addInTree.BuildItems<TestFrameworkDescriptor>(AddInPath, null); |
||||
} |
||||
|
||||
public ITestFramework GetTestFrameworkForProject(IProject project) |
||||
{ |
||||
if (project != null) { |
||||
foreach (TestFrameworkDescriptor descriptor in testFrameworkDescriptors) { |
||||
if (descriptor.IsSupportedProject(project) && descriptor.TestFramework.IsTestProject(project)) { |
||||
return descriptor.TestFramework; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public bool IsTestMember(IMember member) |
||||
{ |
||||
ITestFramework testFramework = GetTestFramework(member); |
||||
if (testFramework != null) { |
||||
return testFramework.IsTestMember(member); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public IEnumerable<TestMember> GetTestMembersFor(IClass @class) { |
||||
ITestFramework testFramework = GetTestFramework(@class); |
||||
if (testFramework != null) |
||||
return testFramework.GetTestMembersFor(@class); |
||||
return new TestMember[0]; |
||||
} |
||||
|
||||
ITestFramework GetTestFramework(IMember member) |
||||
{ |
||||
if (member != null) { |
||||
return GetTestFramework(member.DeclaringType); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
ITestFramework GetTestFramework(IClass c) |
||||
{ |
||||
IProject project = GetProject(c); |
||||
return GetTestFrameworkForProject(project); |
||||
} |
||||
|
||||
IProject GetProject(IClass c) |
||||
{ |
||||
if (c != null) { |
||||
return c.ProjectContent.Project as IProject; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public bool IsTestClass(IClass c) |
||||
{ |
||||
ITestFramework testFramework = GetTestFramework(c); |
||||
if (testFramework != null) { |
||||
return testFramework.IsTestClass(c); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public bool IsTestProject(IProject project) |
||||
{ |
||||
ITestFramework testFramework = GetTestFrameworkForProject(project); |
||||
if (testFramework != null) { |
||||
return testFramework.IsTestProject(project); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public ITestRunner CreateTestRunner(IProject project) |
||||
{ |
||||
ITestFramework testFramework = GetTestFrameworkForProject(project); |
||||
if (testFramework != null) { |
||||
return testFramework.CreateTestRunner(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public ITestRunner CreateTestDebugger(IProject project) |
||||
{ |
||||
ITestFramework testFramework = GetTestFrameworkForProject(project); |
||||
if (testFramework != null) { |
||||
return testFramework.CreateTestDebugger(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public bool IsBuildNeededBeforeTestRunForProject(IProject project) |
||||
{ |
||||
ITestFramework testFramework = GetTestFrameworkForProject(project); |
||||
if (testFramework != null) { |
||||
return testFramework.IsBuildNeededBeforeTestRun; |
||||
} |
||||
return true; |
||||
} |
||||
} |
||||
} |
@ -1,52 +0,0 @@
@@ -1,52 +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 ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Used to determine which classes have been removed by the user in the project.
|
||||
/// </summary>
|
||||
public class RemovedClasses |
||||
{ |
||||
Dictionary<string, IClass> classDictionary = new Dictionary<string, IClass>(); |
||||
|
||||
public RemovedClasses() |
||||
{ |
||||
} |
||||
|
||||
public void Add(IList<IClass> classes) |
||||
{ |
||||
foreach (IClass c in classes) { |
||||
classDictionary[c.DotNetName] = c; |
||||
foreach (IClass innerClass in c.InnerClasses) { |
||||
classDictionary[innerClass.DotNetName] = innerClass; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="c"></param>
|
||||
public void Remove(IClass c) |
||||
{ |
||||
classDictionary.Remove(c.DotNetName); |
||||
foreach (IClass innerClass in c.InnerClasses) { |
||||
classDictionary.Remove(innerClass.DotNetName); |
||||
} |
||||
} |
||||
|
||||
public IList<IClass> GetMissingClasses() |
||||
{ |
||||
List<IClass> missingClasses = new List<IClass>(); |
||||
foreach (IClass c in classDictionary.Values) { |
||||
missingClasses.Add(c); |
||||
} |
||||
return missingClasses; |
||||
} |
||||
} |
||||
} |
@ -1,43 +0,0 @@
@@ -1,43 +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.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class RunProjectTestsInPadCommand : RunTestInPadCommand, ITestTreeView |
||||
{ |
||||
public RunProjectTestsInPadCommand() |
||||
{ |
||||
} |
||||
|
||||
public RunProjectTestsInPadCommand(IRunTestCommandContext context) |
||||
: base(context) |
||||
{ |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
Owner = this; |
||||
base.Run(); |
||||
} |
||||
|
||||
public IMember SelectedMember { |
||||
get { return null; } |
||||
} |
||||
|
||||
public IClass SelectedClass { |
||||
get { return null; } |
||||
} |
||||
|
||||
public IProject SelectedProject { |
||||
get { return ProjectService.CurrentProject; } |
||||
} |
||||
|
||||
public string SelectedNamespace { |
||||
get { return null; } |
||||
} |
||||
} |
||||
} |
@ -1,69 +0,0 @@
@@ -1,69 +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.Core.Services; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class RunTestCommandContext : IRunTestCommandContext |
||||
{ |
||||
UnitTestingOptions options = new UnitTestingOptions(); |
||||
IRegisteredTestFrameworks testFrameworks = TestService.RegisteredTestFrameworks; |
||||
UnitTestTaskService taskService = new UnitTestTaskService(); |
||||
UnitTestWorkbench workbench = new UnitTestWorkbench(); |
||||
UnitTestBuildProjectFactory buildProjectFactory = new UnitTestBuildProjectFactory(); |
||||
UnitTestBuildOptions buildOptions = new UnitTestBuildOptions(); |
||||
MessageViewCategory unitTestCategory = TestService.UnitTestMessageView; |
||||
UnitTestMessageService messageService = new UnitTestMessageService(); |
||||
UnitTestSaveAllFilesCommand saveAllFilesCommand = new UnitTestSaveAllFilesCommand(); |
||||
IStatusBarService statusBarService = SD.StatusBar; |
||||
|
||||
public IRegisteredTestFrameworks RegisteredTestFrameworks { |
||||
get { return testFrameworks; } |
||||
} |
||||
|
||||
public IUnitTestTaskService TaskService { |
||||
get { return taskService; } |
||||
} |
||||
|
||||
public IUnitTestWorkbench Workbench { |
||||
get { return workbench; } |
||||
} |
||||
|
||||
public IBuildProjectFactory BuildProjectFactory { |
||||
get { return buildProjectFactory; } |
||||
} |
||||
|
||||
public IBuildOptions BuildOptions { |
||||
get { return buildOptions; } |
||||
} |
||||
|
||||
public MessageViewCategory UnitTestCategory { |
||||
get { return unitTestCategory; } |
||||
} |
||||
|
||||
public IUnitTestsPad OpenUnitTestsPad { |
||||
get { return UnitTestsPad.Instance; } |
||||
} |
||||
|
||||
public IUnitTestMessageService MessageService { |
||||
get { return messageService; } |
||||
} |
||||
|
||||
public IUnitTestSaveAllFilesCommand SaveAllFilesCommand { |
||||
get { return saveAllFilesCommand; } |
||||
} |
||||
|
||||
public IStatusBarService StatusBarService { |
||||
get { return statusBarService; } |
||||
} |
||||
|
||||
public Solution OpenSolution { |
||||
get { return ProjectService.OpenSolution; } |
||||
} |
||||
} |
||||
} |
@ -1,96 +0,0 @@
@@ -1,96 +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 ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class SelectedTests |
||||
{ |
||||
string namespaceFilter; |
||||
IClass c; |
||||
IMember member; |
||||
List<IProject> projects = new List<IProject>(); |
||||
|
||||
public SelectedTests(IProject project, string namespaceFilter, IClass c, IMember member) |
||||
{ |
||||
this.namespaceFilter = namespaceFilter; |
||||
this.c = c; |
||||
this.member = member; |
||||
|
||||
if (project != null) { |
||||
projects.Add(project); |
||||
} |
||||
} |
||||
|
||||
public SelectedTests(IProject project) |
||||
: this(project, null, null, null) |
||||
{ |
||||
} |
||||
|
||||
public SelectedTests(object owner, IProject[] selectedProjects) |
||||
{ |
||||
IProject project = TestableCondition.GetProject(owner); |
||||
if (project != null) { |
||||
projects.Add(project); |
||||
} else { |
||||
projects.AddRange(selectedProjects); |
||||
} |
||||
|
||||
member = TestableCondition.GetMember(owner); |
||||
c = GetClass(member, owner); |
||||
namespaceFilter = TestableCondition.GetNamespace(owner); |
||||
} |
||||
|
||||
static IClass GetClass(IMember member, Object owner) |
||||
{ |
||||
if (member != null) { |
||||
return member.DeclaringType; |
||||
} |
||||
return TestableCondition.GetClass(owner); |
||||
} |
||||
|
||||
public bool HasProjects { |
||||
get { return projects.Count > 0; } |
||||
} |
||||
|
||||
public void RemoveFirstProject() |
||||
{ |
||||
if (HasProjects) { |
||||
projects.RemoveAt(0); |
||||
} |
||||
} |
||||
|
||||
public IEnumerable<IProject> Projects { |
||||
get { return projects; } |
||||
} |
||||
|
||||
public int ProjectsCount { |
||||
get {return projects.Count;} |
||||
} |
||||
|
||||
public IProject Project { |
||||
get { |
||||
if (projects.Count > 0) { |
||||
return projects[0]; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
public string NamespaceFilter { |
||||
get { return namespaceFilter; } |
||||
} |
||||
|
||||
public IClass Class { |
||||
get { return c; } |
||||
} |
||||
|
||||
public IMember Member { |
||||
get { return member; } |
||||
} |
||||
} |
||||
} |
@ -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.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class NUnitTestAttributeName |
||||
{ |
||||
string name = String.Empty; |
||||
string qualifiedName = String.Empty; |
||||
string fullyQualifiedName = 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"); |
||||
fullyQualifiedName = 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, fullyQualifiedName)) { |
||||
return true; |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
public bool IsEqual(IAttribute attribute) |
||||
{ |
||||
return IsEqual(attribute.AttributeType.FullyQualifiedName); |
||||
} |
||||
} |
||||
} |
@ -1,382 +0,0 @@
@@ -1,382 +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.Linq; |
||||
using System.Collections.Generic; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a class that can be tested.
|
||||
/// </summary>
|
||||
public class TestClass |
||||
{ |
||||
IClass c; |
||||
TestMemberCollection testMembers; |
||||
TestResultType testResultType; |
||||
IRegisteredTestFrameworks testFrameworks; |
||||
|
||||
/// <summary>
|
||||
/// Raised when the test class result is changed.
|
||||
/// </summary>
|
||||
public event EventHandler ResultChanged; |
||||
|
||||
public TestClass(IClass c, IRegisteredTestFrameworks testFrameworks) |
||||
{ |
||||
this.c = c; |
||||
this.testFrameworks = testFrameworks; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying IClass for this test class.
|
||||
/// </summary>
|
||||
public IClass Class { |
||||
get { return c; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the list of other (e.g. base types) classes where from which test members included in this test class come from.
|
||||
/// </summary>
|
||||
private readonly ICollection<string> baseClassesFQNames = new List<string>(); |
||||
|
||||
/// <summary>
|
||||
/// Gets the test classes that exist in the specified namespace.
|
||||
/// </summary>
|
||||
public static TestClass[] GetTestClasses(ICollection<TestClass> classes, string ns) |
||||
{ |
||||
List<TestClass> matchedClasses = new List<TestClass>(); |
||||
foreach (TestClass c in classes) { |
||||
if (c.Namespace == ns) { |
||||
matchedClasses.Add(c); |
||||
} |
||||
} |
||||
return matchedClasses.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test classes that namespaces starts with the specified
|
||||
/// string.
|
||||
/// </summary>
|
||||
public static TestClass[] GetAllTestClasses(ICollection<TestClass> classes, string namespaceStartsWith) |
||||
{ |
||||
List<TestClass> matchedClasses = new List<TestClass>(); |
||||
foreach (TestClass c in classes) { |
||||
if (c.Namespace.StartsWith(namespaceStartsWith)) { |
||||
matchedClasses.Add(c); |
||||
} |
||||
} |
||||
return matchedClasses.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets all child namespaces that starts with the specified string.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the starts with string is 'ICSharpCode' and there is a code coverage
|
||||
/// method with a namespace of 'ICSharpCode.XmlEditor.Tests', then this
|
||||
/// method will return 'XmlEditor' as one of its strings.
|
||||
/// </remarks>
|
||||
public static string[] GetChildNamespaces(ICollection<TestClass> classes, string parentNamespace) { |
||||
List<string> items = new List<string>(); |
||||
foreach (TestClass c in classes) { |
||||
string ns = c.GetChildNamespace(parentNamespace); |
||||
if (ns.Length > 0) { |
||||
if (!items.Contains(ns)) { |
||||
items.Add(ns); |
||||
} |
||||
} |
||||
} |
||||
return items.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the name of the class.
|
||||
/// </summary>
|
||||
public string Name { |
||||
get |
||||
{ |
||||
var currentClass = c; |
||||
var name = c.Name; |
||||
while(currentClass.DeclaringType != null) |
||||
{ |
||||
name = String.Concat(currentClass.DeclaringType.Name, "+", name); |
||||
currentClass = currentClass.DeclaringType; |
||||
} |
||||
return name; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the fully qualified name of the class.
|
||||
/// </summary>
|
||||
public string QualifiedName { |
||||
get { return c.DotNetName; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the namespace of this class.
|
||||
/// </summary>
|
||||
public string Namespace { |
||||
get |
||||
{ |
||||
var currentClass = c; |
||||
while (currentClass.DeclaringType != null) |
||||
currentClass = currentClass.DeclaringType; |
||||
return currentClass.Namespace; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the root namespace for this class.
|
||||
/// </summary>
|
||||
public string RootNamespace { |
||||
get { return GetRootNamespace(c.Namespace); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test result for this class.
|
||||
/// </summary>
|
||||
public TestResultType Result { |
||||
get { return testResultType; } |
||||
set { |
||||
TestResultType previousTestResultType = testResultType; |
||||
testResultType = value; |
||||
if (previousTestResultType != testResultType) { |
||||
OnResultChanged(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the child namespace from the specified namespace
|
||||
/// based on the parent namespace.
|
||||
/// </summary>
|
||||
/// <param name="parentNamespace">Can contain multiple namespaces
|
||||
/// (e.g. ICSharpCode.XmlEditor).</param>
|
||||
public static string GetChildNamespace(string ns, string parentNamespace) |
||||
{ |
||||
if (parentNamespace.Length > 0) { |
||||
if (ns.StartsWith(String.Concat(parentNamespace, "."))) { |
||||
string end = ns.Substring(parentNamespace.Length + 1); |
||||
return GetRootNamespace(end); |
||||
} |
||||
return String.Empty; |
||||
} |
||||
return ns; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the child namespace based on the parent namespace
|
||||
/// from this class.
|
||||
/// </summary>
|
||||
/// <param name="parentNamespace">Can contain multiple namespaces
|
||||
/// (e.g. ICSharpCode.XmlEditor).</param>
|
||||
public string GetChildNamespace(string parentNamespace) |
||||
{ |
||||
return GetChildNamespace(Namespace, parentNamespace); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test members in this class.
|
||||
/// </summary>
|
||||
public TestMemberCollection TestMembers { |
||||
get { |
||||
if (testMembers == null) { |
||||
GetTestMembers(); |
||||
} |
||||
return testMembers; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test member with the specified name.
|
||||
/// </summary>
|
||||
/// <returns>Null if the member cannot be found.</returns>
|
||||
public TestMember GetTestMember(string name) |
||||
{ |
||||
if (TestMembers.Contains(name)) { |
||||
return TestMembers[name]; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the test member with the specified test result.
|
||||
/// </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>
|
||||
/// Resets all the test results back to none.
|
||||
/// </summary>
|
||||
public void ResetTestResults() |
||||
{ |
||||
Result = TestResultType.None; |
||||
TestMembers.ResetTestResults(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the members and class based on the new class
|
||||
/// information that has been parsed.
|
||||
/// </summary>
|
||||
public void UpdateClass(IClass c) |
||||
{ |
||||
this.c = c.GetCompoundClass(); |
||||
|
||||
// Remove missing members.
|
||||
TestMemberCollection newTestMembers = GetTestMembers(this.c); |
||||
TestMemberCollection existingTestMembers = TestMembers; |
||||
for (int i = existingTestMembers.Count - 1; i >= 0; --i) { |
||||
TestMember member = existingTestMembers[i]; |
||||
if (newTestMembers.Contains(member.Name)) { |
||||
member.Update(newTestMembers[member.Name].Member); |
||||
} else { |
||||
existingTestMembers.RemoveAt(i); |
||||
} |
||||
} |
||||
|
||||
// Add new members.
|
||||
foreach (TestMember member in newTestMembers) { |
||||
if (existingTestMembers.Contains(member.Name)) { |
||||
} else { |
||||
existingTestMembers.Add(member); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the first dotted part of the namespace.
|
||||
/// </summary>
|
||||
static string GetRootNamespace(string ns) |
||||
{ |
||||
int index = ns.IndexOf('.'); |
||||
if (index > 0) { |
||||
return ns.Substring(0, index); |
||||
} |
||||
return ns; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test members for the class.
|
||||
/// </summary>
|
||||
void GetTestMembers() |
||||
{ |
||||
testMembers = GetTestMembers(c); |
||||
testMembers.ResultChanged += TestMembersResultChanged; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test members for the specified class.
|
||||
/// </summary>
|
||||
TestMemberCollection GetTestMembers(IClass c) |
||||
{ |
||||
TestMemberCollection testMembers = new TestMemberCollection(); |
||||
foreach (var member in testFrameworks.GetTestMembersFor(c)) |
||||
if (!testMembers.Contains(member.Name)) { |
||||
testMembers.Add(member); |
||||
} |
||||
|
||||
// Add base class test members.
|
||||
IClass declaringType = c; |
||||
while (c.BaseClass != null) |
||||
{ |
||||
foreach (var testMember in testFrameworks.GetTestMembersFor(c.BaseClass)) { |
||||
BaseTestMember baseTestMethod = new BaseTestMember(declaringType, testMember.Member); |
||||
TestMember testMethod = new TestMember(c.BaseClass, baseTestMethod); |
||||
if (testMember.Member.IsVirtual) { |
||||
if (!testMembers.Contains(testMember.Name)) { |
||||
testMembers.Add(testMethod); |
||||
} |
||||
} else { |
||||
if (!testMembers.Contains(testMethod.Name)) { |
||||
testMembers.Add(testMethod); |
||||
} |
||||
} |
||||
} |
||||
c = c.BaseClass; |
||||
} |
||||
|
||||
baseClassesFQNames.Clear(); |
||||
foreach (var memberDeclaringClass in testMembers.Select(member => member.DeclaringType).Distinct()) |
||||
if (memberDeclaringClass.CompareTo(declaringType) != 0) |
||||
baseClassesFQNames.Add(memberDeclaringClass.FullyQualifiedName); |
||||
return testMembers; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the test class's test result after the test member's
|
||||
/// test result has changed.
|
||||
/// </summary>
|
||||
void TestMembersResultChanged(object source, EventArgs e) |
||||
{ |
||||
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; |
||||
} |
||||
|
||||
public bool IsDerivedFrom(IClass c) |
||||
{ |
||||
return baseClassesFQNames.Contains(c.FullyQualifiedName); |
||||
} |
||||
} |
||||
} |
@ -1,98 +0,0 @@
@@ -1,98 +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.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a class that has the [TestFixture] attribute
|
||||
/// associated with it.
|
||||
/// </summary>
|
||||
public class TestClassTreeNode : TestTreeNode |
||||
{ |
||||
TestClass testClass; |
||||
|
||||
public TestClassTreeNode(TestProject project, TestClass testClass) |
||||
: base(project, testClass.Name) |
||||
{ |
||||
this.testClass = testClass; |
||||
testClass.ResultChanged += TestClassResultChanged; |
||||
Nodes.Add(new ExtTreeNode()); |
||||
UpdateImageListIndex(testClass.Result); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying IClass for this test class.
|
||||
/// </summary>
|
||||
public IClass Class { |
||||
get { return testClass.Class; } |
||||
} |
||||
|
||||
public override void Dispose() |
||||
{ |
||||
if (!IsDisposed) { |
||||
testClass.ResultChanged -= TestClassResultChanged; |
||||
testClass.TestMembers.TestMemberAdded -= TestMemberAdded; |
||||
testClass.TestMembers.TestMemberRemoved -= TestMemberRemoved; |
||||
} |
||||
base.Dispose(); |
||||
} |
||||
|
||||
protected override void Initialize() |
||||
{ |
||||
Nodes.Clear(); |
||||
|
||||
foreach (TestMember member in testClass.TestMembers) { |
||||
AddTestMemberTreeNode(member); |
||||
} |
||||
testClass.TestMembers.TestMemberAdded += TestMemberAdded; |
||||
testClass.TestMembers.TestMemberRemoved += TestMemberRemoved; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a new TestMemberTreeNode to this node.
|
||||
/// </summary>
|
||||
void AddTestMemberTreeNode(TestMember member) |
||||
{ |
||||
TestMemberTreeNode node = new TestMemberTreeNode(TestProject, member); |
||||
node.AddTo(this); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the node's icon based on the test class test result.
|
||||
/// </summary>
|
||||
void TestClassResultChanged(object source, EventArgs e) |
||||
{ |
||||
UpdateImageListIndex(testClass.Result); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a new test member tree node to this class node after a new
|
||||
/// TestMember has been added to the TestClass.
|
||||
/// </summary>
|
||||
void TestMemberAdded(object source, TestMemberEventArgs e) |
||||
{ |
||||
AddTestMemberTreeNode(e.TestMember); |
||||
SortChildNodes(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the corresponding test member node after it has been
|
||||
/// removed from the TestClass.
|
||||
/// </summary>
|
||||
void TestMemberRemoved(object source, TestMemberEventArgs e) |
||||
{ |
||||
foreach (TestMemberTreeNode memberNode in Nodes) { |
||||
if (memberNode.Text == e.TestMember.Name) { |
||||
Nodes.Remove(memberNode); |
||||
memberNode.Dispose(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,24 +0,0 @@
@@ -1,24 +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 ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public interface ITestFramework |
||||
{ |
||||
bool IsTestMember(IMember member); |
||||
bool IsTestClass(IClass c); |
||||
bool IsTestProject(IProject project); |
||||
|
||||
IEnumerable<TestMember> GetTestMembersFor(IClass @class); |
||||
|
||||
ITestRunner CreateTestRunner(); |
||||
ITestRunner CreateTestDebugger(); |
||||
|
||||
bool IsBuildNeededBeforeTestRun { get; } |
||||
} |
||||
} |
@ -1,155 +0,0 @@
@@ -1,155 +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.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a member that can be tested.
|
||||
/// </summary>
|
||||
public class TestMember |
||||
{ |
||||
#if unused
|
||||
string prefix = String.Empty; |
||||
#endif
|
||||
IMember member; |
||||
TestResultType testResultType = TestResultType.None; |
||||
|
||||
/// <summary>
|
||||
/// Raised when the test result has changed.
|
||||
/// </summary>
|
||||
public event EventHandler ResultChanged; |
||||
|
||||
public TestMember(IMember member) |
||||
{ |
||||
this.member = member; |
||||
this.DeclaringType = member.DeclaringType; |
||||
} |
||||
|
||||
#if unused
|
||||
/// <summary>
|
||||
/// Creates a new TestMember instance.
|
||||
/// </summary>
|
||||
/// <param name="prefix">The prefix to be added to the
|
||||
/// member name with a dot character. This is specified
|
||||
/// when the test member refers to a base class method. NUnit
|
||||
/// refers to base class test methods by prefixing the
|
||||
/// class name to it:
|
||||
///
|
||||
/// [TestFixture]
|
||||
/// public class DerivedClass : BaseClass
|
||||
///
|
||||
/// Test member name:
|
||||
///
|
||||
/// RootNamespace.DerivedClass.BaseClass.BaseClassMethod
|
||||
/// </param>
|
||||
public TestMember(string prefix, IMember member) |
||||
{ |
||||
this.member = member; |
||||
this.prefix = prefix; |
||||
} |
||||
#endif
|
||||
|
||||
public TestMember(IClass testClass, IMember member) |
||||
{ |
||||
this.DeclaringType = testClass; |
||||
this.member = member; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying IMember for this TestMember.
|
||||
/// </summary>
|
||||
public IMember Member { |
||||
get { return member; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the class where the test member is actually declared.
|
||||
/// In case of test member from base class it will be the base class not the
|
||||
/// </summary>
|
||||
public IClass DeclaringType { get; private set; } |
||||
|
||||
/// <summary>
|
||||
/// Updates the test member based on new information
|
||||
/// in the specified IMember.
|
||||
/// </summary>
|
||||
public void Update(IMember member) |
||||
{ |
||||
this.member = member; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test result for this member.
|
||||
/// </summary>
|
||||
public TestResultType Result { |
||||
get { return testResultType; } |
||||
set { |
||||
TestResultType previousTestResultType = testResultType; |
||||
testResultType = value; |
||||
if (previousTestResultType != testResultType) { |
||||
OnResultChanged(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the member's name.
|
||||
/// </summary>
|
||||
public string Name { |
||||
get { |
||||
#if unused
|
||||
if (prefix.Length > 0) { |
||||
return String.Concat(prefix, ".", member.Name); |
||||
} |
||||
#endif
|
||||
return member.Name; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the member name from a fully qualified name
|
||||
/// of the form:
|
||||
///
|
||||
/// Namespace.Class.Member
|
||||
/// </summary>
|
||||
public static string GetMemberName(string qualifiedName) |
||||
{ |
||||
if (qualifiedName != null) { |
||||
int index = qualifiedName.LastIndexOf('.'); |
||||
if (index >= 0) { |
||||
return qualifiedName.Substring(index + 1); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the namespace and class name from a fully qualified
|
||||
/// name of the form:
|
||||
///
|
||||
/// Namespace.Class.Member
|
||||
/// </summary>
|
||||
public static string GetQualifiedClassName(string qualifiedName) |
||||
{ |
||||
if (qualifiedName != null) { |
||||
int memberIndex = qualifiedName.LastIndexOf('.'); |
||||
if (memberIndex >= 0) { |
||||
return qualifiedName.Substring(0, memberIndex); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Raises the ResultChanged event.
|
||||
/// </summary>
|
||||
void OnResultChanged() |
||||
{ |
||||
if (ResultChanged != null) { |
||||
ResultChanged(this, new EventArgs()); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,53 +0,0 @@
@@ -1,53 +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.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a member that has the [Test] attribute associated with it.
|
||||
/// </summary>
|
||||
public class TestMemberTreeNode : TestTreeNode |
||||
{ |
||||
TestMember testMember; |
||||
|
||||
public TestMemberTreeNode(TestProject project, TestMember testMember) |
||||
: base(project, testMember.Name) |
||||
{ |
||||
this.testMember = testMember; |
||||
testMember.ResultChanged += TestMemberResultChanged; |
||||
UpdateImageListIndex(testMember.Result); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the underlying IMember for this test member.
|
||||
/// </summary>
|
||||
public IMember Member { |
||||
get { return testMember.Member; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the TestMember.ResultChanged event handler.
|
||||
/// </summary>
|
||||
public override void Dispose() |
||||
{ |
||||
if (!IsDisposed) { |
||||
testMember.ResultChanged -= TestMemberResultChanged; |
||||
} |
||||
base.Dispose(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the node's icon after the test member result
|
||||
/// has changed.
|
||||
/// </summary>
|
||||
void TestMemberResultChanged(object source, EventArgs e) |
||||
{ |
||||
UpdateImageListIndex(testMember.Result); |
||||
} |
||||
} |
||||
} |
@ -1,337 +0,0 @@
@@ -1,337 +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.Windows.Forms; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a namespace in the TestTreeView.
|
||||
/// </summary>
|
||||
public class TestNamespaceTreeNode : TestTreeNode |
||||
{ |
||||
string ns = String.Empty; |
||||
string namespacePrefix = String.Empty; |
||||
string fullNamespace; |
||||
TestClassCollection testClasses; |
||||
List<TestNamespaceTreeNode> namespaceChildNodes = new List<TestNamespaceTreeNode>(); |
||||
ExtTreeNode dummyNode; |
||||
|
||||
/// <summary>
|
||||
/// Creates a new TestNamespaceTreeNode
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Note that the Namespace child nodes are added in
|
||||
/// the constructor not whilst the node is expanding
|
||||
/// via the Initialize method. This is so the icon for the
|
||||
/// node can be updated even if the parent node is not
|
||||
/// expanded. The alternative is to have each namespace node,
|
||||
/// even if it does not have any class child nodes, to
|
||||
/// store all the classes that are below it in the tree and
|
||||
/// update the icon based on their results. The assumption
|
||||
/// is that there are fewer namespace nodes than classes so
|
||||
/// adding the namespace nodes here does not matter.
|
||||
/// </remarks>
|
||||
/// <param name="namespacePrefix">The first part of the
|
||||
/// namespace (including any dot characters) before this
|
||||
/// particular namespace.</param>
|
||||
/// <param name="name">The name of the namespace without any
|
||||
/// dot characters (e.g. the name at this particular
|
||||
/// location in the tree).</param>
|
||||
public TestNamespaceTreeNode(TestProject testProject, string namespacePrefix, string name) |
||||
: base(testProject, name) |
||||
{ |
||||
ns = name; |
||||
this.namespacePrefix = namespacePrefix; |
||||
fullNamespace = GetFullNamespace(namespacePrefix, ns); |
||||
GetTestClasses(); |
||||
testProject.TestClasses.TestClassAdded += TestClassAdded; |
||||
testProject.TestClasses.TestClassRemoved += TestClassRemoved; |
||||
|
||||
// Add namespace nodes - do not add them on node expansion.
|
||||
foreach (string namespaceName in TestProject.GetChildNamespaces(fullNamespace)) { |
||||
TestNamespaceTreeNode node = new TestNamespaceTreeNode(TestProject, fullNamespace, namespaceName); |
||||
node.AddTo(this); |
||||
namespaceChildNodes.Add(node); |
||||
node.ImageIndexChanged += TestNamespaceNodeImageIndexChanged; |
||||
} |
||||
|
||||
// Add a dummy node if there are no namespaces since
|
||||
// there might be class nodes which will be added
|
||||
// lazily when the node is expanded.
|
||||
if (namespaceChildNodes.Count == 0) { |
||||
dummyNode = new ExtTreeNode(); |
||||
Nodes.Add(dummyNode); |
||||
} |
||||
|
||||
UpdateImageListIndex(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates a new TestNamespaceTreeNode with the specified
|
||||
/// namespace name. This node will have no namespace prefix.
|
||||
/// </summary>
|
||||
public TestNamespaceTreeNode(TestProject testProject, string name) |
||||
: this(testProject, String.Empty, name) |
||||
{ |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Frees any resources held by this class.
|
||||
/// </summary>
|
||||
public override void Dispose() |
||||
{ |
||||
if (!IsDisposed) { |
||||
TestProject.TestClasses.TestClassAdded -= TestClassAdded; |
||||
TestProject.TestClasses.TestClassRemoved -= TestClassRemoved; |
||||
testClasses.ResultChanged -= TestClassesResultChanged; |
||||
} |
||||
base.Dispose(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets whether this namespace node is considered empty. If
|
||||
/// the node has been expanded then the node is empty if it
|
||||
/// has no child nodes. If it has not been expanded then there
|
||||
/// will be a dummy child node or a set of namespace
|
||||
/// nodes but no test class nodes.
|
||||
/// </summary>
|
||||
public bool IsEmpty { |
||||
get { |
||||
if (isInitialized) { |
||||
return Nodes.Count == 0; |
||||
} else if (dummyNode != null) { |
||||
return testClasses.Count == 0; |
||||
} else { |
||||
return Nodes.Count == 0 && testClasses.Count == 0; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the full namespace of this tree node. This includes any
|
||||
/// parent namespaces prefixed to the namespace associated
|
||||
/// with this tree node.
|
||||
/// </summary>
|
||||
public string FullNamespace { |
||||
get { |
||||
return fullNamespace; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the test class nodes for this namespace when the
|
||||
/// node is expanded.
|
||||
/// </summary>
|
||||
protected override void Initialize() |
||||
{ |
||||
if (dummyNode != null) { |
||||
Nodes.Clear(); |
||||
} |
||||
|
||||
// Add class nodes for this namespace.
|
||||
foreach (TestClass c in testClasses) { |
||||
TestClassTreeNode classNode = new TestClassTreeNode(TestProject, c); |
||||
classNode.AddTo(this); |
||||
} |
||||
|
||||
// Sort the nodes.
|
||||
SortChildNodes(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the child namespace to the namespace prefix.
|
||||
/// </summary>
|
||||
static string GetFullNamespace(string prefix, string name) |
||||
{ |
||||
if (prefix.Length > 0) { |
||||
return String.Concat(prefix, ".", name); |
||||
} |
||||
return name; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates this node's icon because one of its child namespace nodes
|
||||
/// has changed.
|
||||
/// </summary>
|
||||
void TestNamespaceNodeImageIndexChanged(object source, EventArgs e) |
||||
{ |
||||
UpdateImageListIndex(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test classes for this namespace.
|
||||
/// </summary>
|
||||
void GetTestClasses() |
||||
{ |
||||
testClasses = new TestClassCollection(); |
||||
foreach (TestClass c in TestProject.GetTestClasses(fullNamespace)) { |
||||
testClasses.Add(c); |
||||
} |
||||
testClasses.ResultChanged += TestClassesResultChanged; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The overall test result for the classes in this namespace
|
||||
/// have changed so the node's icon is updated.
|
||||
/// </summary>
|
||||
void TestClassesResultChanged(object source, EventArgs e) |
||||
{ |
||||
UpdateImageListIndex(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines the image list index for this node based
|
||||
/// on the current state of all the child nodes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Since the test classes overall test result is
|
||||
/// available via the TestClassCollection we do not
|
||||
/// need to sum all the individual test classes.
|
||||
/// </remarks>
|
||||
void UpdateImageListIndex() |
||||
{ |
||||
int ignoredCount = 0; |
||||
int passedCount = 0; |
||||
int failedCount = 0; |
||||
|
||||
// Count the passes, failures and ignores for the
|
||||
// namespace child nodes.
|
||||
foreach (ExtTreeNode node in namespaceChildNodes) { |
||||
switch (node.ImageIndex) { |
||||
case (int)TestTreeViewImageListIndex.TestFailed: |
||||
failedCount++; |
||||
break; |
||||
case (int)TestTreeViewImageListIndex.TestIgnored: |
||||
ignoredCount++; |
||||
break; |
||||
case (int)TestTreeViewImageListIndex.TestPassed: |
||||
passedCount++; |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Check the passes, failures and ignores for the
|
||||
// test classes that belong to this namespace.
|
||||
switch (testClasses.Result) { |
||||
case TestResultType.Failure: |
||||
failedCount++; |
||||
break; |
||||
case TestResultType.Success: |
||||
passedCount++; |
||||
break; |
||||
case TestResultType.Ignored: |
||||
ignoredCount++; |
||||
break; |
||||
} |
||||
|
||||
// Work out the total number of passes we are expecting
|
||||
int total = namespaceChildNodes.Count; |
||||
if (testClasses.Count > 0) { |
||||
// Only add one for the testClasses since the
|
||||
// overall pass or failure is indicated via
|
||||
// the TestClassCollection so we do not need
|
||||
// to add all the test classes.
|
||||
total++; |
||||
} |
||||
|
||||
// Determine the correct image list index for this node.
|
||||
if (failedCount > 0) { |
||||
UpdateImageListIndex(TestResultType.Failure); |
||||
} else if (ignoredCount > 0) { |
||||
UpdateImageListIndex(TestResultType.Ignored); |
||||
} else if (passedCount == total) { |
||||
UpdateImageListIndex(TestResultType.Success); |
||||
} else { |
||||
UpdateImageListIndex(TestResultType.None); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// A new test class has been added to the project so a new
|
||||
/// tree node is added if the class belongs to this namespace.
|
||||
/// </summary>
|
||||
void TestClassAdded(object source, TestClassEventArgs e) |
||||
{ |
||||
if (e.TestClass.Namespace == fullNamespace) { |
||||
// Add test class to our monitored test classes.
|
||||
testClasses.Add(e.TestClass); |
||||
|
||||
// Add a new tree node.
|
||||
TestClassTreeNode classNode = new TestClassTreeNode(TestProject, e.TestClass); |
||||
classNode.AddTo(this); |
||||
|
||||
// Sort the nodes.
|
||||
SortChildNodes(); |
||||
} else if (isInitialized && NamespaceStartsWith(e.TestClass.Namespace)) { |
||||
// Check if there is a child namespace node for the class.
|
||||
string childNamespace = TestClass.GetChildNamespace(e.TestClass.Namespace, fullNamespace); |
||||
if (!NamespaceNodeExists(childNamespace)) { |
||||
// Add a new namespace node.
|
||||
TestNamespaceTreeNode node = new TestNamespaceTreeNode(TestProject, fullNamespace, childNamespace); |
||||
node.AddTo(this); |
||||
|
||||
// Sort the nodes.
|
||||
SortChildNodes(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines whether the namespace for this node starts
|
||||
/// with the namespace specified.
|
||||
/// </summary>
|
||||
bool NamespaceStartsWith(string ns) |
||||
{ |
||||
return ns.StartsWith(String.Concat(fullNamespace, ".")); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// A test class has been removed from the project so the
|
||||
/// corresponding tree node is removed if it belongs to this
|
||||
/// namespace.
|
||||
/// </summary>
|
||||
void TestClassRemoved(object source, TestClassEventArgs e) |
||||
{ |
||||
if (e.TestClass.Namespace == fullNamespace) { |
||||
// Remove test class from our monitored test classes.
|
||||
testClasses.Remove(e.TestClass); |
||||
|
||||
// Remove the corresponding tree node.
|
||||
foreach (ExtTreeNode node in Nodes) { |
||||
TestClassTreeNode classNode = node as TestClassTreeNode; |
||||
if (classNode != null && classNode.Text == e.TestClass.Name) { |
||||
classNode.Remove(); |
||||
classNode.Dispose(); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
// Remove this namespace node if there are no more child nodes.
|
||||
RemoveIfEmpty(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes this node if it has no child nodes. This
|
||||
/// method also calls the same method on the parent
|
||||
/// namespace node so it can check whether it should
|
||||
/// remove itself.
|
||||
/// </summary>
|
||||
void RemoveIfEmpty() |
||||
{ |
||||
if (IsEmpty) { |
||||
Remove(); |
||||
Dispose(); |
||||
TestNamespaceTreeNode parentNode = Parent as TestNamespaceTreeNode; |
||||
if (parentNode != null) { |
||||
parentNode.RemoveIfEmpty(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,291 +0,0 @@
@@ -1,291 +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.Linq; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a project that has a reference to a unit testing
|
||||
/// framework assembly. Currently only NUnit is supported.
|
||||
/// </summary>
|
||||
public class TestProject |
||||
{ |
||||
IProject project; |
||||
IProjectContent projectContent; |
||||
TestClassCollection testClasses; |
||||
List<string> rootNamespaces; |
||||
IRegisteredTestFrameworks testFrameworks; |
||||
|
||||
public TestProject(IProject project, IProjectContent projectContent, IRegisteredTestFrameworks testFrameworks) |
||||
{ |
||||
this.project = project; |
||||
this.projectContent = projectContent; |
||||
this.testFrameworks = testFrameworks; |
||||
} |
||||
|
||||
public IProject Project { |
||||
get { return project; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test classes in this project.
|
||||
/// </summary>
|
||||
public TestClassCollection TestClasses { |
||||
get { |
||||
if (testClasses == null) { |
||||
GetTestClasses(); |
||||
} |
||||
return testClasses; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test classes that exist in the specified namespace.
|
||||
/// </summary>
|
||||
public TestClass[] GetTestClasses(string ns) |
||||
{ |
||||
return TestClass.GetTestClasses(TestClasses, ns); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the test classes whose namespaces start with the specified string.
|
||||
/// </summary>
|
||||
public TestClass[] GetAllTestClasses(string namespaceStartsWith) |
||||
{ |
||||
return TestClass.GetAllTestClasses(TestClasses, namespaceStartsWith); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets all the child namespaces with the specified parent
|
||||
/// namespace. The parent namespace can be one or more
|
||||
/// namespaces separated with a period.
|
||||
/// </summary>
|
||||
public string[] GetChildNamespaces(string parentNamespace) |
||||
{ |
||||
return TestClass.GetChildNamespaces(TestClasses, parentNamespace); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the project's name.
|
||||
/// </summary>
|
||||
public string Name { |
||||
get { return project.Name; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the distinct root namespaces for all this project.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If one of the namespaces is 'ICSharpCode.XmlEditor' then this
|
||||
/// method will return 'ICSharpCode' as one of the root namespaces.
|
||||
/// </remarks>
|
||||
public IList<string> RootNamespaces { |
||||
get { |
||||
if (rootNamespaces == null) { |
||||
GetRootNamespaces(); |
||||
} |
||||
return rootNamespaces; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the test method based on the test result.
|
||||
/// </summary>
|
||||
public void UpdateTestResult(TestResult testResult) |
||||
{ |
||||
TestClasses.UpdateTestResult(testResult); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sets all the test results back to none.
|
||||
/// </summary>
|
||||
public void ResetTestResults() |
||||
{ |
||||
TestClasses.ResetTestResults(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the classes and methods based on the new parse information.
|
||||
/// </summary>
|
||||
/// <param name="oldUnit">The old compiliation unit
|
||||
/// (ParseInformationEventArgs.ParseInformation.BestCompilationUnit as ICompilationUnit)</param>
|
||||
/// <param name="newUnit">The new compilation unit
|
||||
/// (ParseInformationEventArgs.CompilationUnit).</param>
|
||||
public void UpdateParseInfo(ICompilationUnit oldUnit, ICompilationUnit newUnit) |
||||
{ |
||||
if (!IsParseInfoForThisProject(oldUnit, newUnit)) { |
||||
return; |
||||
} |
||||
|
||||
RemovedClasses removedClasses = new RemovedClasses(); |
||||
|
||||
if (oldUnit != null) { |
||||
removedClasses.Add(oldUnit.Classes); |
||||
} |
||||
if (newUnit != null) { |
||||
foreach (IClass c in newUnit.Classes) { |
||||
UpdateTestClass(c); |
||||
foreach (IClass innerClass in new InnerClassEnumerator(c)) { |
||||
UpdateTestClass(innerClass); |
||||
removedClasses.Remove(innerClass); |
||||
} |
||||
removedClasses.Remove(c); |
||||
} |
||||
} |
||||
|
||||
// Remove missing classes.
|
||||
foreach (IClass c in removedClasses.GetMissingClasses()) { |
||||
IClass existingClass = GetExistingTestClassInProject(c); |
||||
if (existingClass != null) { |
||||
UpdateTestClass(existingClass); |
||||
} else { |
||||
TestClasses.Remove(c.DotNetName); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines whether the new parse information is for this test
|
||||
/// project.
|
||||
/// </summary>
|
||||
public bool IsParseInfoForThisProject(ICompilationUnit oldUnit, ICompilationUnit newUnit) |
||||
{ |
||||
ICompilationUnit unit = oldUnit; |
||||
if (unit == null) { |
||||
unit = newUnit; |
||||
} |
||||
if (unit != null) { |
||||
return Object.ReferenceEquals(unit.ProjectContent, this.projectContent); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a new class to the test project's classes only if
|
||||
/// the class is a test class.
|
||||
/// </summary>
|
||||
void AddNewTestClass(IClass c) |
||||
{ |
||||
if (IsTestClass(c)) { |
||||
TestClass testClass = CreateTestClass(c); |
||||
TestClasses.Add(testClass); |
||||
} |
||||
} |
||||
|
||||
TestClass CreateTestClass(IClass c) |
||||
{ |
||||
return new TestClass(c, testFrameworks); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the test class methods based on the newly parsed class
|
||||
/// information.
|
||||
/// </summary>
|
||||
void UpdateTestClass(IClass c) |
||||
{ |
||||
if (TestClasses.Contains(c.DotNetName)) |
||||
{ |
||||
if (IsTestClass(c)) |
||||
{ |
||||
TestClass testClass = TestClasses[c.DotNetName]; |
||||
testClass.UpdateClass(c); |
||||
} |
||||
else |
||||
{ |
||||
// TestFixture attribute has been removed so
|
||||
// remove the class from the set of TestClasses.
|
||||
TestClasses.Remove(c.DotNetName); |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// TestFixture attribute may have been recently added to
|
||||
// this class so call AddNewTestClass. No need to
|
||||
// check if the class is actually a test class since
|
||||
// AddNewTestClass does this anyway.
|
||||
AddNewTestClass(c); |
||||
} |
||||
|
||||
var derivedTestClasses = GetTestClassesDerivedFrom(c); |
||||
if (derivedTestClasses.Any()) |
||||
UpdateClassesFromProjectContent(derivedTestClasses); |
||||
|
||||
} |
||||
|
||||
private IEnumerable<IClass> GetTestClassesDerivedFrom(IClass c) |
||||
{ |
||||
return TestClasses |
||||
.Where(testClass => testClass.IsDerivedFrom(c)) |
||||
.Select(testClass => testClass.Class) |
||||
.ToArray(); |
||||
} |
||||
|
||||
private void UpdateClassesFromProjectContent(IEnumerable<IClass> classes) |
||||
{ |
||||
foreach (var c in classes) |
||||
{ |
||||
var classInProjectContent = projectContent.GetClass(c.FullyQualifiedName, c.TypeParameters.Count); |
||||
if (classInProjectContent != null) |
||||
UpdateTestClass(classInProjectContent); |
||||
} |
||||
} |
||||
|
||||
void GetTestClasses() |
||||
{ |
||||
testClasses = new TestClassCollection(); |
||||
foreach (IClass c in projectContent.Classes) { |
||||
if (IsTestClass(c)) { |
||||
if (!testClasses.Contains(c.FullyQualifiedName)) { |
||||
testClasses.Add(CreateTestClass(c)); |
||||
} |
||||
} |
||||
foreach (IClass innerClass in new InnerClassEnumerator(c)) { |
||||
if (IsTestClass(innerClass)) { |
||||
if (!testClasses.Contains(innerClass.DotNetName)) { |
||||
testClasses.Add(CreateTestClass(innerClass)); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool IsTestClass(IClass c) |
||||
{ |
||||
return testFrameworks.IsTestClass(c); |
||||
} |
||||
|
||||
void GetRootNamespaces() |
||||
{ |
||||
rootNamespaces = new List<string>(); |
||||
foreach (TestClass c in TestClasses) { |
||||
string rootNamespace = c.RootNamespace; |
||||
if ((rootNamespace.Length > 0) && !rootNamespaces.Contains(rootNamespace)) { |
||||
rootNamespaces.Add(rootNamespace); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets an existing test class with the same name in the project. This
|
||||
/// method is used to check that we do not remove a class after an existing duplicate class name
|
||||
/// is changed.
|
||||
/// </summary>
|
||||
IClass GetExistingTestClassInProject(IClass c) |
||||
{ |
||||
foreach (IClass existingClass in projectContent.Classes) { |
||||
if (IsTestClass(existingClass)) { |
||||
if (existingClass.DotNetName == c.DotNetName) { |
||||
return existingClass; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -1,113 +0,0 @@
@@ -1,113 +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.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// The root tree node for a project that has tests.
|
||||
/// </summary>
|
||||
public class TestProjectTreeNode : TestTreeNode |
||||
{ |
||||
public TestProjectTreeNode(TestProject project) |
||||
: base(project, project.Name) |
||||
{ |
||||
Nodes.Add(new ExtTreeNode()); |
||||
TestProject.TestClasses.ResultChanged += TestClassesResultChanged; |
||||
TestProject.TestClasses.TestClassAdded += TestClassAdded; |
||||
TestProject.TestClasses.TestClassRemoved += TestClassRemoved; |
||||
} |
||||
|
||||
public override void Dispose() |
||||
{ |
||||
if (!IsDisposed) { |
||||
TestProject.TestClasses.ResultChanged -= TestClassesResultChanged; |
||||
TestProject.TestClasses.TestClassAdded -= TestClassAdded; |
||||
TestProject.TestClasses.TestClassRemoved -= TestClassRemoved; |
||||
} |
||||
base.Dispose(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the child nodes after this node has been expanded.
|
||||
/// </summary>
|
||||
protected override void Initialize() |
||||
{ |
||||
Nodes.Clear(); |
||||
|
||||
// Add namespace nodes.
|
||||
foreach (string rootNamespace in TestProject.RootNamespaces) { |
||||
TestNamespaceTreeNode node = new TestNamespaceTreeNode(TestProject, rootNamespace); |
||||
node.AddTo(this); |
||||
} |
||||
|
||||
// Add class nodes.
|
||||
foreach (TestClass c in TestProject.GetTestClasses(String.Empty)) { |
||||
AddClassNode(c); |
||||
} |
||||
|
||||
// Sort the nodes.
|
||||
SortChildNodes(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates this node's icon based on the overall result of the
|
||||
/// test classes.
|
||||
/// </summary>
|
||||
void TestClassesResultChanged(object source, EventArgs e) |
||||
{ |
||||
UpdateImageListIndex(TestProject.TestClasses.Result); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a new class node to this project node if the
|
||||
/// class added has no root namespace.
|
||||
/// </summary>
|
||||
void TestClassAdded(object source, TestClassEventArgs e) |
||||
{ |
||||
if (e.TestClass.Namespace == String.Empty) { |
||||
AddClassNode(e.TestClass); |
||||
SortChildNodes(); |
||||
} else if (isInitialized) { |
||||
// Check that we have a namespace node for this class.
|
||||
if (!NamespaceNodeExists(e.TestClass.RootNamespace)) { |
||||
// Add a new namespace node.
|
||||
TestNamespaceTreeNode node = new TestNamespaceTreeNode(TestProject, e.TestClass.RootNamespace); |
||||
node.AddTo(this); |
||||
SortChildNodes(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the corresponding tree node that is a child of
|
||||
/// this project tree node if the class has no root namespace.
|
||||
/// </summary>
|
||||
void TestClassRemoved(object source, TestClassEventArgs e) |
||||
{ |
||||
if (e.TestClass.Namespace == String.Empty) { |
||||
foreach (ExtTreeNode node in Nodes) { |
||||
TestClassTreeNode classNode = node as TestClassTreeNode; |
||||
if (classNode != null && classNode.Text == e.TestClass.Name) { |
||||
classNode.Remove(); |
||||
classNode.Dispose(); |
||||
break; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a new TestClassTreeNode to this node.
|
||||
/// </summary>
|
||||
void AddClassNode(TestClass c) |
||||
{ |
||||
TestClassTreeNode node = new TestClassTreeNode(TestProject, c); |
||||
node.AddTo(this); |
||||
} |
||||
} |
||||
} |
@ -1,92 +0,0 @@
@@ -1,92 +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.SharpDevelop.Dom; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public enum TestResultType { |
||||
/// <summary>
|
||||
/// The test has not been run.
|
||||
/// </summary>
|
||||
None = 0, |
||||
|
||||
/// <summary>
|
||||
/// The test passed.
|
||||
/// </summary>
|
||||
Success = 1, |
||||
|
||||
/// <summary>
|
||||
/// The test failed.
|
||||
/// </summary>
|
||||
Failure = 2, |
||||
|
||||
/// <summary>
|
||||
/// The test was ignored.
|
||||
/// </summary>
|
||||
Ignored = 3 |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Holds the information about a single test result.
|
||||
/// </summary>
|
||||
public class TestResult |
||||
{ |
||||
string name = String.Empty; |
||||
string message = String.Empty; |
||||
string stackTrace = String.Empty; |
||||
TestResultType resultType = TestResultType.None; |
||||
FilePosition stackTraceFilePosition = FilePosition.Empty; |
||||
|
||||
public TestResult(string name) |
||||
{ |
||||
this.name = name; |
||||
} |
||||
|
||||
public string Name { |
||||
get { return name; } |
||||
} |
||||
|
||||
public bool IsSuccess { |
||||
get { return resultType == TestResultType.Success; } |
||||
} |
||||
|
||||
public bool IsFailure { |
||||
get { return resultType == TestResultType.Failure; } |
||||
} |
||||
|
||||
public bool IsIgnored { |
||||
get { return resultType == TestResultType.Ignored; } |
||||
} |
||||
|
||||
public TestResultType ResultType { |
||||
get { return resultType; } |
||||
set { resultType = value; } |
||||
} |
||||
|
||||
public string Message { |
||||
get { return message; } |
||||
set { message = value; } |
||||
} |
||||
|
||||
public string StackTrace { |
||||
get { return stackTrace; } |
||||
set { |
||||
if (stackTrace != value) { |
||||
stackTrace = value; |
||||
OnStackTraceChanged(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
protected virtual void OnStackTraceChanged() |
||||
{ |
||||
} |
||||
|
||||
public FilePosition StackTraceFilePosition { |
||||
get { return stackTraceFilePosition; } |
||||
set { stackTraceFilePosition = value; } |
||||
} |
||||
} |
||||
} |
@ -1,97 +0,0 @@
@@ -1,97 +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.IO; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class TestResultTask |
||||
{ |
||||
TestResultTask() |
||||
{ |
||||
} |
||||
|
||||
public static Task Create(TestResult result, TestProject project) |
||||
{ |
||||
TaskType taskType = TaskType.Warning; |
||||
FileLineReference lineRef = null; |
||||
string message = String.Empty; |
||||
|
||||
if (result.IsFailure) { |
||||
taskType = TaskType.Error; |
||||
if (!result.StackTraceFilePosition.IsEmpty) { |
||||
lineRef = new FileLineReference(result.StackTraceFilePosition.FileName, result.StackTraceFilePosition.Line - 1, result.StackTraceFilePosition.Column - 1); |
||||
} |
||||
message = GetTestFailedMessage(result); |
||||
} else if (result.IsIgnored) { |
||||
message = GetTestIgnoredMessage(result); |
||||
} |
||||
if (lineRef == null) { |
||||
lineRef = FindTest(result.Name, project); |
||||
} |
||||
FileName fileName = null; |
||||
if (lineRef != null) { |
||||
fileName = new FileName(Path.GetFullPath(lineRef.FileName)); |
||||
int line = lineRef.Line + 1; |
||||
return new Task(fileName, message, lineRef.Column, line, taskType); |
||||
} |
||||
return new Task(fileName, message, 0, 0, taskType); |
||||
} |
||||
|
||||
static string GetTestFailedMessage(TestResult result) |
||||
{ |
||||
string resource = "${res:NUnitPad.NUnitPadContent.TestTreeView.TestFailedMessage}"; |
||||
return GetTestResultMessage(result, resource); |
||||
} |
||||
|
||||
static string GetTestIgnoredMessage(TestResult result) |
||||
{ |
||||
string resource = "${res:NUnitPad.NUnitPadContent.TestTreeView.TestNotExecutedMessage}"; |
||||
return GetTestResultMessage(result, resource); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the test result message if there is on otherwise
|
||||
/// uses the string resource to create a message.
|
||||
/// </summary>
|
||||
static string GetTestResultMessage(TestResult result, string stringResource) |
||||
{ |
||||
if (result.Message.Length > 0) { |
||||
return result.Message; |
||||
} |
||||
return GetTestResultMessageFromResource(result, stringResource); |
||||
} |
||||
|
||||
static string GetTestResultMessageFromResource(TestResult result, string stringResource) |
||||
{ |
||||
return StringParser.Parse(stringResource, new StringTagPair("TestCase", result.Name)); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the location of the specified test member in the
|
||||
/// project being tested.
|
||||
/// </summary>
|
||||
static FileLineReference FindTest(string memberName, TestProject testProject) |
||||
{ |
||||
if (testProject != null) { |
||||
TestMember testMember = testProject.TestClasses.GetTestMember(memberName); |
||||
if (testMember != null) { |
||||
return FindTest(testMember); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
static FileLineReference FindTest(TestMember testMember) |
||||
{ |
||||
MemberResolveResult resolveResult = new MemberResolveResult(null, null, testMember.Member); |
||||
FilePosition filePos = resolveResult.GetDefinitionPosition(); |
||||
return new FileLineReference(filePos.FileName, filePos.Line - 1, filePos.Column - 1); |
||||
} |
||||
} |
||||
} |
@ -1,102 +0,0 @@
@@ -1,102 +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.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for all test tree nodes.
|
||||
/// </summary>
|
||||
public abstract class TestTreeNode : ExtTreeNode |
||||
{ |
||||
TestProject testProject; |
||||
|
||||
public event EventHandler ImageIndexChanged; |
||||
|
||||
public TestTreeNode(TestProject testProject, string text) |
||||
{ |
||||
this.testProject = testProject; |
||||
this.Text = text; |
||||
ImageIndex = (int)TestTreeViewImageListIndex.TestNotRun; |
||||
} |
||||
|
||||
public IProject Project { |
||||
get { |
||||
return testProject.Project; |
||||
} |
||||
} |
||||
|
||||
public TestProject TestProject { |
||||
get { |
||||
return testProject; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Changes the node's icon based on the specified test result.
|
||||
/// </summary>
|
||||
protected void UpdateImageListIndex(TestResultType result) |
||||
{ |
||||
int previousImageIndex = ImageIndex; |
||||
switch (result) { |
||||
case TestResultType.Failure: |
||||
ImageIndex = (int)TestTreeViewImageListIndex.TestFailed; |
||||
break; |
||||
case TestResultType.Success: |
||||
ImageIndex = (int)TestTreeViewImageListIndex.TestPassed; |
||||
break; |
||||
case TestResultType.Ignored: |
||||
ImageIndex = (int)TestTreeViewImageListIndex.TestIgnored; |
||||
break; |
||||
case TestResultType.None: |
||||
ImageIndex = (int)TestTreeViewImageListIndex.TestNotRun; |
||||
break; |
||||
} |
||||
SelectedImageIndex = ImageIndex; |
||||
if (previousImageIndex != ImageIndex) { |
||||
OnImageIndexChanged(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Raises the ImageIndexChanged event.
|
||||
/// </summary>
|
||||
protected void OnImageIndexChanged() |
||||
{ |
||||
if (ImageIndexChanged != null) { |
||||
ImageIndexChanged(this, new EventArgs()); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Checks all the child nodes of this node to see
|
||||
/// if the root namespace (i.e. the first part of the
|
||||
/// namespace) exists in the tree.
|
||||
/// </summary>
|
||||
/// <param name="rootNamespace">The first dotted part
|
||||
/// of the namespace.</param>
|
||||
protected bool NamespaceNodeExists(string rootNamespace) |
||||
{ |
||||
foreach (ExtTreeNode node in Nodes) { |
||||
TestNamespaceTreeNode namespaceNode = node as TestNamespaceTreeNode; |
||||
if (namespaceNode != null && namespaceNode.Text == rootNamespace) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Sorts the immediate child nodes of this node. The sort
|
||||
/// is not done recursively.
|
||||
/// </summary>
|
||||
protected void SortChildNodes() |
||||
{ |
||||
ExtTreeView treeView = (ExtTreeView)TreeView; |
||||
treeView.SortNodes(Nodes, false); |
||||
} |
||||
} |
||||
} |
@ -1,435 +0,0 @@
@@ -1,435 +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.Windows.Forms; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Tree view that shows all the unit tests in a project.
|
||||
/// </summary>
|
||||
public class TestTreeView : ExtTreeView, ITestTreeView, IOwnerState |
||||
{ |
||||
/// <summary>
|
||||
/// The current state of the tree view.
|
||||
/// </summary>
|
||||
[Flags] |
||||
public enum TestTreeViewState { |
||||
None = 0, |
||||
SourceCodeItemSelected = 1 |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The All Tests tree root node that is added if multiple
|
||||
/// test projects exist in the solution. If the solution contains
|
||||
/// only one test project then no such node will be added.
|
||||
/// </summary>
|
||||
AllTestsTreeNode allTestsNode; |
||||
IRegisteredTestFrameworks testFrameworks; |
||||
|
||||
public TestTreeView(IRegisteredTestFrameworks testFrameworks) |
||||
{ |
||||
this.testFrameworks = testFrameworks; |
||||
ImageList = TestTreeViewImageList.ImageList; |
||||
CanClearSelection = false; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the current state of the test tree view.
|
||||
/// </summary>
|
||||
public Enum InternalState { |
||||
get { |
||||
TestTreeNode selectedNode = SelectedNode as TestTreeNode; |
||||
if ((selectedNode is TestClassTreeNode) || (selectedNode is TestMemberTreeNode)) { |
||||
return TestTreeViewState.SourceCodeItemSelected; |
||||
} |
||||
return TestTreeViewState.None; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the solution's projects to the test tree view.
|
||||
/// Only test projects are displayed.
|
||||
/// </summary>
|
||||
public void AddSolution(Solution solution) |
||||
{ |
||||
Clear(); |
||||
AddProjects(solution.Projects); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the projects to the test tree view. Only those projects
|
||||
/// which are determined to have a reference to a supported
|
||||
/// test framework will be added to the tree.
|
||||
/// </summary>
|
||||
public void AddProjects(IEnumerable<IProject> projects) |
||||
{ |
||||
foreach (IProject project in projects) { |
||||
AddProject(project); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the project to the test tree view if the project
|
||||
/// is a test project.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// If the project is already in the tree then it will
|
||||
/// not be added again. If a project is already in the tree then
|
||||
/// an All Tests root node will be added.
|
||||
/// </remarks>
|
||||
public void AddProject(IProject project) |
||||
{ |
||||
if (IsTestProject(project)) { |
||||
if (GetProjectTreeNode(project) == null) { |
||||
AddProjectTreeNode(project); |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool IsTestProject(IProject project) |
||||
{ |
||||
return testFrameworks.IsTestProject(project); |
||||
} |
||||
|
||||
void AddProjectTreeNode(IProject project) |
||||
{ |
||||
TestProjectTreeNode node = CreateProjectTreeNode(project); |
||||
if (node != null) { |
||||
AddProjectTreeNodeToTree(node); |
||||
SortNodes(Nodes, true); |
||||
} |
||||
} |
||||
|
||||
TestProjectTreeNode CreateProjectTreeNode(IProject project) |
||||
{ |
||||
IProjectContent projectContent = GetProjectContent(project); |
||||
if (projectContent != null) { |
||||
TestProject testProject = new TestProject(project, projectContent, testFrameworks); |
||||
return new TestProjectTreeNode(testProject); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
void AddProjectTreeNodeToTree(TestProjectTreeNode node) |
||||
{ |
||||
if (Nodes.Count == 0) { |
||||
node.AddTo(this); |
||||
} else { |
||||
AllTestsTreeNode allTestsNode = GetAllTestsNode(); |
||||
allTestsNode.AddProjectNode(node); |
||||
} |
||||
} |
||||
|
||||
public void RemoveSolutionFolder(ISolutionFolder solutionFolder) |
||||
{ |
||||
IProject project = solutionFolder as IProject; |
||||
if (project != null) { |
||||
RemoveProject(project); |
||||
} |
||||
|
||||
ISolutionFolderContainer solutionFolderContainer = solutionFolder as ISolutionFolderContainer; |
||||
if (solutionFolderContainer != null) { |
||||
foreach (ISolutionFolder subSolutionFolder in solutionFolderContainer.Folders) { |
||||
RemoveSolutionFolder(subSolutionFolder); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the specified project from the test tree view.
|
||||
/// </summary>
|
||||
public void RemoveProject(IProject project) |
||||
{ |
||||
TestProjectTreeNode projectNode = GetProjectTreeNode(project); |
||||
RemoveProjectNode(projectNode); |
||||
RemoveAllTestsNodeIfOnlyOneProjectLeft(); |
||||
} |
||||
|
||||
void RemoveAllTestsNodeIfOnlyOneProjectLeft() |
||||
{ |
||||
if (allTestsNode != null) { |
||||
if (GetProjectNodes().Count == 1) { |
||||
RemoveAllTestsNode(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the projects displayed in the tree.
|
||||
/// </summary>
|
||||
public IProject[] GetProjects() |
||||
{ |
||||
List<IProject> projects = new List<IProject>(); |
||||
foreach (TestProjectTreeNode projectNode in GetProjectNodes()) { |
||||
projects.Add(projectNode.Project); |
||||
} |
||||
return projects.ToArray(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the TestProject associated with the specified project.
|
||||
/// </summary>
|
||||
public TestProject GetTestProject(IProject project) |
||||
{ |
||||
TestProjectTreeNode node = GetProjectTreeNode(project); |
||||
if (node != null) { |
||||
return node.TestProject; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the member of the currently selected tree node.
|
||||
/// </summary>
|
||||
public IMember SelectedMember { |
||||
get { |
||||
TestMemberTreeNode memberNode = SelectedNode as TestMemberTreeNode; |
||||
if (memberNode != null) { |
||||
return memberNode.Member; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the class of the currently selected tree node.
|
||||
/// </summary>
|
||||
public IClass SelectedClass { |
||||
get { |
||||
TestClassTreeNode classNode = SelectedNode as TestClassTreeNode; |
||||
if (classNode == null) { |
||||
classNode = GetClassNodeFromSelectedMemberNode(); |
||||
} |
||||
|
||||
if (classNode != null) { |
||||
return classNode.Class; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
TestClassTreeNode GetClassNodeFromSelectedMemberNode() |
||||
{ |
||||
TestMemberTreeNode memberNode = SelectedNode as TestMemberTreeNode; |
||||
if (memberNode != null) { |
||||
return memberNode.Parent as TestClassTreeNode; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the project associated with the currently selected
|
||||
/// tree node.
|
||||
/// </summary>
|
||||
public IProject SelectedProject { |
||||
get { |
||||
TestProject testProject = SelectedTestProject; |
||||
if (testProject != null) { |
||||
return testProject.Project; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// If a namespace node is selected then the fully qualified namespace
|
||||
/// for this node is returned (i.e. includes the parent namespace prefixed
|
||||
/// to it). For all other nodes this returns null.
|
||||
/// </summary>
|
||||
public string SelectedNamespace { |
||||
get { |
||||
TestNamespaceTreeNode selectedNode = SelectedNode as TestNamespaceTreeNode; |
||||
if (selectedNode != null) { |
||||
return selectedNode.FullNamespace; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the selected test project.
|
||||
/// </summary>
|
||||
public TestProject SelectedTestProject { |
||||
get { |
||||
TestTreeNode selectedNode = SelectedNode as TestTreeNode; |
||||
if (selectedNode != null) { |
||||
return selectedNode.TestProject; |
||||
} |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the classes and members in the test tree view based on the
|
||||
/// parse information.
|
||||
/// </summary>
|
||||
public void UpdateParseInfo(ICompilationUnit oldUnit, ICompilationUnit newUnit) |
||||
{ |
||||
foreach (TestProjectTreeNode projectNode in GetProjectNodes()) { |
||||
TestProject testProject = projectNode.TestProject; |
||||
testProject.UpdateParseInfo(oldUnit, newUnit); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Resets the test results for all the projects in the
|
||||
/// test tree view.
|
||||
/// </summary>
|
||||
public void ResetTestResults() |
||||
{ |
||||
foreach (TestProjectTreeNode projectNode in GetProjectNodes()) { |
||||
TestProject testProject = projectNode.TestProject; |
||||
testProject.ResetTestResults(); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the project content for the specified project.
|
||||
/// </summary>
|
||||
public virtual IProjectContent GetProjectContent(IProject project) |
||||
{ |
||||
return ParserService.GetProjectContent(project); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// A tree node has been selected. Here we make sure the tree node
|
||||
/// uses the context menu strip that the tree view is using. This
|
||||
/// ensures that if the user brings up the context menu using a keyboard
|
||||
/// shortcut (Shift+F10) then it appears over the node rather than in
|
||||
/// the middle of the Unit Tests window.
|
||||
/// </summary>
|
||||
protected override void OnBeforeSelect(TreeViewCancelEventArgs e) |
||||
{ |
||||
TreeNode node = e.Node; |
||||
if (node.ContextMenuStrip == null) { |
||||
node.ContextMenuStrip = ContextMenuStrip; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the project tree node that is associated with the
|
||||
/// specified project.
|
||||
/// </summary>
|
||||
TestProjectTreeNode GetProjectTreeNode(IProject project) |
||||
{ |
||||
foreach (TestProjectTreeNode projectNode in GetProjectNodes()) { |
||||
if (Object.ReferenceEquals(projectNode.Project, project)) { |
||||
return projectNode; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the test project tree nodes taking into account
|
||||
/// if the All Tests root node exists.
|
||||
/// </summary>
|
||||
TreeNodeCollection GetProjectNodes() |
||||
{ |
||||
if (allTestsNode != null) { |
||||
return allTestsNode.Nodes; |
||||
} |
||||
return Nodes; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the project node from the tree.
|
||||
/// </summary>
|
||||
void RemoveProjectNode(TestProjectTreeNode projectNode) |
||||
{ |
||||
if (projectNode != null) { |
||||
if (allTestsNode != null) { |
||||
allTestsNode.RemoveProjectNode(projectNode); |
||||
} else { |
||||
projectNode.Remove(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the All Tests root node which is added if the tree is
|
||||
/// showing multiple test projects. The All Tests root node will
|
||||
/// be added if it does not exist.
|
||||
/// </summary>
|
||||
AllTestsTreeNode GetAllTestsNode() |
||||
{ |
||||
if (allTestsNode == null) { |
||||
AddAllTestsNode(); |
||||
} |
||||
return allTestsNode; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds a new All Tests root node.
|
||||
/// </summary>
|
||||
void AddAllTestsNode() |
||||
{ |
||||
// Save existing nodes (should only be one) before
|
||||
// clearing so we can add these to the new All Tests node.
|
||||
TreeNode[] projectNodes = new TreeNode[Nodes.Count]; |
||||
Nodes.CopyTo(projectNodes, 0); |
||||
Nodes.Clear(); |
||||
|
||||
allTestsNode = new AllTestsTreeNode(); |
||||
allTestsNode.Disposed += AllTestsNodeDisposed; |
||||
Nodes.Add(allTestsNode); |
||||
|
||||
// Add the original project nodes to the new
|
||||
// All Tests node.
|
||||
foreach (TestProjectTreeNode node in projectNodes) { |
||||
allTestsNode.AddProjectNode(node); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Removes the all tests node.
|
||||
/// </summary>
|
||||
void RemoveAllTestsNode() |
||||
{ |
||||
allTestsNode.Remove(); |
||||
|
||||
// Copy project nodes to the root.
|
||||
foreach (TestTreeNode node in allTestsNode.Nodes) { |
||||
Nodes.Add(node); |
||||
} |
||||
|
||||
AllTestsNodeDisposed(null, null); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Ensures that if the TreeView's Clear member is called
|
||||
/// directly the test tree does not think there is still
|
||||
/// an All Tests node.
|
||||
/// </summary>
|
||||
void AllTestsNodeDisposed(object source, EventArgs e) |
||||
{ |
||||
allTestsNode.Disposed -= AllTestsNodeDisposed; |
||||
allTestsNode = null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Adds the test project to the test tree view if it is now recognised as a
|
||||
/// test project and is not already in the test tree.
|
||||
/// </summary>
|
||||
public void ProjectItemAdded(ProjectItem projectItem) |
||||
{ |
||||
AddProject(projectItem.Project); |
||||
} |
||||
|
||||
public void ProjectItemRemoved(ProjectItem projectItem) |
||||
{ |
||||
if (!testFrameworks.IsTestProject(projectItem.Project)) { |
||||
RemoveProject(projectItem.Project); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,55 +0,0 @@
@@ -1,55 +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.Drawing; |
||||
using System.Reflection; |
||||
using System.Windows.Forms; |
||||
using ICSharpCode.Core; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public enum TestTreeViewImageListIndex |
||||
{ |
||||
TestNotRun = 0, |
||||
TestPassed = 1, |
||||
TestFailed = 2, |
||||
TestIgnored = 3 |
||||
} |
||||
|
||||
public class TestTreeViewImageList |
||||
{ |
||||
static ImageList imageList; |
||||
|
||||
TestTreeViewImageList() |
||||
{ |
||||
} |
||||
|
||||
public static ImageList ImageList { |
||||
get { |
||||
if (imageList == null) { |
||||
GetImageList(); |
||||
} |
||||
return imageList; |
||||
} |
||||
} |
||||
|
||||
static void GetImageList() |
||||
{ |
||||
imageList = new ImageList(); |
||||
imageList.ColorDepth = ColorDepth.Depth32Bit; |
||||
|
||||
AddBitmap("Grey.png"); |
||||
AddBitmap("Green.png"); |
||||
AddBitmap("Red.png"); |
||||
AddBitmap("Yellow.png"); |
||||
} |
||||
|
||||
static void AddBitmap(string name) |
||||
{ |
||||
string resourceName = String.Concat("ICSharpCode.UnitTesting.Resources.", name); |
||||
Assembly assembly = typeof(TestTreeViewImageList).Assembly; |
||||
imageList.Images.Add(new Bitmap(assembly.GetManifestResourceStream(resourceName))); |
||||
} |
||||
} |
||||
} |
@ -1,123 +0,0 @@
@@ -1,123 +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.Core; |
||||
using ICSharpCode.SharpDevelop.Bookmarks; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui.ClassBrowser; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
/// <summary>
|
||||
/// Supplies a "Unit test" menu item if the class is a test fixture.
|
||||
/// </summary>
|
||||
public class TestableCondition : IConditionEvaluator |
||||
{ |
||||
IRegisteredTestFrameworks testFrameworks; |
||||
|
||||
public TestableCondition(IRegisteredTestFrameworks testFrameworks) |
||||
{ |
||||
this.testFrameworks = testFrameworks; |
||||
} |
||||
|
||||
public TestableCondition() |
||||
: this(TestService.RegisteredTestFrameworks) |
||||
{ |
||||
} |
||||
|
||||
public static IMember GetMember(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 null; |
||||
} |
||||
|
||||
public static IClass 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; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static IProject GetProject(object caller) |
||||
{ |
||||
ITestTreeView testTreeView = caller as ITestTreeView; |
||||
if (testTreeView != null) { |
||||
return testTreeView.SelectedProject; |
||||
} |
||||
IClass c = GetClassFromMemberOrCaller(caller); |
||||
return GetProject(c); |
||||
} |
||||
|
||||
static IClass GetClassFromMemberOrCaller(object caller) |
||||
{ |
||||
IMember m = GetMember(caller); |
||||
if (m != null) { |
||||
return m.DeclaringType; |
||||
} |
||||
return GetClass(caller); |
||||
} |
||||
|
||||
static IProject GetProject(IClass c) |
||||
{ |
||||
if (c != null) { |
||||
return (IProject)c.ProjectContent.Project; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Returns the namespace selected if any.
|
||||
/// </summary>
|
||||
public static string GetNamespace(object caller) |
||||
{ |
||||
ITestTreeView testTreeView = caller as ITestTreeView; |
||||
if (testTreeView != null) { |
||||
return testTreeView.SelectedNamespace; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public bool IsValid(object caller, Condition condition) |
||||
{ |
||||
IMember m = GetMember(caller); |
||||
if (m != null) { |
||||
return testFrameworks.IsTestMember(m); |
||||
} |
||||
IClass c = GetClass(caller); |
||||
if (ClassHasProject(c)) { |
||||
return testFrameworks.IsTestClass(c); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
static bool ClassHasProject(IClass c) |
||||
{ |
||||
return (c != null) && (c.ProjectContent.Project != null); |
||||
} |
||||
} |
||||
} |
@ -1,119 +0,0 @@
@@ -1,119 +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.Windows.Forms; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class StopTestsCommand : AbstractMenuCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
AbstractRunTestCommand runTestCommand = AbstractRunTestCommand.RunningTestCommand; |
||||
if (runTestCommand != null) { |
||||
runTestCommand.Stop(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class AddNUnitReferenceCommand : AbstractMenuCommand |
||||
{ |
||||
public void Run(IProject project) |
||||
{ |
||||
if (project != null) { |
||||
ReferenceProjectItem nunitRef = new ReferenceProjectItem(project, "nunit.framework"); |
||||
ProjectService.AddProjectItem(project, nunitRef); |
||||
project.Save(); |
||||
} |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
Run(ProjectService.CurrentProject); |
||||
} |
||||
} |
||||
|
||||
public class GotoDefinitionCommand : AbstractMenuCommand |
||||
{ |
||||
IUnitTestFileService fileService; |
||||
|
||||
public GotoDefinitionCommand() |
||||
: this(new UnitTestFileService()) |
||||
{ |
||||
} |
||||
|
||||
public GotoDefinitionCommand(IUnitTestFileService fileService) |
||||
{ |
||||
this.fileService = fileService; |
||||
} |
||||
|
||||
public override void Run() |
||||
{ |
||||
ITestTreeView treeView = Owner as ITestTreeView; |
||||
if (treeView != null) { |
||||
IMember member = GetMember(treeView); |
||||
IClass c = treeView.SelectedClass; |
||||
if (member != null) { |
||||
GotoMember(member); |
||||
} else if (c != null) { |
||||
GotoClass(c); |
||||
} |
||||
} |
||||
} |
||||
|
||||
IMember GetMember(ITestTreeView treeView) |
||||
{ |
||||
IMember member = treeView.SelectedMember; |
||||
if (member != null) { |
||||
BaseTestMember baseTestMethod = member as BaseTestMember; |
||||
if (baseTestMethod != null) { |
||||
return baseTestMethod.Member; |
||||
} |
||||
} |
||||
return member; |
||||
} |
||||
|
||||
void GotoMember(IMember member) |
||||
{ |
||||
MemberResolveResult resolveResult = new MemberResolveResult(null, null, member); |
||||
GotoFilePosition(resolveResult.GetDefinitionPosition()); |
||||
} |
||||
|
||||
void GotoClass(IClass c) |
||||
{ |
||||
TypeResolveResult resolveResult = new TypeResolveResult(null, null, c); |
||||
GotoFilePosition(resolveResult.GetDefinitionPosition()); |
||||
} |
||||
|
||||
void GotoFilePosition(FilePosition filePosition) |
||||
{ |
||||
if (filePosition.Position.IsEmpty) { |
||||
fileService.OpenFile(filePosition.FileName); |
||||
} else { |
||||
fileService.JumpToFilePosition(filePosition.FileName, filePosition.Line - 1, filePosition.Column - 1); |
||||
} |
||||
} |
||||
} |
||||
|
||||
public class CollapseAllTestsCommand : AbstractMenuCommand |
||||
{ |
||||
public override void Run() |
||||
{ |
||||
if (!(this.Owner is TreeView)) |
||||
return; |
||||
|
||||
var treeView = (TreeView)this.Owner; |
||||
treeView.CollapseAll(); |
||||
|
||||
if (treeView.Nodes.Count > 0) { |
||||
treeView.Nodes[0].Expand(); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -1,40 +0,0 @@
@@ -1,40 +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.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestTaskService : IUnitTestTaskService |
||||
{ |
||||
public void ClearExceptCommentTasks() |
||||
{ |
||||
TaskService.ClearExceptCommentTasks(); |
||||
} |
||||
|
||||
public bool InUpdate { |
||||
get { return TaskService.InUpdate; } |
||||
set { TaskService.InUpdate = value; } |
||||
} |
||||
|
||||
public MessageViewCategory BuildMessageViewCategory { |
||||
get { return TaskService.BuildMessageViewCategory; } |
||||
} |
||||
|
||||
public void Add(Task task) |
||||
{ |
||||
TaskService.Add(task); |
||||
} |
||||
|
||||
public bool SomethingWentWrong { |
||||
get { return TaskService.SomethingWentWrong; } |
||||
} |
||||
|
||||
public bool HasCriticalErrors(bool treatWarningsAsErrors) |
||||
{ |
||||
return TaskService.HasCriticalErrors(treatWarningsAsErrors); |
||||
} |
||||
} |
||||
} |
@ -1,106 +0,0 @@
@@ -1,106 +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.Core; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestingOptions |
||||
{ |
||||
/// <summary>
|
||||
/// The name of the options as read from the PropertyService.
|
||||
/// </summary>
|
||||
public static readonly string AddInOptionsName = "UnitTesting.Options"; |
||||
|
||||
/// <summary>
|
||||
/// The name of the noshadow property stored in SharpDevelop's options.
|
||||
/// </summary>
|
||||
public static readonly string NoShadowProperty = "NoShadow"; |
||||
|
||||
/// <summary>
|
||||
/// The name of the nothread property stored in SharpDevelop's options.
|
||||
/// </summary>
|
||||
public static readonly string NoThreadProperty = "NoThread"; |
||||
|
||||
/// <summary>
|
||||
/// The name of the nologo property stored in SharpDevelop's options.
|
||||
/// </summary>
|
||||
public static readonly string NoLogoProperty = "NoLogo"; |
||||
|
||||
/// <summary>
|
||||
/// The name of the nodots property stored in SharpDevelop's options.
|
||||
/// </summary>
|
||||
public static readonly string NoDotsProperty = "NoDots"; |
||||
|
||||
/// <summary>
|
||||
/// The name of the labels property stored in SharpDevelop's options.
|
||||
/// </summary>
|
||||
public static readonly string LabelsProperty = "Labels"; |
||||
|
||||
/// <summary>
|
||||
/// The name of the create xml file property stored in SharpDevelop's options.
|
||||
/// </summary>
|
||||
public static readonly string CreateXmlOutputFileProperty = "CreateXmlOutputFile"; |
||||
|
||||
Properties properties; |
||||
|
||||
public UnitTestingOptions() |
||||
: this(PropertyService.Get(AddInOptionsName, new Properties())) |
||||
{ |
||||
} |
||||
|
||||
public UnitTestingOptions(Properties properties) |
||||
{ |
||||
this.properties = properties; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Disables the use of a separate thread for running tests.
|
||||
/// </summary>
|
||||
public bool NoThread { |
||||
get { return properties.Get<bool>(NoThreadProperty, false); } |
||||
set { properties.Set<bool>(NoThreadProperty, value); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Disables shadow copying of the assemblies being tested.
|
||||
/// </summary>
|
||||
public bool NoShadow { |
||||
get { return properties.Get<bool>(NoShadowProperty, false); } |
||||
set { properties.Set<bool>(NoShadowProperty, value); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Disables the display of the NUnit logo when running NUnit-Console.
|
||||
/// </summary>
|
||||
public bool NoLogo { |
||||
get { return properties.Get<bool>(NoLogoProperty, false); } |
||||
set { properties.Set<bool>(NoLogoProperty, value); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Disables the display of progress when running the unit tests.
|
||||
/// </summary>
|
||||
public bool NoDots { |
||||
get { return properties.Get<bool>(NoDotsProperty, false); } |
||||
set { properties.Set<bool>(NoDotsProperty, value); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Labels each test in the console output.
|
||||
/// </summary>
|
||||
public bool Labels { |
||||
get { return properties.Get<bool>(LabelsProperty, false); } |
||||
set { properties.Set<bool>(LabelsProperty, value); } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Creates an XML output file.
|
||||
/// </summary>
|
||||
public bool CreateXmlOutputFile { |
||||
get { return properties.Get<bool>(CreateXmlOutputFileProperty, false); } |
||||
set { properties.Set<bool>(CreateXmlOutputFileProperty, value); } |
||||
} |
||||
} |
||||
} |
@ -1,77 +0,0 @@
@@ -1,77 +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 ICSharpCode.SharpDevelop.Gui.OptionPanels; |
||||
using System; |
||||
using System.Drawing; |
||||
using System.Windows.Forms; |
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestingOptionsPanel : XmlFormsOptionPanel |
||||
{ |
||||
UnitTestingOptions options; |
||||
CheckBox labelsCheckBox; |
||||
CheckBox showLogoCheckBox; |
||||
CheckBox showProgressCheckBox; |
||||
CheckBox threadCheckBox; |
||||
CheckBox shadowCopyCheckBox; |
||||
CheckBox createXmlOutputFileCheckBox; |
||||
|
||||
public UnitTestingOptionsPanel() : this(new UnitTestingOptions()) |
||||
{ |
||||
} |
||||
|
||||
public UnitTestingOptionsPanel(UnitTestingOptions options) |
||||
{ |
||||
this.options = options; |
||||
} |
||||
|
||||
public override void LoadPanelContents() |
||||
{ |
||||
SetupFromManifestResource("ICSharpCode.UnitTesting.Resources.UnitTestingOptionsPanel.xfrm"); |
||||
|
||||
labelsCheckBox = (CheckBox)ControlDictionary["labelsCheckBox"]; |
||||
labelsCheckBox.Checked = options.Labels; |
||||
|
||||
showLogoCheckBox = (CheckBox)ControlDictionary["showLogoCheckBox"]; |
||||
showLogoCheckBox.Checked = !options.NoLogo; |
||||
|
||||
showProgressCheckBox = (CheckBox)ControlDictionary["showProgressCheckBox"]; |
||||
showProgressCheckBox.Checked = !options.NoDots; |
||||
|
||||
shadowCopyCheckBox = (CheckBox)ControlDictionary["shadowCopyCheckBox"]; |
||||
shadowCopyCheckBox.Checked = !options.NoShadow; |
||||
|
||||
threadCheckBox = (CheckBox)ControlDictionary["threadCheckBox"]; |
||||
threadCheckBox.Checked = !options.NoThread; |
||||
|
||||
createXmlOutputFileCheckBox = (CheckBox)ControlDictionary["createXmlOutputFileCheckBox"]; |
||||
createXmlOutputFileCheckBox.Checked = options.CreateXmlOutputFile; |
||||
} |
||||
|
||||
public override bool StorePanelContents() |
||||
{ |
||||
options.Labels = labelsCheckBox.Checked; |
||||
options.NoLogo = !showLogoCheckBox.Checked; |
||||
options.NoDots = !showProgressCheckBox.Checked; |
||||
options.NoShadow = !shadowCopyCheckBox.Checked; |
||||
options.NoThread = !threadCheckBox.Checked; |
||||
options.CreateXmlOutputFile = createXmlOutputFileCheckBox.Checked; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Calls SetupFromXmlStream after creating a stream from the current
|
||||
/// assembly using the specified manifest resource name.
|
||||
/// </summary>
|
||||
/// <param name="resource">The manifest resource name used to create the stream.</param>
|
||||
protected virtual void SetupFromManifestResource(string resource) |
||||
{ |
||||
SetupFromXmlStream(typeof(UnitTestingOptionsPanel).Assembly.GetManifestResourceStream(resource)); |
||||
} |
||||
} |
||||
} |
@ -1,332 +0,0 @@
@@ -1,332 +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.Windows.Forms; |
||||
|
||||
using ICSharpCode.Core; |
||||
using ICSharpCode.Core.WinForms; |
||||
using ICSharpCode.SharpDevelop; |
||||
using ICSharpCode.SharpDevelop.Dom; |
||||
using ICSharpCode.SharpDevelop.Gui; |
||||
using ICSharpCode.SharpDevelop.Project; |
||||
|
||||
namespace ICSharpCode.UnitTesting |
||||
{ |
||||
public class UnitTestsPad : AbstractPadContent, IUnitTestsPad |
||||
{ |
||||
TestTreeView treeView; |
||||
bool disposed; |
||||
Panel panel; |
||||
ToolStrip toolStrip; |
||||
List<ICompilationUnit[]> pending = new List<ICompilationUnit[]>(); |
||||
static UnitTestsPad instance; |
||||
|
||||
public UnitTestsPad() |
||||
: this(TestService.RegisteredTestFrameworks) |
||||
{ |
||||
} |
||||
|
||||
public UnitTestsPad(IRegisteredTestFrameworks testFrameworks) |
||||
{ |
||||
instance = this; |
||||
|
||||
panel = new Panel(); |
||||
treeView = CreateTestTreeView(testFrameworks); |
||||
treeView.Dock = DockStyle.Fill; |
||||
treeView.DoubleClick += TestTreeViewDoubleClick; |
||||
treeView.KeyPress += TestTreeViewKeyPress; |
||||
panel.Controls.Add(treeView); |
||||
|
||||
toolStrip = CreateToolStrip("/SharpDevelop/Pads/UnitTestsPad/Toolbar"); |
||||
toolStrip.GripStyle = ToolStripGripStyle.Hidden; |
||||
panel.Controls.Add(toolStrip); |
||||
|
||||
// Add the load solution projects thread ended handler before
|
||||
// we try to display the open solution so the event does not
|
||||
// get missed.
|
||||
ParserService.LoadSolutionProjectsThreadEnded += LoadSolutionProjectsThreadEnded; |
||||
OnAddedLoadSolutionProjectsThreadEndedHandler(); |
||||
|
||||
// Display currently open solution.
|
||||
if (!IsParserLoadingSolution) { |
||||
Solution openSolution = GetOpenSolution(); |
||||
if (openSolution != null) { |
||||
SolutionLoaded(openSolution); |
||||
} |
||||
} |
||||
|
||||
ParserService.ParseInformationUpdated += ParseInformationUpdated; |
||||
ProjectService.SolutionClosed += SolutionClosed; |
||||
ProjectService.SolutionFolderRemoved += SolutionFolderRemoved; |
||||
ProjectService.ProjectAdded += ProjectAdded; |
||||
ProjectService.ProjectItemAdded += ProjectItemAdded; |
||||
ProjectService.ProjectItemRemoved += ProjectItemRemoved; |
||||
|
||||
treeView.ContextMenuStrip = CreateContextMenu("/SharpDevelop/Pads/UnitTestsPad/ContextMenu"); |
||||
} |
||||
|
||||
public static UnitTestsPad Instance { |
||||
get { return instance; } |
||||
} |
||||
|
||||
public override object Control { |
||||
get { return panel; } |
||||
} |
||||
|
||||
public override void Dispose() |
||||
{ |
||||
if (!disposed) { |
||||
disposed = true; |
||||
treeView.Dispose(); |
||||
treeView = null; |
||||
|
||||
ProjectService.ProjectItemRemoved -= ProjectItemRemoved; |
||||
ProjectService.ProjectItemAdded -= ProjectItemAdded; |
||||
ProjectService.ProjectAdded -= ProjectAdded; |
||||
ProjectService.SolutionFolderRemoved -= SolutionFolderRemoved; |
||||
ProjectService.SolutionClosed -= SolutionClosed; |
||||
ParserService.ParseInformationUpdated -= ParseInformationUpdated; |
||||
ParserService.LoadSolutionProjectsThreadEnded -= LoadSolutionProjectsThreadEnded; |
||||
} |
||||
} |
||||
|
||||
public TestTreeView TestTreeView { |
||||
get { return treeView; } |
||||
} |
||||
|
||||
public void ResetTestResults() |
||||
{ |
||||
treeView.ResetTestResults(); |
||||
} |
||||
|
||||
public IProject[] GetProjects() |
||||
{ |
||||
return treeView.GetProjects(); |
||||
} |
||||
|
||||
public TestProject GetTestProject(IProject project) |
||||
{ |
||||
return treeView.GetTestProject(project); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Updates the state of the buttons on the Unit Tests pad's
|
||||
/// toolbar.
|
||||
/// </summary>
|
||||
public void UpdateToolbar() |
||||
{ |
||||
ToolbarService.UpdateToolbar(toolStrip); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Collapses all nodes.
|
||||
/// </summary>
|
||||
public void CollapseAll() |
||||
{ |
||||
if (treeView == null || treeView.Nodes == null || treeView.Nodes.Count == 0) |
||||
return; |
||||
|
||||
treeView.CollapseAll(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called when a solution has been loaded.
|
||||
/// </summary>
|
||||
protected void SolutionLoaded(Solution solution) |
||||
{ |
||||
// SolutionLoaded will be invoked from another thread.
|
||||
// The UnitTestsPad might be disposed by the time the event is processed by the main thread.
|
||||
if (treeView != null) { |
||||
if (solution != null) { |
||||
treeView.AddSolution(solution); |
||||
} else { |
||||
treeView.Clear(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Called when a solution has been closed.
|
||||
/// </summary>
|
||||
protected void SolutionClosed() |
||||
{ |
||||
treeView.Clear(); |
||||
} |
||||
|
||||
protected void SolutionFolderRemoved(ISolutionFolder solutionFolder) |
||||
{ |
||||
treeView.RemoveSolutionFolder(solutionFolder); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// The project is added to the tree view only if it has a
|
||||
/// reference to a unit testing framework.
|
||||
/// </summary>
|
||||
protected void ProjectAdded(IProject project) |
||||
{ |
||||
treeView.AddProject(project); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// If the project item removed is a reference to a unit
|
||||
/// test framework then the project will be removed from the
|
||||
/// test tree.
|
||||
/// </summary>
|
||||
protected void ProjectItemRemoved(ProjectItem projectItem) |
||||
{ |
||||
treeView.ProjectItemRemoved(projectItem); |
||||
} |
||||
|
||||
protected void ProjectItemAdded(ProjectItem projectItem) |
||||
{ |
||||
treeView.ProjectItemAdded(projectItem); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Protected method so we can test this method.
|
||||
/// </summary>
|
||||
protected void UpdateParseInfo(ICompilationUnit oldUnit, ICompilationUnit newUnit) |
||||
{ |
||||
treeView.UpdateParseInfo(oldUnit, newUnit); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Virtual method so we can override this method and return
|
||||
/// a dummy toolstrip when testing.
|
||||
/// </summary>
|
||||
protected virtual ToolStrip CreateToolStrip(string name) |
||||
{ |
||||
return ToolbarService.CreateToolStrip(treeView, name); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Virtual method so we can override this method and return
|
||||
/// a dummy ContextMenuStrip when testing.
|
||||
/// </summary>
|
||||
protected virtual ContextMenuStrip CreateContextMenu(string name) |
||||
{ |
||||
return MenuService.CreateContextMenu(treeView, name); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Virtual method so we can override this method and return
|
||||
/// a dummy TestTreeView when testing.
|
||||
/// </summary>
|
||||
protected virtual TestTreeView CreateTestTreeView(IRegisteredTestFrameworks testFrameworks) |
||||
{ |
||||
return new TestTreeView(testFrameworks); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets the currently open solution.
|
||||
/// </summary>
|
||||
protected virtual Solution GetOpenSolution() |
||||
{ |
||||
return ProjectService.OpenSolution; |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Determines whether the parser is currently still loading the
|
||||
/// solution.
|
||||
/// </summary>
|
||||
protected virtual bool IsParserLoadingSolution { |
||||
get { return ParserService.LoadSolutionProjectsThreadRunning; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Indicates that an event handler for the ParserService's
|
||||
/// LoadSolutionProjectsThreadEnded event has been added
|
||||
/// </summary>
|
||||
protected virtual void OnAddedLoadSolutionProjectsThreadEndedHandler() |
||||
{ |
||||
} |
||||
|
||||
void SolutionClosed(object source, EventArgs e) |
||||
{ |
||||
SolutionClosed(); |
||||
UpdateToolbar(); |
||||
} |
||||
|
||||
void SolutionFolderRemoved(object source, SolutionFolderEventArgs e) |
||||
{ |
||||
SolutionFolderRemoved(e.SolutionFolder); |
||||
UpdateToolbar(); |
||||
} |
||||
|
||||
void ProjectAdded(object source, ProjectEventArgs e) |
||||
{ |
||||
ProjectAdded(e.Project); |
||||
UpdateToolbar(); |
||||
} |
||||
|
||||
void LoadSolutionProjectsThreadEnded(object source, EventArgs e) |
||||
{ |
||||
WorkbenchSingleton.SafeThreadAsyncCall(UpdateToolbar); |
||||
Solution solution = ProjectService.OpenSolution; |
||||
WorkbenchSingleton.SafeThreadAsyncCall(SolutionLoaded, solution); |
||||
} |
||||
|
||||
void ParseInformationUpdated(object source, ParseInformationEventArgs e) |
||||
{ |
||||
lock (pending) { |
||||
ICompilationUnit[] units = new ICompilationUnit[] {e.OldCompilationUnit, e.NewCompilationUnit}; |
||||
pending.Add(units); |
||||
} |
||||
WorkbenchSingleton.SafeThreadAsyncCall(UpdateParseInfo); |
||||
} |
||||
|
||||
void UpdateParseInfo() |
||||
{ |
||||
lock (pending) { |
||||
foreach (ICompilationUnit[] units in pending) { |
||||
UpdateParseInfo(units[0], units[1]); |
||||
} |
||||
pending.Clear(); |
||||
} |
||||
} |
||||
|
||||
void TestTreeViewDoubleClick(object source, EventArgs e) |
||||
{ |
||||
GotoDefinition(); |
||||
} |
||||
|
||||
void TestTreeViewKeyPress(object source, KeyPressEventArgs e) |
||||
{ |
||||
if (e.KeyChar == '\r') { |
||||
e.Handled = true; |
||||
GotoDefinition(); |
||||
} else if (e.KeyChar == ' ') { |
||||
e.Handled = true; |
||||
RunTests(); |
||||
} |
||||
} |
||||
|
||||
void GotoDefinition() |
||||
{ |
||||
RunCommand(new GotoDefinitionCommand()); |
||||
} |
||||
|
||||
void RunTests() |
||||
{ |
||||
RunCommand(new RunTestInPadCommand()); |
||||
} |
||||
|
||||
void RunCommand(ICommand command) |
||||
{ |
||||
command.Owner = treeView; |
||||
command.Run(); |
||||
} |
||||
|
||||
void ProjectItemAdded(object source, ProjectItemEventArgs e) |
||||
{ |
||||
ProjectItemAdded(e.ProjectItem); |
||||
} |
||||
|
||||
void ProjectItemRemoved(object source, ProjectItemEventArgs e) |
||||
{ |
||||
ProjectItemRemoved(e.ProjectItem); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue